Customify – A Theme Customizer Booster - Version 1.7.4

Version Description

  • Reorganized Customizer custom sections and grouped them into Theme Options, thus making the Style Manager panel stand out.
  • Refactored parts for more performance and clarity.
Download this release

Release Info

Developer vlad.olaru
Plugin Icon Customify – A Theme Customizer Booster
Version 1.7.4
Comparing to
See all releases

Code changes from version 1.7.3 to 1.7.4

Files changed (39) hide show
  1. +development.rb +0 -5
  2. +production.rb +0 -6
  3. README.md +0 -490
  4. class-pixcustomify.php +93 -40
  5. core/.gitattributes +0 -14
  6. core/.gitignore +0 -52
  7. css/customizer.css +252 -95
  8. customify.php +4 -4
  9. features/class-Font_Selector.php +53 -8
  10. features/customizer/controls/class-Pix_Customize_Font_Control.php +97 -49
  11. features/customizer/controls/class-Pix_Customize_Preset_Control.php +77 -7
  12. features/customizer/controls/class-Pix_Customize_Textarea_Control.php +2 -1
  13. gulpfile.js +0 -210
  14. includes/class-customify-color-palettes.php +890 -0
  15. includes/class-customify-font-palettes.php +1473 -0
  16. includes/class-customify-style-manager.php +192 -971
  17. includes/class-customify-theme-configs.php +378 -0
  18. includes/{class-customify-array.php → lib/class-customify-array.php} +0 -0
  19. includes/lib/class-customify-cloud-api.php +199 -0
  20. includes/lib/class-customify-design-assets.php +240 -0
  21. js/ace/mode-plain_text.js +0 -0
  22. js/customizer.js +62 -619
  23. js/customizer/color-palettes-variations.js +68 -0
  24. js/customizer/color-palettes.js +521 -0
  25. js/customizer/customify-palette-variations.js +48 -48
  26. js/customizer/customify-palettes.js +22 -77
  27. js/customizer/font-palettes-variations.js +11 -0
  28. js/customizer/font-palettes.js +350 -0
  29. js/customizer/font-select-fields.js +449 -0
  30. js/customizer/scale-iframe.js +55 -0
  31. js/customizer/style-manager.js +158 -0
  32. js/customizer/swap-values.js +45 -0
  33. js/customizer_preview.js +109 -52
  34. package-lock.json +0 -4776
  35. package.json +0 -22
  36. palettes.md +137 -0
  37. readme.txt +7 -3
  38. scss/customizer.scss +212 -34
  39. settings/general.php +6 -0
+development.rb DELETED
@@ -1,5 +0,0 @@
1
- #!/usr/bin/env ruby
2
-
3
- # run compass compiler
4
- puts 'Compass/Sass now running in the background.'
5
- Kernel.exec('sass --watch --compass --sourcemap scss:css --style expanded -E utf-8 2> /dev/null')
 
 
 
 
 
+production.rb DELETED
@@ -1,6 +0,0 @@
1
- #!/usr/bin/env ruby
2
-
3
- # change to script
4
- Dir.chdir File.expand_path(File.dirname(__FILE__))
5
- # run compass compiler
6
- Kernel.exec('sass --compass --force --update scss:css --style expanded -E utf-8 2> /dev/null')
 
 
 
 
 
 
README.md DELETED
@@ -1,490 +0,0 @@
1
- Customify [![Build Status](https://travis-ci.org/pixelgrade/customify.svg?branch=wporg)](https://travis-ci.org/pixelgrade/customify) [![Code Climate](https://lima.codeclimate.com/github/pixelgrade/customify/badges/gpa.svg)](https://lima.codeclimate.com/github/pixelgrade/customify) [![Issue Count](https://lima.codeclimate.com/github/pixelgrade/customify/badges/issue_count.svg)](https://lima.codeclimate.com/github/pixelgrade/customify)
2
- ========
3
- **A Theme Customizer Booster**
4
-
5
- With Customify, you can easily add Fonts, Colors, Live CSS Editor and other options to your theme.
6
-
7
- ### How to use it?
8
-
9
- First you need to install and activate the stable version. This will always be on [wordpress.org](https://wordpress.org/plugins/customify/)
10
-
11
- Now go to ‘Appearance -> Customize’ menu and have fun with the new fields.
12
-
13
- ### Make your own customizer
14
-
15
- So this plugin adds some fields in customizer, no big deal right? How about adding your own customizer fields?
16
-
17
- The Customify [$config](#about_config_var) can be filtered by any theme and this is how you do it, include this filter in your theme(probably in functions.php)
18
-
19
- ```
20
- // Advice: change this function's name and make sure it is unique
21
-
22
- add_filter('customify_filter_fields', 'make_this_function_name_unique' );
23
-
24
- function make_this_function_name_unique( $config ) {
25
-
26
- // usually the sections key will be here, but a check won't hurt
27
- if ( ! isset($config['sections']) ) {
28
- $config['sections'] = array();
29
- }
30
-
31
- // this means that we add a new entry named "theme_added_settings" in the sections area
32
- $config['sections']['theme_added_settings'] = array(
33
- 'title' => 'Section added dynamically',
34
- 'settings' => array(
35
-
36
- // this is the field id and it must be unique
37
- 'field_example' => array(
38
- 'type' => 'color', // there is a list of types below
39
- 'label' => 'Body color', // the label is optional but is nice to have one
40
- 'css' => array(
41
-
42
- // the CSS key is the one which controls the output of this field
43
- array(
44
- // a CSS selector
45
- 'selector' => '#logo',
46
- // the CSS property which should be affected by this field
47
- 'property' => 'background-color',
48
- )
49
-
50
- // repeat this as long as you need
51
- array(
52
- 'selector' => 'body',
53
- 'property' => 'color',
54
- )
55
- )
56
- )
57
- )
58
- );
59
-
60
- // when working with filters always return filtered value
61
- return $config;
62
- }
63
- ```
64
-
65
- The Customify plugin also create's its own defaults this way. You can see that in `customify/customify_config.php`
66
- Personally I like to simply copy this file in my child theme and include it in `functions.php` with
67
-
68
- `require 'customify_config.php'`
69
-
70
- And after that the sky is the limit, I can style any elements or group of elements in customizer.
71
-
72
- The intro is over let's get to some advanced stuff.
73
-
74
- # List of fields
75
-
76
- Fields<a name="list_of_fields"></a> | [Live Preview Support!](#live_preview_support) | Description
77
- ------------- | ------------- | -------------
78
- Text | Yes [with classes](#live_preview_with_classes) | A simple text input
79
- Textarea | Yes [with classes](#live_preview_with_classes) | A simple text area input
80
- Ace Editor | Yes [with classes](#live_preview_with_classes) | An ace editor that supports plain_text / css / html / javascript / json / markdown
81
- Color | Yes | A simple color picker
82
- Range | Yes | The default html5 range input
83
- Font | Custom Live Preview | A complete font selector with Live Preview, google fonts, filtrable theme fonts and custom callbacks
84
- Typography | No | This is a font selector but it will be soon depricated, use Font instead
85
- Select | No | The standard HTML select
86
- Radio | No |
87
- Checkbox | No |
88
- Upload | No | This field allows you to upload a file which you can use it later in front-end
89
- Image | No | This is like the upload field, but it accepts only images
90
- Date | No |
91
- Pages select | No | The standard WordPress Page Select
92
- [Select2](https://select2.github.io/) | No | An awesome select
93
- [Presets](#presets_title) | No | An radio input option to select a group of options (inception style ^^)
94
-
95
- # Advanced Things
96
-
97
- ### The $config variable<a name="about_config_var"></a> ###
98
-
99
- This is the array which is processed by the `customify_filter_fields` filter and it contains:
100
- * 'sections' an array with sections(each section holds an array with fields)
101
- * 'panels' an array of panels( each panel holds an array with sections)
102
- * 'opt-name' the option key name which will hold all these options
103
-
104
- ### Media queries<a name="media_query_config"></a>
105
-
106
- The `css` configuration can also hold a `media` parameter which will make the output of the CSS property, to wrap in the specified media query, for example:
107
-
108
- ```
109
- 'site_title_size' => array(
110
- 'type' => 'range',
111
- 'label' => 'Site Title Size',
112
- 'default' => 24,
113
- 'css' => array(
114
- array(
115
- 'property' => 'font-size',
116
- 'selector' => '.site-title',
117
- 'media' => 'screen and (min-width: 1000px)'
118
- )
119
- )
120
- )
121
- ```
122
-
123
- This will make the property take effect only on screens larger than 1000px, because on mobile devices you may not want a bigger logo.
124
-
125
- ### Field callbacks<a name="callback_example"></a>
126
-
127
- Each field can take a 'callback_filter' parameter.This should be a function name which should be called when a field is changed.
128
-
129
- For example let's take this range field:
130
- ```
131
- 'sidebar_width' => array(
132
- 'type' => 'range',
133
- 'label' => 'Sidebar width',
134
- 'input_attrs' => array(
135
- 'min' => 60,
136
- 'max' => 320,
137
- 'step' => 60,
138
- ),
139
- 'css' => array(
140
- array(
141
- 'selector' => 'span.col',
142
- 'property' => 'width',
143
- 'unit' => 'px',
144
- 'callback_filter' => 'this_setting_can_call_this_function'
145
- )
146
- )
147
- )
148
-
149
- ```
150
-
151
- Now let's create a callback which multiplies the effect of this css property
152
- Let's say that we want the sidebar to grow faster in length and double its value when the slider is changed
153
-
154
- ```
155
- function this_setting_can_call_this_function( $value, $selector, $property, $unit ) {
156
-
157
- $this_property_output = $selector . ' { '. $property .': '. ( $value * 2 ) . $unit . "; } \n";
158
-
159
- return $this_property_output;
160
- }
161
-
162
- ```
163
-
164
- HTML field | No | A field which allows you to add custom HTML in customizer and hook into it with javascript later ;)
165
-
166
- ### Live Preview Support<a name="live_preview_support"></a>
167
-
168
- There are a few fields which support this feature for now, but those are awesome.These fields are capable to update the previewer iframe without refreshing the iframe, the preview should be instant.
169
-
170
- This is recommended for color fields because you won't need to stop drag-and-dropping the color select to see what color would be better.
171
-
172
- **Note<a name="live_preview_with_classes"></a>**
173
- All the text fields have support for a **live preview** but they require an array of classes instead of the boolean `true` for the `live` parameter.
174
-
175
- For example a fields which would provide the copyright text from footer whould be like this:
176
- ```
177
- 'footer_copyright' => array(
178
- 'type' => 'text',
179
- 'label' => 'Footer Copyright'
180
- 'default' => 'All contents &copy; Pixelgrade 2011-2015'
181
- 'sanitize_callback' => 'wp_kses_post',
182
- 'live' => array( '.copyright-class' )
183
- )
184
- ```
185
-
186
- For this example the element with the `.copyright-class` class will get the text replaced as soon as the user types a
187
- new text. I bet this is awesome.
188
-
189
-
190
- ### Conditional fields<a name="conditional_fields"></a>
191
-
192
- Along with version 1.2.3 we've added support for conditional fields. This means that you can use the `show_if` argument
193
- to display a field only when another field has a certain value.
194
-
195
- This [gist](https://gist.github.com/andreilupu/3a71618fb6d2ea2c2b1429544c667cd1) shows how this can be done.
196
-
197
- ### Presets<a name="presets_title"></a>
198
-
199
- Since version 1.1.0 we added support for presets options. With this fields, you can pre-define other options.
200
- Here is and example of how to config this.
201
-
202
- ```
203
- 'theme_style' => array(
204
- 'type' => 'preset',
205
- 'label' => __( 'Select a style:', 'customify' ),
206
- 'desc' => __( 'Conveniently change the design of your site with built-in style presets. Easy as pie.', 'customify' ),
207
- 'default' => 'silk',
208
- 'choices_type' => 'select',
209
- 'choices' => array(
210
- 'silk' => array(
211
- 'label' => __( 'Silk', 'customify' ),
212
- 'options' => array(
213
- 'links_color' => '#FAC2A8', //second
214
- 'headings_color' => '#A84469', //main
215
- 'body_color' => '#ffffff', // -
216
- 'headings_font' => 'Playfair Display', //main
217
- 'body_font' => 'Merriweather'
218
- )
219
- ),
220
- 'red' => array(
221
- 'label' => __( 'Urban', 'customify' ),
222
- 'options' => array(
223
- 'links_color' => 'red',
224
- 'headings_color' => 'red',
225
- 'body_color' => 'red',
226
- 'headings_font' => 'Exo',
227
- 'body_font' => 'Pacifico'
228
- )
229
- ),
230
- 'black' => array(
231
- 'label' => __( 'Black', 'customify' ),
232
- 'options' => array(
233
- 'links_color' => '#ebebeb',
234
- 'headings_color' => '#333',
235
- 'body_color' => '#989898',
236
- 'headings_font' => 'Arvo',
237
- 'body_font' => 'Lora'
238
- )
239
- ),
240
- )
241
- )
242
- ```
243
-
244
- The above example will output a select which will change all the fields configured in the `options` array.
245
-
246
- If you don't like the select type, at `choices_type` you can choose between `select`, `button` and an `awesome` radio select which allows you to not only change the font-end options but also the preview button style.
247
-
248
- Wanna have a preset like this?
249
-
250
- ![img](https://cloud.githubusercontent.com/assets/1893980/6652930/86b7a1aa-ca88-11e4-8997-ba63be1598d8.png)
251
-
252
- Just add this section in your config
253
-
254
- ```
255
- 'presets_section' => array(
256
- 'title' => __( 'Style Presets', 'customify' ),
257
- 'options' => array(
258
- 'theme_style' => array(
259
- 'type' => 'preset',
260
- 'label' => __( 'Select a style:', 'customify' ),
261
- 'desc' => __( 'Conveniently change the design of your site with built-in style presets. Easy as pie.', 'customify' ),
262
- 'default' => 'royal',
263
- 'choices_type' => 'awesome',
264
- 'choices' => array(
265
- 'royal' => array(
266
- 'label' => __( 'Royal', 'customify' ),
267
- 'preview' => array(
268
- 'color-text' => '#ffffff',
269
- 'background-card' => '#615375',
270
- 'background-label' => '#46414c',
271
- 'font-main' => 'Abril Fatface',
272
- 'font-alt' => 'PT Serif',
273
- ),
274
- 'options' => array(
275
- 'links_color' => '#8eb2c5',
276
- 'headings_color' => '#725c92',
277
- 'body_color' => '#6f8089',
278
- 'page_background' => '#615375',
279
- 'headings_font' => 'Abril Fatface',
280
- 'body_font' => 'PT Serif',
281
- )
282
- ),
283
- 'lovely' => array(
284
- 'label' => __( 'Lovely', 'customify' ),
285
- 'preview' => array(
286
- 'color-text' => '#ffffff',
287
- 'background-card' => '#d15c57',
288
- 'background-label' => '#5c374b',
289
- 'font-main' => 'Playfair Display',
290
- 'font-alt' => 'Playfair Display',
291
- ),
292
- 'options' => array(
293
- 'links_color' => '#cc3747',
294
- 'headings_color' => '#d15c57',
295
- 'body_color' => '#5c374b',
296
- 'page_background' => '#d15c57',
297
- 'headings_font' => 'Playfair Display',
298
- 'body_font' => 'Playfair Display',
299
- )
300
- ),
301
- 'queen' => array(
302
- 'label' => __( 'Queen', 'customify' ),
303
- 'preview' => array(
304
- 'color-text' => '#fbedec',
305
- 'background-card' => '#773347',
306
- 'background-label' => '#41212a',
307
- 'font-main' => 'Cinzel Decorative',
308
- 'font-alt' => 'Gentium Basic',
309
- ),
310
- 'options' => array(
311
- 'links_color' => '#cd8085',
312
- 'headings_color' => '#54323c',
313
- 'body_color' => '#cd8085',
314
- 'page_background' => '#fff',
315
- 'headings_font' => 'Cinzel Decorative',
316
- 'body_font' => 'Gentium Basic',
317
- )
318
- ),
319
- 'carrot' => array(
320
- 'label' => __( 'Carrot', 'customify' ),
321
- 'preview' => array(
322
- 'color-text' => '#ffffff',
323
- 'background-card' => '#df421d',
324
- 'background-label' => '#85210a',
325
- 'font-main' => 'Oswald',
326
- 'font-alt' => 'PT Sans Narrow',
327
- ),
328
- 'options' => array(
329
- 'links_color' => '#df421d',
330
- 'headings_color' => '#df421d',
331
- 'body_color' => '#7e7e7e',
332
- 'page_background' => '#fff',
333
- 'headings_font' => 'Oswald',
334
- 'body_font' => 'PT Sans Narrow',
335
- )
336
- ),
337
- 'adler' => array(
338
- 'label' => __( 'Adler', 'customify' ),
339
- 'preview' => array(
340
- 'color-text' => '#fff',
341
- 'background-card' => '#0e364f',
342
- 'background-label' => '#000000',
343
- 'font-main' => 'Permanent Marker',
344
- 'font-alt' => 'Droid Sans Mono',
345
- ),
346
- 'options' => array(
347
- 'links_color' => '#68f3c8',
348
- 'headings_color' => '#0e364f',
349
- 'body_color' => '#45525a',
350
- 'page_background' => '#ffffff',
351
- 'headings_font' => 'Permanent Marker',
352
- 'body_font' => 'Droid Sans Mono'
353
- )
354
- ),
355
- 'velvet' => array(
356
- 'label' => __( 'Velvet', 'customify' ),
357
- 'preview' => array(
358
- 'color-text' => '#ffffff',
359
- 'background-card' => '#282828',
360
- 'background-label' => '#000000',
361
- 'font-main' => 'Pinyon Script',
362
- 'font-alt' => 'Josefin Sans',
363
- ),
364
- 'options' => array(
365
- 'links_color' => '#000000',
366
- 'headings_color' => '#000000',
367
- 'body_color' => '#000000',
368
- 'page_background' => '#000000',
369
- 'headings_font' => 'Pinyon Script',
370
- 'body_font' => 'Josefin Sans',
371
- )
372
- ),
373
- )
374
- ),
375
- )
376
- )
377
- ```
378
-
379
-
380
- ### Font Selector<a name="font_selector"></a>
381
-
382
- In 1.3.0 we introduced the new font selector, it works with live preview only and it has this possible configs:
383
-
384
- ```
385
- 'headings_font' => array(
386
- 'type' => 'font',
387
- 'label' => esc_html__( 'Headings', 'customify' ),
388
- 'desc' => esc_html__( 'o descriere', 'customify' ),
389
- 'selector' => 'h1, h2, h3, h4, .title, .sub-title',
390
-
391
- // Set the defaults
392
- 'default' => array(
393
- 'font-family' => 'Open Sans',
394
- 'font-weight' => '400',
395
- 'font-size' => 24,
396
- 'line-height' => 1.5,
397
- 'letter-spacing' => 1,
398
- 'text-align' => 'initial',
399
- 'text-transform' => 'uppercase',
400
- 'text-decoration' => 'underline'
401
- ),
402
-
403
- //'load_all_weights' => true,
404
-
405
- 'recommended' => $recommended_headings_fonts, // List of recommended fonts defined by theme
406
-
407
- // Sub Fields Configuration (optional)
408
- 'fields' => array(
409
- 'font-size' => array( // Set custom values for a range slider
410
- 'min' => 10,
411
- 'max' => 40,
412
- 'step' => 1,
413
- 'unit' => 'px',
414
- ),
415
- 'line-height' => array(0, 2, 0.1, ''), // Short-hand version
416
- 'letter-spacing' => array(-1, 4, 0.1, 'em'),
417
- 'text-align' => true, // Disable sub-field (False by default)
418
- 'text-transform' => true,
419
- 'text-decoration'=> true,
420
- ),
421
- 'callback' => 'your_custom_callback_function'
422
- ),
423
- ```
424
-
425
- In the above example you can see the callback parameter, it supports a PHP or Javascript function
426
- which should replace the current output of the font
427
-
428
- ```
429
- function your_custom_callback_function( $value, $font ) {
430
- return $combined_css';
431
- }
432
-
433
- function add_javascript_callback_function() { ?>
434
- <script>
435
- function your_custom_callback_function( $values, field ) {
436
- return $combined_css;
437
- }
438
-
439
- </script>
440
- <?php }
441
- add_action( 'customize_preview_init', 'add_javascript_callback_function' );
442
- ```
443
-
444
-
445
- ### Local Fonts
446
-
447
- Also this font selector comes with the ability to add custom fonts from a theme.
448
- If a theme comes with the name of a font and a stylesheet with its fontface it
449
- will be added as the first option of the font selector
450
- ```
451
- function theme_add_customify_theme_fonts ( $fonts ) {
452
- $fonts['Custom Font'] = array(
453
- 'family' => 'Custom Font',
454
- 'src' => get_template_directory_uri() . '/assets/fonts/custom_font/stylesheet.css',
455
- 'variants' => array( '400', '700' )
456
- );
457
- return $fonts;
458
- }
459
- add_filter( 'customify_theme_fonts', 'theme_add_customify_theme_fonts' );
460
- ```
461
-
462
- # Developer Love
463
-
464
- We know developers are a special kind of breed and they need special kinds of treats. That is why we have introduced options dedicated to them.
465
-
466
- ### Reset Buttons
467
-
468
- In the plugin's settings page (*WP Dashboard > Settings > Customify*) you will find a checkbox called **Enable Reset Buttons** that once activated will show a new Customizer section called **Customify Toolbox** and also introduce buttons in each section or panel configured via the plugin.
469
-
470
- All these buttons will reset the options to their default values.
471
-
472
- ### Continuous Default Values
473
-
474
- If you want to go even further, there is a nuclear option. Simply define the `CUSTOMIFY_DEV_FORCE_DEFAULTS` constant to `true` and everywhere the default value will be used. You can play with the values in the Customizer and the live preview will work, but no value gets saved in the database.
475
-
476
- Add this in your `wp-config.php` file:
477
- ```php
478
- define( 'CUSTOMIFY_DEV_FORCE_DEFAULTS', true);
479
- ```
480
-
481
- ## License
482
-
483
- GPLv2 and later, of course!
484
-
485
- ## Thanks!
486
- This plugin also includes the following libraries:
487
-
488
- * Select 2 - https://select2.github.io/
489
- * Ace Editor - https://ace.c9.io/
490
- * React jQuery Plugin - https://github.com/natedavisolds/jquery-react
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
class-pixcustomify.php CHANGED
@@ -44,13 +44,6 @@ class PixCustomifyPlugin {
44
  */
45
  protected $plugin_screen_hook_suffix = null;
46
 
47
- /**
48
- * Path to the plugin.
49
- * @since 1.0.0
50
- * @var string
51
- */
52
- protected $plugin_basepath = null;
53
-
54
  public $display_admin_menu = false;
55
 
56
  private $config;
@@ -147,9 +140,6 @@ class PixCustomifyPlugin {
147
  //the current plugin version
148
  $this->_version = $version;
149
 
150
- // Remember our base path
151
- $this->plugin_basepath = plugin_dir_path( $file );
152
-
153
  if ( $this->php_version_check() ) {
154
  // Only load and run the init function if we know PHP version can parse it.
155
  $this->init();
@@ -166,7 +156,7 @@ class PixCustomifyPlugin {
166
  $this->plugin_settings = get_option( $this->config['settings-key'] );
167
 
168
  /* Initialize the Style Manager logic. */
169
- require_once( $this->plugin_basepath . 'includes/class-customify-style-manager.php' );
170
  if ( is_null( $this->style_manager ) ) {
171
  $this->style_manager = Customify_Style_Manager::instance( $this );
172
  }
@@ -260,12 +250,12 @@ class PixCustomifyPlugin {
260
  }
261
 
262
  /**
263
- * Initialize Configs, Options and Values methods
264
  */
265
  function init_plugin_configs() {
266
  $this->customizer_config = get_option( 'pixcustomify_config' );
267
 
268
- // no option so go for default
269
  if ( empty( $this->customizer_config ) ) {
270
  $this->customizer_config = $this->get_config_option( 'default_options' );
271
  }
@@ -276,12 +266,15 @@ class PixCustomifyPlugin {
276
  }
277
 
278
  /**
279
- * Load the plugin configuration and options
280
  */
281
  function load_plugin_configs() {
282
 
283
  // Allow themes or other plugins to filter the config.
284
  $this->customizer_config = apply_filters( 'customify_filter_fields', $this->customizer_config );
 
 
 
285
  $this->opt_name = $this->localized['options_name'] = $this->customizer_config['opt-name'];
286
  $this->options_list = $this->get_options();
287
 
@@ -364,13 +357,15 @@ class PixCustomifyPlugin {
364
  wp_register_script( 'customify_select2', plugins_url( 'js/select2/js/select2.js', $this->file ), array( 'jquery' ), $this->_version );
365
  wp_register_script( 'jquery-react', plugins_url( 'js/jquery-react.js', $this->file ), array( 'jquery' ), $this->_version );
366
 
367
- wp_register_script( 'customify-scale', plugins_url( 'js/customizer/customify-scale.js', $this->file ), array( 'jquery' ), $this->_version );
 
368
 
369
  wp_register_script( $this->plugin_slug . '-customizer-scripts', plugins_url( 'js/customizer.js', $this->file ), array(
370
  'jquery',
371
  'customify_select2',
372
  'underscore',
373
  'customize-controls',
 
374
 
375
  'customify-scale',
376
  ), $this->_version );
@@ -383,7 +378,7 @@ class PixCustomifyPlugin {
383
  wp_enqueue_script( 'jquery-react' );
384
  wp_enqueue_script( $this->plugin_slug . '-customizer-scripts' );
385
 
386
- wp_localize_script( $this->plugin_slug . '-customizer-scripts', 'customify_settings', $this->localized );
387
  }
388
 
389
  /** Register Customizer scripts loaded only on previewer page */
@@ -1179,10 +1174,11 @@ class PixCustomifyPlugin {
1179
  }
1180
 
1181
  $panel_args = array(
1182
- 'priority' => 10,
1183
- 'capability' => 'edit_theme_options',
1184
- 'title' => __( 'Panel title is required', 'pixcustomify' ),
1185
- 'description' => __( 'Description of what this panel does.', 'pixcustomify' ),
 
1186
  );
1187
 
1188
  if ( isset( $panel_config['priority'] ) && ! empty( $panel_config['priority'] ) ) {
@@ -1197,6 +1193,11 @@ class PixCustomifyPlugin {
1197
  $panel_args['description'] = $panel_config['description'];
1198
  }
1199
 
 
 
 
 
 
1200
  $wp_customize->add_panel( $panel_id, $panel_args );
1201
 
1202
  foreach ( $panel_config['sections'] as $section_id => $section_config ) {
@@ -1291,18 +1292,6 @@ class PixCustomifyPlugin {
1291
  return;
1292
  }
1293
 
1294
- // Merge the section settings with the defaults
1295
- $section_args = wp_parse_args( $section_config, array(
1296
- 'priority' => 10,
1297
- 'panel' => $panel_id,
1298
- 'capability' => 'edit_theme_options',
1299
- 'theme_supports' => '',
1300
- 'title' => esc_html__( 'Title Section is required', 'customify' ),
1301
- 'description' => '',
1302
- 'type' => 'default',
1303
- 'description_hidden' => false,
1304
- ) );
1305
-
1306
  // If we have been explicitly given a section ID we will use that
1307
  if ( ! empty( $section_config['section_id'] ) ) {
1308
  $section_id = $section_config['section_id'];
@@ -1310,8 +1299,22 @@ class PixCustomifyPlugin {
1310
  $section_id = $options_name . '[' . $section_key . ']';
1311
  }
1312
 
1313
- // Add the new section to the Customizer
1314
- $wp_customize->add_section( $section_id, $section_args );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1315
 
1316
  // Now go through each section option and add the fields
1317
  foreach ( $section_config['options'] as $option_id => $option_config ) {
@@ -1520,7 +1523,8 @@ class PixCustomifyPlugin {
1520
  $control_class_name = 'Pix_Customize_Background_Control';
1521
  break;
1522
 
1523
- case 'cropped_media':
 
1524
  if ( isset( $field_config['width'] ) ) {
1525
  $control_args['width'] = $field_config['width'];
1526
  }
@@ -1537,6 +1541,10 @@ class PixCustomifyPlugin {
1537
  $control_args['flex_height'] = $field_config['flex_height'];
1538
  }
1539
 
 
 
 
 
1540
  $control_class_name = 'WP_Customize_Cropped_Image_Control';
1541
  break;
1542
 
@@ -1832,6 +1840,10 @@ class PixCustomifyPlugin {
1832
  <?php
1833
  }
1834
 
 
 
 
 
1835
  public function get_base_path() {
1836
  return plugin_dir_path( $this->file );
1837
  }
@@ -1999,7 +2011,7 @@ class PixCustomifyPlugin {
1999
  public function get_option( $option, $default = null, $alt_opt_name = null ) {
2000
  // If the development constant CUSTOMIFY_DEV_FORCE_DEFAULTS has been defined we will not retrieve anything from the database
2001
  // Always go with the default
2002
- if ( defined( 'CUSTOMIFY_DEV_FORCE_DEFAULTS' ) && true === CUSTOMIFY_DEV_FORCE_DEFAULTS ) {
2003
  $return = null;
2004
  } else {
2005
  $return = $this->get_value( $option, $alt_opt_name );
@@ -2154,7 +2166,7 @@ class PixCustomifyPlugin {
2154
  $controller->init();
2155
  }
2156
 
2157
- function get_options_configs() {
2158
  return $this->options_list;
2159
  }
2160
 
@@ -2223,9 +2235,9 @@ class PixCustomifyPlugin {
2223
  $options_key = $this->customizer_config['opt-name'];
2224
  if ( ! empty( $options_key ) ) {
2225
  // Remove any Customify data thus preventing it from saving
2226
- foreach ( $data as $key => $value ) {
2227
- if ( false !== strpos( $key, $options_key ) ) {
2228
- unset( $data[$key] );
2229
  }
2230
  }
2231
  }
@@ -2233,6 +2245,47 @@ class PixCustomifyPlugin {
2233
  return $data;
2234
  }
2235
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2236
  public function prevent_changeset_save_in_devmode_notification() { ?>
2237
  <script type="application/javascript">
2238
  (function ( $, exports, wp ) {
44
  */
45
  protected $plugin_screen_hook_suffix = null;
46
 
 
 
 
 
 
 
 
47
  public $display_admin_menu = false;
48
 
49
  private $config;
140
  //the current plugin version
141
  $this->_version = $version;
142
 
 
 
 
143
  if ( $this->php_version_check() ) {
144
  // Only load and run the init function if we know PHP version can parse it.
145
  $this->init();
156
  $this->plugin_settings = get_option( $this->config['settings-key'] );
157
 
158
  /* Initialize the Style Manager logic. */
159
+ require_once( $this->get_base_path() . 'includes/class-customify-style-manager.php' );
160
  if ( is_null( $this->style_manager ) ) {
161
  $this->style_manager = Customify_Style_Manager::instance( $this );
162
  }
250
  }
251
 
252
  /**
253
+ * Initialize Configs, Options and Values methods.
254
  */
255
  function init_plugin_configs() {
256
  $this->customizer_config = get_option( 'pixcustomify_config' );
257
 
258
+ // no option so go for default.
259
  if ( empty( $this->customizer_config ) ) {
260
  $this->customizer_config = $this->get_config_option( 'default_options' );
261
  }
266
  }
267
 
268
  /**
269
+ * Load the plugin configuration and options.
270
  */
271
  function load_plugin_configs() {
272
 
273
  // Allow themes or other plugins to filter the config.
274
  $this->customizer_config = apply_filters( 'customify_filter_fields', $this->customizer_config );
275
+ // We apply a second filter for those that wish to work with the final config and not rely on a a huge priority number.
276
+ $this->customizer_config = apply_filters( 'customify_final_config', $this->customizer_config );
277
+
278
  $this->opt_name = $this->localized['options_name'] = $this->customizer_config['opt-name'];
279
  $this->options_list = $this->get_options();
280
 
357
  wp_register_script( 'customify_select2', plugins_url( 'js/select2/js/select2.js', $this->file ), array( 'jquery' ), $this->_version );
358
  wp_register_script( 'jquery-react', plugins_url( 'js/jquery-react.js', $this->file ), array( 'jquery' ), $this->_version );
359
 
360
+ wp_register_script( 'customify-scale', plugins_url( 'js/customizer/scale-iframe.js', $this->file ), array( 'jquery' ), $this->_version );
361
+ wp_register_script( 'customify-fontselectfields', plugins_url( 'js/customizer/font-select-fields.js', $this->file ), array( 'jquery' ), $this->_version );
362
 
363
  wp_register_script( $this->plugin_slug . '-customizer-scripts', plugins_url( 'js/customizer.js', $this->file ), array(
364
  'jquery',
365
  'customify_select2',
366
  'underscore',
367
  'customize-controls',
368
+ 'customify-fontselectfields',
369
 
370
  'customify-scale',
371
  ), $this->_version );
378
  wp_enqueue_script( 'jquery-react' );
379
  wp_enqueue_script( $this->plugin_slug . '-customizer-scripts' );
380
 
381
+ wp_localize_script( $this->plugin_slug . '-customizer-scripts', 'customify_settings', apply_filters( 'customify_localized_js_settings', $this->localized ) );
382
  }
383
 
384
  /** Register Customizer scripts loaded only on previewer page */
1174
  }
1175
 
1176
  $panel_args = array(
1177
+ 'priority' => 10,
1178
+ 'capability' => 'edit_theme_options',
1179
+ 'title' => __( 'Panel title is required', 'pixcustomify' ),
1180
+ 'description' => __( 'Description of what this panel does.', 'pixcustomify' ),
1181
+ 'auto_expand_sole_section' => false,
1182
  );
1183
 
1184
  if ( isset( $panel_config['priority'] ) && ! empty( $panel_config['priority'] ) ) {
1193
  $panel_args['description'] = $panel_config['description'];
1194
  }
1195
 
1196
+ if ( isset( $panel_config['auto_expand_sole_section'] ) ) {
1197
+ $panel_args['auto_expand_sole_section'] = $panel_config['auto_expand_sole_section'];
1198
+ }
1199
+
1200
+
1201
  $wp_customize->add_panel( $panel_id, $panel_args );
1202
 
1203
  foreach ( $panel_config['sections'] as $section_id => $section_config ) {
1292
  return;
1293
  }
1294
 
 
 
 
 
 
 
 
 
 
 
 
 
1295
  // If we have been explicitly given a section ID we will use that
1296
  if ( ! empty( $section_config['section_id'] ) ) {
1297
  $section_id = $section_config['section_id'];
1299
  $section_id = $options_name . '[' . $section_key . ']';
1300
  }
1301
 
1302
+ // Add the new section to the Customizer, but only if it is not already added.
1303
+ if ( ! $wp_customize->get_section( $section_id ) ) {
1304
+ // Merge the section settings with the defaults
1305
+ $section_args = wp_parse_args( $section_config, array(
1306
+ 'priority' => 10,
1307
+ 'panel' => $panel_id,
1308
+ 'capability' => 'edit_theme_options',
1309
+ 'theme_supports' => '',
1310
+ 'title' => esc_html__( 'Title Section is required', 'customify' ),
1311
+ 'description' => '',
1312
+ 'type' => 'default',
1313
+ 'description_hidden' => false,
1314
+ ) );
1315
+
1316
+ $wp_customize->add_section( $section_id, $section_args );
1317
+ }
1318
 
1319
  // Now go through each section option and add the fields
1320
  foreach ( $section_config['options'] as $option_id => $option_config ) {
1523
  $control_class_name = 'Pix_Customize_Background_Control';
1524
  break;
1525
 
1526
+ case 'cropped_image':
1527
+ case 'cropped_media': // 'cropped_media' no longer works
1528
  if ( isset( $field_config['width'] ) ) {
1529
  $control_args['width'] = $field_config['width'];
1530
  }
1541
  $control_args['flex_height'] = $field_config['flex_height'];
1542
  }
1543
 
1544
+ if ( isset( $field_config['button_labels'] ) ) {
1545
+ $control_args['button_labels'] = $field_config['button_labels'];
1546
+ }
1547
+
1548
  $control_class_name = 'WP_Customize_Cropped_Image_Control';
1549
  break;
1550
 
1840
  <?php
1841
  }
1842
 
1843
+ public function get_file() {
1844
+ return $this->file;
1845
+ }
1846
+
1847
  public function get_base_path() {
1848
  return plugin_dir_path( $this->file );
1849
  }
2011
  public function get_option( $option, $default = null, $alt_opt_name = null ) {
2012
  // If the development constant CUSTOMIFY_DEV_FORCE_DEFAULTS has been defined we will not retrieve anything from the database
2013
  // Always go with the default
2014
+ if ( defined( 'CUSTOMIFY_DEV_FORCE_DEFAULTS' ) && true === CUSTOMIFY_DEV_FORCE_DEFAULTS && ! $this->skip_dev_mode_force_defaults( $option ) ) {
2015
  $return = null;
2016
  } else {
2017
  $return = $this->get_value( $option, $alt_opt_name );
2166
  $controller->init();
2167
  }
2168
 
2169
+ public function get_options_configs() {
2170
  return $this->options_list;
2171
  }
2172
 
2235
  $options_key = $this->customizer_config['opt-name'];
2236
  if ( ! empty( $options_key ) ) {
2237
  // Remove any Customify data thus preventing it from saving
2238
+ foreach ( $data as $option_id => $value ) {
2239
+ if ( false !== strpos( $option_id, $options_key ) && ! $this->skip_dev_mode_force_defaults( $option_id ) ) {
2240
+ unset( $data[ $option_id ] );
2241
  }
2242
  }
2243
  }
2245
  return $data;
2246
  }
2247
 
2248
+ /**
2249
+ * Determine if we should NOT enforce the CUSTOMIFY_DEV_FORCE_DEFAULTS behavior on a certain option.
2250
+ *
2251
+ * @param string $option_id
2252
+ *
2253
+ * @return bool
2254
+ */
2255
+ private function skip_dev_mode_force_defaults( $option_id ) {
2256
+ // Preprocess the $option_id.
2257
+ if ( false !== strpos( $option_id, '::' ) ) {
2258
+ $option_id = substr( $option_id, strpos( $option_id, '::' ) + 2 );
2259
+ }
2260
+ if ( false !== strpos( $option_id, '[' ) ) {
2261
+ $option_id = explode( '[', $option_id );
2262
+ $option_id = rtrim( $option_id[1], ']' );
2263
+ }
2264
+
2265
+ $option_config = $this->get_option_customizer_config( $option_id );
2266
+ if ( empty( $option_config ) ) {
2267
+ return false;
2268
+ }
2269
+
2270
+ // We will skip certain field types that generally don't have a default value.
2271
+ if ( ! empty( $option_config['type'] ) ) {
2272
+ switch ( $option_config['type'] ) {
2273
+ case 'cropped_image':
2274
+ case 'cropped_media':
2275
+ case 'image':
2276
+ case 'media':
2277
+ case 'custom_background':
2278
+ case 'upload':
2279
+ return true;
2280
+ break;
2281
+ default:
2282
+ break;
2283
+ }
2284
+ }
2285
+
2286
+ return false;
2287
+ }
2288
+
2289
  public function prevent_changeset_save_in_devmode_notification() { ?>
2290
  <script type="application/javascript">
2291
  (function ( $, exports, wp ) {
core/.gitattributes DELETED
@@ -1,14 +0,0 @@
1
- # remove CRLF
2
- * text=auto
3
-
4
- *.php text eol=lf
5
- *.rb text eol=lf
6
- *.scss text eol=lf
7
- *.js text eol=lf
8
- *.json text eol=lf
9
- *.xml text eol=lf
10
- *.md text eol=lf
11
- *.log text eol=lf
12
-
13
- install-vendor text eol=lf
14
- order text eol=lf
 
 
 
 
 
 
 
 
 
 
 
 
 
 
core/.gitignore DELETED
@@ -1,52 +0,0 @@
1
- ##
2
- ## Collection of junk files
3
- ##
4
-
5
- # eclipse junk
6
- .settings/
7
- .project
8
- .buildpath
9
-
10
- # Numerous always-ignore extensions
11
- *.diff
12
- *.err
13
- *.orig
14
- *.log
15
- *.rej
16
- *.swo
17
- *.swp
18
- *.vi
19
- *~
20
- *.sass-cache
21
-
22
- # OS or Editor folders
23
- .DS_Store
24
- Thumbs.db
25
- .cache
26
- .project
27
- .settings
28
- .tmproj
29
- *.esproj
30
- nbproject
31
- *.sublime-project
32
- *.sublime-workspace
33
-
34
- # Dreamweaver added files
35
- _notes
36
- dwsync.xml
37
-
38
- # Komodo
39
- *.komodoproject
40
- .komodotools
41
-
42
- # Folders to ignore
43
- .hg
44
- .svn
45
- .CVS
46
- intermediate
47
- publish
48
- .idea
49
-
50
- # build script local files
51
- build/buildinfo.properties
52
- build/config/buildinfo.properties
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
css/customizer.css CHANGED
@@ -1,4 +1,4 @@
1
- .wp-full-overlay-sidebar *,
2
  .wp-full-overlay-sidebar *:before,
3
  .wp-full-overlay-sidebar *:after
4
  {
@@ -55,9 +55,6 @@
55
  #customize-theme-controls .control-panel-content .control-section:nth-child(3)
56
  {
57
  border-top: none;
58
- }#customize-theme-controls .control-panel-content .control-section:nth-last-child(2)
59
- {
60
- border-bottom: 1px solid #e0e8ef;
61
  }#customize-theme-controls #accordion-section-add_menu
62
  {
63
  border-bottom: none;
@@ -68,9 +65,8 @@
68
  {
69
  height: 100%;
70
  }#customize-controls .description
71
- {font-size: 12px;font-weight: 300;font-style: normal;line-height: 1.6;
72
-
73
- margin-bottom: 9px;text-indent: 0;color: #4d7b90;
74
  }.customize-control-description
75
  {
76
  margin-top: 6px;
@@ -1255,16 +1251,16 @@ li#customize-control-site_logo .actions
1255
  }#customize-control-sm_color_palette_control ~ [id*='sm_light_tertiary'] .wp-picker-container button:before
1256
  {
1257
  top: -216px;right: -140px;
1258
- }.c-palette
1259
  {
1260
  position: relative;
1261
- }.c-palette .c-palette__label
1262
  {
1263
  -ms-flex-positive: 1;flex-grow: 1;
1264
- }.c-palette:after
1265
  {
1266
  height: 64px;border-radius: 5px;
1267
- }.c-palette:after
1268
  {position: absolute;top: 0;right: 0;left: 0;display: block;
1269
 
1270
  content: '';pointer-events: none;box-shadow: inset 0 0 3px 0 rgba(0,0,0,.15),inset 0 1px 3px 0 rgba(0,0,0,.15);
@@ -1272,7 +1268,7 @@ li#customize-control-site_logo .actions
1272
  {z-index: 2;padding: 7px 12px 7px 7px;
1273
 
1274
  color: #000;border-radius: 3px;background: #f5f6f1;box-shadow: 0 2px 5px rgba(0,0,0,.15);
1275
- }.c-palette__label
1276
  {
1277
  display: -ms-flexbox ;display: flex;height: 40px;padding: 12px;color: black;background: white;-ms-flex-align: center;align-items: center;
1278
  }.colors
@@ -1284,7 +1280,7 @@ li#customize-control-site_logo .actions
1284
  }.fill
1285
  {
1286
  position: relative;height: 64px;
1287
- }.c-palette__overlay
1288
  {
1289
  position: absolute;top: 0;right: 0;left: 0;display: -ms-flexbox;display: flex;height: 64px;-ms-flex-align: center;align-items: center;
1290
  }.fill:before
@@ -1332,85 +1328,85 @@ li#customize-control-site_logo .actions
1332
  }.colors.next .picker:after
1333
  {
1334
  opacity: 0;
1335
- }.c-palette.animate .next .fill:before
1336
  {
1337
  -webkit-animation: fill 1s cubic-bezier(.215, .61, .355, 1) forwards ;animation: fill 1s cubic-bezier(.215, .61, .355, 1) forwards;
1338
- }.c-palette.animate .next .picker
1339
  {
1340
  -webkit-animation: picker-filter 1s cubic-bezier(.215, .61, .355, 1) forwards ;animation: picker-filter 1s cubic-bezier(.215, .61, .355, 1) forwards;
1341
- }.c-palette.animate .next .picker:before
1342
  {
1343
  -webkit-animation: fill-picker-before 1s cubic-bezier(.215, .61, .355, 1) forwards ;animation: fill-picker-before 1s cubic-bezier(.215, .61, .355, 1) forwards;
1344
- }.c-palette.animate .next .picker:after
1345
  {
1346
  -webkit-animation: fill-picker-after 1s cubic-bezier(.215, .61, .355, 1) forwards ;animation: fill-picker-after 1s cubic-bezier(.215, .61, .355, 1) forwards;
1347
- }.c-palette.animate .current .fill,
1348
- .c-palette.animate .current .picker
1349
  {
1350
  -webkit-animation: fade-out 1s forwards ;animation: fade-out 1s forwards;
1351
- }.c-palette.animate .color:nth-child(1) .fill,
1352
- .c-palette.animate .color:nth-child(1) .fill:before,
1353
- .c-palette.animate .color:nth-child(1) .picker,
1354
- .c-palette.animate .color:nth-child(1) .picker:after,
1355
- .c-palette.animate .color:nth-child(1) .picker:before
1356
  {
1357
  -webkit-animation-delay: .3s ;animation-delay: .3s;
1358
- }.c-palette.animate .color:nth-child(2) .fill,
1359
- .c-palette.animate .color:nth-child(2) .fill:before,
1360
- .c-palette.animate .color:nth-child(2) .picker,
1361
- .c-palette.animate .color:nth-child(2) .picker:after,
1362
- .c-palette.animate .color:nth-child(2) .picker:before
1363
  {
1364
- -webkit-animation-delay: .05s ;animation-delay: .05s;
1365
- }.c-palette.animate .color:nth-child(3) .fill,
1366
- .c-palette.animate .color:nth-child(3) .fill:before,
1367
- .c-palette.animate .color:nth-child(3) .picker,
1368
- .c-palette.animate .color:nth-child(3) .picker:after,
1369
- .c-palette.animate .color:nth-child(3) .picker:before
1370
- {
1371
- -webkit-animation-delay: .4s ;animation-delay: .4s;
1372
- }.c-palette.animate .color:nth-child(4) .fill,
1373
- .c-palette.animate .color:nth-child(4) .fill:before,
1374
- .c-palette.animate .color:nth-child(4) .picker,
1375
- .c-palette.animate .color:nth-child(4) .picker:after,
1376
- .c-palette.animate .color:nth-child(4) .picker:before
1377
  {
1378
  -webkit-animation-delay: .2s ;animation-delay: .2s;
1379
- }.c-palette.animate .color:nth-child(5) .fill,
1380
- .c-palette.animate .color:nth-child(5) .fill:before,
1381
- .c-palette.animate .color:nth-child(5) .picker,
1382
- .c-palette.animate .color:nth-child(5) .picker:after,
1383
- .c-palette.animate .color:nth-child(5) .picker:before
1384
  {
1385
- -webkit-animation-delay: .1s ;animation-delay: .1s;
1386
- }.c-palette.animate .color:nth-child(6) .fill,
1387
- .c-palette.animate .color:nth-child(6) .fill:before,
1388
- .c-palette.animate .color:nth-child(6) .picker,
1389
- .c-palette.animate .color:nth-child(6) .picker:after,
1390
- .c-palette.animate .color:nth-child(6) .picker:before
1391
  {
1392
- -webkit-animation-delay: .35s ;animation-delay: .35s;
1393
- }.c-palette.animate .color:nth-child(7) .fill,
1394
- .c-palette.animate .color:nth-child(7) .fill:before,
1395
- .c-palette.animate .color:nth-child(7) .picker,
1396
- .c-palette.animate .color:nth-child(7) .picker:after,
1397
- .c-palette.animate .color:nth-child(7) .picker:before
 
 
 
 
 
 
 
1398
  {
1399
  -webkit-animation-delay: .25s ;animation-delay: .25s;
1400
- }.c-palette.animate .color:nth-child(8) .fill,
1401
- .c-palette.animate .color:nth-child(8) .fill:before,
1402
- .c-palette.animate .color:nth-child(8) .picker,
1403
- .c-palette.animate .color:nth-child(8) .picker:after,
1404
- .c-palette.animate .color:nth-child(8) .picker:before
1405
  {
1406
- -webkit-animation-delay: .45s ;animation-delay: .45s;
1407
- }.c-palette.animate .color:nth-child(9) .fill,
1408
- .c-palette.animate .color:nth-child(9) .fill:before,
1409
- .c-palette.animate .color:nth-child(9) .picker,
1410
- .c-palette.animate .color:nth-child(9) .picker:after,
1411
- .c-palette.animate .color:nth-child(9) .picker:before
1412
  {
1413
- -webkit-animation-delay: .15s ;animation-delay: .15s;
1414
  }@-webkit-keyframes fill
1415
  {
1416
  30%
@@ -1572,63 +1568,63 @@ li#customize-control-site_logo .actions
1572
  }.label
1573
  {
1574
  margin-right: auto;
1575
- }.c-palette__blur
1576
  {
1577
  display: none;
1578
  }#customize-theme-controls [id*='sm_current_color_palette_control']
1579
  {
1580
  display: block;width: auto;margin: -12px -12px 19px;
1581
- }#customize-theme-controls [id*='sm_current_color_palette_control'] .palette-container
1582
  {
1583
  padding: 19px;background: white;
1584
- }.c-palette__name
1585
  {
1586
  margin-right: auto;
1587
- }.c-palette__control
1588
  {display: -ms-flexbox;display: flex;
1589
 
1590
  width: 2em;height: 2em;margin-left: .25em;border-radius: 50%;-ms-flex-pack: center;justify-content: center;-ms-flex-align: center;align-items: center;
1591
- }.c-palette__control,
1592
- .c-palette__control span
1593
  {
1594
  transition: color .3s ease-in-out;
1595
- }.c-palette__control span
1596
  {-webkit-transform: scale(.8) ;transform: scale(.8);
1597
 
1598
  color: rgba(0,0,0,.25);
1599
- }.c-palette__control.active
1600
  {
1601
  background: currentColor;
1602
- }.c-palette__control.active span
1603
  {
1604
  color: white;
1605
- }#sub-accordion-section-style_manager_section
1606
  {
1607
  display: -ms-flexbox !important ;display: flex !important;overflow: hidden;flex-direction: column;padding: 12px 0 0 !important;-ms-flex-direction: column;
1608
- }#sub-accordion-section-style_manager_section > *
1609
  {
1610
  display: block !important;padding: 0 12px;-ms-flex-positive: 0;flex-grow: 0;
1611
- }#sub-accordion-section-style_manager_section #customize-control-sm_color_palette_control
1612
  {overflow-y: scroll;margin-top: -19px;margin-bottom: 0;padding-top: 19px;
1613
 
1614
- -ms-flex-preferred-size: 0;flex-basis: 0;-ms-flex-positive: 1;flex-grow: 1;
1615
- }#sub-accordion-section-style_manager_section:not(.advanced) #customize-control-sm_color_palette_control ~ li:not([id='customize-control-sm_toggle_advanced_settings_control'])
1616
  {
1617
  display: none !important;
1618
- }#sub-accordion-section-style_manager_section.advanced #customize-control-sm_color_palette_control
1619
  {
1620
  display: none !important;
1621
- }.c-palette .iris-picker
1622
  {
1623
  position: absolute;z-index: 100;top: 100%;left: 0;margin-top: 1em;border: 0;box-shadow: black 0 3px 12px -4px;
1624
- }.c-palette .iris-picker .iris-square-handle
1625
  {top: -6px;left: -6px;
1626
 
1627
  border-color: transparent;
1628
- }.c-palette .iris-picker .iris-square-handle:after
1629
  {
1630
  position: absolute;top: 0;right: 0;bottom: 0;left: 0;border: 2px solid white;
1631
- }.c-palette .iris-picker .iris-square-value
1632
  {
1633
  box-shadow: none !important;
1634
  }.color .picker
@@ -1650,20 +1646,20 @@ li#customize-control-site_logo .actions
1650
  }.color.inactive .picker:hover
1651
  {
1652
  opacity: 1;
1653
- }.c-palette__tooltip
1654
  {
1655
  position: absolute;z-index: 300;bottom: 100%;left: 50%;margin-bottom: 5px;padding: 4px 14px;transition: opacity .2s ease-out;-webkit-transform: translateX(-50%);transform: translateX(-50%);opacity: 0;color: white;background-color: #606a72;box-shadow: 0 2px 5px 0 rgba(0,0,0,.15);
1656
- }.c-palette__tooltip:after
1657
  {position: absolute;top: 100%;left: 50%;display: block;
1658
 
1659
  content: '';-webkit-transform: translateX(-50%);transform: translateX(-50%);border: 5px solid transparent;border-top-color: #606a72;border-bottom-width: 0;
1660
- }.c-palette__control:hover .c-palette__tooltip
1661
  {
1662
  opacity: 1;
1663
- }.c-palette__control
1664
  {
1665
  position: relative;cursor: pointer;
1666
- }input.c-palette__input[class]
1667
  {
1668
  margin-top: 1em;
1669
  }#customize-control-sm_toggle_advanced_settings_control
@@ -1672,4 +1668,165 @@ li#customize-control-site_logo .actions
1672
  }#customize-control-sm_toggle_advanced_settings_control button
1673
  {
1674
  width: 100%;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1675
  }
1
+ .wp-full-overlay-sidebar *,
2
  .wp-full-overlay-sidebar *:before,
3
  .wp-full-overlay-sidebar *:after
4
  {
55
  #customize-theme-controls .control-panel-content .control-section:nth-child(3)
56
  {
57
  border-top: none;
 
 
 
58
  }#customize-theme-controls #accordion-section-add_menu
59
  {
60
  border-bottom: none;
65
  {
66
  height: 100%;
67
  }#customize-controls .description
68
+ {
69
+ font-size: 12px;font-weight: 300;font-style: normal;line-height: 1.6;text-indent: 0;color: #4d7b90;
 
70
  }.customize-control-description
71
  {
72
  margin-top: 6px;
1251
  }#customize-control-sm_color_palette_control ~ [id*='sm_light_tertiary'] .wp-picker-container button:before
1252
  {
1253
  top: -216px;right: -140px;
1254
+ }.c-color-palette
1255
  {
1256
  position: relative;
1257
+ }.c-color-palette .c-color-palette__label
1258
  {
1259
  -ms-flex-positive: 1;flex-grow: 1;
1260
+ }.c-color-palette:after
1261
  {
1262
  height: 64px;border-radius: 5px;
1263
+ }.c-color-palette:after
1264
  {position: absolute;top: 0;right: 0;left: 0;display: block;
1265
 
1266
  content: '';pointer-events: none;box-shadow: inset 0 0 3px 0 rgba(0,0,0,.15),inset 0 1px 3px 0 rgba(0,0,0,.15);
1268
  {z-index: 2;padding: 7px 12px 7px 7px;
1269
 
1270
  color: #000;border-radius: 3px;background: #f5f6f1;box-shadow: 0 2px 5px rgba(0,0,0,.15);
1271
+ }.c-color-palette__label
1272
  {
1273
  display: -ms-flexbox ;display: flex;height: 40px;padding: 12px;color: black;background: white;-ms-flex-align: center;align-items: center;
1274
  }.colors
1280
  }.fill
1281
  {
1282
  position: relative;height: 64px;
1283
+ }.c-color-palette__overlay
1284
  {
1285
  position: absolute;top: 0;right: 0;left: 0;display: -ms-flexbox;display: flex;height: 64px;-ms-flex-align: center;align-items: center;
1286
  }.fill:before
1328
  }.colors.next .picker:after
1329
  {
1330
  opacity: 0;
1331
+ }.c-color-palette.animate .next .fill:before
1332
  {
1333
  -webkit-animation: fill 1s cubic-bezier(.215, .61, .355, 1) forwards ;animation: fill 1s cubic-bezier(.215, .61, .355, 1) forwards;
1334
+ }.c-color-palette.animate .next .picker
1335
  {
1336
  -webkit-animation: picker-filter 1s cubic-bezier(.215, .61, .355, 1) forwards ;animation: picker-filter 1s cubic-bezier(.215, .61, .355, 1) forwards;
1337
+ }.c-color-palette.animate .next .picker:before
1338
  {
1339
  -webkit-animation: fill-picker-before 1s cubic-bezier(.215, .61, .355, 1) forwards ;animation: fill-picker-before 1s cubic-bezier(.215, .61, .355, 1) forwards;
1340
+ }.c-color-palette.animate .next .picker:after
1341
  {
1342
  -webkit-animation: fill-picker-after 1s cubic-bezier(.215, .61, .355, 1) forwards ;animation: fill-picker-after 1s cubic-bezier(.215, .61, .355, 1) forwards;
1343
+ }.c-color-palette.animate .current .fill,
1344
+ .c-color-palette.animate .current .picker
1345
  {
1346
  -webkit-animation: fade-out 1s forwards ;animation: fade-out 1s forwards;
1347
+ }.c-color-palette.animate .color:nth-child(1) .fill,
1348
+ .c-color-palette.animate .color:nth-child(1) .fill:before,
1349
+ .c-color-palette.animate .color:nth-child(1) .picker,
1350
+ .c-color-palette.animate .color:nth-child(1) .picker:after,
1351
+ .c-color-palette.animate .color:nth-child(1) .picker:before
1352
  {
1353
  -webkit-animation-delay: .3s ;animation-delay: .3s;
1354
+ }.c-color-palette.animate .color:nth-child(2) .fill,
1355
+ .c-color-palette.animate .color:nth-child(2) .fill:before,
1356
+ .c-color-palette.animate .color:nth-child(2) .picker,
1357
+ .c-color-palette.animate .color:nth-child(2) .picker:after,
1358
+ .c-color-palette.animate .color:nth-child(2) .picker:before
1359
  {
1360
+ -webkit-animation-delay: .1s ;animation-delay: .1s;
1361
+ }.c-color-palette.animate .color:nth-child(3) .fill,
1362
+ .c-color-palette.animate .color:nth-child(3) .fill:before,
1363
+ .c-color-palette.animate .color:nth-child(3) .picker,
1364
+ .c-color-palette.animate .color:nth-child(3) .picker:after,
1365
+ .c-color-palette.animate .color:nth-child(3) .picker:before
 
 
 
 
 
 
 
1366
  {
1367
  -webkit-animation-delay: .2s ;animation-delay: .2s;
1368
+ }.c-color-palette.animate .color:nth-child(4) .fill,
1369
+ .c-color-palette.animate .color:nth-child(4) .fill:before,
1370
+ .c-color-palette.animate .color:nth-child(4) .picker,
1371
+ .c-color-palette.animate .color:nth-child(4) .picker:after,
1372
+ .c-color-palette.animate .color:nth-child(4) .picker:before
1373
  {
1374
+ -webkit-animation-delay: .45s ;animation-delay: .45s;
1375
+ }.c-color-palette.animate .color:nth-child(5) .fill,
1376
+ .c-color-palette.animate .color:nth-child(5) .fill:before,
1377
+ .c-color-palette.animate .color:nth-child(5) .picker,
1378
+ .c-color-palette.animate .color:nth-child(5) .picker:after,
1379
+ .c-color-palette.animate .color:nth-child(5) .picker:before
1380
  {
1381
+ -webkit-animation-delay: .15s ;animation-delay: .15s;
1382
+ }.c-color-palette.animate .color:nth-child(6) .fill,
1383
+ .c-color-palette.animate .color:nth-child(6) .fill:before,
1384
+ .c-color-palette.animate .color:nth-child(6) .picker,
1385
+ .c-color-palette.animate .color:nth-child(6) .picker:after,
1386
+ .c-color-palette.animate .color:nth-child(6) .picker:before
1387
+ {
1388
+ -webkit-animation-delay: .05s ;animation-delay: .05s;
1389
+ }.c-color-palette.animate .color:nth-child(7) .fill,
1390
+ .c-color-palette.animate .color:nth-child(7) .fill:before,
1391
+ .c-color-palette.animate .color:nth-child(7) .picker,
1392
+ .c-color-palette.animate .color:nth-child(7) .picker:after,
1393
+ .c-color-palette.animate .color:nth-child(7) .picker:before
1394
  {
1395
  -webkit-animation-delay: .25s ;animation-delay: .25s;
1396
+ }.c-color-palette.animate .color:nth-child(8) .fill,
1397
+ .c-color-palette.animate .color:nth-child(8) .fill:before,
1398
+ .c-color-palette.animate .color:nth-child(8) .picker,
1399
+ .c-color-palette.animate .color:nth-child(8) .picker:after,
1400
+ .c-color-palette.animate .color:nth-child(8) .picker:before
1401
  {
1402
+ -webkit-animation-delay: .4s ;animation-delay: .4s;
1403
+ }.c-color-palette.animate .color:nth-child(9) .fill,
1404
+ .c-color-palette.animate .color:nth-child(9) .fill:before,
1405
+ .c-color-palette.animate .color:nth-child(9) .picker,
1406
+ .c-color-palette.animate .color:nth-child(9) .picker:after,
1407
+ .c-color-palette.animate .color:nth-child(9) .picker:before
1408
  {
1409
+ -webkit-animation-delay: .35s ;animation-delay: .35s;
1410
  }@-webkit-keyframes fill
1411
  {
1412
  30%
1568
  }.label
1569
  {
1570
  margin-right: auto;
1571
+ }.c-color-palette__blur
1572
  {
1573
  display: none;
1574
  }#customize-theme-controls [id*='sm_current_color_palette_control']
1575
  {
1576
  display: block;width: auto;margin: -12px -12px 19px;
1577
+ }#customize-theme-controls [id*='sm_current_color_palette_control'] .color-palette-container
1578
  {
1579
  padding: 19px;background: white;
1580
+ }.c-color-palette__name
1581
  {
1582
  margin-right: auto;
1583
+ }.c-color-palette__control
1584
  {display: -ms-flexbox;display: flex;
1585
 
1586
  width: 2em;height: 2em;margin-left: .25em;border-radius: 50%;-ms-flex-pack: center;justify-content: center;-ms-flex-align: center;align-items: center;
1587
+ }.c-color-palette__control,
1588
+ .c-color-palette__control span
1589
  {
1590
  transition: color .3s ease-in-out;
1591
+ }.c-color-palette__control span
1592
  {-webkit-transform: scale(.8) ;transform: scale(.8);
1593
 
1594
  color: rgba(0,0,0,.25);
1595
+ }.c-color-palette__control.active
1596
  {
1597
  background: currentColor;
1598
+ }.c-color-palette__control.active span
1599
  {
1600
  color: white;
1601
+ }#sub-accordion-section-sm_color_palettes_section
1602
  {
1603
  display: -ms-flexbox !important ;display: flex !important;overflow: hidden;flex-direction: column;padding: 12px 0 0 !important;-ms-flex-direction: column;
1604
+ }#sub-accordion-section-sm_color_palettes_section > *
1605
  {
1606
  display: block !important;padding: 0 12px;-ms-flex-positive: 0;flex-grow: 0;
1607
+ }#sub-accordion-section-sm_color_palettes_section #customize-control-sm_color_palette_control
1608
  {overflow-y: scroll;margin-top: -19px;margin-bottom: 0;padding-top: 19px;
1609
 
1610
+ -ms-flex-negative: 0;flex-shrink: 0;-ms-flex-positive: 1;flex-grow: 1;
1611
+ }#sub-accordion-section-sm_color_palettes_section:not(.advanced) #customize-control-sm_color_palette_control ~ li:not([id='customize-control-sm_toggle_advanced_settings_control'])
1612
  {
1613
  display: none !important;
1614
+ }#sub-accordion-section-sm_color_palettes_section.advanced #customize-control-sm_color_palette_control
1615
  {
1616
  display: none !important;
1617
+ }.c-color-palette .iris-picker
1618
  {
1619
  position: absolute;z-index: 100;top: 100%;left: 0;margin-top: 1em;border: 0;box-shadow: black 0 3px 12px -4px;
1620
+ }.c-color-palette .iris-picker .iris-square-handle
1621
  {top: -6px;left: -6px;
1622
 
1623
  border-color: transparent;
1624
+ }.c-color-palette .iris-picker .iris-square-handle:after
1625
  {
1626
  position: absolute;top: 0;right: 0;bottom: 0;left: 0;border: 2px solid white;
1627
+ }.c-color-palette .iris-picker .iris-square-value
1628
  {
1629
  box-shadow: none !important;
1630
  }.color .picker
1646
  }.color.inactive .picker:hover
1647
  {
1648
  opacity: 1;
1649
+ }.c-color-palette__tooltip
1650
  {
1651
  position: absolute;z-index: 300;bottom: 100%;left: 50%;margin-bottom: 5px;padding: 4px 14px;transition: opacity .2s ease-out;-webkit-transform: translateX(-50%);transform: translateX(-50%);opacity: 0;color: white;background-color: #606a72;box-shadow: 0 2px 5px 0 rgba(0,0,0,.15);
1652
+ }.c-color-palette__tooltip:after
1653
  {position: absolute;top: 100%;left: 50%;display: block;
1654
 
1655
  content: '';-webkit-transform: translateX(-50%);transform: translateX(-50%);border: 5px solid transparent;border-top-color: #606a72;border-bottom-width: 0;
1656
+ }.c-color-palette__control:hover .c-color-palette__tooltip
1657
  {
1658
  opacity: 1;
1659
+ }.c-color-palette__control
1660
  {
1661
  position: relative;cursor: pointer;
1662
+ }input.c-color-palette__input[class]
1663
  {
1664
  margin-top: 1em;
1665
  }#customize-control-sm_toggle_advanced_settings_control
1668
  }#customize-control-sm_toggle_advanced_settings_control button
1669
  {
1670
  width: 100%;
1671
+ }.sm_color_matrix
1672
+ {
1673
+ display: -ms-flexbox ;display: flex;margin-top: -15px;margin-left: -15px;-ms-flex-wrap: wrap;flex-wrap: wrap;
1674
+ }.sm_color_matrix > *
1675
+ {
1676
+ display: -ms-flexbox ;display: flex;padding-top: 15px;padding-left: 15px;-ms-flex-wrap: wrap;flex-wrap: wrap;-ms-flex-line-pack: start;align-content: flex-start;-ms-flex: 0 0 33.33333%;flex: 0 0 33.33333%;
1677
+ }.sm_color_matrix > * > *
1678
+ {-webkit-animation-name: bounceIn ;animation-name: bounceIn;-webkit-animation-duration: .75s;animation-duration: .75s;border: 1px solid #ccc;border-radius: 50%;
1679
+ background-color: currentColor;
1680
+ }.sm_color_matrix > *
1681
+ {
1682
+ display: grid;grid-auto-rows: 2px;grid-auto-columns: 2px;
1683
+ }.sm_color_matrix > * > :nth-child(1)
1684
+ {
1685
+ grid-area: 16 / 12 / span 12 / span 12;
1686
+ }.sm_color_matrix > * > :nth-child(2)
1687
+ {
1688
+ grid-area: 26 / 24 / span 4 / span 4;
1689
+ }.sm_color_matrix > * > :nth-child(3)
1690
+ {
1691
+ grid-area: 13 / 24 / span 4 / span 4;
1692
+ }.sm_color_matrix > * > :nth-child(4)
1693
+ {
1694
+ grid-area: 8 / 8 / span 8 / span 8;
1695
+ }.sm_color_matrix > * > :nth-child(5)
1696
+ {
1697
+ grid-area: 32 / 8 / span 4 / span 4;
1698
+ }.sm_color_matrix > * > :nth-child(6)
1699
+ {
1700
+ grid-area: 30 / 16 / span 8 / span 8;
1701
+ }.sm_color_matrix > * > :nth-child(7)
1702
+ {
1703
+ grid-area: 4 / 20 / span 8 / span 8;
1704
+ }.sm_color_matrix > * > :nth-child(8)
1705
+ {
1706
+ grid-area: 17 / 26 / span 8 / span 8;
1707
+ }.sm_color_matrix > * > :nth-child(9)
1708
+ {
1709
+ grid-area: 22 / 2 / span 8 / span 8;
1710
+ }.sm_color_matrix > * > :nth-child(10)
1711
+ {
1712
+ grid-area: 28 / 11 / span 2 / span 2;
1713
+ }.sm_color_matrix > * > :nth-child(11)
1714
+ {
1715
+ grid-area: 9 / 31 / span 6 / span 6;
1716
+ }.sm_color_matrix > * > :nth-child(11)
1717
+ {
1718
+ grid-area: 26 / 30 / span 9 / span 9;
1719
+ }.sm_color_matrix > * > :nth-child(12)
1720
+ {
1721
+ grid-area: 17 / 7 / span 4 / span 4;
1722
+ }.sm_color_matrix > * > :nth-child(13)
1723
+ {
1724
+ grid-area: 19 / 36 / span 6 / span 6;
1725
+ }.sm_color_matrix > * > :nth-child(14)
1726
+ {
1727
+ grid-area: 12 / 18 / span 2 / span 2;
1728
+ }@-webkit-keyframes bounceIn
1729
+ {
1730
+ 0%,
1731
+ 20%,
1732
+ 40%,
1733
+ 60%,
1734
+ 80%,
1735
+ 100%
1736
+ {
1737
+ -webkit-animation-timing-function: cubic-bezier(.215, .61, .355, 1) ;animation-timing-function: cubic-bezier(.215, .61, .355, 1);
1738
+ }0%
1739
+ {-webkit-transform: scale3d(.3, .3, .3) ;transform: scale3d(.3, .3, .3);
1740
+
1741
+ opacity: 0;
1742
+ }20%
1743
+ {
1744
+ -webkit-transform: scale3d(1.1, 1.1, 1.1) ;transform: scale3d(1.1, 1.1, 1.1);
1745
+ }40%
1746
+ {
1747
+ -webkit-transform: scale3d(.9, .9, .9) ;transform: scale3d(.9, .9, .9);
1748
+ }60%
1749
+ {-webkit-transform: scale3d(1.03, 1.03, 1.03) ;transform: scale3d(1.03, 1.03, 1.03);
1750
+
1751
+ opacity: 1;
1752
+ }80%
1753
+ {
1754
+ -webkit-transform: scale3d(.97, .97, .97) ;transform: scale3d(.97, .97, .97);
1755
+ }100%
1756
+ {-webkit-transform: scale3d(1, 1, 1) ;transform: scale3d(1, 1, 1);
1757
+
1758
+ opacity: 1;
1759
+ }
1760
+ }@keyframes bounceIn
1761
+ {
1762
+ 0%,
1763
+ 20%,
1764
+ 40%,
1765
+ 60%,
1766
+ 80%,
1767
+ 100%
1768
+ {
1769
+ -webkit-animation-timing-function: cubic-bezier(.215, .61, .355, 1) ;animation-timing-function: cubic-bezier(.215, .61, .355, 1);
1770
+ }0%
1771
+ {-webkit-transform: scale3d(.3, .3, .3) ;transform: scale3d(.3, .3, .3);
1772
+
1773
+ opacity: 0;
1774
+ }20%
1775
+ {
1776
+ -webkit-transform: scale3d(1.1, 1.1, 1.1) ;transform: scale3d(1.1, 1.1, 1.1);
1777
+ }40%
1778
+ {
1779
+ -webkit-transform: scale3d(.9, .9, .9) ;transform: scale3d(.9, .9, .9);
1780
+ }60%
1781
+ {-webkit-transform: scale3d(1.03, 1.03, 1.03) ;transform: scale3d(1.03, 1.03, 1.03);
1782
+
1783
+ opacity: 1;
1784
+ }80%
1785
+ {
1786
+ -webkit-transform: scale3d(.97, .97, .97) ;transform: scale3d(.97, .97, .97);
1787
+ }100%
1788
+ {-webkit-transform: scale3d(1, 1, 1) ;transform: scale3d(1, 1, 1);
1789
+
1790
+ opacity: 1;
1791
+ }
1792
+ }#customize-theme-controls #sub-accordion-panel-style_manager_panel .customize-panel-description,
1793
+ #customize-theme-controls #sub-accordion-panel-theme_options_panel .customize-panel-description
1794
+ {
1795
+ display: block;
1796
+ }#customize-theme-controls li#accordion-panel-style_manager_panel h3.accordion-section-title:before
1797
+ {font-family: dashicons;font-size: 17px;
1798
+
1799
+ position: relative;float: right;margin-right: 28px;padding: 1px;content: '';color: #aed2e5;-webkit-font-smoothing: antialiased;
1800
+ }#customize-theme-controls li#accordion-panel-style_manager_panel h3.accordion-section-title:before
1801
+ {
1802
+ font-size: 18px;color: #f8bc30;
1803
+ }#customize-theme-controls li#accordion-section-sm_color_palettes_section h3.accordion-section-title:before
1804
+ {font-family: dashicons;font-size: 17px;
1805
+
1806
+ position: relative;float: right;margin-right: 28px;padding: 1px;content: '';color: #aed2e5;-webkit-font-smoothing: antialiased;
1807
+ }#customize-theme-controls li#accordion-section-sm_color_palettes_section h3.accordion-section-title
1808
+ {
1809
+ border-top: none;
1810
+ }#customize-theme-controls li#accordion-section-sm_font_palettes_section h3.accordion-section-title:before
1811
+ {font-family: dashicons;font-size: 17px;
1812
+
1813
+ position: relative;float: right;margin-right: 28px;padding: 1px;content: '';color: #aed2e5;-webkit-font-smoothing: antialiased;
1814
+ }#customize-theme-controls li#accordion-section-sm_color_palettes_section h3.accordion-section-title:before,
1815
+ #customize-theme-controls li#accordion-section-sm_font_palettes_section h3.accordion-section-title:before
1816
+ {margin-top: -2px;margin-right: 5px;
1817
+ padding: 3px;
1818
+ }#customize-theme-controls li#accordion-panel-theme_options_panel h3.accordion-section-title:before
1819
+ {font-family: dashicons;font-size: 17px;
1820
+
1821
+ position: relative;float: right;margin-right: 28px;padding: 1px;content: '';color: #aed2e5;-webkit-font-smoothing: antialiased;
1822
+ }#customize-theme-controls li#accordion-panel-theme_options_panel h3.accordion-section-title
1823
+ {margin: 0 0 15px 0;border-right: none;
1824
+ border-bottom: 1px solid #ddd;border-left: none;
1825
+ }#customize-theme-controls li[id$='[general]'],
1826
+ #customize-theme-controls li[id$='[footer_section]']
1827
+ {margin: 0 0 15px 0;border-right: none;
1828
+ border-bottom: 1px solid #ddd;border-left: none;
1829
+ }#customize-theme-controls li[id$='[general]'] h3.accordion-section-title
1830
+ {
1831
+ border-top: none;
1832
  }
customify.php CHANGED
@@ -3,7 +3,7 @@
3
  Plugin Name: Customify
4
  Plugin URI: https://wordpress.org/plugins/customify/
5
  Description: A Theme Customizer Booster
6
- Version: 1.7.3
7
  Author: Pixelgrade
8
  Author URI: https://pixelgrade.com
9
  Author Email: contact@pixelgrade.com
@@ -26,7 +26,7 @@ if ( ! defined('EXT')) {
26
  require 'core/bootstrap' . EXT;
27
 
28
  // Include our helper array class.
29
- require 'includes/class-customify-array' . EXT;
30
 
31
  $config = include 'plugin-config' . EXT;
32
 
@@ -59,9 +59,9 @@ function PixCustomifyPlugin() {
59
  * The core plugin class that is used to define internationalization,
60
  * admin-specific hooks, and public-facing site hooks.
61
  */
62
- require_once( plugin_dir_path( __FILE__ ) . 'class-pixcustomify.php' );
63
 
64
- $instance = PixCustomifyPlugin::instance( __FILE__, '1.7.2' );
65
 
66
  return $instance;
67
  }
3
  Plugin Name: Customify
4
  Plugin URI: https://wordpress.org/plugins/customify/
5
  Description: A Theme Customizer Booster
6
+ Version: 1.7.4
7
  Author: Pixelgrade
8
  Author URI: https://pixelgrade.com
9
  Author Email: contact@pixelgrade.com
26
  require 'core/bootstrap' . EXT;
27
 
28
  // Include our helper array class.
29
+ require 'includes/lib/class-customify-array' . EXT;
30
 
31
  $config = include 'plugin-config' . EXT;
32
 
59
  * The core plugin class that is used to define internationalization,
60
  * admin-specific hooks, and public-facing site hooks.
61
  */
62
+ require_once plugin_dir_path( __FILE__ ) . 'class-pixcustomify.php';
63
 
64
+ $instance = PixCustomifyPlugin::instance( __FILE__, '1.7.4' );
65
 
66
  return $instance;
67
  }
features/class-Font_Selector.php CHANGED
@@ -165,7 +165,7 @@ class Customify_Font_Selector {
165
 
166
  //Handle special logic for when the $value array is not an associative array
167
  if ( ! $local_plugin->is_assoc( $value ) ) {
168
- $value = $local_plugin->process_a_not_associative_font_default( $value );
169
  }
170
 
171
  if ( isset( $value['font_family'] ) && isset( $value['type'] ) && $value['type'] == 'google' ) {
@@ -240,7 +240,7 @@ class Customify_Font_Selector {
240
 
241
  // Handle special logic for when the $value array is not an associative array
242
  if ( ! $local_plugin->is_assoc( $value ) ) {
243
- $value = $local_plugin->process_a_not_associative_font_default( $value );
244
  }
245
 
246
  $this->output_font_style( $key, $font, $value );
@@ -373,18 +373,63 @@ class Customify_Font_Selector {
373
  }
374
 
375
  if ( ! empty( $value['font_size'] ) ) {
376
- $unit = $this->get_field_unit( $font, 'font-size' );
377
- $this->display_property( 'font-size', $value['font_size'], $unit );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
378
  }
379
 
380
  if ( isset( $value['line_height'] ) ) {
381
- $unit = $this->get_field_unit( $font, 'line-height' );
382
- $this->display_property( 'line-height', $value['line_height'], $unit );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
383
  }
384
 
385
  if ( isset( $value['letter_spacing'] ) ) {
386
- $unit = $this->get_field_unit( $font, 'letter-spacing' );
387
- $this->display_property( 'letter-spacing', $value['letter_spacing'], $unit );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
388
  }
389
 
390
  if ( ! empty( $value['text_align'] ) ) {
165
 
166
  //Handle special logic for when the $value array is not an associative array
167
  if ( ! $local_plugin->is_assoc( $value ) ) {
168
+ $value = $local_plugin->standardize_non_associative_font_default( $value );
169
  }
170
 
171
  if ( isset( $value['font_family'] ) && isset( $value['type'] ) && $value['type'] == 'google' ) {
240
 
241
  // Handle special logic for when the $value array is not an associative array
242
  if ( ! $local_plugin->is_assoc( $value ) ) {
243
+ $value = $local_plugin->standardize_non_associative_font_default( $value );
244
  }
245
 
246
  $this->output_font_style( $key, $font, $value );
373
  }
374
 
375
  if ( ! empty( $value['font_size'] ) ) {
376
+ // If the value already contains a unit, go with that.
377
+ // We also handle receiving the value in a standardized format ( array with 'value' and 'unit').
378
+ $font_size = $value['font_size'];
379
+ $unit = '';
380
+ if ( is_numeric( $value['font_size'] ) ) {
381
+ $unit = $this->get_field_unit( $font, 'font-size' );
382
+ } elseif ( is_array( $value['font_size'] ) ) {
383
+ if ( isset( $value['font_size']['unit'] ) ) {
384
+ $unit = $value['font_size']['unit'];
385
+ }
386
+
387
+ if ( isset( $value['font_size']['value'] ) ) {
388
+ $font_size = $value['font_size']['value'];
389
+ }
390
+ }
391
+
392
+ $this->display_property( 'font-size', $font_size, $unit );
393
  }
394
 
395
  if ( isset( $value['line_height'] ) ) {
396
+ // If the value already contains a unit, go with that.
397
+ // We also handle receiving the value in a standardized format ( array with 'value' and 'unit').
398
+ $line_height = $value['line_height'];
399
+ $unit = '';
400
+ if ( is_numeric( $value['line_height'] ) ) {
401
+ $unit = $this->get_field_unit( $font, 'line-height' );
402
+ } elseif ( is_array( $value['line_height'] ) ) {
403
+ if ( isset( $value['line_height']['unit'] ) ) {
404
+ $unit = $value['line_height']['unit'];
405
+ }
406
+
407
+ if ( isset( $value['line_height']['value'] ) ) {
408
+ $line_height = $value['line_height']['value'];
409
+ }
410
+ }
411
+
412
+ $this->display_property( 'line-height', $line_height, $unit );
413
  }
414
 
415
  if ( isset( $value['letter_spacing'] ) ) {
416
+ // If the value already contains a unit, go with that.
417
+ // We also handle receiving the value in a standardized format ( array with 'value' and 'unit').
418
+ $letter_spacing = $value['letter_spacing'];
419
+ $unit = '';
420
+ if ( is_numeric( $value['letter_spacing'] ) ) {
421
+ $unit = $this->get_field_unit( $font, 'letter-spacing' );
422
+ } elseif ( is_array( $value['letter_spacing'] ) ) {
423
+ if ( isset( $value['letter_spacing']['unit'] ) ) {
424
+ $unit = $value['letter_spacing']['unit'];
425
+ }
426
+
427
+ if ( isset( $value['letter_spacing']['value'] ) ) {
428
+ $letter_spacing = $value['letter_spacing']['value'];
429
+ }
430
+ }
431
+
432
+ $this->display_property( 'letter-spacing', $letter_spacing, $unit );
433
  }
434
 
435
  if ( ! empty( $value['text_align'] ) ) {
features/customizer/controls/class-Pix_Customize_Font_Control.php CHANGED
@@ -37,6 +37,8 @@ class Pix_Customize_Font_Control extends Pix_Customize_Control {
37
  public function __construct( $manager, $id, $args = array() ) {
38
  global $wp_customize;
39
 
 
 
40
  self::$std_fonts = apply_filters( 'customify_filter_standard_fonts_list', array(
41
  "Arial, Helvetica, sans-serif" => "Arial, Helvetica, sans-serif",
42
  "'Arial Black', Gadget, sans-serif" => "'Arial Black', Gadget, sans-serif",
@@ -57,37 +59,6 @@ class Pix_Customize_Font_Control extends Pix_Customize_Control {
57
  "Verdana, Geneva, sans-serif" => "Verdana, Geneva, sans-serif",
58
  ) );
59
 
60
- $keys = array_keys( get_object_vars( $this ) );
61
- foreach ( $keys as $key ) {
62
- if ( isset( $args[ $key ] ) ) {
63
- $this->$key = $args[ $key ];
64
- }
65
- }
66
-
67
- $this->manager = $manager;
68
- $this->id = $id;
69
- if ( empty( $this->active_callback ) ) {
70
- $this->active_callback = array( $this, 'active_callback' );
71
- }
72
- self::$instance_count += 1;
73
- $this->instance_number = self::$instance_count;
74
-
75
- // Process settings.
76
- if ( empty( $this->settings ) ) {
77
- $this->settings = $id;
78
- }
79
-
80
- $settings = array();
81
- if ( is_array( $this->settings ) ) {
82
- foreach ( $this->settings as $key => $setting ) {
83
- $settings[ $key ] = $this->manager->get_setting( $setting );
84
- }
85
- } else {
86
- $this->setting = $this->manager->get_setting( $this->settings );
87
- $settings['default'] = $this->setting;
88
- }
89
-
90
- $this->settings = $settings;
91
  $this->CSSID = $this->get_CSS_ID();
92
  $this->load_google_fonts();
93
 
@@ -132,7 +103,7 @@ class Pix_Customize_Font_Control extends Pix_Customize_Control {
132
  }
133
  } else {
134
  //if we've got a string then it is clear we need to decode it
135
- $current_value = json_decode( $current_value );
136
  }
137
 
138
  $current_value = $this->validate_font_values( $current_value );
@@ -294,15 +265,12 @@ class Pix_Customize_Font_Control extends Pix_Customize_Control {
294
  }
295
 
296
  function display_font_weight_field( $current_value ) {
297
-
298
  $display = 'none';
299
-
300
  if ( ! $this->load_all_weights && $this->font_weight ) {
301
  $display = 'inline-block';
302
  } ?>
303
- <li class="customify_weights_wrapper customize-control font-options__option"
304
- style="display: <?php echo $display; ?>">
305
- <select class="customify_font_weight" data-field="selected_variants" <?php echo ! empty( $current_value->selected_variants ) ? 'data-default="' . $current_value->selected_variants . '"' : null; ?>>
306
  <?php
307
  $selected = array();
308
  if ( isset( $current_value->selected_variants ) ) {
@@ -331,9 +299,8 @@ class Pix_Customize_Font_Control extends Pix_Customize_Control {
331
  if ( $this->subsets && ! empty( $current_value->subsets ) ) {
332
  $display = 'inline-block';
333
  } ?>
334
- <li class="customify_subsets_wrapper customize-control font-options__option"
335
- style="display: <?php echo $display; ?>">
336
- <select multiple class="customify_font_subsets" data-field="selected_subsets">
337
  <?php
338
  $selected = array();
339
  if ( isset( $current_value->selected_subsets ) ) {
@@ -363,7 +330,34 @@ class Pix_Customize_Font_Control extends Pix_Customize_Control {
363
 
364
  function display_font_size_field( $current_value ) {
365
  if ( ! empty( $this->fields['font-size'] ) ) {
366
- $fs_val = empty( $current_value->font_size ) ? 0 : $current_value->font_size; ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
367
  <li class="customify_font_size_wrapper customize-control font-options__option">
368
  <label><?php esc_html_e( 'Font Size', 'customify' ); ?></label>
369
  <input type="range"
@@ -375,7 +369,34 @@ class Pix_Customize_Font_Control extends Pix_Customize_Control {
375
 
376
  function display_line_height_field( $current_value ) {
377
  if ( ! empty( $this->fields['line-height'] ) ) {
378
- $lh_val = isset( $current_value->line_height ) ? $current_value->line_height : 0 ; ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
379
  <li class="customify_line_height_wrapper customize-control font-options__option">
380
  <label><?php esc_html_e( 'Line height', 'customify' ); ?></label>
381
  <input type="range"
@@ -388,7 +409,34 @@ class Pix_Customize_Font_Control extends Pix_Customize_Control {
388
  function display_letter_spacing_field( $current_value ) {
389
 
390
  if ( ! empty( $this->fields['letter-spacing'] ) ) {
391
- $ls_val = isset( $current_value->letter_spacing ) ? $current_value->letter_spacing : 0; ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
392
  <li class="customify_letter_spacing_wrapper customize-control font-options__option">
393
  <label><?php esc_html_e( 'Letter Spacing', 'customify' ); ?></label>
394
  <input type="range"
@@ -579,10 +627,10 @@ class Pix_Customize_Font_Control extends Pix_Customize_Control {
579
 
580
  if ( isset( $this->default ) && is_array( $this->default ) ) {
581
 
582
- //Handle special logic for when the $value array is not an associative array
583
  if ( ! PixCustomifyPlugin()->is_assoc( $this->default ) ) {
584
 
585
- //Let's determine some type of font
586
  if ( ! isset( $this->default[2] ) || ( isset( $this->default[2] ) && 'google' == $this->default[2] ) ) {
587
  if ( isset( self::$google_fonts[ $this->default[0] ] ) ) {
588
  $to_return = self::$google_fonts[ $this->default[0] ];
@@ -593,13 +641,13 @@ class Pix_Customize_Font_Control extends Pix_Customize_Control {
593
  $to_return['type'] = $this->default[2];
594
  }
595
 
596
- //The first entry is the font-family
597
  if ( isset( $this->default[0] ) ) {
598
  $to_return['font_family'] = $this->default[0];
599
  }
600
 
601
- //In case we don't have an associative array
602
- //The second entry is the variants
603
  if ( isset( $this->default[1] ) ) {
604
  $to_return['selected_variants'] = $this->default[1];
605
  }
@@ -639,7 +687,7 @@ class Pix_Customize_Font_Control extends Pix_Customize_Control {
639
  }
640
  }
641
 
642
- // rare case when there is a standard font we need to get the custom variants if there are some
643
  if ( ! isset( $to_return['variants'] ) && isset( $to_return['font_family'] ) && isset( self::$std_fonts[ $to_return['font_family'] ] ) && isset( self::$std_fonts[ $to_return['font_family'] ]['variants'] ) ) {
644
  $to_return['variants'] = self::$std_fonts[ $to_return['font_family'] ]['variants'];
645
  }
37
  public function __construct( $manager, $id, $args = array() ) {
38
  global $wp_customize;
39
 
40
+ parent::__construct( $manager, $id, $args );
41
+
42
  self::$std_fonts = apply_filters( 'customify_filter_standard_fonts_list', array(
43
  "Arial, Helvetica, sans-serif" => "Arial, Helvetica, sans-serif",
44
  "'Arial Black', Gadget, sans-serif" => "'Arial Black', Gadget, sans-serif",
59
  "Verdana, Geneva, sans-serif" => "Verdana, Geneva, sans-serif",
60
  ) );
61
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
62
  $this->CSSID = $this->get_CSS_ID();
63
  $this->load_google_fonts();
64
 
103
  }
104
  } else {
105
  //if we've got a string then it is clear we need to decode it
106
+ $current_value = json_decode( $current_value, true );
107
  }
108
 
109
  $current_value = $this->validate_font_values( $current_value );
265
  }
266
 
267
  function display_font_weight_field( $current_value ) {
 
268
  $display = 'none';
 
269
  if ( ! $this->load_all_weights && $this->font_weight ) {
270
  $display = 'inline-block';
271
  } ?>
272
+ <li class="customify_weights_wrapper customize-control font-options__option" style="display: <?php echo $display; ?>;">
273
+ <select class="customify_font_weight" data-field="selected_variants" <?php echo ! empty( $current_value->selected_variants ) ? 'data-default="' . $current_value->selected_variants . '"' : ''; echo ( isset( $this->fields['font-weight'] ) && false === $this->fields['font-weight'] ) ? 'data-disabled' : ''; ?>>
 
274
  <?php
275
  $selected = array();
276
  if ( isset( $current_value->selected_variants ) ) {
299
  if ( $this->subsets && ! empty( $current_value->subsets ) ) {
300
  $display = 'inline-block';
301
  } ?>
302
+ <li class="customify_subsets_wrapper customize-control font-options__option" style="display: <?php echo $display; ?>;">
303
+ <select multiple class="customify_font_subsets" data-field="selected_subsets" <?php echo ( isset( $this->fields['subsets'] ) && false === $this->fields['subsets'] ) ? 'data-disabled' : ''; ?>>
 
304
  <?php
305
  $selected = array();
306
  if ( isset( $current_value->selected_subsets ) ) {
330
 
331
  function display_font_size_field( $current_value ) {
332
  if ( ! empty( $this->fields['font-size'] ) ) {
333
+ $fs_val = empty( $current_value->font_size ) ? 0 : $current_value->font_size;
334
+ // If the current val also contains the unit, we need to take that into account.
335
+ if ( ! is_numeric( $fs_val ) ) {
336
+ if ( is_string( $fs_val ) ) {
337
+ // We will get everything in front that is a valid part of a number (float including).
338
+ preg_match( "/^([\d.\-+]+)/i", $fs_val, $match );
339
+
340
+ if ( ! empty( $match ) && isset( $match[0] ) ) {
341
+ if ( ! PixCustomifyPlugin()->is_assoc( $this->fields['font-size'] ) ) {
342
+ $this->fields['font-size'][3] = substr( $fs_val, strlen( $match[0] ) );
343
+ } else {
344
+ $this->fields['font-size']['unit'] = substr( $fs_val, strlen( $match[0] ) );
345
+ }
346
+ $fs_val = $match[0];
347
+ }
348
+ } elseif ( is_array( $fs_val ) ) {
349
+ if ( isset( $fs_val['unit']) ) {
350
+ if ( ! PixCustomifyPlugin()->is_assoc( $this->fields['font-size'] ) ) {
351
+ $this->fields['font-size'][3] = $fs_val['unit'];
352
+ } else {
353
+ $this->fields['font-size']['unit'] = $fs_val['unit'];
354
+ }
355
+ }
356
+
357
+ $fs_val = $fs_val['value'];
358
+ }
359
+ }
360
+ ?>
361
  <li class="customify_font_size_wrapper customize-control font-options__option">
362
  <label><?php esc_html_e( 'Font Size', 'customify' ); ?></label>
363
  <input type="range"
369
 
370
  function display_line_height_field( $current_value ) {
371
  if ( ! empty( $this->fields['line-height'] ) ) {
372
+ $lh_val = isset( $current_value->line_height ) ? $current_value->line_height : 0 ;
373
+ // If the current val also contains the unit, we need to take that into account.
374
+ if ( ! is_numeric( $lh_val ) ) {
375
+ if ( is_string( $lh_val ) ) {
376
+ // We will get everything in front that is a valid part of a number (float including).
377
+ preg_match( "/^([\d.\-+]+)/i", $lh_val, $match );
378
+
379
+ if ( ! empty( $match ) && isset( $match[0] ) ) {
380
+ if ( ! PixCustomifyPlugin()->is_assoc( $this->fields['line-height'] ) ) {
381
+ $this->fields['line-height'][3] = substr( $lh_val, strlen( $match[0] ) );
382
+ } else {
383
+ $this->fields['line-height']['unit'] = substr( $lh_val, strlen( $match[0] ) );
384
+ }
385
+ $lh_val = $match[0];
386
+ }
387
+ } elseif ( is_array( $lh_val ) ) {
388
+ if ( isset( $lh_val['unit']) ) {
389
+ if ( ! PixCustomifyPlugin()->is_assoc( $this->fields['line-height'] ) ) {
390
+ $this->fields['line-height'][3] = $lh_val['unit'];
391
+ } else {
392
+ $this->fields['line-height']['unit'] = $lh_val['unit'];
393
+ }
394
+ }
395
+
396
+ $lh_val = $lh_val['value'];
397
+ }
398
+ }
399
+ ?>
400
  <li class="customify_line_height_wrapper customize-control font-options__option">
401
  <label><?php esc_html_e( 'Line height', 'customify' ); ?></label>
402
  <input type="range"
409
  function display_letter_spacing_field( $current_value ) {
410
 
411
  if ( ! empty( $this->fields['letter-spacing'] ) ) {
412
+ $ls_val = isset( $current_value->letter_spacing ) ? $current_value->letter_spacing : 0;
413
+ // If the current val also contains the unit, we need to take that into account.
414
+ if ( ! is_numeric( $ls_val ) ) {
415
+ if ( is_string( $ls_val ) ) {
416
+ // We will get everything in front that is a valid part of a number (float including).
417
+ preg_match( "/^([\d.\-+]+)/i", $ls_val, $match );
418
+
419
+ if ( ! empty( $match ) && isset( $match[0] ) ) {
420
+ if ( ! PixCustomifyPlugin()->is_assoc( $this->fields['letter-spacing'] ) ) {
421
+ $this->fields['letter-spacing'][3] = substr( $ls_val, strlen( $match[0] ) );
422
+ } else {
423
+ $this->fields['letter-spacing']['unit'] = substr( $ls_val, strlen( $match[0] ) );
424
+ }
425
+ $ls_val = $match[0];
426
+ }
427
+ } elseif ( is_array( $ls_val ) ) {
428
+ if ( isset( $ls_val['unit']) ) {
429
+ if ( ! PixCustomifyPlugin()->is_assoc( $this->fields['letter-spacing'] ) ) {
430
+ $this->fields['letter-spacing'][3] = $ls_val['unit'];
431
+ } else {
432
+ $this->fields['letter-spacing']['unit'] = $ls_val['unit'];
433
+ }
434
+ }
435
+
436
+ $ls_val = $ls_val['value'];
437
+ }
438
+ }
439
+ ?>
440
  <li class="customify_letter_spacing_wrapper customize-control font-options__option">
441
  <label><?php esc_html_e( 'Letter Spacing', 'customify' ); ?></label>
442
  <input type="range"
627
 
628
  if ( isset( $this->default ) && is_array( $this->default ) ) {
629
 
630
+ // Handle special logic for when the $value array is not an associative array.
631
  if ( ! PixCustomifyPlugin()->is_assoc( $this->default ) ) {
632
 
633
+ // Let's determine some type of font.
634
  if ( ! isset( $this->default[2] ) || ( isset( $this->default[2] ) && 'google' == $this->default[2] ) ) {
635
  if ( isset( self::$google_fonts[ $this->default[0] ] ) ) {
636
  $to_return = self::$google_fonts[ $this->default[0] ];
641
  $to_return['type'] = $this->default[2];
642
  }
643
 
644
+ // The first entry is the font-family.
645
  if ( isset( $this->default[0] ) ) {
646
  $to_return['font_family'] = $this->default[0];
647
  }
648
 
649
+ // In case we don't have an associative array.
650
+ // The second entry is the variants.
651
  if ( isset( $this->default[1] ) ) {
652
  $to_return['selected_variants'] = $this->default[1];
653
  }
687
  }
688
  }
689
 
690
+ // Rare case when there is a standard font we need to get the custom variants if there are some.
691
  if ( ! isset( $to_return['variants'] ) && isset( $to_return['font_family'] ) && isset( self::$std_fonts[ $to_return['font_family'] ] ) && isset( self::$std_fonts[ $to_return['font_family'] ]['variants'] ) ) {
692
  $to_return['variants'] = self::$std_fonts[ $to_return['font_family'] ]['variants'];
693
  }
features/customizer/controls/class-Pix_Customize_Preset_Control.php CHANGED
@@ -140,7 +140,7 @@ class Pix_Customize_Preset_Control extends Pix_Customize_Control {
140
  // Make sure that the preview defaults are in place
141
  $choice_config['preview'] = wp_parse_args( $choice_config['preview'], array(
142
  'sample_letter' => 'A',
143
- 'background_image_url' => plugins_url( 'images/color_palette_image.jpg', PixCustomifyPlugin()->file ),
144
  ) );
145
 
146
  // Determine a (primary) color with fallback for missing options
@@ -194,18 +194,19 @@ class Pix_Customize_Preset_Control extends Pix_Customize_Control {
194
  ?>
195
 
196
  <span class="customize-inside-control-row <?php echo ( (string) $this->value() === (string) $choice_value ? 'current-color-palette' : '' );?>" style="background-image: url( <?php echo esc_url( $choice_config['preview']['background_image_url'] ); ?> );">
197
- <input <?php $this->link(); echo 'name="' . $this->setting->id . '" id="' . esc_attr( $choice_value ) . '" type="radio" value="' . esc_attr( $choice_value ) . '" ' . selected( $this->value(), $choice_value, false ) . $data .' />'; ?>
198
- <label for="<?php echo esc_attr( $choice_value ); ?>">
199
  <span class="label__inner" style="color: <?php echo esc_attr( $this->lightOrDark( $sm_light ) ); ?>; background: <?php echo esc_attr( $sm_light ); ?>;">
200
  <i class="preview__letter" style="background: <?php echo $sm_color; ?>"><?php echo $choice_config['preview']['sample_letter']; ?></i>
201
- <i class="preview__letter--checked" style="background-color: <?php echo $sm_color; ?>; background-image: url('<?php echo plugins_url( 'images/check.svg', PixCustomifyPlugin()->file ); ?>')"></i>
202
  <?php echo esc_html( $label ); ?>
203
  </span>
204
  </label>
205
  <div class="palette">
206
- <?php foreach ( $choice_config['options'] as $color_name => $color_value ) {
207
- if ( ! empty( $customizer_config["sections"]["style_manager_section"]["options"][$color_name]['connected_fields'] ) ) {
208
- echo '<div class="palette__item ' . esc_attr( $color_name ) . '" style="background: ' . esc_attr( $color_value ) . '"></div>' . PHP_EOL;
 
209
  }
210
  } ?>
211
  </div>
@@ -216,6 +217,75 @@ class Pix_Customize_Preset_Control extends Pix_Customize_Control {
216
  <?php break;
217
  }
218
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
219
  case 'awesome' : { ?>
220
  <label>
221
  <?php if ( ! empty( $this->label ) ) { ?>
140
  // Make sure that the preview defaults are in place
141
  $choice_config['preview'] = wp_parse_args( $choice_config['preview'], array(
142
  'sample_letter' => 'A',
143
+ 'background_image_url' => plugins_url( 'images/color_palette_image.jpg', PixCustomifyPlugin()->get_file() ),
144
  ) );
145
 
146
  // Determine a (primary) color with fallback for missing options
194
  ?>
195
 
196
  <span class="customize-inside-control-row <?php echo ( (string) $this->value() === (string) $choice_value ? 'current-color-palette' : '' );?>" style="background-image: url( <?php echo esc_url( $choice_config['preview']['background_image_url'] ); ?> );">
197
+ <input <?php $this->link(); echo 'name="' . $this->setting->id . '" id="' . esc_attr( $choice_value ) . '-color-palette" type="radio" value="' . esc_attr( $choice_value ) . '" ' . selected( $this->value(), $choice_value, false ) . $data .' />'; ?>
198
+ <label for="<?php echo esc_attr( $choice_value ) . '-color-palette'; ?>">
199
  <span class="label__inner" style="color: <?php echo esc_attr( $this->lightOrDark( $sm_light ) ); ?>; background: <?php echo esc_attr( $sm_light ); ?>;">
200
  <i class="preview__letter" style="background: <?php echo $sm_color; ?>"><?php echo $choice_config['preview']['sample_letter']; ?></i>
201
+ <i class="preview__letter--checked" style="background-color: <?php echo $sm_color; ?>; background-image: url('<?php echo plugins_url( 'images/check.svg', PixCustomifyPlugin()->get_file() ); ?>')"></i>
202
  <?php echo esc_html( $label ); ?>
203
  </span>
204
  </label>
205
  <div class="palette">
206
+ <?php foreach ( $choice_config['options'] as $color_setting_id => $color_value ) {
207
+ $field_config = PixCustomifyPlugin()->get_option_customizer_config( $color_setting_id );
208
+ if ( ! empty( $field_config['connected_fields'] ) ) {
209
+ echo '<div class="palette__item ' . esc_attr( $color_setting_id ) . '" style="background: ' . esc_attr( $color_value ) . '"></div>' . PHP_EOL;
210
  }
211
  } ?>
212
  </div>
217
  <?php break;
218
  }
219
 
220
+ case 'font_palette' : { ?>
221
+ <?php if ( ! empty( $this->label ) ) { ?>
222
+ <span class="customize-control-title"><?php echo esc_html( $this->label ); ?></span>
223
+ <?php }
224
+
225
+ if ( ! empty( $this->description ) ) { ?>
226
+ <span class="description customize-control-description"><?php echo $this->description; ?></span>
227
+ <?php } ?>
228
+
229
+ <div class="customify_preset font_palette customize-control customize-control-radio">
230
+ <?php
231
+ foreach ( $this->choices as $choice_value => $choice_config ){
232
+ if ( empty( $choice_config['options'] ) && empty( $choice_config['fonts_logic'] ) ) {
233
+ continue;
234
+ }
235
+
236
+ // Make sure that the defaults are in place
237
+ $choice_config = wp_parse_args( $choice_config, array(
238
+ 'label' => '',
239
+ 'preview' => array(),
240
+ ) );
241
+
242
+ // Make sure that the preview defaults are in place
243
+ $choice_config['preview'] = wp_parse_args( $choice_config['preview'], array(
244
+ 'sample_letter' => 'A',
245
+ 'background_image_url' => plugins_url( 'images/color_palette_image.jpg', PixCustomifyPlugin()->get_file() ),
246
+ ) );
247
+
248
+ $label = $choice_config['label'];
249
+
250
+ if ( empty( $choice_config['options'] ) ) {
251
+ $choice_config['options'] = array();
252
+ }
253
+ $options = $this->convertChoiceOptionsIdsToSettingIds( $choice_config['options'] );
254
+ $data = ' data-options=\'' . json_encode( $options ) . '\'';
255
+
256
+ if ( empty( $choice_config['fonts_logic'] ) ) {
257
+ $choice_config['fonts_logic'] = array();
258
+ }
259
+ $fonts = $this->convertChoiceOptionsIdsToSettingIds( $choice_config['fonts_logic'] );
260
+ $data .= ' data-fonts_logic=\'' . json_encode( $fonts ) . '\'';
261
+
262
+ $customizer_config = PixCustomifyPlugin()->get_customizer_config();
263
+
264
+ ?>
265
+
266
+ <span class="customize-inside-control-row <?php echo ( (string) $this->value() === (string) $choice_value ? 'current-font-palette' : '' );?>" style="background-image: url( <?php echo esc_url( $choice_config['preview']['background_image_url'] ); ?> );">
267
+ <input <?php $this->link(); echo 'name="' . $this->setting->id . '" id="' . esc_attr( $choice_value ) . '-font-palette" type="radio" value="' . esc_attr( $choice_value ) . '" ' . selected( $this->value(), $choice_value, false ) . $data .' />'; ?>
268
+ <label for="<?php echo esc_attr( $choice_value ) . '-font-palette'; ?>">
269
+ <span class="label__inner" style="">
270
+ <i class="preview__letter" style=""><?php echo $choice_config['preview']['sample_letter']; ?></i>
271
+ <i class="preview__letter--checked" style="background-image: url('<?php echo plugins_url( 'images/check.svg', PixCustomifyPlugin()->get_file() ); ?>')"></i>
272
+ <?php echo esc_html( $label ); ?>
273
+ </span>
274
+ </label>
275
+ <div class="palette">
276
+ <?php foreach ( $choice_config['fonts_logic'] as $font_name => $font_value ) {
277
+ if ( ! empty( $customizer_config['sections']['style_manager_section']['options'][$font_name]['connected_fields'] ) ) {
278
+ echo '<div class="palette__item ' . esc_attr( $font_name ) . '" style=""></div>' . PHP_EOL;
279
+ }
280
+ } ?>
281
+ </div>
282
+ </span>
283
+ <?php } ?>
284
+ </div>
285
+
286
+ <?php break;
287
+ }
288
+
289
  case 'awesome' : { ?>
290
  <label>
291
  <?php if ( ! empty( $this->label ) ) { ?>
features/customizer/controls/class-Pix_Customize_Textarea_Control.php CHANGED
@@ -14,11 +14,12 @@ class Pix_Customize_Textarea_Control extends Pix_Customize_Control {
14
  * @since 3.4.0
15
  */
16
  public function render_content() { ?>
 
17
  <label>
18
  <?php if ( ! empty( $this->label ) ) : ?>
19
  <span class="customize-control-title"><?php echo esc_html( $this->label ); ?></span>
20
  <?php endif; ?>
21
- <textarea rows="5" <?php $this->link(); ?>><?php echo esc_textarea( $this->value() ); ?></textarea>
22
  <?php if ( ! empty( $this->description ) ) : ?>
23
  <span class="description customize-control-description"><?php echo $this->description; ?></span>
24
  <?php endif; ?>
14
  * @since 3.4.0
15
  */
16
  public function render_content() { ?>
17
+
18
  <label>
19
  <?php if ( ! empty( $this->label ) ) : ?>
20
  <span class="customize-control-title"><?php echo esc_html( $this->label ); ?></span>
21
  <?php endif; ?>
22
+ <textarea id="<?php echo $this->id; ?>" rows="5" <?php $this->link(); ?>><?php echo esc_textarea( $this->value() ); ?></textarea>
23
  <?php if ( ! empty( $this->description ) ) : ?>
24
  <span class="description customize-control-description"><?php echo $this->description; ?></span>
25
  <?php endif; ?>
gulpfile.js DELETED
@@ -1,210 +0,0 @@
1
- var plugin = 'customify',
2
- source_SCSS = 'scss/**/*.scss',
3
- dest_CSS = './css/',
4
-
5
- gulp = require('gulp'),
6
- sass = require('gulp-sass'),
7
- prefix = require('gulp-autoprefixer'),
8
- exec = require('gulp-exec'),
9
- replace = require('gulp-replace'),
10
- minify = require('gulp-minify-css'),
11
- concat = require('gulp-concat'),
12
- notify = require('gulp-notify'),
13
- beautify = require('gulp-beautify'),
14
- csscomb = require('gulp-csscomb'),
15
- cmq = require('gulp-combine-media-queries'),
16
- fs = require('fs'),
17
- rtlcss = require('rtlcss'),
18
- postcss = require('gulp-postcss'),
19
- del = require('del'),
20
- rename = require('gulp-rename');
21
-
22
- require('es6-promise').polyfill();
23
-
24
- var jsFiles = [
25
- './assets/js/vendor/*.js',
26
- './assets/js/main/wrapper_start.js',
27
- './assets/js/main/shared_vars.js',
28
- './assets/js/modules/*.js',
29
- './assets/js/main/main.js',
30
- './assets/js/main/functions.js',
31
- './assets/js/main/wrapper_end.js'
32
- ];
33
-
34
-
35
- var options = {
36
- silent: true,
37
- continueOnError: true // default: false
38
- };
39
-
40
- // styles related
41
- gulp.task('styles-dev', function () {
42
- return gulp.src(source_SCSS)
43
- .pipe(sass({'sourcemap': true, outputStyle: 'expanded'}))
44
- .on('error', function (e) {
45
- console.log(e.message);
46
- })
47
- .pipe(prefix("last 1 version", "> 1%", "ie 8", "ie 7"))
48
- .pipe(gulp.dest(dest_CSS));
49
- // .pipe(postcss([
50
- // require('rtlcss')({ /* options */ })
51
- // ]))
52
- // .pipe(rename("rtl.css"))
53
- // .pipe(gulp.dest('./'))
54
- });
55
-
56
- gulp.task('styles', function () {
57
- return gulp.src(source_SCSS)
58
- .pipe(sass({'sourcemap': false, outputStyle: 'compressed'}))
59
- .pipe(prefix("last 1 version", "> 1%", "ie 8", "ie 7"))
60
- .pipe(csscomb())
61
- .pipe(gulp.dest(dest_CSS, {"mode": "0644"}))
62
- });
63
-
64
- gulp.task('styles-watch', [ 'styles-dev' ], function () {
65
- return gulp.watch(source_SCSS, ['styles']);
66
- });
67
-
68
- // javascript stuff
69
- gulp.task('scripts', function () {
70
- return gulp.src(jsFiles)
71
- .pipe(concat('main.js'))
72
- .pipe(beautify({indentSize: 2}))
73
- .pipe(gulp.dest('./assets/js/', {"mode": "0644"}));
74
- });
75
-
76
- gulp.task('scripts-watch', function () {
77
- return gulp.watch(source_SCSS, ['scripts']);
78
- });
79
-
80
- gulp.task('watch', function () {
81
- gulp.watch(source_SCSS, ['styles-dev']);
82
- // gulp.watch('assets/js/**/*.js', ['scripts']);
83
- });
84
-
85
- // usually there is a default task for lazy people who just wanna type gulp
86
- gulp.task('start', ['styles', 'scripts'], function () {
87
- // silence
88
- });
89
-
90
- gulp.task('server', ['styles', 'scripts'], function () {
91
- console.log('The styles and scripts have been compiled for production! Go and clear the caches!');
92
- });
93
-
94
- /**
95
- * Create a zip archive out of the cleaned folder and delete the folder
96
- */
97
- gulp.task( 'zip', ['build'], function() {
98
- var versionString = '';
99
- // get plugin version from the main plugin file
100
- var contents = fs.readFileSync("./" + plugin + ".php", "utf8");
101
-
102
- // split it by lines
103
- var lines = contents.split(/[\r\n]/);
104
-
105
- function checkIfVersionLine(value, index, ar) {
106
- var myRegEx = /^[\s\*]*[Vv]ersion:/;
107
- if (myRegEx.test(value)) {
108
- return true;
109
- }
110
- return false;
111
- }
112
-
113
- // apply the filter
114
- var versionLine = lines.filter(checkIfVersionLine);
115
-
116
- versionString = versionLine[0].replace(/^[\s\*]*[Vv]ersion:/, '').trim();
117
- versionString = '-' + versionString.replace(/\./g, '-');
118
-
119
- return gulp.src('./')
120
- .pipe(exec('cd ./../; rm -rf ' + plugin[0].toUpperCase() + plugin.slice(1) + '*.zip; cd ./build/; zip -r -X ./../' + plugin[0].toUpperCase() + plugin.slice(1) + versionString + '.zip ./; cd ./../; rm -rf build'));
121
-
122
- } );
123
-
124
- /**
125
- * Copy theme folder outside in a build folder, recreate styles before that
126
- */
127
- gulp.task( 'copy-folder', function() {
128
-
129
- return gulp.src( './' )
130
- .pipe( exec( 'rm -Rf ./../build; mkdir -p ./../build/customify; cp -Rf ./* ./../build/customify/' ) );
131
- } );
132
-
133
- /**
134
- * Clean the folder of unneeded files and folders
135
- */
136
- gulp.task( 'build', ['copy-folder'], function() {
137
-
138
- // files that should not be present in build zip
139
- files_to_remove = [
140
- '**/codekit-config.json',
141
- 'node_modules',
142
- 'config.rb',
143
- 'gulpfile.js',
144
- 'package.json',
145
- 'package-lock.json',
146
- 'pxg.json',
147
- 'build',
148
- '.idea',
149
- '**/*.css.map',
150
- '**/.git*',
151
- '*.sublime-project',
152
- '.DS_Store',
153
- '**/.DS_Store',
154
- '__MACOSX',
155
- '**/__MACOSX',
156
- '+development.rb',
157
- '+production.rb',
158
- 'README.md',
159
- '.labels',
160
- '.csscomb',
161
- '.csscomb.json',
162
- '.codeclimate.yml',
163
- 'tests',
164
- 'circle.yml',
165
- '.circleci',
166
- '.labels',
167
- '.jscsrc',
168
- '.jshintignore',
169
- 'browserslist'
170
- ];
171
-
172
- files_to_remove.forEach( function( e, k ) {
173
- files_to_remove[k] = '../build/customify/' + e;
174
- } );
175
-
176
- return del.sync(files_to_remove, {force: true});
177
- } );
178
-
179
- // usually there is a default task for lazy people who just wanna type gulp
180
- gulp.task('default', ['start'], function () {
181
- // silence
182
- });
183
-
184
- /**
185
- * Short commands help
186
- */
187
-
188
- gulp.task('help', function () {
189
-
190
- var $help = '\nCommands available : \n \n' +
191
- '=== General Commands === \n' +
192
- 'start (default)Compiles all styles and scripts and makes the theme ready to start \n' +
193
- 'zip Generate the zip archive \n' +
194
- 'build Generate the build directory with the cleaned theme \n' +
195
- 'help Print all commands \n' +
196
- '=== Style === \n' +
197
- 'styles Compiles styles in production mode\n' +
198
- 'styles-dev Compiles styles in development mode \n' +
199
- 'styles-admin Compiles admin styles \n' +
200
- '=== Scripts === \n' +
201
- 'scripts Concatenate all js scripts \n' +
202
- 'scripts-dev Concatenate all js scripts \n' +
203
- '=== Watchers === \n' +
204
- 'watch Watches all js and scss files \n' +
205
- 'styles-watch Watch only styles\n' +
206
- 'scripts-watch Watch scripts only \n';
207
-
208
- console.log($help);
209
-
210
- });
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
includes/class-customify-color-palettes.php ADDED
@@ -0,0 +1,890 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * This is the class that handles the logic for Color Palettes.
4
+ *
5
+ * @see https://pixelgrade.com
6
+ * @author Pixelgrade
7
+ * @since 1.7.4
8
+ */
9
+
10
+ if ( ! defined( 'ABSPATH' ) ) {
11
+ exit; // Exit if accessed directly
12
+ }
13
+
14
+ if ( ! class_exists( 'Customify_Color_Palettes' ) ) :
15
+
16
+ class Customify_Color_Palettes {
17
+
18
+ /**
19
+ * Holds the only instance of this class.
20
+ * @var null|Customify_Font_Palettes
21
+ * @access protected
22
+ * @since 1.7.4
23
+ */
24
+ protected static $_instance = null;
25
+
26
+ /**
27
+ * Constructor.
28
+ *
29
+ * @since 1.7.4
30
+ */
31
+ protected function __construct() {
32
+ $this->init();
33
+ }
34
+
35
+ /**
36
+ * Initialize this module.
37
+ *
38
+ * @since 1.7.4
39
+ */
40
+ public function init() {
41
+ // Hook up.
42
+ $this->add_hooks();
43
+ }
44
+
45
+ /**
46
+ * Initiate our hooks
47
+ *
48
+ * @since 1.7.4
49
+ */
50
+ public function add_hooks() {
51
+ /*
52
+ * Handle the Customizer Style Manager section config.
53
+ */
54
+ add_filter( 'customify_filter_fields', array( $this, 'add_style_manager_section_master_colors_config' ), 12, 1 );
55
+ // This needs to come after the external theme config has been applied
56
+ add_filter( 'customify_filter_fields', array( $this, 'add_current_palette_control' ), 110, 1 );
57
+
58
+ /*
59
+ * Scripts enqueued in the Customizer.
60
+ */
61
+ add_action( 'customize_controls_init', array( $this, 'register_admin_customizer_scripts' ), 10 );
62
+ add_action( 'customize_controls_enqueue_scripts', array( $this, 'enqueue_admin_customizer_scripts' ), 10 );
63
+
64
+ /*
65
+ * Handle the logic on settings update/save.
66
+ */
67
+ add_action( 'customize_save_after', array( $this, 'update_custom_palette_in_use' ), 10, 1 );
68
+
69
+ /**
70
+ * Add color palettes usage to site data.
71
+ */
72
+ add_filter( 'customify_style_manager_get_site_data', array( $this, 'add_palettes_to_site_data' ), 10, 1 );
73
+ }
74
+
75
+ /**
76
+ * Register Customizer admin scripts
77
+ */
78
+ public function register_admin_customizer_scripts() {
79
+ wp_register_script( PixCustomifyPlugin()->get_slug() . '-swap-values', plugins_url( 'js/customizer/swap-values.js', PixCustomifyPlugin()->get_file() ), array( 'jquery' ), PixCustomifyPlugin()->get_version() );
80
+ wp_register_script( PixCustomifyPlugin()->get_slug() . '-color-palettes-variations', plugins_url( 'js/customizer/color-palettes-variations.js', PixCustomifyPlugin()->get_file() ), array( 'jquery' ), PixCustomifyPlugin()->get_version() );
81
+ wp_register_script( PixCustomifyPlugin()->get_slug() . '-color-palettes', plugins_url( 'js/customizer/color-palettes.js', PixCustomifyPlugin()->get_file() ), array( 'jquery', PixCustomifyPlugin()->get_slug() . '-color-palettes-variations', PixCustomifyPlugin()->get_slug() . '-swap-values' ), PixCustomifyPlugin()->get_version() );
82
+ }
83
+
84
+ /**
85
+ * Enqueue Customizer admin scripts
86
+ */
87
+ public function enqueue_admin_customizer_scripts() {
88
+ // If there is no color palettes support, bail early.
89
+ if ( ! $this->is_supported() ) {
90
+ return;
91
+ }
92
+
93
+ wp_enqueue_script( PixCustomifyPlugin()->get_slug() . '-color-palettes' );
94
+ }
95
+
96
+ /**
97
+ * Get the color palettes configuration.
98
+ *
99
+ * @since 1.7.4
100
+ *
101
+ * @param bool $skip_cache Optional. Whether to use the cached config or fetch a new one.
102
+ *
103
+ * @return array
104
+ */
105
+ public function get_palettes( $skip_cache = false ) {
106
+ // Make sure that the Design Assets class is loaded.
107
+ require_once 'lib/class-customify-design-assets.php';
108
+
109
+ // Get the design assets data.
110
+ $design_assets = Customify_Design_Assets::instance()->get( $skip_cache );
111
+ if ( false === $design_assets || empty( $design_assets['color_palettes'] ) ) {
112
+ $color_palettes_config = $this->get_default_config();
113
+ } else {
114
+ $color_palettes_config = $design_assets['color_palettes'];
115
+ }
116
+
117
+ return apply_filters( 'customify_get_color_palettes', $color_palettes_config );
118
+ }
119
+
120
+ /**
121
+ * Determine if Color Palettes are supported.
122
+ *
123
+ * @since 1.7.4
124
+ *
125
+ * @return bool
126
+ */
127
+ public function is_supported() {
128
+ // For now we will only use the fact that Style Manager is supported.
129
+ return apply_filters( 'customify_color_palettes_are_supported', Customify_Style_Manager::instance()->is_supported() );
130
+ }
131
+
132
+ /**
133
+ * Setup the Style Manager Customizer section master colors config.
134
+ *
135
+ * This handles the base configuration for the controls in the Style Manager section. We expect other parties (e.g. the theme),
136
+ * to come and fill up the missing details (e.g. connected fields).
137
+ *
138
+ * @since 1.7.4
139
+ *
140
+ * @param array $config This holds required keys for the plugin config like 'opt-name', 'panels', 'settings'.
141
+ *
142
+ * @return array
143
+ */
144
+ public function add_style_manager_section_master_colors_config( $config ) {
145
+ // If there is no style manager support, bail early.
146
+ if ( ! $this->is_supported() ) {
147
+ return $config;
148
+ }
149
+
150
+ if ( ! isset( $config['sections']['style_manager_section'] ) ) {
151
+ $config['sections']['style_manager_section'] = array();
152
+ }
153
+
154
+ // The section might be already defined, thus we merge, not replace the entire section config.
155
+ $config['sections']['style_manager_section'] = array_replace_recursive( $config['sections']['style_manager_section'], array(
156
+ 'options' => array(
157
+ 'sm_color_palette' => array(
158
+ 'type' => 'preset',
159
+ // We will bypass the plugin setting regarding where to store - we will store it cross-theme in wp_options
160
+ 'setting_type' => 'option',
161
+ // We will force this setting id preventing prefixing and other regular processing.
162
+ 'setting_id' => 'sm_color_palette',
163
+ // We don't want to refresh the preview window, even though we have no direct effect on it through this field.
164
+ 'live' => true,
165
+ 'priority' => 10,
166
+ 'label' => esc_html__( 'Select a color palette:', 'customify' ),
167
+ 'desc' => esc_html__( 'Conveniently change the design of your site with color palettes. Easy as pie.', 'customify' ),
168
+ 'default' => 'lilac',
169
+ 'choices_type' => 'color_palette',
170
+ 'choices' => $this->get_palettes(),
171
+ ),
172
+ 'sm_color_palette_variation' => array(
173
+ 'type' => 'radio',
174
+ 'setting_type' => 'option',
175
+ 'setting_id' => 'sm_color_palette_variation',
176
+ 'label' => esc_html__( 'Palette Variation', 'customify' ),
177
+ 'default' => 'light',
178
+ 'live' => true,
179
+ 'priority' => 10.5,
180
+ 'choices' => array(
181
+ 'light' => esc_html__( 'light', 'customify' ),
182
+ 'light_alt' => esc_html__( 'light_alt', 'customify' ),
183
+
184
+ 'dark' => esc_html__( 'dark', 'customify' ),
185
+ 'dark_alt' => esc_html__( 'dark_alt', 'customify' ),
186
+
187
+ 'colorful' => esc_html__( 'colorful', 'customify' ),
188
+ 'colorful_alt' => esc_html__( 'colorful_alt', 'customify' ),
189
+ ),
190
+ ),
191
+ 'sm_color_primary' => array(
192
+ 'type' => 'color',
193
+ // We will bypass the plugin setting regarding where to store - we will store it cross-theme in wp_options
194
+ 'setting_type' => 'option',
195
+ // We will force this setting id preventing prefixing and other regular processing.
196
+ 'setting_id' => 'sm_color_primary',
197
+ // We don't want to refresh the preview window, even though we have no direct effect on it through this field.
198
+ 'live' => true,
199
+ 'priority' => 20,
200
+ 'label' => esc_html__( 'Color Primary', 'customify' ),
201
+ 'default' => '#ffeb00',
202
+ 'connected_fields' => array(),
203
+ ),
204
+ 'sm_color_secondary' => array(
205
+ 'type' => 'color',
206
+ 'setting_type' => 'option',
207
+ 'setting_id' => 'sm_color_secondary',
208
+ 'live' => true,
209
+ 'priority' => 20.1,
210
+ 'label' => esc_html__( 'Color Secondary', 'customify' ),
211
+ 'default' => '#00ecff',
212
+ 'connected_fields' => array(),
213
+ ),
214
+ 'sm_color_tertiary' => array(
215
+ 'type' => 'color',
216
+ 'setting_type' => 'option',
217
+ 'setting_id' => 'sm_color_tertiary',
218
+ 'live' => true,
219
+ 'priority' => 20.2,
220
+ 'label' => esc_html__( 'Color Tertiary', 'customify' ),
221
+ 'default' => '#00ecff',
222
+ 'connected_fields' => array(),
223
+ ),
224
+ 'sm_dark_primary' => array(
225
+ 'type' => 'color',
226
+ 'setting_type' => 'option',
227
+ 'setting_id' => 'sm_dark_primary',
228
+ 'live' => true,
229
+ 'priority' => 20.3,
230
+ 'label' => esc_html__( 'Dark Primary', 'customify' ),
231
+ 'default' => '#171617',
232
+ 'connected_fields' => array(),
233
+ ),
234
+ 'sm_dark_secondary' => array(
235
+ 'type' => 'color',
236
+ 'setting_type' => 'option',
237
+ 'setting_id' => 'sm_dark_secondary',
238
+ 'live' => true,
239
+ 'priority' => 20.4,
240
+ 'label' => esc_html__( 'Dark Secondary', 'customify' ),
241
+ 'default' => '#383c50',
242
+ 'connected_fields' => array(),
243
+ ),
244
+ 'sm_dark_tertiary' => array(
245
+ 'type' => 'color',
246
+ 'setting_type' => 'option',
247
+ 'setting_id' => 'sm_dark_tertiary',
248
+ 'live' => true,
249
+ 'priority' => 20.5,
250
+ 'label' => esc_html__( 'Dark Tertiary', 'customify' ),
251
+ 'default' => '#65726F',
252
+ 'connected_fields' => array(),
253
+ ),
254
+ 'sm_light_primary' => array(
255
+ 'type' => 'color',
256
+ 'setting_type' => 'option',
257
+ 'setting_id' => 'sm_light_primary',
258
+ 'live' => true,
259
+ 'priority' => 20.6,
260
+ 'label' => esc_html__( 'Light Primary', 'customify' ),
261
+ 'default' => '#ffffff',
262
+ 'connected_fields' => array(),
263
+ ),
264
+ 'sm_light_secondary' => array(
265
+ 'type' => 'color',
266
+ 'setting_type' => 'option',
267
+ 'setting_id' => 'sm_light_secondary',
268
+ 'live' => true,
269
+ 'priority' => 20.7,
270
+ 'label' => esc_html__( 'Light Secondary', 'customify' ),
271
+ 'default' => '#ffffff',
272
+ 'connected_fields' => array(),
273
+ ),
274
+ 'sm_light_tertiary' => array(
275
+ 'type' => 'color',
276
+ 'setting_type' => 'option',
277
+ 'setting_id' => 'sm_light_tertiary',
278
+ 'live' => true,
279
+ 'priority' => 20.8,
280
+ 'label' => esc_html__( 'Light Tertiary', 'customify' ),
281
+ 'default' => '#ffffff',
282
+ 'connected_fields' => array(),
283
+ ),
284
+ 'sm_swap_colors' => array(
285
+ 'type' => 'button',
286
+ 'setting_type' => 'option',
287
+ 'setting_id' => 'sm_swap_colors',
288
+ 'priority' => 30,
289
+ 'label' => esc_html__( 'Swap Colors', 'customify' ),
290
+ 'action' => 'sm_swap_colors',
291
+ ),
292
+ 'sm_swap_dark_light' => array(
293
+ 'type' => 'button',
294
+ 'setting_type' => 'option',
295
+ 'setting_id' => 'sm_swap_dark_light',
296
+ 'priority' => 30.1,
297
+ 'label' => esc_html__( 'Swap Dark ⇆ Light', 'customify' ),
298
+ 'action' => 'sm_swap_dark_light',
299
+ ),
300
+ 'sm_swap_colors_dark' => array(
301
+ 'type' => 'button',
302
+ 'setting_type' => 'option',
303
+ 'setting_id' => 'sm_swap_colors_dark',
304
+ 'priority' => 30.2,
305
+ 'label' => esc_html__( 'Swap Colors ⇆ Dark', 'customify' ),
306
+ 'action' => 'sm_swap_colors_dark',
307
+ ),
308
+ 'sm_swap_secondary_colors_dark' => array(
309
+ 'type' => 'button',
310
+ 'setting_type' => 'option',
311
+ 'setting_id' => 'sm_swap_secondary_colors_dark',
312
+ 'priority' => 30.3,
313
+ 'label' => esc_html__( 'Swap Secondary Color ⇆ Secondary Dark', 'customify' ),
314
+ 'action' => 'sm_swap_secondary_colors_dark',
315
+ ),
316
+ 'sm_advanced_toggle' => array(
317
+ 'type' => 'button',
318
+ 'setting_type' => 'option',
319
+ 'setting_id' => 'sm_toggle_advanced_settings',
320
+ 'priority' => 30.4,
321
+ 'label' => esc_html__( 'Toggle Advanced Settings', 'customify' ),
322
+ 'action' => 'sm_toggle_advanced_settings',
323
+ ),
324
+ ),
325
+ ) );
326
+
327
+ return $config;
328
+ }
329
+
330
+ /**
331
+ * Add the current color palette control to the Style Manager section.
332
+ *
333
+ * @since 1.7.4
334
+ *
335
+ * @param array $config
336
+ *
337
+ * @return array
338
+ */
339
+ public function add_current_palette_control( $config ) {
340
+ // If there is no style manager support, bail early.
341
+ if ( ! $this->is_supported() ) {
342
+ return $config;
343
+ }
344
+
345
+ if ( ! isset( $config['sections']['style_manager_section'] ) ) {
346
+ $config['sections']['style_manager_section'] = array();
347
+ }
348
+
349
+ $current_palette = '';
350
+ $current_palette_sets = array( 'current', 'next' );
351
+
352
+ $master_color_controls_ids = $this->get_all_master_color_controls_ids( $config['sections']['style_manager_section']['options'] );
353
+
354
+ foreach ( $current_palette_sets as $set ) {
355
+ $current_palette .= '<div class="colors ' . $set . '">';
356
+ foreach ( $master_color_controls_ids as $setting_id ) {
357
+ $current_palette .=
358
+ '<div class="color ' . $setting_id . '" data-setting="' . $setting_id . '">' . PHP_EOL .
359
+ '<div class="fill"></div>' . PHP_EOL .
360
+ '<div class="picker">' .
361
+ '<i></i>'.
362
+ '</div>' . PHP_EOL .
363
+ '</div>' . PHP_EOL;
364
+ }
365
+ $current_palette .= '</div>';
366
+ }
367
+
368
+ $current_palette .= '<div class="c-color-palette__fields">';
369
+ foreach ( $master_color_controls_ids as $setting_id ) {
370
+ $current_palette .= '<input id="current-palette-' . $setting_id . '" class="c-color-palette__input ' . $setting_id . '" type="text">';
371
+ }
372
+ $current_palette .= '</div>';
373
+
374
+ // The section might be already defined, thus we merge, not replace the entire section config.
375
+ $config['sections']['style_manager_section']['options'] = array(
376
+ 'sm_current_color_palette' => array(
377
+ 'type' => 'html',
378
+ 'setting_id' => 'sm_current_color_palette',
379
+ 'html' =>
380
+ '<div class="color-palette-container">' . PHP_EOL .
381
+ '<span class="customize-control-title">Current Color Palette:</span>' . PHP_EOL .
382
+ '<span class="description customize-control-description">Choose a color palette to start with. Adjust its style using the variation buttons below.</span>' . PHP_EOL .
383
+ '<div class="c-color-palette">' . PHP_EOL .
384
+ $current_palette .
385
+ '<div class="c-color-palette__overlay">' . PHP_EOL .
386
+ '<div class="c-color-palette__label">' .
387
+ '<div class="c-color-palette__name">' . 'Original Style' . '</div>' .
388
+ '<div class="c-color-palette__control variation-light active" data-target="#_customize-input-sm_color_palette_variation_control-radio-light">' .
389
+ '<span class="dashicons dashicons-image-rotate"></span>' .
390
+ '<div class="c-color-palette__tooltip">Light</div>' .
391
+ '</div>' .
392
+ '<div class="c-color-palette__control variation-dark" data-target="#_customize-input-sm_color_palette_variation_control-radio-dark">' .
393
+ '<span class="dashicons dashicons-image-filter"></span>'.
394
+ '<div class="c-color-palette__tooltip">Dark</div>' .
395
+ '</div>' .
396
+ '<div class="c-color-palette__control variation-colorful" data-target="#_customize-input-sm_color_palette_variation_control-radio-colorful">' .
397
+ '<span class="dashicons dashicons-admin-appearance"></span>' .
398
+ '<div class="c-color-palette__tooltip">Colorful</div>' .
399
+ '</div>' .
400
+ '</div>' . PHP_EOL .
401
+ '</div>' . PHP_EOL .
402
+ '</div>' . PHP_EOL .
403
+ '</div>' . PHP_EOL .
404
+ '<svg class="c-color-palette__blur" width="15em" height="15em" viewBox="0 0 15 15" xmlns="http://www.w3.org/2000/svg" version="1.1">' . PHP_EOL .
405
+ '<defs>' . PHP_EOL .
406
+ '<filter id="goo">' . PHP_EOL .
407
+ '<feGaussianBlur in="SourceGraphic" stdDeviation="10" result="blur" />' . PHP_EOL .
408
+ '<feColorMatrix in="blur" mode="matrix" values="1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 50 -20" result="goo" />' . PHP_EOL .
409
+ '<feBlend in="SourceGraphic" in2="goo" />' . PHP_EOL .
410
+ '</filter>' . PHP_EOL .
411
+ '</defs>' . PHP_EOL .
412
+ '</svg>',
413
+ ),
414
+ 'sm_color_matrix' => array(
415
+ 'type' => 'html',
416
+ 'setting_id' => 'sm_color_matrix',
417
+ 'html' => '<div class="sm_color_matrix"></div>'
418
+ ),
419
+ // 'sm_dark_color_master_slider' => array(
420
+ // 'setting_id' => 'sm_dark_color_master_slider',
421
+ // 'type' => 'range',
422
+ // 'label' => esc_html__( 'Dark to Color (master)', 'customify' ),
423
+ // 'desc' => '',
424
+ // 'live' => true,
425
+ // 'default' => 50, // this should be set by the theme (previously 1300)
426
+ // 'input_attrs' => array(
427
+ // 'min' => 0,
428
+ // 'max' => 100,
429
+ // 'step' => 1,
430
+ // 'data-preview' => true,
431
+ // ),
432
+ // 'css' => array(),
433
+ // ),
434
+ // 'sm_dark_color_primary_slider' => array(
435
+ // 'setting_id' => 'sm_dark_color_primary_slider',
436
+ // 'type' => 'range',
437
+ // 'label' => esc_html__( 'Dark to Color (primary)', 'customify' ),
438
+ // 'desc' => '',
439
+ // 'live' => true,
440
+ // 'default' => $this->get_dark_to_color_slider_default_value( $config['sections']['style_manager_section']['options'], 'sm_dark_primary', 'sm_color_primary' ),
441
+ // 'input_attrs' => array(
442
+ // 'min' => 0,
443
+ // 'max' => 100,
444
+ // 'step' => 1,
445
+ // 'data-preview' => true,
446
+ // ),
447
+ // 'css' => array(),
448
+ // ),
449
+ // 'sm_dark_color_secondary_slider' => array(
450
+ // 'setting_id' => 'sm_dark_color_secondary_slider',
451
+ // 'type' => 'range',
452
+ // 'label' => esc_html__( 'Dark to Color (secondary)', 'customify' ),
453
+ // 'desc' => '',
454
+ // 'live' => true,
455
+ // 'default' => $this->get_dark_to_color_slider_default_value( $config['sections']['style_manager_section']['options'], 'sm_dark_secondary', 'sm_color_secondary' ), // this should be set by the theme (previously 1300)
456
+ // 'input_attrs' => array(
457
+ // 'min' => 0,
458
+ // 'max' => 100,
459
+ // 'step' => 1,
460
+ // 'data-preview' => true,
461
+ // ),
462
+ // 'css' => array(),
463
+ // ),
464
+ // 'sm_dark_color_tertiary_slider' => array(
465
+ // 'setting_id' => 'sm_dark_color_tertiary_slider',
466
+ // 'type' => 'range',
467
+ // 'label' => esc_html__( 'Dark to Color (tertiary)', 'customify' ),
468
+ // 'desc' => '',
469
+ // 'live' => true,
470
+ // 'default' => $this->get_dark_to_color_slider_default_value( $config['sections']['style_manager_section']['options'], 'sm_dark_tertiary', 'sm_color_tertiary' ), // this should be set by the theme (previously 1300)
471
+ // 'input_attrs' => array(
472
+ // 'min' => 0,
473
+ // 'max' => 100,
474
+ // 'step' => 1,
475
+ // 'data-preview' => true,
476
+ // ),
477
+ // 'css' => array(),
478
+ // ),
479
+ // 'sm_colors_dispersion' => array(
480
+ // 'setting_id' => 'sm_colors_dispersion',
481
+ // 'type' => 'range',
482
+ // 'label' => esc_html__( 'Colors dispersion range', 'customify' ),
483
+ // 'desc' => '',
484
+ // 'live' => true,
485
+ // 'default' => $this->get_color_dispersion_slider_default_value( $config['sections']['style_manager_section']['options'] ),
486
+ // 'input_attrs' => array(
487
+ // 'min' => 1,
488
+ // 'max' => 100,
489
+ // 'step' => 1,
490
+ // 'data-preview' => true,
491
+ // ),
492
+ // 'css' => array(),
493
+ // ),
494
+ // 'sm_colors_focus_point' => array(
495
+ // 'setting_id' => 'sm_colors_focus_point',
496
+ // 'type' => 'range',
497
+ // 'label' => esc_html__( 'Colors focus point', 'customify' ),
498
+ // 'desc' => '',
499
+ // 'live' => true,
500
+ // 'default' => $this->get_color_focus_slider_default_value( $config['sections']['style_manager_section']['options'] ),
501
+ // 'input_attrs' => array(
502
+ // 'min' => 0,
503
+ // 'max' => 100,
504
+ // 'step' => 1,
505
+ // 'data-preview' => true,
506
+ // ),
507
+ // 'css' => array(),
508
+ // ),
509
+ ) + $config['sections']['style_manager_section']['options'];
510
+
511
+ return $config;
512
+ }
513
+
514
+ private function get_dark_to_color_slider_default_value( $options, $dark_id, $color_id ) {
515
+ $dark_count = count($options[$dark_id]['connected_fields']);
516
+ $color_count = count($options[$color_id]['connected_fields']);
517
+ $total_count = $dark_count + $color_count;
518
+
519
+ if ( $total_count === 0 ) {
520
+ return 0;
521
+ }
522
+
523
+ return 100 * $color_count / $total_count;
524
+ }
525
+
526
+
527
+ private function get_color_dispersion_slider_default_value( $options ) {
528
+ $primary_count = count($options['sm_color_primary']['connected_fields']);
529
+ $secondary_count = count($options['sm_color_secondary']['connected_fields']);
530
+ $tertiary_count = count($options['sm_color_tertiary']['connected_fields']);
531
+ $total_count = $primary_count + $secondary_count + $tertiary_count;
532
+ $n = 3;
533
+
534
+ $average = ( $primary_count + $secondary_count + $tertiary_count ) / $n;
535
+
536
+ $diff_primary = pow( $primary_count - $average, 2 );
537
+ $diff_secondary = pow( $secondary_count - $average, 2 );
538
+ $diff_tertiary = pow( $tertiary_count - $average, 2 );
539
+
540
+ $diff_average = ( $diff_primary + $diff_secondary + $diff_tertiary ) / $n; // presupun ca e intre 0 si total * 2 / 3
541
+
542
+ $diff1 = pow( $total_count - $average, 2);
543
+ $diff2 = pow( $average, 2);
544
+ $diff3 = $diff2;
545
+
546
+ $min = 0; // dispersion = 1
547
+ $max = ($diff1 + $diff2 + $diff3) / 3;
548
+ // $max = 2 * ($n - 1) * $average / $n; // dispersion = 0;
549
+
550
+ // avoid division by zero
551
+ if ( $max === 0 ) {
552
+ return 100;
553
+ }
554
+
555
+ return 100 * ($diff_average / max($primary_count, $secondary_count, $tertiary_count));
556
+ }
557
+
558
+ private function get_color_focus_slider_default_value( $options ) {
559
+ $primary_count = count($options['sm_color_primary']['connected_fields']);
560
+ $secondary_count = count($options['sm_color_secondary']['connected_fields']);
561
+ $tertiary_count = count($options['sm_color_tertiary']['connected_fields']);
562
+ $total_count = $primary_count + $secondary_count + $tertiary_count;
563
+
564
+ // avoid division by zero
565
+ if ( $total_count === 0 ) {
566
+ return 50;
567
+ }
568
+
569
+ $focus_point = (0 * $primary_count + 0.5 * $secondary_count + 1 * $tertiary_count ) / $total_count;
570
+
571
+ return $focus_point * 100;
572
+ }
573
+
574
+ /**
575
+ * Get the default (hard-coded) color palettes configuration.
576
+ *
577
+ * This is only a fallback config in case we can't communicate with the cloud, the first time.
578
+ *
579
+ * @since 1.7.4
580
+ *
581
+ * @return array
582
+ */
583
+ protected function get_default_config() {
584
+ $default_config = array(
585
+ 'vasco' => array(
586
+ 'label' => esc_html__( 'Restful Beach', 'customify' ),
587
+ 'preview' => array(
588
+ 'background_image_url' => 'http://pxgcdn.com/images/style-manager/color-palettes/vasco-theme-palette.jpg',
589
+ ),
590
+ 'options' => array(
591
+ 'sm_color_primary' => '#38C3C8',
592
+ 'sm_color_secondary' => '#F59828',
593
+ 'sm_color_tertiary' => '#FB551C',
594
+ 'sm_dark_primary' => '#2b2b28',
595
+ 'sm_dark_secondary' => '#2B3D39',
596
+ 'sm_dark_tertiary' => '#65726F',
597
+ 'sm_light_primary' => '#F5F6F1',
598
+ 'sm_light_secondary' => '#E6F7F7',
599
+ 'sm_light_tertiary' => '#FAEDE8',
600
+ ),
601
+ ),
602
+ 'felt' => array(
603
+ 'label' => esc_html__( 'Warm Summer', 'customify' ),
604
+ 'preview' => array(
605
+ 'background_image_url' => 'http://pxgcdn.com/images/style-manager/color-palettes/felt-theme-palette.jpg',
606
+ ),
607
+ 'options' => array(
608
+ 'sm_color_primary' => '#ff6000',
609
+ 'sm_color_secondary' => '#FF9200',
610
+ 'sm_color_tertiary' => '#FF7019',
611
+ 'sm_dark_primary' => '#1C1C1C',
612
+ 'sm_dark_secondary' => '#161616',
613
+ 'sm_dark_tertiary' => '#161616',
614
+ 'sm_light_primary' => '#FFFCFC',
615
+ 'sm_light_secondary' => '#FFF4E8',
616
+ 'sm_light_tertiary' => '#F7F3F0',
617
+ ),
618
+ ),
619
+ 'julia' => array(
620
+ 'label' => esc_html__( 'Serenity', 'customify' ),
621
+ 'preview' => array(
622
+ 'background_image_url' => 'http://pxgcdn.com/images/style-manager/color-palettes/julia-theme-palette.jpg',
623
+ ),
624
+ 'options' => array(
625
+ 'sm_color_primary' => '#3349B8',
626
+ 'sm_color_secondary' => '#3393B8',
627
+ 'sm_color_tertiary' => '#C18866',
628
+ 'sm_dark_primary' => '#161616',
629
+ 'sm_dark_secondary' => '#383C50',
630
+ 'sm_dark_tertiary' => '#383C50',
631
+ 'sm_light_primary' => '#f7f6f5',
632
+ 'sm_light_secondary' => '#E7F2F8',
633
+ 'sm_light_tertiary' => '#F7ECE6',
634
+ ),
635
+ ),
636
+ 'gema' => array(
637
+ 'label' => esc_html__( 'Burning Red', 'customify' ),
638
+ 'preview' => array(
639
+ 'background_image_url' => 'http://pxgcdn.com/images/style-manager/color-palettes/gema-theme-palette.jpg',
640
+ ),
641
+ 'options' => array(
642
+ 'sm_color_primary' => '#E03A3A',
643
+ 'sm_color_secondary' => '#F75034',
644
+ 'sm_color_tertiary' => '#AD2D2D',
645
+ 'sm_dark_primary' => '#000000',
646
+ 'sm_dark_secondary' => '#000000',
647
+ 'sm_dark_tertiary' => '#A3A3A1',
648
+ 'sm_light_primary' => '#FFFFFF',
649
+ 'sm_light_secondary' => '#F7F5F5',
650
+ 'sm_light_tertiary' => '#F7F2F2',
651
+ ),
652
+ ),
653
+ 'patch' => array(
654
+ 'label' => esc_html__( 'Fresh Lemon', 'customify' ),
655
+ 'preview' => array(
656
+ 'background_image_url' => 'http://pxgcdn.com/images/style-manager/color-palettes/patch-theme-palette.jpg',
657
+ ),
658
+ 'options' => array(
659
+ 'sm_color_primary' => '#ffeb00',
660
+ 'sm_color_secondary' => '#19CDFF',
661
+ 'sm_color_tertiary' => '#0BE8DD',
662
+ 'sm_dark_primary' => '#171617',
663
+ 'sm_dark_secondary' => '#3d3e40',
664
+ 'sm_dark_tertiary' => '#b5b5b5',
665
+ 'sm_light_primary' => '#FFFFFF',
666
+ 'sm_light_secondary' => '#E8FAFF',
667
+ 'sm_light_tertiary' => '#F2FFFE',
668
+ ),
669
+ ),
670
+ 'silk' => array(
671
+ 'label' => esc_html__( 'Floral Bloom', 'customify' ),
672
+ 'preview' => array(
673
+ 'background_image_url' => 'http://pxgcdn.com/images/style-manager/color-palettes/silk-theme-palette.jpg',
674
+ ),
675
+ 'options' => array(
676
+ 'sm_color_primary' => '#A33B61',
677
+ 'sm_color_secondary' => '#FCC9B0',
678
+ 'sm_color_tertiary' => '#C9648A',
679
+ 'sm_dark_primary' => '#000000',
680
+ 'sm_dark_secondary' => '#000000',
681
+ 'sm_dark_tertiary' => '#A3A3A1',
682
+ 'sm_light_primary' => '#FFFFFF',
683
+ 'sm_light_secondary' => '#F7F5F6',
684
+ 'sm_light_tertiary' => '#F7F0F3',
685
+ ),
686
+ ),
687
+ 'hive' => array(
688
+ 'label' => esc_html__( 'Powerful', 'customify' ),
689
+ 'preview' => array(
690
+ 'background_image_url' => 'http://pxgcdn.com/images/style-manager/color-palettes/hive-theme-palette.jpg',
691
+ ),
692
+ 'options' => array(
693
+ 'sm_color_primary' => '#ffeb00',
694
+ 'sm_color_secondary' => '#3200B2',
695
+ 'sm_color_tertiary' => '#740AC9',
696
+ 'sm_dark_primary' => '#171617',
697
+ 'sm_dark_secondary' => '#171617',
698
+ 'sm_dark_tertiary' => '#363636',
699
+ 'sm_light_primary' => '#FFFFFF',
700
+ 'sm_light_secondary' => '#F2F5F7',
701
+ 'sm_light_tertiary' => '#F5F2F7',
702
+ ),
703
+ ),
704
+ 'lilac' => array(
705
+ 'label' => esc_html__( 'Soft Lilac', 'customify' ),
706
+ 'preview' => array(
707
+ 'background_image_url' => 'http://pxgcdn.com/images/style-manager/color-palettes/lilac-color-palette.jpg',
708
+ ),
709
+ 'options' => array(
710
+ 'sm_color_primary' => '#DD8CA9',
711
+ 'sm_color_secondary' => '#8C9CDE',
712
+ 'sm_color_tertiary' => '#E3B4A6',
713
+ 'sm_dark_primary' => '#1A1A1A',
714
+ 'sm_dark_secondary' => '#303030',
715
+ 'sm_dark_tertiary' => '#A3A3A1',
716
+ 'sm_light_primary' => '#F0F2F1',
717
+ 'sm_light_secondary' => '#CED5F2',
718
+ 'sm_light_tertiary' => '#F7E1DA',
719
+ ),
720
+ ),
721
+ );
722
+
723
+ return apply_filters( 'customify_style_manager_default_color_palettes', $default_config );
724
+ }
725
+
726
+
727
+
728
+ /**
729
+ * Get the current color palette ID or false if none is selected.
730
+ *
731
+ * @since 1.7.4
732
+ *
733
+ * @return string|false
734
+ */
735
+ protected function get_current_palette() {
736
+ return get_option( 'sm_color_palette', false );
737
+ }
738
+
739
+ /**
740
+ * Get the current color palette variation ID or false if none is selected.
741
+ *
742
+ * @since 1.7.4
743
+ *
744
+ * @return string|false
745
+ */
746
+ protected function get_current_palette_variation() {
747
+ return get_option( 'sm_color_palette_variation', false );
748
+ }
749
+
750
+ /**
751
+ * Determine if the selected color palette has been customized and remember this in an option.
752
+ *
753
+ * @since 1.7.4
754
+ *
755
+ * @return bool
756
+ */
757
+ public function update_custom_palette_in_use() {
758
+ // If there is no style manager support, bail early.
759
+ if ( ! $this->is_supported() ) {
760
+ return false;
761
+ }
762
+
763
+ $current_palette = $this->get_current_palette();
764
+ if ( empty( $current_palette ) ) {
765
+ return false;
766
+ }
767
+
768
+ $color_palettes = $this->get_palettes();
769
+ if ( ! isset( $color_palettes[ $current_palette ] ) || empty( $color_palettes[ $current_palette ]['options'] ) ) {
770
+ return false;
771
+ }
772
+
773
+ $is_custom_palette = false;
774
+ // If any of the current master colors has a different value than the one provided by the color palette,
775
+ // it means a custom color palette is in use.
776
+ $current_palette_options = $color_palettes[ $current_palette ]['options'];
777
+ foreach ( $current_palette_options as $setting_id => $value ) {
778
+ if ( $value != get_option( $setting_id ) ) {
779
+ $is_custom_palette = true;
780
+ break;
781
+ }
782
+ }
783
+
784
+ update_option( 'sm_is_custom_color_palette', $is_custom_palette, true );
785
+
786
+ do_action( 'customify_style_manager_updated_custom_palette_in_use', $is_custom_palette );
787
+
788
+ return true;
789
+ }
790
+
791
+ /**
792
+ * Determine if a custom color palette is in use.
793
+ *
794
+ * @since 1.7.4
795
+ *
796
+ * @return bool
797
+ */
798
+ protected function is_using_custom_palette(){
799
+ return (bool) get_option( 'sm_is_custom_color_palette', false );
800
+ }
801
+
802
+ /**
803
+ * Get all the defined Style Manager master color field ids.
804
+ *
805
+ * @since 1.7.4
806
+ *
807
+ * @param array $options
808
+ *
809
+ * @return array
810
+ */
811
+ public function get_all_master_color_controls_ids( $options ) {
812
+ $master_color_controls = array();
813
+
814
+ if ( empty( $options ) ) {
815
+ return $master_color_controls;
816
+ }
817
+
818
+ foreach ( $options as $option_id => $option_settings ) {
819
+ if ( ! empty( $option_settings['type'] ) && 'color' === $option_settings['type'] ) {
820
+ $master_color_controls[] = $option_id;
821
+ }
822
+ }
823
+
824
+ return $master_color_controls;
825
+ }
826
+
827
+ /**
828
+ * Add color palettes usage data to the site data sent to the cloud.
829
+ *
830
+ * @since 1.7.4
831
+ *
832
+ * @param array $site_data
833
+ *
834
+ * @return array
835
+ */
836
+ public function add_palettes_to_site_data( $site_data ) {
837
+ if ( empty( $site_data['color_palettes'] ) ) {
838
+ $site_data['color_palettes'] = array();
839
+ }
840
+
841
+ // If others have added data before us, we will merge with it.
842
+ $site_data['color_palettes'] = array_merge( $site_data['color_palettes'], array(
843
+ 'current' => $this->get_current_palette(),
844
+ 'variation' => $this->get_current_palette_variation(),
845
+ 'custom' => $this->is_using_custom_palette(),
846
+ ) );
847
+
848
+ return $site_data;
849
+ }
850
+
851
+ /**
852
+ * Main Customify_Color_Palettes Instance
853
+ *
854
+ * Ensures only one instance of Customify_Color_Palettes is loaded or can be loaded.
855
+ *
856
+ * @since 1.7.4
857
+ * @static
858
+ *
859
+ * @return Customify_Font_Palettes Main Customify_Color_Palettes instance
860
+ */
861
+ public static function instance() {
862
+
863
+ if ( is_null( self::$_instance ) ) {
864
+ self::$_instance = new self();
865
+ }
866
+ return self::$_instance;
867
+ } // End instance ()
868
+
869
+ /**
870
+ * Cloning is forbidden.
871
+ *
872
+ * @since 1.7.4
873
+ */
874
+ public function __clone() {
875
+
876
+ _doing_it_wrong( __FUNCTION__,esc_html( __( 'Cheatin&#8217; huh?' ) ), null );
877
+ } // End __clone ()
878
+
879
+ /**
880
+ * Unserializing instances of this class is forbidden.
881
+ *
882
+ * @since 1.7.4
883
+ */
884
+ public function __wakeup() {
885
+
886
+ _doing_it_wrong( __FUNCTION__, esc_html( __( 'Cheatin&#8217; huh?' ) ), null );
887
+ } // End __wakeup ()
888
+ }
889
+
890
+ endif;
includes/class-customify-font-palettes.php ADDED
@@ -0,0 +1,1473 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * This is the class that handles the logic for Font Palettes.
4
+ *
5
+ * @see https://pixelgrade.com
6
+ * @author Pixelgrade
7
+ * @since 1.7.4
8
+ */
9
+
10
+ if ( ! defined( 'ABSPATH' ) ) {
11
+ exit; // Exit if accessed directly
12
+ }
13
+
14
+ if ( ! class_exists( 'Customify_Font_Palettes' ) ) :
15
+
16
+ class Customify_Font_Palettes {
17
+
18
+ /**
19
+ * Holds the only instance of this class.
20
+ * @var null|Customify_Font_Palettes
21
+ * @access protected
22
+ * @since 1.7.4
23
+ */
24
+ protected static $_instance = null;
25
+
26
+ /**
27
+ * Constructor.
28
+ *
29
+ * @since 1.7.4
30
+ */
31
+ protected function __construct() {
32
+ $this->init();
33
+ }
34
+
35
+ /**
36
+ * Initialize this module.
37
+ *
38
+ * @since 1.7.4
39
+ */
40
+ public function init() {
41
+ // Hook up.
42
+ $this->add_hooks();
43
+ }
44
+
45
+ /**
46
+ * Initiate our hooks
47
+ *
48
+ * @since 1.7.4
49
+ */
50
+ public function add_hooks() {
51
+ /*
52
+ * Handle the font palettes preprocessing.
53
+ */
54
+ add_filter( 'customify_get_font_palettes', array( $this, 'preprocess_config' ), 5, 1 );
55
+
56
+ /*
57
+ * Handle the Customizer Style Manager section config.
58
+ */
59
+ add_filter( 'customify_filter_fields', array( $this, 'add_style_manager_section_master_fonts_config' ), 12, 1 );
60
+ // This needs to come after the external theme config has been applied
61
+ // add_filter( 'customify_filter_fields', array( $this, 'add_current_palette_control' ), 110, 1 );
62
+ add_filter( 'customify_final_config', array( $this, 'standardize_connected_fields' ), 10, 1 );
63
+
64
+ /*
65
+ * Scripts enqueued in the Customizer.
66
+ */
67
+ add_action( 'customize_controls_init', array( $this, 'register_admin_customizer_scripts' ), 10 );
68
+ add_action( 'customize_controls_enqueue_scripts', array( $this, 'enqueue_admin_customizer_scripts' ), 10 );
69
+
70
+ /*
71
+ * Handle the logic on settings update/save.
72
+ */
73
+ add_action( 'customize_save_after', array( $this, 'update_custom_palette_in_use' ), 10, 1 );
74
+
75
+ /**
76
+ * Add font palettes usage to site data.
77
+ */
78
+ add_filter( 'customify_style_manager_get_site_data', array( $this, 'add_palettes_to_site_data' ), 10, 1 );
79
+ }
80
+
81
+ /**
82
+ * Register Customizer admin scripts
83
+ */
84
+ public function register_admin_customizer_scripts() {
85
+ wp_register_script( PixCustomifyPlugin()->get_slug() . '-font-swap-values', plugins_url( 'js/customizer/font-swap-values.js', PixCustomifyPlugin()->get_file() ), array( 'jquery' ), PixCustomifyPlugin()->get_version() );
86
+ wp_register_script( PixCustomifyPlugin()->get_slug() . '-font-palettes-variations', plugins_url( 'js/customizer/font-palettes-variations.js', PixCustomifyPlugin()->get_file() ), array( 'jquery' ), PixCustomifyPlugin()->get_version() );
87
+ wp_register_script( PixCustomifyPlugin()->get_slug() . '-font-palettes', plugins_url( 'js/customizer/font-palettes.js', PixCustomifyPlugin()->get_file() ), array(
88
+ 'jquery',
89
+ PixCustomifyPlugin()->get_slug() . '-font-palettes-variations',
90
+ PixCustomifyPlugin()->get_slug() . '-swap-values',
91
+ PixCustomifyPlugin()->get_slug() . '-fontselectfields',
92
+ ), PixCustomifyPlugin()->get_version() );
93
+ }
94
+
95
+ /**
96
+ * Enqueue Customizer admin scripts
97
+ */
98
+ public function enqueue_admin_customizer_scripts() {
99
+ // If there is no font palettes support, bail early.
100
+ if ( ! $this->is_supported() ) {
101
+ return;
102
+ }
103
+
104
+ wp_enqueue_script( PixCustomifyPlugin()->get_slug() . '-font-palettes' );
105
+ }
106
+
107
+ /**
108
+ * Preprocess the font palettes configuration.
109
+ *
110
+ * Things like transforming font_size_line_height_points to a polynomial function for easy use client side,
111
+ * or processing the styles intervals and making sure that we get to a state where there are no overlaps and the order is right.
112
+ *
113
+ * @since 1.7.4
114
+ *
115
+ * @param array $config
116
+ *
117
+ * @return array
118
+ */
119
+ public function preprocess_config( $config ) {
120
+ if ( empty( $config ) ) {
121
+ return $config;
122
+ }
123
+
124
+ foreach ( $config as $palette_id => $palette_config ) {
125
+ $config[ $palette_id ] = $this->preprocess_palette_config( $palette_config );
126
+ }
127
+
128
+ return $config;
129
+ }
130
+
131
+ /**
132
+ * Preprocess a font palette config before using it.
133
+ *
134
+ * @since 1.7.4
135
+ *
136
+ * @param array $palette_config
137
+ *
138
+ * @return array
139
+ */
140
+ private function preprocess_palette_config( $palette_config ) {
141
+ if ( empty( $palette_config ) ) {
142
+ return $palette_config;
143
+ }
144
+
145
+ global $wp_customize;
146
+ // We only need to do the fonts logic preprocess when we are in the Customizer.
147
+ if ( ! empty( $wp_customize ) && $wp_customize instanceof WP_Customize_Manager && ! empty( $palette_config['fonts_logic'] ) ) {
148
+ $palette_config['fonts_logic'] = $this->preprocess_fonts_logic_config( $palette_config['fonts_logic'] );
149
+ }
150
+
151
+ return $palette_config;
152
+ }
153
+
154
+ /**
155
+ * Before using a font logic config, preprocess it to allow for standardization, fill up of missing info, etc.
156
+ *
157
+ * @since 1.7.4
158
+ *
159
+ * @param array $fonts_logic_config
160
+ *
161
+ * @return array
162
+ */
163
+ private function preprocess_fonts_logic_config( $fonts_logic_config ) {
164
+ if ( empty( $fonts_logic_config ) ) {
165
+ return $fonts_logic_config;
166
+ }
167
+
168
+ foreach ( $fonts_logic_config as $font_setting_id => $font_logic ) {
169
+ if ( empty( $font_logic['font_family'] ) ) {
170
+ // If we don't have a font family we can't do much with this config - remove it.
171
+ unset( $fonts_logic_config[ $font_setting_id ] );
172
+ continue;
173
+ }
174
+
175
+ if ( empty( $font_logic['type'] ) ) {
176
+ // Default to 'google'
177
+ $fonts_logic_config[ $font_setting_id ]['type'] = 'google';
178
+ }
179
+
180
+ // Process the font_styles_intervals and make sure that they are in the right order and not overlapping.
181
+ if ( ! empty( $font_logic['font_styles_intervals'] ) && is_array( $font_logic['font_styles_intervals'] ) ) {
182
+ $font_styles = array( array_shift( $font_logic['font_styles_intervals'] ) );
183
+ // Make sure that the interval has a start
184
+ if ( ! isset( $font_styles[0]['start'] ) ) {
185
+ $font_styles[0]['start'] = 0;
186
+ }
187
+
188
+ foreach ( $font_logic['font_styles_intervals'] as $font_styles_interval ) {
189
+ // Make sure that the interval has a start
190
+ if ( ! isset( $font_styles_interval['start'] ) ) {
191
+ $font_styles_interval['start'] = 0;
192
+ }
193
+ // Go through the current font_styles and determine the place where this interval should fit in.
194
+ for ( $i = 0; $i < count( $font_styles ); $i++ ) {
195
+ // Determine if the new interval overlaps with this existing one.
196
+ if ( ! isset( $font_styles[$i]['end'] ) ) {
197
+ // Since this interval is without end, there is nothing after it.
198
+ // We need to adjust the old interval end.
199
+ if ( $font_styles[ $i ]['start'] < $font_styles_interval['start'] ) {
200
+ $font_styles[ $i ]['end'] = $font_styles_interval['start'];
201
+ } else {
202
+ if ( ! isset( $font_styles_interval['end'] ) ) {
203
+ // We need to delete the old interval altogether.
204
+ unset($font_styles[ $i ]);
205
+ $i--;
206
+ continue;
207
+ } else {
208
+ // Adjust the old interval and insert in front of it.
209
+ $font_styles[ $i ]['end'] = $font_styles_interval['end'];
210
+ $font_styles = array_slice( $font_styles, 0, $i ) + array( $font_styles_interval );
211
+ break;
212
+ }
213
+ }
214
+ } else {
215
+ if ( $font_styles[ $i ]['end'] > $font_styles_interval['start'] ) {
216
+ // We need to shrink this interval and make room for the new interval.
217
+ $font_styles[ $i ]['end'] = $font_styles_interval['start'];
218
+ } else {
219
+ // There is not overlap. Move to the next one.
220
+ continue;
221
+ }
222
+
223
+ if ( ! isset( $font_styles_interval['end'] ) ) {
224
+ // Everything after the existing interval is gone and the new one takes precedence.
225
+ array_splice( $font_styles, $i + 1, count( $font_styles ), array( $font_styles_interval ) );
226
+ break;
227
+ } else {
228
+ // Now go forward and see where the end of the new interval fits in.
229
+ for ( $j = $i + 1; $j < count( $font_styles ); $j ++ ) {
230
+ if ( $font_styles[ $j ]['start'] < $font_styles_interval['end'] ) {
231
+ // We have an overlapping after-interval.
232
+ if ( ! isset( $font_styles[ $j ]['end'] ) ) {
233
+ // Since this interval is without end, there is nothing after it.
234
+ $font_styles[ $j ]['start'] = $font_styles_interval['end'];
235
+ break;
236
+ } elseif ( $font_styles[ $j ]['end'] <= $font_styles_interval['end'] ) {
237
+ // We need to delete this interval since it is completely overwritten by the new one.
238
+ unset( $font_styles[ $j ] );
239
+ $j --;
240
+ continue;
241
+ } else {
242
+ // The new interval partially overlaps with the old one. Adjust.
243
+ $font_styles[ $j ]['end'] = $font_styles_interval['end'];
244
+ break;
245
+ }
246
+ } else {
247
+ // We can insert the new interval since this interval is after it
248
+ break;
249
+ }
250
+ }
251
+
252
+ // Insert the new interval.
253
+ array_splice( $font_styles, $j, 0, array( $font_styles_interval ) );
254
+ break;
255
+ }
256
+ }
257
+ }
258
+
259
+ // If we have reached the end of the list, we will insert it at the end.
260
+ if ( $i === count( $font_styles ) ) {
261
+ array_push( $font_styles, $font_styles_interval );
262
+ }
263
+ }
264
+
265
+ // We need to do a last pass and ensure no breaks in the intervals. We need them to be continuous.
266
+ // We will extend intervals to their next (right-hand) neighbour to achieve continuity.
267
+ if ( count( $font_styles ) > 1 ) {
268
+ // The first interval should start at zero, just in case.
269
+ $font_styles[0]['start'] = 0;
270
+ for( $i = 1; $i < count( $font_styles ); $i++ ) {
271
+ // Extend the previous interval, just in case.
272
+ $font_styles[ $i-1 ]['end'] = $font_styles[ $i ]['start'];
273
+ }
274
+ }
275
+
276
+ // The last interval should not have an end.
277
+ unset( $font_styles[ count( $font_styles )-1 ]['end'] );
278
+
279
+ // Finally, go through each font style and standardize it.
280
+ foreach( $font_styles as $key => $value ) {
281
+ if ( isset( $value['letter_spacing'] ) ) {
282
+ $font_styles[ $key ]['letter_spacing'] = $this->maybe_standardize_value( $value['letter_spacing'] );
283
+ }
284
+ }
285
+
286
+ $fonts_logic_config[ $font_setting_id ]['font_styles'] = $font_styles;
287
+ }
288
+ }
289
+
290
+ return $fonts_logic_config;
291
+ }
292
+
293
+ /**
294
+ * Get the font palettes configuration.
295
+ *
296
+ * @since 1.7.4
297
+ *
298
+ * @param bool $skip_cache Optional. Whether to use the cached config or fetch a new one.
299
+ *
300
+ * @return array
301
+ */
302
+ public function get_palettes( $skip_cache = false ) {
303
+ // Make sure that the Design Assets class is loaded.
304
+ require_once 'lib/class-customify-design-assets.php';
305
+
306
+ // Get the design assets data.
307
+ $design_assets = Customify_Design_Assets::instance()->get( $skip_cache );
308
+ if ( false === $design_assets || empty( $design_assets['font_palettes'] ) ) {
309
+ $config = $this->get_default_config();
310
+ } else {
311
+ $config = $design_assets['font_palettes'];
312
+ }
313
+
314
+ return apply_filters( 'customify_get_font_palettes', $config );
315
+ }
316
+
317
+ /**
318
+ * Determine if Font Palettes are supported.
319
+ *
320
+ * @since 1.7.4
321
+ *
322
+ * @return bool
323
+ */
324
+ public function is_supported() {
325
+ // For now we will only use the fact that Style Manager is supported.
326
+ return apply_filters( 'customify_font_palettes_are_supported', Customify_Style_Manager::instance()->is_supported() );
327
+ }
328
+
329
+ /**
330
+ * Setup the Style Manager Customizer section master fonts config.
331
+ *
332
+ * This handles the base configuration for the controls in the Style Manager section. We expect other parties (e.g. the theme),
333
+ * to come and fill up the missing details (e.g. connected fields).
334
+ *
335
+ * @since 1.7.4
336
+ *
337
+ * @param array $config This holds required keys for the plugin config like 'opt-name', 'panels', 'settings'.
338
+ *
339
+ * @return array
340
+ */
341
+ public function add_style_manager_section_master_fonts_config( $config ) {
342
+ // If there is no style manager support, bail early.
343
+ if ( ! $this->is_supported() ) {
344
+ return $config;
345
+ }
346
+
347
+ if ( ! isset( $config['sections']['style_manager_section'] ) ) {
348
+ $config['sections']['style_manager_section'] = array();
349
+ }
350
+
351
+ // The section might be already defined, thus we merge, not replace the entire section config.
352
+ $config['sections']['style_manager_section'] = array_replace_recursive( $config['sections']['style_manager_section'], array(
353
+ 'options' => array(
354
+ 'sm_font_palette' => array(
355
+ 'type' => 'preset',
356
+ // We will bypass the plugin setting regarding where to store - we will store it cross-theme in wp_options
357
+ 'setting_type' => 'option',
358
+ // We will force this setting id preventing prefixing and other regular processing.
359
+ 'setting_id' => 'sm_font_palette',
360
+ // We don't want to refresh the preview window, even though we have no direct effect on it through this field.
361
+ 'live' => true,
362
+ 'priority' => 5,
363
+ 'label' => esc_html__( 'Select a font palette:', 'customify' ),
364
+ 'desc' => esc_html__( 'Conveniently change the design of your site with font palettes. Easy as pie.', 'customify' ),
365
+ 'default' => 'julia',
366
+ 'choices_type' => 'font_palette',
367
+ 'choices' => $this->get_palettes(),
368
+ ),
369
+ 'sm_font_palette_variation' => array(
370
+ 'type' => 'radio',
371
+ 'setting_type' => 'option',
372
+ 'setting_id' => 'sm_font_palette_variation',
373
+ 'label' => esc_html__( 'Palette Variation', 'customify' ),
374
+ 'default' => 'regular',
375
+ 'live' => true,
376
+ 'priority' => 5.5,
377
+ 'choices' => array(
378
+ 'light' => esc_html__( 'not light', 'customify' ),
379
+ 'regular' => esc_html__( 'not regular', 'customify' ),
380
+ 'big' => esc_html__( 'not big', 'customify' ),
381
+ ),
382
+ ),
383
+ 'sm_font_primary' => array(
384
+ 'type' => 'font',
385
+ // We will bypass the plugin setting regarding where to store - we will store it cross-theme in wp_options
386
+ 'setting_type' => 'option',
387
+ // We will force this setting id preventing prefixing and other regular processing.
388
+ 'setting_id' => 'sm_font_primary',
389
+ // We don't want to refresh the preview window, even though we have no direct effect on it through this field.
390
+ 'live' => true,
391
+ 'priority' => 7,
392
+ 'label' => esc_html__( 'Font Primary', 'customify' ),
393
+ 'default' => array(
394
+ 'font-family' => 'Montserrat',
395
+ 'font-weight' => '400',
396
+ 'font-size' => 20,
397
+ 'line-height' => 1.25,
398
+ 'letter-spacing' => 0.029,
399
+ 'text-transform' => 'uppercase'
400
+ ),
401
+ // Sub Fields Configuration
402
+ 'fields' => array(
403
+ // These subfields are disabled because they are calculated through the font palette logic.
404
+ 'font-size' => false,
405
+ 'font-weight' => false,
406
+ 'line-height' => false,
407
+ 'letter-spacing' => false,
408
+ 'text-align' => false,
409
+ 'text-transform' => false,
410
+ 'text-decoration' => false,
411
+ ),
412
+ 'connected_fields' => array(),
413
+ ),
414
+ 'sm_font_secondary' => array(
415
+ 'type' => 'font',
416
+ 'setting_type' => 'option',
417
+ 'setting_id' => 'sm_font_secondary',
418
+ 'live' => true,
419
+ 'priority' => 7.1,
420
+ 'label' => esc_html__( 'Font Secondary', 'customify' ),
421
+ 'default' => array(
422
+ 'font-family' => 'Montserrat',
423
+ 'font-weight' => '300',
424
+ 'font-size' => 10,
425
+ 'line-height' => 1.625,
426
+ 'letter-spacing' => 0.029,
427
+ 'text-transform' => 'uppercase'
428
+ ),
429
+ // Sub Fields Configuration
430
+ 'fields' => array(
431
+ // These subfields are disabled because they are calculated through the font palette logic.
432
+ 'font-size' => false,
433
+ 'font-weight' => false,
434
+ 'line-height' => false,
435
+ 'letter-spacing' => false,
436
+ 'text-align' => false,
437
+ 'text-transform' => false,
438
+ 'text-decoration' => false,
439
+ ),
440
+ 'connected_fields' => array(),
441
+ ),
442
+ 'sm_font_body' => array(
443
+ 'type' => 'font',
444
+ 'setting_type' => 'option',
445
+ 'setting_id' => 'sm_font_body',
446
+ 'live' => true,
447
+ 'priority' => 7.2,
448
+ 'label' => esc_html__( 'Font Body', 'customify' ),
449
+ 'default' => array(
450
+ 'font-family' => 'Montserrat',
451
+ 'font-weight' => '300',
452
+ 'font-size' => 14,
453
+ 'line-height' => 1.6,
454
+ 'letter-spacing' => 0.029,
455
+ 'text-transform' => 'uppercase'
456
+ ),
457
+ // Sub Fields Configuration
458
+ 'fields' => array(
459
+ // These subfields are disabled because they are calculated through the font palette logic.
460
+ 'font-size' => false,
461
+ 'font-weight' => false,
462
+ 'line-height' => false,
463
+ 'letter-spacing' => false,
464
+ 'text-align' => false,
465
+ 'text-transform' => false,
466
+ 'text-decoration' => false,
467
+ ),
468
+ 'connected_fields' => array(),
469
+ ),
470
+ 'sm_swap_fonts' => array(
471
+ 'type' => 'button',
472
+ 'setting_type' => 'option',
473
+ 'setting_id' => 'sm_swap_fonts',
474
+ 'priority' => 9,
475
+ 'label' => esc_html__( 'Swap Fonts', 'customify' ),
476
+ 'action' => 'sm_swap_fonts',
477
+ ),
478
+ 'sm_swap_primary_secondary_fonts' => array(
479
+ 'type' => 'button',
480
+ 'setting_type' => 'option',
481
+ 'setting_id' => 'sm_swap_primary_secondary_fonts',
482
+ 'priority' => 9.1,
483
+ 'label' => esc_html__( 'Swap Primary ⇆ Secondary', 'customify' ),
484
+ 'action' => 'sm_swap_dark_light',
485
+ ),
486
+ ),
487
+ ) );
488
+
489
+ return $config;
490
+ }
491
+
492
+ /**
493
+ * Add the current font palette control to the Style Manager section.
494
+ *
495
+ * @since 1.7.4
496
+ *
497
+ * @param array $config
498
+ *
499
+ * @return array
500
+ */
501
+ public function add_current_palette_control( $config ) {
502
+ // If there is no style manager support, bail early.
503
+ if ( ! $this->is_supported() ) {
504
+ return $config;
505
+ }
506
+
507
+ if ( ! isset( $config['sections']['style_manager_section'] ) ) {
508
+ $config['sections']['style_manager_section'] = array();
509
+ }
510
+
511
+ $current_palette = '';
512
+ $current_palette_sets = array( 'current', 'next' );
513
+
514
+ $master_font_controls_ids = $this->get_all_master_font_controls_ids( $config['sections']['style_manager_section']['options'] );
515
+
516
+ foreach ( $current_palette_sets as $set ) {
517
+ $current_palette .= '<div class="fonts ' . $set . '">';
518
+ foreach ( $master_font_controls_ids as $setting_id ) {
519
+ if ( ! empty( $config['sections']['style_manager_section']['options'][ $setting_id ]['connected_fields'] ) ) {
520
+ $current_palette .=
521
+ '<div class="font ' . $setting_id . '" data-setting="' . $setting_id . '">' . PHP_EOL .
522
+ '<div class="fill"></div>' . PHP_EOL .
523
+ '<div class="picker"><i></i></div>' . PHP_EOL .
524
+ '</div>' . PHP_EOL;
525
+ }
526
+ }
527
+ $current_palette .= '</div>';
528
+ }
529
+
530
+ // The section might be already defined, thus we merge, not replace the entire section config.
531
+ $config['sections']['style_manager_section']['options'] = array(
532
+ 'sm_current_font_palette' => array(
533
+ 'type' => 'html',
534
+ 'html' =>
535
+ '<div class="font-palette-container">' . PHP_EOL .
536
+ '<span class="customize-control-title">Current Font Palette:</span>' . PHP_EOL .
537
+ '<span class="description customize-control-description">Choose a font palette to start with. Adjust its style using the variation buttons below.</span>' . PHP_EOL .
538
+ '<div class="c-font-palette">' . PHP_EOL .
539
+ $current_palette .
540
+ '<div class="c-font-palette__overlay">' . PHP_EOL .
541
+ '<div class="c-font-palette__label">' .
542
+ '<div class="c-font-palette__name">' . 'Original Style' . '</div>' .
543
+ '<div class="c-font-palette__control variation-light active" data-target="#_customize-input-sm_font_palette_variation_control-radio-light">' .
544
+ '<span class="dashicons dashicons-image-rotate"></span>' .
545
+ '<div class="c-font-palette__tooltip">Light</div>' .
546
+ '</div>' .
547
+ '<div class="c-font-palette__control variation-dark" data-target="#_customize-input-sm_font_palette_variation_control-radio-dark">' .
548
+ '<span class="dashicons dashicons-image-filter"></span>'.
549
+ '<div class="c-font-palette__tooltip">Dark</div>' .
550
+ '</div>' .
551
+ '<div class="c-font-palette__control variation-fontful" data-target="#_customize-input-sm_font_palette_variation_control-radio-fontful">' .
552
+ '<span class="dashicons dashicons-admin-appearance"></span>' .
553
+ '<div class="c-font-palette__tooltip">Fontful</div>' .
554
+ '</div>' .
555
+ '</div>' . PHP_EOL .
556
+ '</div>' . PHP_EOL .
557
+ '</div>' . PHP_EOL .
558
+ '</div>' . PHP_EOL .
559
+ '<svg class="c-font-palette__blur" width="15em" height="15em" viewBox="0 0 15 15" xmlns="http://www.w3.org/2000/svg" version="1.1">' . PHP_EOL .
560
+ '<defs>' . PHP_EOL .
561
+ '<filter id="goo">' . PHP_EOL .
562
+ '<feGaussianBlur in="SourceGraphic" stdDeviation="10" result="blur" />' . PHP_EOL .
563
+ '<feFontMatrix in="blur" mode="matrix" values="1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 50 -20" result="goo" />' . PHP_EOL .
564
+ '<feBlend in="SourceGraphic" in2="goo" />' . PHP_EOL .
565
+ '</filter>' . PHP_EOL .
566
+ '</defs>' . PHP_EOL .
567
+ '</svg>',
568
+ ),
569
+ ) + $config['sections']['style_manager_section']['options'];
570
+
571
+ return $config;
572
+ }
573
+
574
+ /**
575
+ * Process any configured connected fields that relate to fonts and standardize their config.
576
+ *
577
+ * Think things like filling up the default font_size if not present.
578
+ *
579
+ * @since 1.7.4
580
+ *
581
+ * @param array $config
582
+ *
583
+ * @return array
584
+ */
585
+ public function standardize_connected_fields( $config ) {
586
+ // If there is no style manager support, bail early.
587
+ if ( ! $this->is_supported() ) {
588
+ return $config;
589
+ }
590
+
591
+ $style_manager_options = $config['sections']['style_manager_section']['options'];
592
+ $master_font_controls_ids = $this->get_all_master_font_controls_ids( $style_manager_options );
593
+ if ( empty( $master_font_controls_ids ) ) {
594
+ return $config;
595
+ }
596
+
597
+ foreach ( $master_font_controls_ids as $id ) {
598
+ if ( ! empty( $style_manager_options[ $id ]['connected_fields'] ) ) {
599
+ $connected_fields_config = array();
600
+ foreach ( $style_manager_options[ $id ]['connected_fields'] as $key => $value ) {
601
+ // If we have a shorthand connected field config, change it to a standard one.
602
+ if ( ! is_array( $value ) ) {
603
+ $key = $value;
604
+ $value = array();
605
+ }
606
+
607
+ $option_config = $this->get_option_config( $key, $config );
608
+ if ( empty( $option_config ) ) {
609
+ continue;
610
+ }
611
+
612
+ // If we didn't get a font_size we will try and grab the default value for the connected field.
613
+ if ( ! isset( $value['font_size'] ) ) {
614
+ if ( isset( $option_config['default']['font-size'] ) ) {
615
+ $value['font_size'] = array( 'value' => $option_config['default']['font-size'] );
616
+ } else {
617
+ $value['font_size'] = false;
618
+ }
619
+ }
620
+
621
+ // Handle the case when the received font_size value is a number with a unit - split them.
622
+ $value['font_size'] = $this->maybe_standardize_value( $value['font_size'] );
623
+
624
+ // If we don't have an unit, maybe we can make an educated guess.
625
+ // If the value is bellow 9, then probably we are talking about ems, else pxs.
626
+ if ( ! empty( $value['font_size'] ) && ! empty( $value['font_size']['value'] ) && ! isset( $value['font_size']['unit'] ) ) {
627
+ if ( $value['font_size']['value'] < 9 ) {
628
+ $value['font_size']['unit'] = 'em';
629
+ } else {
630
+ $value['font_size']['unit'] = 'px';
631
+ }
632
+ }
633
+
634
+ $connected_fields_config[ $key ] = $value;
635
+ }
636
+
637
+ $config['sections']['style_manager_section']['options'][ $id ]['connected_fields'] = $connected_fields_config;
638
+ }
639
+ }
640
+
641
+ return $config;
642
+ }
643
+
644
+ /**
645
+ * Standardize a numerical value for a font CSS property.
646
+ *
647
+ * The standard format is an associative array with the following entries:
648
+ * - 'value': holds the actual numerical value (int or float)
649
+ * - 'unit : optional; it holds the unit that should be used for the value
650
+ *
651
+ * @param mixed $value
652
+ *
653
+ * @return array|bool
654
+ */
655
+ private function maybe_standardize_value( $value ) {
656
+ $new_value = false;
657
+
658
+ if ( false === $value ) {
659
+ return $new_value;
660
+ }
661
+
662
+ if ( is_array( $value ) ) {
663
+ $new_value = $value;
664
+ }
665
+
666
+ if ( is_string( $value ) ) {
667
+ if ( is_numeric( $value ) ) {
668
+ $new_value = array( 'value' => (float) $value );
669
+ } else {
670
+ // We will get everything in front that is a valid part of a number (float including).
671
+ preg_match("/^([\d.\-+]+)/i", $value, $match);
672
+
673
+ if ( ! empty( $match ) && isset( $match[0] ) ) {
674
+ $new_value = array(
675
+ 'value' => (float) $match[0],
676
+ 'unit' => substr( $value, strlen( $match[0] ) ),
677
+ );
678
+ }
679
+ }
680
+ }
681
+
682
+ if ( is_numeric( $value ) ) {
683
+ $new_value = array( 'value' => $value );
684
+ }
685
+
686
+ return $new_value;
687
+ }
688
+
689
+ /**
690
+ * Get the Customify configuration of a certain option.
691
+ *
692
+ * @param string $option_id
693
+ *
694
+ * @return array|false The option config or false on failure.
695
+ */
696
+ private function get_option_config( $option_id, $config ) {
697
+ // We need to search for the option configured under the given id (the array key)
698
+ if ( isset ( $config['panels'] ) ) {
699
+ foreach ( $config['panels'] as $panel_id => $panel_settings ) {
700
+ if ( isset( $panel_settings['sections'] ) ) {
701
+ foreach ( $panel_settings['sections'] as $section_id => $section_settings ) {
702
+ if ( isset( $section_settings['options'] ) ) {
703
+ foreach ( $section_settings['options'] as $id => $option_config ) {
704
+ if ( $id === $option_id ) {
705
+ return $option_config;
706
+ }
707
+ }
708
+ }
709
+ }
710
+ }
711
+ }
712
+ }
713
+
714
+ if ( isset ( $config['sections'] ) ) {
715
+ foreach ( $config['sections'] as $section_id => $section_settings ) {
716
+ if ( isset( $section_settings['options'] ) ) {
717
+ foreach ( $section_settings['options'] as $id => $option_config ) {
718
+ if ( $id === $option_id ) {
719
+ return $option_config;
720
+ }
721
+ }
722
+ }
723
+ }
724
+ }
725
+
726
+ return false;
727
+ }
728
+
729
+ /**
730
+ * Get the default (hard-coded) font palettes configuration.
731
+ *
732
+ * This is only a fallback config in case we can't communicate with the cloud, the first time.
733
+ *
734
+ * @since 1.7.4
735
+ *
736
+ * @return array
737
+ */
738
+ protected function get_default_config() {
739
+ $default_config = array(
740
+ 'gema' => array(
741
+ 'label' => esc_html__( 'Gema', 'customify' ),
742
+ 'preview' => array(
743
+ // Font Palette Name
744
+ 'title' => esc_html__( 'Gema', 'customify' ),
745
+ 'description' => esc_html__( 'A graceful nature, truly tasteful and polished.', 'customify' ),
746
+ 'background_image_url' => 'http://pxgcdn.com/images/style-manager/color-palettes/gema-theme-palette.jpg',
747
+
748
+ // Use the following options to style the preview card fonts
749
+ // Including font-family, size, line-height, weight, letter-spacing and text transform
750
+ 'title_font' => array(
751
+ 'font' => 'font_primary',
752
+ 'size' => 32,
753
+ ),
754
+ 'description_font' => array(
755
+ 'font' => 'font_body',
756
+ 'size' => 16,
757
+ ),
758
+ ),
759
+
760
+ 'fonts_logic' => array(
761
+ // Primary is used for main headings [Display, H1, H2, H3]
762
+ 'sm_font_primary' => array(
763
+ // Define the font type ('google' or 'theme_font'). By default it's 'google'.
764
+ 'type' => 'google',
765
+ // Font loaded when a palette is selected
766
+ 'font_family' => 'Montserrat',
767
+ // Load all these fonts weights.
768
+ 'font_weights' => array( 100, 300, 700 ),
769
+ // "Generate" the graph to be used for font-size and line-height.
770
+ 'font_size_to_line_height_points' => array(
771
+ array( 17, 1.7 ),
772
+ array( 20, 1.3 ),
773
+ array( 32, 1.3 ),
774
+ array( 48, 1.2 ),
775
+ ),
776
+
777
+ // Define how fonts will look based on the font size.
778
+ 'font_styles_intervals' => array(
779
+ array(
780
+ 'start' => 10,
781
+ 'font_weight' => 300,
782
+ 'letter_spacing' => '0.03em',
783
+ 'text_transform' => 'uppercase',
784
+ ),
785
+ array(
786
+ 'start' => 12,
787
+ 'font_weight' => 700,
788
+ 'letter_spacing' => '0em',
789
+ 'text_transform' => 'uppercase',
790
+ ),
791
+ array(
792
+ 'start' => 18,
793
+ 'font_weight' => 100,
794
+ 'letter_spacing' => '0.03em',
795
+ 'text_transform' => 'uppercase',
796
+ ),
797
+ ),
798
+ ),
799
+
800
+ // Secondary font is used for smaller headings [H4, H5, H6], including meta details
801
+ 'sm_font_secondary' => array(
802
+ 'font_family' => 'Montserrat',
803
+ 'font_weights' => array( 200, 400 ),
804
+ 'font_size_to_line_height_points' => array(
805
+ array( 10, 1.6 ),
806
+ array( 12, 1.5 ),
807
+ array( 18, 1.5 )
808
+ ),
809
+ 'font_styles_intervals' => array(
810
+ array(
811
+ 'start' => 0,
812
+ 'font_weight' => 200,
813
+ 'letter_spacing' => '0.03em',
814
+ 'text_transform' => 'uppercase',
815
+ ),
816
+ array(
817
+ 'start' => 13,
818
+ 'font_weight' => 400,
819
+ 'letter_spacing' => '0.015em',
820
+ 'text_transform' => 'uppercase',
821
+ ),
822
+ ),
823
+ ),
824
+
825
+ // Used for Body Font [eg. entry-content]
826
+ 'sm_font_body' => array(
827
+ 'font_family' => 'Montserrat',
828
+ 'font_weights' => array( 200, '200italic', 700, '700italic' ),
829
+ 'font_size_to_line_height_points' => array(
830
+ array( 15, 1.7 ),
831
+ array( 16, 1.8 ),
832
+ array( 18, 1.7 ),
833
+ ),
834
+
835
+ // Define how fonts will look based on their size
836
+ 'font_styles_intervals' => array(
837
+ array(
838
+ 'font_weight' => 200,
839
+ 'letter_spacing' => 0,
840
+ 'text_transform' => 'none',
841
+ ),
842
+ ),
843
+ ),
844
+ ),
845
+ ),
846
+ 'julia' => array(
847
+ 'label' => esc_html__( 'Julia', 'customify' ),
848
+ 'preview' => array(
849
+ // Font Palette Name
850
+ 'title' => esc_html__( 'Julia', 'customify' ),
851
+ 'description' => esc_html__( 'A graceful nature, truly tasteful and polished.', 'customify' ),
852
+ 'background_image_url' => 'http://pxgcdn.com/images/style-manager/color-palettes/julia-theme-palette.jpg',
853
+
854
+ // Use the following options to style the preview card fonts
855
+ // Including font-family, size, line-height, weight, letter-spacing and text transform
856
+ 'title_font' => array(
857
+ 'font' => 'font_primary',
858
+ 'size' => 30,
859
+ ),
860
+ 'description_font' => array(
861
+ 'font' => 'font_body',
862
+ 'size' => 17,
863
+ ),
864
+ ),
865
+
866
+ 'fonts_logic' => array(
867
+ // Primary is used for main headings [Display, H1, H2, H3]
868
+ 'sm_font_primary' => array(
869
+ // Define the font type ('google' or 'theme_font'). By default it's 'google'.
870
+ 'type' => 'google',
871
+ // Font loaded when a palette is selected
872
+ 'font_family' => 'Lora',
873
+ // Load all these fonts weights.
874
+ 'font_weights' => array( 700 ),
875
+ // "Generate" the graph to be used for font-size and line-height.
876
+ 'font_size_to_line_height_points' => array(
877
+ array( 24, 1.25 ),
878
+ array( 44, 1.2 ),
879
+ array( 66, 1.15 ),
880
+ ),
881
+
882
+ // Define how fonts will look based on the font size.
883
+ 'font_styles_intervals' => array(
884
+ array(
885
+ 'start' => 0,
886
+ 'font_weight' => 700,
887
+ 'letter_spacing' => '0em',
888
+ 'text_transform' => 'none',
889
+ ),
890
+ ),
891
+ ),
892
+
893
+ // Secondary font is used for smaller headings [H4, H5, H6], including meta details
894
+ 'sm_font_secondary' => array(
895
+ 'font_family' => 'Montserrat',
896
+ 'font_weights' => array( 'regular', 600 ),
897
+ 'font_size_to_line_height_points' => array(
898
+ array( 14, 1.2 ),
899
+ array( 16, 1.2 )
900
+ ),
901
+ 'font_styles_intervals' => array(
902
+ array(
903
+ 'start' => 0,
904
+ 'font_weight' => 600,
905
+ 'letter_spacing' => '0.154em',
906
+ 'text_transform' => 'uppercase',
907
+ ),
908
+ array(
909
+ 'start' => 13,
910
+ 'font_weight' => 'regular',
911
+ 'letter_spacing' => '0em',
912
+ 'text_transform' => 'uppercase',
913
+ ),
914
+ array(
915
+ 'start' => 14,
916
+ 'font_weight' => 'regular',
917
+ 'letter_spacing' => '0.1em',
918
+ 'text_transform' => 'uppercase',
919
+ ),
920
+ array(
921
+ 'start' => 16,
922
+ 'font_weight' => 'regular',
923
+ 'letter_spacing' => '0em',
924
+ 'text_transform' => 'uppercase',
925
+ ),
926
+ array(
927
+ 'start' => 17,
928
+ 'font_weight' => 'regular',
929
+ 'letter_spacing' => '0em',
930
+ 'text_transform' => 'none',
931
+ ),
932
+ ),
933
+ ),
934
+
935
+ // Used for Body Font [eg. entry-content]
936
+ 'sm_font_body' => array(
937
+ 'font_family' => 'PT Serif',
938
+ 'font_weights' => array( 'regular', '400italic', 700, '700italic' ),
939
+ 'font_size_to_line_height_points' => array(
940
+ array( 15, 1.7 ),
941
+ array( 17, 1.6 ),
942
+ array( 18, 1.5 ),
943
+ ),
944
+
945
+ // Define how fonts will look based on their size
946
+ 'font_styles_intervals' => array(
947
+ array(
948
+ 'start' => 0,
949
+ 'font_weight' => 'regular',
950
+ 'letter_spacing' => 0,
951
+ 'text_transform' => 'none',
952
+ ),
953
+ ),
954
+ ),
955
+ ),
956
+ ),
957
+ 'patch' => array(
958
+ 'label' => esc_html__( 'Patch', 'customify' ),
959
+ 'preview' => array(
960
+ // Font Palette Name
961
+ 'title' => esc_html__( 'Patch', 'customify' ),
962
+ 'description' => esc_html__( 'A graceful nature, truly tasteful and polished.', 'customify' ),
963
+ 'background_image_url' => 'http://pxgcdn.com/images/style-manager/color-palettes/patch-theme-palette.jpg',
964
+
965
+ // Use the following options to style the preview card fonts
966
+ // Including font-family, size, line-height, weight, letter-spacing and text transform
967
+ 'title_font' => array(
968
+ 'font' => 'font_primary',
969
+ 'size' => 26,
970
+ ),
971
+ 'description_font' => array(
972
+ 'font' => 'font_body',
973
+ 'size' => 16,
974
+ ),
975
+ ),
976
+
977
+ 'fonts_logic' => array(
978
+ // Primary is used for main headings [Display, H1, H2, H3]
979
+ 'sm_font_primary' => array(
980
+ // Define the font type ('google' or 'theme_font'). By default it's 'google'.
981
+ 'type' => 'google',
982
+ // Font loaded when a palette is selected
983
+ 'font_family' => 'Oswald',
984
+ // Load all these fonts weights.
985
+ 'font_weights' => array( 300, 400, 500 ),
986
+ // "Generate" the graph to be used for font-size and line-height.
987
+ 'font_size_to_line_height_points' => array(
988
+ array( 20, 1.15 ),
989
+ array( 26, 1.45 ),
990
+ array( 30, 1.25 ),
991
+ array( 56, 1.25 ),
992
+ ),
993
+
994
+ // Define how fonts will look based on the font size.
995
+ 'font_styles_intervals' => array(
996
+ array(
997
+ 'start' => 0,
998
+ 'font_weight' => 500,
999
+ 'letter_spacing' => '0.04em',
1000
+ 'text_transform' => 'uppercase',
1001
+ ),
1002
+ array(
1003
+ 'start' => 24,
1004
+ 'font_weight' => 300,
1005
+ 'letter_spacing' => '0.06em',
1006
+ 'text_transform' => 'uppercase',
1007
+ ),
1008
+ array(
1009
+ 'start' => 25,
1010
+ 'font_weight' => 400,
1011
+ 'letter_spacing' => '0.04em',
1012
+ 'text_transform' => 'uppercase',
1013
+ ),
1014
+ array(
1015
+ 'start' => 26,
1016
+ 'font_weight' => 500,
1017
+ 'letter_spacing' => '0.04em',
1018
+ 'text_transform' => 'uppercase',
1019
+ ),
1020
+ ),
1021
+ ),
1022
+
1023
+ // Secondary font is used for smaller headings [H4, H5, H6], including meta details
1024
+ 'sm_font_secondary' => array(
1025
+ 'font_family' => 'Oswald',
1026
+ 'font_weights' => array( 200, '200italic', 500, '500italic' ),
1027
+ 'font_size_to_line_height_points' => array(
1028
+ array( 14, 1.625 ),
1029
+ array( 22, 1.55 ),
1030
+ array( 24, 1.625 ),
1031
+ ),
1032
+ 'font_styles_intervals' => array(
1033
+ array(
1034
+ 'start' => 0,
1035
+ 'font_weight' => 500,
1036
+ 'letter_spacing' => '0.01em',
1037
+ 'text_transform' => 'uppercase',
1038
+ ),
1039
+ array(
1040
+ 'start' => 20,
1041
+ 'font_weight' => 500,
1042
+ 'letter_spacing' => '0em',
1043
+ 'text_transform' => 'uppercase',
1044
+ ),
1045
+ array(
1046
+ 'start' => 24,
1047
+ 'font_weight' => 200,
1048
+ 'letter_spacing' => '0em',
1049
+ 'text_transform' => 'none',
1050
+ ),
1051
+ ),
1052
+ ),
1053
+
1054
+ // Used for Body Font [eg. entry-content]
1055
+ 'sm_font_body' => array(
1056
+ 'font_family' => 'Roboto',
1057
+ 'font_weights' => array( 300, '300italic', 400, '400italic', 500, '500italic' ),
1058
+ 'font_size_to_line_height_points' => array(
1059
+ array( 10, 1.6 ),
1060
+ array( 16, 1.625 ),
1061
+ array( 18, 1.75 ),
1062
+ ),
1063
+
1064
+ // Define how fonts will look based on their size
1065
+ 'font_styles_intervals' => array(
1066
+ array(
1067
+ 'start' => 0,
1068
+ 'end' => 10.9,
1069
+ 'font_weight' => 500,
1070
+ 'letter_spacing' => '0.03em',
1071
+ 'text_transform' => 'none',
1072
+ ),
1073
+ array(
1074
+ 'start' => 10.9,
1075
+ 'end' => 12,
1076
+ 'font_weight' => 500,
1077
+ 'letter_spacing' => '0.02em',
1078
+ 'text_transform' => 'uppercase',
1079
+ ),
1080
+ array(
1081
+ 'start' => 12,
1082
+ 'font_weight' => 300,
1083
+ 'letter_spacing' => 0,
1084
+ 'text_transform' => 'none',
1085
+ ),
1086
+ ),
1087
+ ),
1088
+ ),
1089
+ ),
1090
+ 'hive' => array(
1091
+ 'label' => esc_html__( 'Hive', 'customify' ),
1092
+ 'preview' => array(
1093
+ // Font Palette Name
1094
+ 'title' => esc_html__( 'Hive', 'customify' ),
1095
+ 'description' => esc_html__( 'A graceful nature, truly tasteful and polished.', 'customify' ),
1096
+ 'background_image_url' => 'http://pxgcdn.com/images/style-manager/color-palettes/hive-theme-palette.jpg',
1097
+
1098
+ // Use the following options to style the preview card fonts
1099
+ // Including font-family, size, line-height, weight, letter-spacing and text transform
1100
+ 'title_font' => array(
1101
+ 'font' => 'font_primary',
1102
+ 'size' => 36,
1103
+ ),
1104
+ 'description_font' => array(
1105
+ 'font' => 'font_body',
1106
+ 'size' => 18,
1107
+ ),
1108
+ ),
1109
+
1110
+ 'fonts_logic' => array(
1111
+ // Primary is used for main headings [Display, H1, H2, H3]
1112
+ 'sm_font_primary' => array(
1113
+ // Define the font type ('google' or 'theme_font'). By default it's 'google'.
1114
+ 'type' => 'google',
1115
+ // Font loaded when a palette is selected
1116
+ 'font_family' => 'Playfair Display',
1117
+ // Load all these fonts weights.
1118
+ 'font_weights' => array( 400, '400italic', 700, '700italic', 900, '900italic' ),
1119
+ // "Generate" the graph to be used for font-size and line-height.
1120
+ 'font_size_to_line_height_points' => array(
1121
+ array( 20, 1.55 ),
1122
+ array( 28, 1.5 ),
1123
+ array( 40, 1.35 ),
1124
+ array( 65, 1.15 ),
1125
+ ),
1126
+
1127
+ // Define how fonts will look based on the font size.
1128
+ 'font_styles_intervals' => array(
1129
+ array(
1130
+ 'start' => 0,
1131
+ 'font_weight' => 400,
1132
+ 'letter_spacing' => '0em',
1133
+ 'text_transform' => 'none',
1134
+ ),
1135
+ ),
1136
+ ),
1137
+
1138
+ // Secondary font is used for smaller headings [H4, H5, H6], including meta details
1139
+ 'sm_font_secondary' => array(
1140
+ 'font_family' => 'Noto Serif',
1141
+ 'font_weights' => array( 400, '400italic', 700, '700italic' ),
1142
+ 'font_size_to_line_height_points' => array(
1143
+ array( 13, 1.33 ),
1144
+ array( 18, 1.5 ),
1145
+ ),
1146
+ 'font_styles_intervals' => array(
1147
+ array(
1148
+ 'start' => 0,
1149
+ 'font_weight' => 400,
1150
+ 'letter_spacing' => '0em',
1151
+ 'text_transform' => 'none',
1152
+ ),
1153
+ ),
1154
+ ),
1155
+
1156
+ // Used for Body Font [eg. entry-content]
1157
+ 'sm_font_body' => array(
1158
+ 'font_family' => 'Noto Serif',
1159
+ 'font_weights' => array( 400, '400italic', 700, '700italic' ),
1160
+ 'font_size_to_line_height_points' => array(
1161
+ array( 13, 1.4 ),
1162
+ array( 18, 1.5 ),
1163
+ ),
1164
+
1165
+ // Define how fonts will look based on their size
1166
+ 'font_styles_intervals' => array(
1167
+ array(
1168
+ 'start' => 0,
1169
+ 'font_weight' => 400,
1170
+ 'letter_spacing' => 0,
1171
+ 'text_transform' => 'none',
1172
+ ),
1173
+ ),
1174
+ ),
1175
+ ),
1176
+ ),
1177
+ 'vasco' => array(
1178
+ 'label' => esc_html__( 'Not Vasco', 'customify' ),
1179
+ 'preview' => array(
1180
+ // Font Palette Name
1181
+ 'title' => esc_html__( 'Not Vasco', 'customify' ),
1182
+ 'description' => esc_html__( 'Just awesome.', 'customify' ),
1183
+ 'background_image_url' => 'http://pxgcdn.com/images/style-manager/color-palettes/vasco-theme-palette.jpg',
1184
+
1185
+ // Use the following options to style the preview card fonts
1186
+ // Including font-family, size, line-height, weight, letter-spacing and text transform
1187
+ 'title_font' => array(
1188
+ 'font' => 'font_primary',
1189
+ 'size' => 26,
1190
+ ),
1191
+ 'description_font' => array(
1192
+ 'font' => 'font_body',
1193
+ 'size' => 14,
1194
+ ),
1195
+ ),
1196
+
1197
+ 'fonts_logic' => array(
1198
+ // Primary is used for main headings [Display, H1, H2, H3]
1199
+ 'sm_font_primary' => array(
1200
+ // Define the font type ('google', 'theme_font', 'system'). By default it's 'google'.
1201
+ 'type' => 'google',
1202
+ // Font loaded when a palette is selected
1203
+ 'font_family' => 'Playfair Display',
1204
+ // Load all these fonts weights.
1205
+ 'font_weights' => array( 'regular',700,900 ),
1206
+ // "Generate" the graph to be used for font-size and line-height.
1207
+ 'font_size_to_line_height_points' => array(
1208
+ array( 14, 2 ),
1209
+ array( 40, 1.6 ),
1210
+ array( 60, 1.1 ),
1211
+ ),
1212
+
1213
+ // These are not used right now.
1214
+ // 'font_size_min' => 30,
1215
+ // 'font_size_max' => 100,
1216
+
1217
+ // Define how fonts will look based on the font size.
1218
+ // The current logic is as follows:
1219
+ // - for an interval, if the start is missing, it is assumed to be 0;
1220
+ // - for an interval, if the end is missing, it is assumed to be infinity;
1221
+ // - later intervals overwrite earlier ones and apply their own styles; so the order in which you define intervals might influence things;
1222
+ // - if there are gaps between intervals, we will "extend" the first interval to the start of it's next neighbour;
1223
+ // - neighbouring intervals will have, in the end, the same end and start, and on the border, the first interval will apply
1224
+ // i.e. end takes precedence over start.
1225
+ 'font_styles_intervals' => array(
1226
+ array(
1227
+ 'start' => 0,
1228
+ 'end' => 20,
1229
+ 'font_weight' => 'regular',
1230
+ 'letter_spacing' => '0em',
1231
+ 'text_transform' => 'none',
1232
+ ),
1233
+ array(
1234
+ 'start' => 20,
1235
+ 'end' => 50,
1236
+ 'font_weight' => 700,
1237
+ 'letter_spacing' => '0em',
1238
+ 'text_transform' => 'uppercase',
1239
+ ),
1240
+ array(
1241
+ 'start' => 30,
1242
+ 'font_weight' => 900,
1243
+ 'letter_spacing' => '0em',
1244
+ 'text_transform' => 'uppercase',
1245
+ ),
1246
+ ),
1247
+ ),
1248
+
1249
+ // Secondary font is used for smaller headings [H4, H5, H6], including meta details
1250
+ 'sm_font_secondary' => array(
1251
+ 'font_family' => 'Noto Serif',
1252
+ 'font_weights' => array( 400, 500, 700 ),
1253
+ 'font_size_to_line_height_points' => array(
1254
+ array( 14, 1.7 ),
1255
+ array( 50, 1.3 ),
1256
+ array( 80, 1 ),
1257
+ ),
1258
+ 'font_styles_intervals' => array(
1259
+ array(
1260
+ 'end' => 14,
1261
+ 'font_weight' => 400,
1262
+ 'letter_spacing' => '0.08em',
1263
+ 'text_transform' => 'uppercase',
1264
+ ),
1265
+ array(
1266
+ 'start' => 14,
1267
+ 'end' => 19,
1268
+ 'font_weight' => 700,
1269
+ 'letter_spacing' => '0.07em',
1270
+ 'text_transform' => 'uppercase',
1271
+ ),
1272
+ array(
1273
+ 'start' => 19,
1274
+ 'font_weight' => 500,
1275
+ 'letter_spacing' => 0,
1276
+ 'text_transform' => 'none',
1277
+ ),
1278
+ ),
1279
+ ),
1280
+
1281
+ // Used for Body Font [eg. entry-content]
1282
+ 'sm_font_body' => array(
1283
+ 'type' => 'google',
1284
+ 'font_family' => 'Roboto Slab',
1285
+ 'font_weights' => array( 400, '400italic', 700, '700italic' ),
1286
+ 'font_size_to_line_height_points' => array(
1287
+ array( 15, 1.7 ),
1288
+ array( 17, 1.6 ),
1289
+ array( 18, 1.5 ),
1290
+ ),
1291
+
1292
+ // Define how fonts will look based on their size
1293
+ 'font_styles_intervals' => array(
1294
+ array(
1295
+ 'start' => 0,
1296
+ 'font_weight' => '400italic',
1297
+ 'letter_spacing' => 0,
1298
+ 'text_transform' => 'none',
1299
+ ),
1300
+ ),
1301
+ ),
1302
+ ),
1303
+ ),
1304
+ );
1305
+
1306
+ return apply_filters( 'customify_style_manager_default_font_palettes', $default_config );
1307
+ }
1308
+
1309
+
1310
+
1311
+ /**
1312
+ * Get the current font palette ID or false if none is selected.
1313
+ *
1314
+ * @since 1.7.4
1315
+ *
1316
+ * @return string|false
1317
+ */
1318
+ protected function get_current_palette() {
1319
+ return get_option( 'sm_font_palette', false );
1320
+ }
1321
+
1322
+ /**
1323
+ * Get the current font palette variation ID or false if none is selected.
1324
+ *
1325
+ * @since 1.7.4
1326
+ *
1327
+ * @return string|false
1328
+ */
1329
+ protected function get_current_palette_variation() {
1330
+ return get_option( 'sm_font_palette_variation', false );
1331
+ }
1332
+
1333
+ /**
1334
+ * Determine if the selected font palette has been customized and remember this in an option.
1335
+ *
1336
+ * @since 1.7.4
1337
+ *
1338
+ * @return bool
1339
+ */
1340
+ public function update_custom_palette_in_use() {
1341
+ // If there is no style manager support, bail early.
1342
+ if ( ! $this->is_supported() ) {
1343
+ return false;
1344
+ }
1345
+
1346
+ $current_palette = $this->get_current_palette();
1347
+ if ( empty( $current_palette ) ) {
1348
+ return false;
1349
+ }
1350
+
1351
+ $font_palettes = $this->get_palettes();
1352
+ if ( ! isset( $font_palettes[ $current_palette ] ) || empty( $font_palettes[ $current_palette ]['options'] ) ) {
1353
+ return false;
1354
+ }
1355
+
1356
+ $is_custom_palette = false;
1357
+ // If any of the current master fonts has a different value than the one provided by the font palette,
1358
+ // it means a custom font palette is in use.
1359
+ $current_palette_options = $font_palettes[ $current_palette ]['options'];
1360
+ foreach ( $current_palette_options as $setting_id => $value ) {
1361
+ if ( $value != get_option( $setting_id ) ) {
1362
+ $is_custom_palette = true;
1363
+ break;
1364
+ }
1365
+ }
1366
+
1367
+ update_option( 'sm_is_custom_font_palette', $is_custom_palette, true );
1368
+
1369
+ do_action( 'customify_style_manager_updated_custom_palette_in_use', $is_custom_palette );
1370
+
1371
+ return true;
1372
+ }
1373
+
1374
+ /**
1375
+ * Determine if a custom font palette is in use.
1376
+ *
1377
+ * @since 1.7.4
1378
+ *
1379
+ * @return bool
1380
+ */
1381
+ protected function is_using_custom_palette(){
1382
+ return (bool) get_option( 'sm_is_custom_font_palette', false );
1383
+ }
1384
+
1385
+ /**
1386
+ * Get all the defined Style Manager master font field ids.
1387
+ *
1388
+ * @since 1.7.4
1389
+ *
1390
+ * @param array $options
1391
+ *
1392
+ * @return array
1393
+ */
1394
+ public function get_all_master_font_controls_ids( $options ) {
1395
+ $master_font_controls = array();
1396
+
1397
+ if ( empty( $options ) ) {
1398
+ return $master_font_controls;
1399
+ }
1400
+
1401
+ foreach ( $options as $option_id => $option_settings ) {
1402
+ if ( ! empty( $option_settings['type'] ) && 'font' === $option_settings['type'] ) {
1403
+ $master_font_controls[] = $option_id;
1404
+ }
1405
+ }
1406
+
1407
+ return $master_font_controls;
1408
+ }
1409
+
1410
+ /**
1411
+ * Add font palettes usage data to the site data sent to the cloud.
1412
+ *
1413
+ * @since 1.7.4
1414
+ *
1415
+ * @param array $site_data
1416
+ *
1417
+ * @return array
1418
+ */
1419
+ public function add_palettes_to_site_data( $site_data ) {
1420
+ if ( empty( $site_data['font_palettes'] ) ) {
1421
+ $site_data['font_palettes'] = array();
1422
+ }
1423
+
1424
+ // If others have added data before us, we will merge with it.
1425
+ $site_data['font_palettes'] = array_merge( $site_data['font_palettes'], array(
1426
+ 'current' => $this->get_current_palette(),
1427
+ 'variation' => $this->get_current_palette_variation(),
1428
+ 'custom' => $this->is_using_custom_palette(),
1429
+ ) );
1430
+
1431
+ return $site_data;
1432
+ }
1433
+
1434
+ /**
1435
+ * Main Customify_Font_Palettes Instance
1436
+ *
1437
+ * Ensures only one instance of Customify_Font_Palettes is loaded or can be loaded.
1438
+ *
1439
+ * @since 1.7.4
1440
+ * @static
1441
+ *
1442
+ * @return Customify_Font_Palettes Main Customify_Font_Palettes instance
1443
+ */
1444
+ public static function instance() {
1445
+
1446
+ if ( is_null( self::$_instance ) ) {
1447
+ self::$_instance = new self();
1448
+ }
1449
+ return self::$_instance;
1450
+ } // End instance ()
1451
+
1452
+ /**
1453
+ * Cloning is forbidden.
1454
+ *
1455
+ * @since 1.7.4
1456
+ */
1457
+ public function __clone() {
1458
+
1459
+ _doing_it_wrong( __FUNCTION__,esc_html( __( 'Cheatin&#8217; huh?' ) ), null );
1460
+ } // End __clone ()
1461
+
1462
+ /**
1463
+ * Unserializing instances of this class is forbidden.
1464
+ *
1465
+ * @since 1.7.4
1466
+ */
1467
+ public function __wakeup() {
1468
+
1469
+ _doing_it_wrong( __FUNCTION__, esc_html( __( 'Cheatin&#8217; huh?' ) ), null );
1470
+ } // End __wakeup ()
1471
+ }
1472
+
1473
+ endif;
includes/class-customify-style-manager.php CHANGED
@@ -1,46 +1,67 @@
1
  <?php
 
 
 
 
 
 
 
 
 
 
 
 
 
2
 
3
  class Customify_Style_Manager {
4
 
5
  /**
6
  * Holds the only instance of this class.
7
- * @var null|Customify_Style_Manager
8
- * @access protected
9
- * @since 1.7.0
10
  */
11
  protected static $_instance = null;
12
 
13
  /**
14
  * The main plugin object (the parent).
15
- * @var PixCustomifyPlugin
16
  * @access public
17
- * @since 1.7.0
18
  */
19
  public $parent = null;
20
 
21
  /**
22
- * External REST API endpoints used for communicating with the Pixelgrade Cloud.
23
- * @var array
24
- * @access public
25
- * @since 1.7.0
26
  */
27
- public static $externalApiEndpoints;
28
 
29
  /**
30
- * The current design assets config.
31
- * @var array
32
  * @access public
33
- * @since 1.7.0
34
  */
35
- public $design_assets = null;
36
 
37
  /**
38
- * The external theme config.
39
- * @var array
40
  * @access public
41
- * @since 1.7.5
42
  */
43
- public $external_theme_config = null;
 
 
 
 
 
 
 
 
44
 
45
  /**
46
  * Constructor.
@@ -52,22 +73,38 @@ class Customify_Style_Manager {
52
  protected function __construct( $parent = null ) {
53
  $this->parent = $parent;
54
 
55
- // Make sure our constants are in place, if not already defined.
56
- defined( 'PIXELGRADE_CLOUD__API_BASE' ) || define( 'PIXELGRADE_CLOUD__API_BASE', 'https://cloud.pixelgrade.com/' );
57
-
58
- // Save the external API endpoints in a easy to get property.
59
- self::$externalApiEndpoints = apply_filters( 'customify_style_manager_external_api_endpoints', array(
60
- 'cloud' => array(
61
- 'getDesignAssets' => array(
62
- 'method' => 'GET',
63
- 'url' => PIXELGRADE_CLOUD__API_BASE . 'wp-json/pixcloud/v1/front/design_assets',
64
- ),
65
- 'stats' => array(
66
- 'method' => 'POST',
67
- 'url' => PIXELGRADE_CLOUD__API_BASE . 'wp-json/pixcloud/v1/front/stats',
68
- ),
69
- ),
70
- ) );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
71
 
72
  // Hook up.
73
  $this->add_hooks();
@@ -83,27 +120,11 @@ class Customify_Style_Manager {
83
  * Handle the Customizer Style Manager base config.
84
  */
85
  add_filter( 'customify_filter_fields', array( $this, 'style_manager_section_base_config' ), 12, 1 );
86
- // This needs to come after the external theme config has been applied
87
- add_filter( 'customify_filter_fields', array( $this, 'add_current_color_palette_control' ), 110, 1 );
88
-
89
- /*
90
- * Handle the external theme configuration logic. We use a late priority to be able to overwrite if we have to.
91
- */
92
- add_filter( 'customify_filter_fields', array( $this, 'maybe_activate_external_theme_config' ), 10, 1 );
93
- add_filter( 'customify_filter_fields', array( $this, 'maybe_apply_external_theme_config' ), 100, 1 );
94
- // Maybe the theme has instructed us to do things like removing sections or controls.
95
- add_action( 'customize_register', array( $this, 'maybe_process_external_theme_config_extras' ), 11 );
96
-
97
- // Determine if we should use the config in the theme root and skip the external config.
98
- if ( defined('CUSTOMIFY_SM_LOAD_THEME_ROOT_CONFIG') && true === CUSTOMIFY_SM_LOAD_THEME_ROOT_CONFIG ) {
99
- add_filter( 'customify_style_manager_maybe_fetch_design_assets', array( $this, 'maybe_load_external_config_from_theme_root' ), 10, 1 );
100
- add_filter( 'customize_controls_print_styles', array( $this, 'maybe_output_json_external_config_from_theme_root' ), 0 );
101
- }
102
 
103
  /*
104
- * Handle the logic on settings update/save.
105
  */
106
- add_action( 'customize_save_after', array( $this, 'update_custom_palette_in_use' ), 10, 1 );
107
 
108
  /*
109
  * Handle the logic for user feedback.
@@ -119,12 +140,10 @@ class Customify_Style_Manager {
119
  }
120
 
121
  /**
122
- * Register Customizer admin scripts
123
  */
124
  function register_admin_customizer_scripts() {
125
- wp_register_script( $this->parent->get_slug() . '-swap-values', plugins_url( 'js/customizer/customify-swap-values.js', $this->parent->file ), array( 'jquery' ), $this->parent->get_version() );
126
- wp_register_script( $this->parent->get_slug() . '-palette-variations', plugins_url( 'js/customizer/customify-palette-variations.js', $this->parent->file ), array( 'jquery' ), $this->parent->get_version() );
127
- wp_register_script( $this->parent->get_slug() . '-palettes', plugins_url( 'js/customizer/customify-palettes.js', $this->parent->file ), array( 'jquery', $this->parent->get_slug() . '-palette-variations', $this->parent->get_slug() . '-swap-values' ), $this->parent->get_version() );
128
  }
129
 
130
  /**
@@ -136,7 +155,8 @@ class Customify_Style_Manager {
136
  return;
137
  }
138
 
139
- wp_enqueue_script( $this->parent->get_slug() . '-palettes' );
 
140
  }
141
 
142
  /**
@@ -178,958 +198,164 @@ class Customify_Style_Manager {
178
  'title' => esc_html__( 'Style Manager', 'customify' ),
179
  'section_id' => 'style_manager_section', // We will force this section id preventing prefixing and other regular processing.
180
  'priority' => 1,
181
- 'options' => array(
182
- 'sm_color_palette' => array(
183
- 'type' => 'preset',
184
- // We will bypass the plugin setting regarding where to store - we will store it cross-theme in wp_options
185
- 'setting_type' => 'option',
186
- // We will force this setting id preventing prefixing and other regular processing.
187
- 'setting_id' => 'sm_color_palette',
188
- // We don't want to refresh the preview window, even though we have no direct effect on it through this field.
189
- 'live' => true,
190
- 'label' => esc_html__( 'Select a color palette:', 'customify' ),
191
- 'desc' => esc_html__( 'Conveniently change the design of your site with color palettes. Easy as pie.', 'customify' ),
192
- 'default' => 'lilac',
193
- 'choices_type' => 'color_palette',
194
- 'choices' => $this->get_color_palettes(),
195
- ),
196
- 'sm_color_palette_variation' => array(
197
- 'type' => 'radio',
198
- 'setting_type' => 'option',
199
- 'setting_id' => 'sm_color_palette_variation',
200
- 'label' => esc_html__( 'Palette Variation', 'customify' ),
201
- 'default' => 'light',
202
- 'live' => true,
203
- 'choices' => array(
204
- 'light' => esc_html__( 'light', 'customify' ),
205
- 'light_alt' => esc_html__( 'light_alt', 'customify' ),
206
-
207
- 'dark' => esc_html__( 'dark', 'customify' ),
208
- 'dark_alt' => esc_html__( 'dark_alt', 'customify' ),
209
-
210
- 'colorful' => esc_html__( 'colorful', 'customify' ),
211
- 'colorful_alt' => esc_html__( 'colorful_alt', 'customify' ),
212
- ),
213
- ),
214
- 'sm_color_primary' => array(
215
- 'type' => 'color',
216
- // We will bypass the plugin setting regarding where to store - we will store it cross-theme in wp_options
217
- 'setting_type' => 'option',
218
- // We will force this setting id preventing prefixing and other regular processing.
219
- 'setting_id' => 'sm_color_primary',
220
- // We don't want to refresh the preview window, even though we have no direct effect on it through this field.
221
- 'live' => true,
222
- 'label' => esc_html__( 'Color Primary', 'customify' ),
223
- 'default' => '#ffeb00',
224
- 'connected_fields' => array(),
225
- ),
226
- 'sm_color_secondary' => array(
227
- 'type' => 'color',
228
- 'setting_type' => 'option',
229
- 'setting_id' => 'sm_color_secondary',
230
- 'live' => true,
231
- 'label' => esc_html__( 'Color Secondary', 'customify' ),
232
- 'default' => '#00ecff',
233
- 'connected_fields' => array(),
234
- ),
235
- 'sm_color_tertiary' => array(
236
- 'type' => 'color',
237
- 'setting_type' => 'option',
238
- 'setting_id' => 'sm_color_tertiary',
239
- 'live' => true,
240
- 'label' => esc_html__( 'Color Tertiary', 'customify' ),
241
- 'default' => '#00ecff',
242
- 'connected_fields' => array(),
243
- ),
244
- 'sm_dark_primary' => array(
245
- 'type' => 'color',
246
- 'setting_type' => 'option',
247
- 'setting_id' => 'sm_dark_primary',
248
- 'live' => true,
249
- 'label' => esc_html__( 'Dark Primary', 'customify' ),
250
- 'default' => '#171617',
251
- 'connected_fields' => array(),
252
- ),
253
- 'sm_dark_secondary' => array(
254
- 'type' => 'color',
255
- 'setting_type' => 'option',
256
- 'setting_id' => 'sm_dark_secondary',
257
- 'live' => true,
258
- 'label' => esc_html__( 'Dark Secondary', 'customify' ),
259
- 'default' => '#383c50',
260
- 'connected_fields' => array(),
261
- ),
262
- 'sm_dark_tertiary' => array(
263
- 'type' => 'color',
264
- 'setting_type' => 'option',
265
- 'setting_id' => 'sm_dark_tertiary',
266
- 'live' => true,
267
- 'label' => esc_html__( 'Dark Tertiary', 'customify' ),
268
- 'default' => '#65726F',
269
- 'connected_fields' => array(),
270
- ),
271
- 'sm_light_primary' => array(
272
- 'type' => 'color',
273
- 'setting_type' => 'option',
274
- 'setting_id' => 'sm_light_primary',
275
- 'live' => true,
276
- 'label' => esc_html__( 'Light Primary', 'customify' ),
277
- 'default' => '#ffffff',
278
- 'connected_fields' => array(),
279
- ),
280
- 'sm_light_secondary' => array(
281
- 'type' => 'color',
282
- 'setting_type' => 'option',
283
- 'setting_id' => 'sm_light_secondary',
284
- 'live' => true,
285
- 'label' => esc_html__( 'Light Secondary', 'customify' ),
286
- 'default' => '#ffffff',
287
- 'connected_fields' => array(),
288
- ),
289
- 'sm_light_tertiary' => array(
290
- 'type' => 'color',
291
- 'setting_type' => 'option',
292
- 'setting_id' => 'sm_light_tertiary',
293
- 'live' => true,
294
- 'label' => esc_html__( 'Light Tertiary', 'customify' ),
295
- 'default' => '#ffffff',
296
- 'connected_fields' => array(),
297
- ),
298
- 'sm_swap_colors' => array(
299
- 'type' => 'button',
300
- 'setting_type' => 'option',
301
- 'setting_id' => 'sm_swap_colors',
302
- 'label' => esc_html__( 'Swap Colors', 'customify' ),
303
- 'action' => 'sm_swap_colors',
304
- ),
305
- 'sm_swap_dark_light' => array(
306
- 'type' => 'button',
307
- 'setting_type' => 'option',
308
- 'setting_id' => 'sm_swap_dark_light',
309
- 'label' => esc_html__( 'Swap Dark ⇆ Light', 'customify' ),
310
- 'action' => 'sm_swap_dark_light',
311
- ),
312
- 'sm_swap_colors_dark' => array(
313
- 'type' => 'button',
314
- 'setting_type' => 'option',
315
- 'setting_id' => 'sm_swap_colors_dark',
316
- 'label' => esc_html__( 'Swap Colors ⇆ Dark', 'customify' ),
317
- 'action' => 'sm_swap_colors_dark',
318
- ),
319
- 'sm_swap_secondary_colors_dark' => array(
320
- 'type' => 'button',
321
- 'setting_type' => 'option',
322
- 'setting_id' => 'sm_swap_secondary_colors_dark',
323
- 'label' => esc_html__( 'Swap Secondary Color ⇆ Secondary Dark', 'customify' ),
324
- 'action' => 'sm_swap_secondary_colors_dark',
325
- ),
326
- 'sm_advanced_toggle' => array(
327
- 'type' => 'button',
328
- 'setting_type' => 'option',
329
- 'setting_id' => 'sm_toggle_advanced_settings',
330
- 'label' => esc_html__( 'Toggle Advanced Settings', 'customify' ),
331
- 'action' => 'sm_toggle_advanced_settings',
332
- ),
333
- ),
334
  ) );
335
 
336
  return $config;
337
  }
338
 
339
  /**
340
- * Add the current color palette control to the Style Manager section.
341
  *
342
- * @since 1.7.0
343
  *
344
- * @param array $config
345
  * @return array
346
  */
347
- public function add_current_color_palette_control( $config ) {
348
  // If there is no style manager support, bail early.
349
  if ( ! $this->is_supported() ) {
350
  return $config;
351
  }
352
 
 
353
  if ( ! isset( $config['sections']['style_manager_section'] ) ) {
354
- $config['sections']['style_manager_section'] = array();
355
- }
356
-
357
- $current_palette = '';
358
- $current_palette_sets = array( 'current', 'next' );
359
-
360
- $master_color_controls_ids = $this->get_all_master_color_controls_ids( $config['sections']['style_manager_section']['options'] );
361
-
362
- foreach ( $current_palette_sets as $set ) {
363
- $current_palette .= '<div class="colors ' . $set . '">';
364
- foreach ( $master_color_controls_ids as $setting_id ) {
365
- $current_palette .=
366
- '<div class="color ' . $setting_id . '" data-setting="' . $setting_id . '">' . PHP_EOL .
367
- '<div class="fill"></div>' . PHP_EOL .
368
- '<div class="picker">' .
369
- '<i></i>'.
370
- '</div>' . PHP_EOL .
371
- '</div>' . PHP_EOL;
372
- }
373
- $current_palette .= '</div>';
374
- }
375
-
376
- $current_palette .= '<div class="c-palette__fields">';
377
- foreach ( $master_color_controls_ids as $setting_id ) {
378
- $current_palette .= '<input id="current-palette-' . $setting_id . '" class="c-palette__input ' . $setting_id . '" type="text">';
379
- }
380
- $current_palette .= '</div>';
381
-
382
- // The section might be already defined, thus we merge, not replace the entire section config.
383
- $config['sections']['style_manager_section']['options'] = array(
384
- 'sm_current_color_palette' => array(
385
- 'type' => 'html',
386
- 'html' =>
387
- '<div class="palette-container">' . PHP_EOL .
388
- '<span class="customize-control-title">Current Color Palette:</span>' . PHP_EOL .
389
- '<span class="description customize-control-description">Choose a color palette to start with. Adjust its style using the variation buttons below.</span>' . PHP_EOL .
390
- '<div class="c-palette">' . PHP_EOL .
391
- $current_palette .
392
- '<div class="c-palette__overlay">' . PHP_EOL .
393
- '<div class="c-palette__label">' .
394
- '<div class="c-palette__name">' . 'Original Style' . '</div>' .
395
- '<div class="c-palette__control variation-light active" data-target="#_customize-input-sm_color_palette_variation_control-radio-light">' .
396
- '<span class="dashicons dashicons-image-rotate"></span>' .
397
- '<div class="c-palette__tooltip">Light</div>' .
398
- '</div>' .
399
- '<div class="c-palette__control variation-dark" data-target="#_customize-input-sm_color_palette_variation_control-radio-dark">' .
400
- '<span class="dashicons dashicons-image-filter"></span>'.
401
- '<div class="c-palette__tooltip">Dark</div>' .
402
- '</div>' .
403
- '<div class="c-palette__control variation-colorful" data-target="#_customize-input-sm_color_palette_variation_control-radio-colorful">' .
404
- '<span class="dashicons dashicons-admin-appearance"></span>' .
405
- '<div class="c-palette__tooltip">Colorful</div>' .
406
- '</div>' .
407
- '</div>' . PHP_EOL .
408
- '</div>' . PHP_EOL .
409
- '</div>' . PHP_EOL .
410
- '</div>' . PHP_EOL .
411
- '<svg class="c-palette__blur" width="15em" height="15em" viewBox="0 0 15 15" xmlns="http://www.w3.org/2000/svg" version="1.1">' . PHP_EOL .
412
- '<defs>' . PHP_EOL .
413
- '<filter id="goo">' . PHP_EOL .
414
- '<feGaussianBlur in="SourceGraphic" stdDeviation="10" result="blur" />' . PHP_EOL .
415
- '<feColorMatrix in="blur" mode="matrix" values="1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 50 -20" result="goo" />' . PHP_EOL .
416
- '<feBlend in="SourceGraphic" in2="goo" />' . PHP_EOL .
417
- '</filter>' . PHP_EOL .
418
- '</defs>' . PHP_EOL .
419
- '</svg>',
420
- ),
421
- ) + $config['sections']['style_manager_section']['options'];
422
-
423
- return $config;
424
- }
425
-
426
- /**
427
- * Maybe activate an external theme config.
428
- *
429
- * If the conditions are met, activate an external theme config by declaring support for the style manager and saving the config.
430
- *
431
- * @since 1.7.5
432
- *
433
- * @param array $config This holds required keys for the plugin config like 'opt-name', 'panels', 'settings'
434
- * @return array
435
- */
436
- public function maybe_activate_external_theme_config( $config ) {
437
- // If somebody else already declared support for the Style Manager, we stop and let them have it.
438
- if ( $this->is_supported() ) {
439
- return $config;
440
- }
441
-
442
- $external_theme_config = false;
443
-
444
- // First gather details about the current (parent) theme.
445
- $theme = wp_get_theme( get_template() );
446
- // Bail if for some strange reason we couldn't find the theme.
447
- if ( ! $theme->exists() ) {
448
- return $config;
449
- }
450
-
451
- // Now determine if we have a theme config for the current theme.
452
- $design_assets = $this->get_design_assets();
453
- if ( empty( $design_assets['theme_configs'] ) || ! is_array( $design_assets['theme_configs'] ) ) {
454
  return $config;
455
  }
456
 
457
- $theme_configs = $design_assets['theme_configs'];
458
-
459
- // We will go through every theme config and determine it's match score
460
- foreach ( $theme_configs as $hashid => $theme_config ) {
461
- // Loose matching means that the theme doesn't have to match all the conditions.
462
- $loose_match = false;
463
- if ( ! empty( $theme_config['loose_match'] ) ) {
464
- $loose_match = true;
465
- }
466
-
467
- $matches = 0;
468
- $total = 0;
469
- if ( ! empty( $theme_config['name'] ) && $theme_config['name'] == $theme->get('Name') ) {
470
- $matches++;
471
- $total++;
472
- }
473
- if ( ! empty( $theme_config['slug'] ) && $theme_config['slug'] == $theme->get_stylesheet() ) {
474
- $matches++;
475
- $total++;
476
- }
477
- if ( ! empty( $theme_config['txtd'] ) && $theme_config['txtd'] == $theme->get('TextDomain') ) {
478
- $matches++;
479
- $total++;
480
- }
481
-
482
- $theme_configs[ $hashid ]['match_score'] = 0;
483
- if ( true === $loose_match ) {
484
- $theme_configs[ $hashid ]['match_score'] = $matches;
485
- } elseif( $matches === $total ) {
486
- $theme_configs[ $hashid ]['match_score'] = $matches;
487
- }
488
- }
489
-
490
- // Now we will order the theme configs by match scores, descending and get the highest matching candidate, if any.
491
- $theme_configs = Customify_Array::array_orderby( $theme_configs, 'match_score', SORT_DESC );
492
- $external_theme_config = array_shift( $theme_configs );
493
- // If we've ended up with a theme config with a zero match score, bail.
494
- if ( empty( $external_theme_config['match_score'] ) || empty( $external_theme_config['config']['sections'] ) ) {
495
- return $config;
496
- }
497
-
498
- // Now we have a theme config to work with. Save it for later use.
499
- $this->external_theme_config = $external_theme_config;
500
-
501
- // Declare support for the Style Manager if there is such a section in the config
502
- if ( isset( $external_theme_config['config']['sections']['style_manager_section'] ) ) {
503
- add_theme_support( 'customizer_style_manager' );
504
- }
505
-
506
- return $config;
507
- }
508
 
509
- /**
510
- * Maybe apply an external theme config.
511
- *
512
- * If the conditions are met, apply an external theme config. Right now we are only handling sections and their controls.
513
- *
514
- * @since 1.7.5
515
- *
516
- * @param array $config This holds required keys for the plugin config like 'opt-name', 'panels', 'settings'
517
- * @return array
518
- */
519
- public function maybe_apply_external_theme_config( $config ) {
520
- // Bail if we have no external theme config data.
521
- if ( empty( $this->external_theme_config ) ) {
522
- return $config;
523
  }
524
 
525
- // Apply the theme config.
526
- // If we are dealing with the Customify default config, we need a clean slate, sort of.
527
- if ( 'customify_defaults' === $config['opt-name'] ) {
528
- // We will save the Style Manager config so we can merge with it. But the rest goes away.
529
- $style_manager_section = array();
530
- if ( isset( $config['sections']['style_manager_section'] ) ) {
531
- $style_manager_section = $config['sections']['style_manager_section'];
532
- }
533
-
534
- $config['opt-name'] = get_template() . '_options';
535
- if ( ! empty( $this->external_theme_config['config']['opt-name'] ) ) {
536
- $config['opt-name'] = $this->external_theme_config['config']['opt-name'];
537
- }
538
 
539
- $config['sections'] = array(
540
- 'style_manager_section' => $style_manager_section,
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
541
  );
542
- }
543
-
544
- // Now merge things.
545
- $config['sections'] = Customify_Array::array_merge_recursive_distinct( $config['sections'],$this->external_theme_config['config']['sections'] );
546
-
547
- return $config;
548
- }
549
-
550
- /**
551
- * Maybe process certain "commands" from the external theme config.
552
- *
553
- * Mainly things like removing sections, controls, etc.
554
- *
555
- * @since 1.7.5
556
- *
557
- * @param WP_Customize_Manager $wp_customize
558
- */
559
- public function maybe_process_external_theme_config_extras( $wp_customize ) {
560
- // Bail if we have no external theme config data.
561
- if ( empty( $this->external_theme_config ) ) {
562
- return;
563
- }
564
 
565
- // Maybe remove panels
566
- if ( ! empty( $this->external_theme_config['config']['remove_panels'] ) ) {
567
- // Standardize it.
568
- if ( is_string( $this->external_theme_config['config']['remove_panels'] ) ) {
569
- $this->external_theme_config['config']['remove_panels'] = array( $this->external_theme_config['config']['remove_panels'] );
570
- }
571
-
572
- foreach ( $this->external_theme_config['config']['remove_panels'] as $panel_id ) {
573
- $wp_customize->remove_panel( $panel_id );
574
- }
575
- }
576
-
577
- // Maybe remove sections
578
- if ( ! empty( $this->external_theme_config['config']['remove_sections'] ) ) {
579
- // Standardize it.
580
- if ( is_string( $this->external_theme_config['config']['remove_sections'] ) ) {
581
- $this->external_theme_config['config']['remove_sections'] = array( $this->external_theme_config['config']['remove_sections'] );
582
- }
583
-
584
- foreach ( $this->external_theme_config['config']['remove_sections'] as $section_id ) {
585
-
586
- if ( 'widgets' === $section_id ) {
587
- global $wp_registered_sidebars;
588
-
589
- foreach ( $wp_registered_sidebars as $widget => $settings ) {
590
- $wp_customize->remove_section( 'sidebar-widgets-' . $widget );
591
- }
592
  continue;
593
  }
594
 
595
- $wp_customize->remove_section( $section_id );
596
- }
597
- }
598
-
599
- // Maybe remove settings
600
- if ( ! empty( $this->external_theme_config['config']['remove_settings'] ) ) {
601
- // Standardize it.
602
- if ( is_string( $this->external_theme_config['config']['remove_settings'] ) ) {
603
- $this->external_theme_config['config']['remove_settings'] = array( $this->external_theme_config['config']['remove_settings'] );
604
- }
605
-
606
- foreach ( $this->external_theme_config['config']['remove_settings'] as $setting_id ) {
607
- $wp_customize->remove_setting( $setting_id );
608
- }
609
- }
610
-
611
- // Maybe remove controls
612
- if ( ! empty( $this->external_theme_config['config']['remove_controls'] ) ) {
613
- // Standardize it.
614
- if ( is_string( $this->external_theme_config['config']['remove_controls'] ) ) {
615
- $this->external_theme_config['config']['remove_controls'] = array( $this->external_theme_config['config']['remove_controls'] );
616
- }
617
-
618
- foreach ( $this->external_theme_config['config']['remove_controls'] as $control_id ) {
619
- $wp_customize->remove_control( $control_id );
620
  }
621
- }
622
- }
623
-
624
- /**
625
- * Get the color palettes configuration.
626
- *
627
- * @since 1.7.0
628
- *
629
- * @param bool $skip_cache Optional. Whether to use the cached config or fetch a new one.
630
- * @return array
631
- */
632
- protected function get_color_palettes( $skip_cache = false ) {
633
- // Get the design assets data.
634
- $design_assets = $this->get_design_assets( $skip_cache );
635
- if ( false === $design_assets || empty( $design_assets['color_palettes'] ) ) {
636
- $color_palettes_config = $this->get_default_color_palettes_config();
637
- } else {
638
- $color_palettes_config = $design_assets['color_palettes'];
639
- }
640
-
641
- return apply_filters( 'customify_get_color_palettes', $color_palettes_config );
642
- }
643
-
644
- /**
645
- * Get the themes configuration.
646
- *
647
- * @since 1.7.5
648
- *
649
- * @param bool $skip_cache Optional. Whether to use the cached config or fetch a new one.
650
- * @return array
651
- */
652
- protected function get_theme_configs( $skip_cache = false ) {
653
- // Get the design assets data.
654
- $design_assets = $this->get_design_assets( $skip_cache );
655
- if ( false === $design_assets || empty( $design_assets['theme_configs'] ) ) {
656
- $theme_configs = $this->get_default_color_palettes_config();
657
- } else {
658
- $theme_configs = $design_assets['theme_configs'];
659
- }
660
-
661
- return apply_filters( 'customify_get_theme_configs', $theme_configs );
662
- }
663
-
664
- /**
665
- * Get the design assets configuration.
666
- *
667
- * @since 1.7.0
668
- *
669
- * @param bool $skip_cache Optional. Whether to use the cached config or fetch a new one.
670
- * @return array
671
- */
672
- protected function get_design_assets( $skip_cache = false ) {
673
- if ( ! is_null( $this->design_assets ) ) {
674
- return $this->design_assets;
675
- }
676
 
677
- $this->design_assets = apply_filters( 'customify_style_manager_maybe_fetch_design_assets', $this->maybe_fetch_design_assets( $skip_cache ) );
678
-
679
- return $this->design_assets;
680
- }
681
-
682
- /**
683
- * Fetch the design assets data from the Pixelgrade Cloud.
684
- *
685
- * Caches the data for 12 hours. Use local defaults if not available.
686
- *
687
- * @since 1.7.0
688
- *
689
- * @param bool $skip_cache Optional. Whether to use the cached data or fetch a new one.
690
- * @return array|false
691
- */
692
- protected function maybe_fetch_design_assets( $skip_cache = false ) {
693
- // First try and get the cached data
694
- $data = get_option( $this->_get_design_assets_cache_key() );
695
-
696
- // For performance reasons, we will ONLY fetch remotely when in the WP ADMIN area or via an ADMIN AJAX call, regardless of settings.
697
- if ( ! is_admin() ) {
698
- return $data;
699
  }
700
 
701
- // Get the cache data expiration timestamp.
702
- $expire_timestamp = get_option( $this->_get_design_assets_cache_key() . '_timestamp' );
703
 
704
- // We don't force skip the cache for AJAX requests for performance reasons.
705
- if ( ! wp_doing_ajax() && defined('CUSTOMIFY_SM_ALWAYS_FETCH_DESIGN_ASSETS' ) && true === CUSTOMIFY_SM_ALWAYS_FETCH_DESIGN_ASSETS ) {
706
- $skip_cache = true;
707
- }
708
-
709
- // The data isn't set, is expired or we were instructed to skip the cache; we need to fetch fresh data.
710
- if ( true === $skip_cache || false === $data || false === $expire_timestamp || $expire_timestamp < time() ) {
711
- $request_data = apply_filters( 'customify_pixelgrade_cloud_request_data', array(
712
- 'site_url' => home_url('/'),
713
- // We are only interested in data needed to identify the theme and eventually deliver only design assets suitable for it.
714
- 'theme_data' => $this->get_active_theme_data(),
715
- // We are only interested in data needed to identify the plugin version and eventually deliver design assets suitable for it.
716
- 'site_data' => $this->get_site_data(),
717
- ), $this );
718
-
719
- $request_args = array(
720
- 'method' => self::$externalApiEndpoints['cloud']['getDesignAssets']['method'],
721
- 'timeout' => 4,
722
- 'blocking' => true,
723
- 'body' => $request_data,
724
- 'sslverify' => false,
725
  );
726
- // Get the design assets from the cloud.
727
- $response = wp_remote_request( self::$externalApiEndpoints['cloud']['getDesignAssets']['url'], $request_args );
728
- // Bail in case of decode error or failure to retrieve data.
729
- // We will return the data already available.
730
- if ( is_wp_error( $response ) ) {
731
- return $data;
732
- }
733
- $response_data = json_decode( wp_remote_retrieve_body( $response ), true );
734
- // Bail in case of decode error or failure to retrieve data.
735
- // We will return the data already available.
736
- if ( null === $response_data || empty( $response_data['data'] ) || empty( $response_data['code'] ) || 'success' !== $response_data['code'] ) {
737
- return $data;
738
- }
739
-
740
- $data = apply_filters( 'customify_style_manager_fetch_design_assets', $response_data['data'] );
741
-
742
- // Cache the data in an option for 6 hours
743
- update_option( $this->_get_design_assets_cache_key() , $data, true );
744
- update_option( $this->_get_design_assets_cache_key() . '_timestamp' , time() + 6 * HOUR_IN_SECONDS, true );
745
- }
746
-
747
- return $data;
748
- }
749
-
750
- /**
751
- * Get the design assets cache key.
752
- *
753
- * @since 1.7.0
754
- *
755
- * @return string
756
- */
757
- protected function _get_design_assets_cache_key() {
758
- return 'customify_style_manager_design_assets';
759
- }
760
-
761
- /**
762
- * Get the default (hard-coded) color palettes configuration.
763
- *
764
- * @since 1.7.0
765
- *
766
- * @return array
767
- */
768
- protected function get_default_color_palettes_config() {
769
- $default_color_palettes = array(
770
- 'vasco' => array(
771
- 'label' => esc_html__( 'Restful Beach', 'customify' ),
772
- 'preview' => array(
773
- 'background_image_url' => 'http://pxgcdn.com/images/style-manager/color-palettes/vasco-theme-palette.jpg',
774
- ),
775
- 'options' => array(
776
- 'sm_color_primary' => '#38C3C8',
777
- 'sm_color_secondary' => '#F59828',
778
- 'sm_color_tertiary' => '#FB551C',
779
- 'sm_dark_primary' => '#2b2b28',
780
- 'sm_dark_secondary' => '#2B3D39',
781
- 'sm_dark_tertiary' => '#65726F',
782
- 'sm_light_primary' => '#F5F6F1',
783
- 'sm_light_secondary' => '#E6F7F7',
784
- 'sm_light_tertiary' => '#FAEDE8',
785
- ),
786
- ),
787
- 'felt' => array(
788
- 'label' => esc_html__( 'Warm Summer', 'customify' ),
789
- 'preview' => array(
790
- 'background_image_url' => 'http://pxgcdn.com/images/style-manager/color-palettes/felt-theme-palette.jpg',
791
- ),
792
- 'options' => array(
793
- 'sm_color_primary' => '#ff6000',
794
- 'sm_color_secondary' => '#FF9200',
795
- 'sm_color_tertiary' => '#FF7019',
796
- 'sm_dark_primary' => '#1C1C1C',
797
- 'sm_dark_secondary' => '#161616',
798
- 'sm_dark_tertiary' => '#161616',
799
- 'sm_light_primary' => '#FFFCFC',
800
- 'sm_light_secondary' => '#FFF4E8',
801
- 'sm_light_tertiary' => '#F7F3F0',
802
- ),
803
- ),
804
- 'julia' => array(
805
- 'label' => esc_html__( 'Serenity', 'customify' ),
806
- 'preview' => array(
807
- 'background_image_url' => 'http://pxgcdn.com/images/style-manager/color-palettes/julia-theme-palette.jpg',
808
- ),
809
- 'options' => array(
810
- 'sm_color_primary' => '#3349B8',
811
- 'sm_color_secondary' => '#3393B8',
812
- 'sm_color_tertiary' => '#C18866',
813
- 'sm_dark_primary' => '#161616',
814
- 'sm_dark_secondary' => '#383C50',
815
- 'sm_dark_tertiary' => '#383C50',
816
- 'sm_light_primary' => '#f7f6f5',
817
- 'sm_light_secondary' => '#E7F2F8',
818
- 'sm_light_tertiary' => '#F7ECE6',
819
- ),
820
- ),
821
- 'gema' => array(
822
- 'label' => esc_html__( 'Burning Red', 'customify' ),
823
- 'preview' => array(
824
- 'background_image_url' => 'http://pxgcdn.com/images/style-manager/color-palettes/gema-theme-palette.jpg',
825
- ),
826
- 'options' => array(
827
- 'sm_color_primary' => '#E03A3A',
828
- 'sm_color_secondary' => '#F75034',
829
- 'sm_color_tertiary' => '#AD2D2D',
830
- 'sm_dark_primary' => '#000000',
831
- 'sm_dark_secondary' => '#000000',
832
- 'sm_dark_tertiary' => '#A3A3A1',
833
- 'sm_light_primary' => '#FFFFFF',
834
- 'sm_light_secondary' => '#F7F5F5',
835
- 'sm_light_tertiary' => '#F7F2F2',
836
- ),
837
- ),
838
- 'patch' => array(
839
- 'label' => esc_html__( 'Fresh Lemon', 'customify' ),
840
- 'preview' => array(
841
- 'background_image_url' => 'http://pxgcdn.com/images/style-manager/color-palettes/patch-theme-palette.jpg',
842
- ),
843
- 'options' => array(
844
- 'sm_color_primary' => '#ffeb00',
845
- 'sm_color_secondary' => '#19CDFF',
846
- 'sm_color_tertiary' => '#0BE8DD',
847
- 'sm_dark_primary' => '#171617',
848
- 'sm_dark_secondary' => '#3d3e40',
849
- 'sm_dark_tertiary' => '#b5b5b5',
850
- 'sm_light_primary' => '#FFFFFF',
851
- 'sm_light_secondary' => '#E8FAFF',
852
- 'sm_light_tertiary' => '#F2FFFE',
853
- ),
854
- ),
855
- 'silk' => array(
856
- 'label' => esc_html__( 'Floral Bloom', 'customify' ),
857
- 'preview' => array(
858
- 'background_image_url' => 'http://pxgcdn.com/images/style-manager/color-palettes/silk-theme-palette.jpg',
859
- ),
860
- 'options' => array(
861
- 'sm_color_primary' => '#A33B61',
862
- 'sm_color_secondary' => '#FCC9B0',
863
- 'sm_color_tertiary' => '#C9648A',
864
- 'sm_dark_primary' => '#000000',
865
- 'sm_dark_secondary' => '#000000',
866
- 'sm_dark_tertiary' => '#A3A3A1',
867
- 'sm_light_primary' => '#FFFFFF',
868
- 'sm_light_secondary' => '#F7F5F6',
869
- 'sm_light_tertiary' => '#F7F0F3',
870
- ),
871
- ),
872
- 'hive' => array(
873
- 'label' => esc_html__( 'Powerful', 'customify' ),
874
- 'preview' => array(
875
- 'background_image_url' => 'http://pxgcdn.com/images/style-manager/color-palettes/hive-theme-palette.jpg',
876
- ),
877
- 'options' => array(
878
- 'sm_color_primary' => '#ffeb00',
879
- 'sm_color_secondary' => '#3200B2',
880
- 'sm_color_tertiary' => '#740AC9',
881
- 'sm_dark_primary' => '#171617',
882
- 'sm_dark_secondary' => '#171617',
883
- 'sm_dark_tertiary' => '#363636',
884
- 'sm_light_primary' => '#FFFFFF',
885
- 'sm_light_secondary' => '#F2F5F7',
886
- 'sm_light_tertiary' => '#F5F2F7',
887
- ),
888
- ),
889
- 'lilac' => array(
890
- 'label' => esc_html__( 'Soft Lilac', 'customify' ),
891
- 'preview' => array(
892
- 'background_image_url' => 'http://pxgcdn.com/images/style-manager/color-palettes/lilac-palette.jpg',
893
- ),
894
- 'options' => array(
895
- 'sm_color_primary' => '#DD8CA9',
896
- 'sm_color_secondary' => '#8C9CDE',
897
- 'sm_color_tertiary' => '#E3B4A6',
898
- 'sm_dark_primary' => '#1A1A1A',
899
- 'sm_dark_secondary' => '#303030',
900
- 'sm_dark_tertiary' => '#A3A3A1',
901
- 'sm_light_primary' => '#F0F2F1',
902
- 'sm_light_secondary' => '#CED5F2',
903
- 'sm_light_tertiary' => '#F7E1DA',
904
- ),
905
- ),
906
- );
907
-
908
- return apply_filters( 'customify_style_manager_default_color_palettes', $default_color_palettes );
909
- }
910
-
911
- /**
912
- * Include the customify "external" config file in the theme root and overwrite the existing theme configs.
913
- *
914
- * @param array $design_assets
915
- *
916
- * @return array
917
- */
918
- public function maybe_load_external_config_from_theme_root( $design_assets ) {
919
- $file_name = 'customify_theme_root.php';
920
-
921
- // First gather details about the current (parent) theme.
922
- $theme = wp_get_theme( get_template() );
923
- // Bail if for some strange reason we couldn't find the theme.
924
- if ( ! $theme->exists() ) {
925
- return $design_assets;
926
- }
927
-
928
- $file = trailingslashit( $theme->get_template_directory() ) . $file_name;
929
- if ( ! file_exists( $file ) ) {
930
- return $design_assets;
931
- }
932
-
933
- // We expect to get from the file include a $config variable with the entire Customify (partial) config.
934
- include $file;
935
-
936
- if ( ! isset( $config ) || ! is_array( $config ) || empty( $config['sections'] ) ) {
937
- // Alert the developers that things are not alright.
938
- _doing_it_wrong( __METHOD__, 'The Customify theme root config is not good! Please check it! We will not apply it.', null );
939
-
940
- return $design_assets;
941
- }
942
 
943
- // Construct the pseudo-external theme config.
944
- // Start with a clean slate.
945
- $design_assets['theme_configs'] = array();
946
-
947
- $design_assets['theme_configs']['theme_root'] = array(
948
- 'id' => 1,
949
- 'name' => $theme->get( 'Name' ),
950
- 'slug' => $theme->get_stylesheet(),
951
- 'txtd' => $theme->get( 'TextDomain' ),
952
- 'loose_match' => true,
953
- 'config' => $config,
954
- 'created' => '2018-05-16 15:13:58',
955
- 'last_modified' => '2018-05-16 15:13:58',
956
- 'hashid' => 'theme_root',
957
- );
958
-
959
- return $design_assets;
960
- }
961
-
962
- /**
963
- * Output the theme root JSON in the Customizer page source.
964
- */
965
- public function maybe_output_json_external_config_from_theme_root() {
966
- if ( ! empty( $this->external_theme_config['config'] ) ) {
967
- // Also output the JSON in a special hidden div for easy copy pasting.
968
- // Also remove any multiple tabs.
969
- echo PHP_EOL . '<!--' . PHP_EOL . 'Just copy&paste this:' . PHP_EOL . PHP_EOL . trim( str_replace( '\t\t', '', json_encode( $this->external_theme_config['config'] ) ) ) . PHP_EOL . PHP_EOL . '-->' . PHP_EOL;
970
- }
971
- }
972
-
973
- /**
974
- * Get the active theme data.
975
- *
976
- * @since 1.7.0
977
- *
978
- * @return array
979
- */
980
- public function get_active_theme_data() {
981
- $theme_data = array();
982
-
983
- $slug = basename( get_template_directory() );
984
-
985
- $theme_data['slug'] = $slug;
986
 
987
- // Get the current theme style.css data.
988
- $current_theme = wp_get_theme( get_template() );
989
- if ( ! empty( $current_theme ) && ! is_wp_error( $current_theme ) ) {
990
- $theme_data['name'] = $current_theme->get('Name');
991
- $theme_data['themeuri'] = $current_theme->get('ThemeURI');
992
- $theme_data['version'] = $current_theme->get('Version');
993
- $theme_data['textdomain'] = $current_theme->get('TextDomain');
994
- }
995
 
996
- // Maybe get the WUpdates theme info if it's a theme delivered from WUpdates.
997
- $wupdates_ids = apply_filters( 'wupdates_gather_ids', array() );
998
- if ( ! empty( $wupdates_ids[ $slug ] ) ) {
999
- $theme_data['wupdates'] = $wupdates_ids[ $slug ];
1000
  }
1001
 
1002
- return apply_filters( 'customify_style_manager_get_theme_data', $theme_data );
1003
- }
1004
-
1005
- /**
1006
- * Get the site data.
1007
- *
1008
- * @since 1.7.0
1009
- *
1010
- * @return array
1011
- */
1012
- public function get_site_data() {
1013
- $site_data = array(
1014
- 'url' => home_url('/'),
1015
- 'is_ssl' => is_ssl(),
1016
  );
1017
 
1018
- $site_data['wp'] = array(
1019
- 'version' => get_bloginfo('version'),
1020
- );
1021
-
1022
- $site_data['customify'] = array(
1023
- 'version' => PixCustomifyPlugin()->get_version(),
1024
- );
1025
-
1026
- $site_data['color_palettes'] = array(
1027
- 'current' => $this->get_current_color_palette(),
1028
- 'variation' => $this->get_current_color_palette_variation(),
1029
- 'custom' => $this->is_using_custom_color_palette(),
1030
- );
1031
-
1032
- // If there isn't a color palette selected, there is not point in having variation or custom.
1033
- if ( empty( $site_data['color_palettes']['current'] ) ) {
1034
- $site_data['color_palettes']['variation'] = false;
1035
- $site_data['color_palettes']['custom'] = false;
1036
- }
1037
-
1038
- return apply_filters( 'customify_style_manager_get_site_data', $site_data );
1039
- }
1040
-
1041
- /**
1042
- * Get the current color palette ID or false if none is selected.
1043
- *
1044
- * @since 1.7.0
1045
- *
1046
- * @return string|false
1047
- */
1048
- protected function get_current_color_palette() {
1049
- return get_option( 'sm_color_palette', false );
1050
- }
1051
-
1052
- /**
1053
- * Get the current color palette variation ID or false if none is selected.
1054
- *
1055
- * @since 1.7.0
1056
- *
1057
- * @return string|false
1058
- */
1059
- protected function get_current_color_palette_variation() {
1060
- return get_option( 'sm_color_palette_variation', 'light' );
1061
- }
1062
-
1063
- /**
1064
- * Determine if the selected color palette has been customized and remember this in an option.
1065
- *
1066
- * @since 1.7.0
1067
- *
1068
- * @return bool
1069
- */
1070
- public function update_custom_palette_in_use() {
1071
- // If there is no style manager support, bail early.
1072
- if ( ! $this->is_supported() ) {
1073
- return false;
1074
- }
1075
-
1076
- $current_palette = $this->get_current_color_palette();
1077
- if ( empty( $current_palette ) ) {
1078
- return false;
1079
- }
1080
-
1081
- $color_palettes = $this->get_color_palettes();
1082
- if ( ! isset( $color_palettes[ $current_palette ] ) || empty( $color_palettes[ $current_palette ]['options'] ) ) {
1083
- return false;
1084
- }
1085
-
1086
- $is_custom_palette = false;
1087
- // If any of the current master colors has a different value than the one provided by the color palette,
1088
- // it means a custom color palette is in use.
1089
- $current_palette_options = $color_palettes[ $current_palette ]['options'];
1090
- foreach ( $current_palette_options as $setting_id => $value ) {
1091
- if ( $value != get_option( $setting_id ) ) {
1092
- $is_custom_palette = true;
1093
- break;
1094
- }
1095
- }
1096
-
1097
- update_option( 'sm_is_custom_color_palette', $is_custom_palette, true );
1098
-
1099
- do_action( 'customify_style_manager_updated_custom_palette_in_use', $is_custom_palette, $this );
1100
 
1101
- return true;
1102
  }
1103
 
1104
  /**
1105
- * Determine if a custom color palette is in use.
1106
  *
1107
- * @since 1.7.0
1108
- *
1109
- * @return bool
1110
- */
1111
- protected function is_using_custom_color_palette(){
1112
- return (bool) get_option( 'sm_is_custom_color_palette', false );
1113
- }
1114
-
1115
- /**
1116
- * Get all the defined Style Manager master color field ids.
1117
  *
1118
- * @since 1.7.0
1119
- *
1120
- * @param array $options
1121
- * @return array
1122
  */
1123
- public function get_all_master_color_controls_ids( $options ) {
1124
- $master_color_controls = array();
1125
-
1126
- foreach ( $options as $option_id => $option_settings ) {
1127
- if ( 'color' === $option_settings['type'] ) {
1128
- $master_color_controls[] = $option_id;
1129
- }
1130
- }
1131
-
1132
- return $master_color_controls;
1133
  }
1134
 
1135
  /**
@@ -1265,25 +491,17 @@ class Customify_Style_Manager {
1265
  $message = wp_kses_post( $_POST['message'] );
1266
  }
1267
 
1268
- $request_data = apply_filters( 'customify_pixelgrade_cloud_request_data', array(
1269
  'site_url' => home_url( '/' ),
1270
  'satisfaction_data' => array(
1271
  'type' => $type,
1272
  'rating' => $rating,
1273
  'message' => $message,
1274
  ),
1275
- ), $this );
1276
-
1277
- $request_args = array(
1278
- 'method' => self::$externalApiEndpoints['cloud']['stats']['method'],
1279
- 'timeout' => 5,
1280
- 'blocking' => true,
1281
- 'body' => $request_data,
1282
- 'sslverify' => false,
1283
  );
1284
 
1285
  // Send the feedback.
1286
- $response = wp_remote_request( self::$externalApiEndpoints['cloud']['stats']['url'], $request_args );
1287
  if ( is_wp_error( $response ) ) {
1288
  wp_send_json_error( esc_html__( 'Sorry, something went wrong and we couldn\'t save your feedback.', 'customify' ) );
1289
  }
@@ -1315,6 +533,7 @@ class Customify_Style_Manager {
1315
  if ( is_null( self::$_instance ) ) {
1316
  self::$_instance = new self( $parent );
1317
  }
 
1318
  return self::$_instance;
1319
  } // End instance ()
1320
 
@@ -1338,3 +557,5 @@ class Customify_Style_Manager {
1338
  _doing_it_wrong( __FUNCTION__, esc_html( __( 'Cheatin&#8217; huh?' ) ), null );
1339
  } // End __wakeup ()
1340
  }
 
 
1
  <?php
2
+ /**
3
+ * This is the class that handles the overall logic for the Style Manager.
4
+ *
5
+ * @see https://pixelgrade.com
6
+ * @author Pixelgrade
7
+ * @since 1.7.0
8
+ */
9
+
10
+ if ( ! defined( 'ABSPATH' ) ) {
11
+ exit; // Exit if accessed directly
12
+ }
13
+
14
+ if ( ! class_exists( 'Customify_Style_Manager' ) ) :
15
 
16
  class Customify_Style_Manager {
17
 
18
  /**
19
  * Holds the only instance of this class.
20
+ * @var null|Customify_Style_Manager
21
+ * @access protected
22
+ * @since 1.7.0
23
  */
24
  protected static $_instance = null;
25
 
26
  /**
27
  * The main plugin object (the parent).
28
+ * @var null|PixCustomifyPlugin
29
  * @access public
30
+ * @since 1.7.0
31
  */
32
  public $parent = null;
33
 
34
  /**
35
+ * The external theme configs object.
36
+ * @var null|Customify_Theme_Configs
37
+ * @access public
38
+ * @since 1.7.4
39
  */
40
+ protected $theme_configs = null;
41
 
42
  /**
43
+ * The color palettes object.
44
+ * @var null|Customify_Color_Palettes
45
  * @access public
46
+ * @since 1.7.4
47
  */
48
+ protected $color_palettes = null;
49
 
50
  /**
51
+ * The font palettes object.
52
+ * @var null|Customify_Font_Palettes
53
  * @access public
54
+ * @since 1.7.4
55
  */
56
+ protected $font_palettes = null;
57
+
58
+ /**
59
+ * The Cloud API object.
60
+ * @var null|Customify_Cloud_Api
61
+ * @access public
62
+ * @since 1.7.4
63
+ */
64
+ protected $cloud_api = null;
65
 
66
  /**
67
  * Constructor.
73
  protected function __construct( $parent = null ) {
74
  $this->parent = $parent;
75
 
76
+ $this->init();
77
+ }
78
+
79
+ /**
80
+ * Initialize this module.
81
+ *
82
+ * @since 1.7.4
83
+ */
84
+ public function init() {
85
+ /**
86
+ * Initialize the Themes Config logic.
87
+ */
88
+ require_once 'class-customify-theme-configs.php';
89
+ $this->theme_configs = Customify_Theme_Configs::instance();
90
+
91
+ /**
92
+ * Initialize the Color Palettes logic.
93
+ */
94
+ require_once 'class-customify-color-palettes.php';
95
+ $this->color_palettes = Customify_Color_Palettes::instance();
96
+
97
+ /**
98
+ * Initialize the Font Palettes logic.
99
+ */
100
+ // require_once 'class-customify-font-palettes.php';
101
+ // $this->font_palettes = Customify_Font_Palettes::instance();
102
+
103
+ /**
104
+ * Initialize the Cloud API logic.
105
+ */
106
+ require_once 'lib/class-customify-cloud-api.php';
107
+ $this->cloud_api = new Customify_Cloud_Api();
108
 
109
  // Hook up.
110
  $this->add_hooks();
120
  * Handle the Customizer Style Manager base config.
121
  */
122
  add_filter( 'customify_filter_fields', array( $this, 'style_manager_section_base_config' ), 12, 1 );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
123
 
124
  /*
125
+ * Handle the grouping and reorganization of the Customizer theme sections when the Style Manager is active.
126
  */
127
+ add_filter( 'customify_final_config', array( $this, 'reorganize_sections' ), 10, 1 );
128
 
129
  /*
130
  * Handle the logic for user feedback.
140
  }
141
 
142
  /**
143
+ * Register Customizer admin scripts.
144
  */
145
  function register_admin_customizer_scripts() {
146
+ wp_register_script( PixCustomifyPlugin()->get_slug() . '-style-manager', plugins_url( 'js/customizer/style-manager.js', PixCustomifyPlugin()->get_file() ), array( 'jquery' ), PixCustomifyPlugin()->get_version() );
 
 
147
  }
148
 
149
  /**
155
  return;
156
  }
157
 
158
+ // Enqueue the needed scripts, already registered.
159
+ wp_enqueue_script( PixCustomifyPlugin()->get_slug() . '-style-manager' );
160
  }
161
 
162
  /**
198
  'title' => esc_html__( 'Style Manager', 'customify' ),
199
  'section_id' => 'style_manager_section', // We will force this section id preventing prefixing and other regular processing.
200
  'priority' => 1,
201
+ 'options' => array(),
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
202
  ) );
203
 
204
  return $config;
205
  }
206
 
207
  /**
208
+ * Reorganize the Customizer sections.
209
  *
210
+ * @since 1.7.4
211
  *
212
+ * @param array $config This holds required keys for the plugin config like 'opt-name', 'panels', 'settings'.
213
  * @return array
214
  */
215
+ public function reorganize_sections( $config ) {
216
  // If there is no style manager support, bail early.
217
  if ( ! $this->is_supported() ) {
218
  return $config;
219
  }
220
 
221
+ // If there is no Style Manager section, bail.
222
  if ( ! isset( $config['sections']['style_manager_section'] ) ) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
223
  return $config;
224
  }
225
 
226
+ $style_manager_section_config = $config['sections']['style_manager_section'];
227
+ unset( $config['sections']['style_manager_section'] );
228
+ // All the other sections.
229
+ $other_theme_sections_config = $config['sections'];
230
+ unset( $config['sections'] );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
231
 
232
+ // Now group them in panels.
233
+ if ( ! isset( $config['panels'] ) ) {
234
+ $config['panels'] = array();
 
 
 
 
 
 
 
 
 
 
 
235
  }
236
 
237
+ // The Style Manager panel.
238
+ $config['panels']['style_manager_panel'] = array(
239
+ 'priority' => 22,
240
+ 'capability' => 'edit_theme_options',
241
+ 'panel_id' => 'style_manager_panel',
242
+ 'title' => __( 'Style Manager', 'pixcustomify' ),
243
+ 'description' => __( '<strong>Style Manager</strong> is an intuitive system to help you change the look of your website and make an excellent impression.', 'pixcustomify' ),
244
+ 'sections' => array(),
245
+ 'auto_expand_sole_section' => true, // If there is only one section in the panel, auto-expand it.
246
+ );
 
 
 
247
 
248
+ // Maybe handle the color palettes.
249
+ if ( class_exists( 'Customify_Color_Palettes' ) && Customify_Color_Palettes::instance()->is_supported() ) {
250
+
251
+ // We need to split the fields in the Style Manager section into two: color palettes and fonts.
252
+ $color_palettes_fields = array(
253
+ 'sm_current_color_palette',
254
+ 'sm_color_matrix',
255
+ 'sm_dark_color_master_slider',
256
+ 'sm_dark_color_primary_slider',
257
+ 'sm_dark_color_secondary_slider',
258
+ 'sm_dark_color_tertiary_slider',
259
+ 'sm_colors_dispersion',
260
+ 'sm_colors_focus_point',
261
+ 'sm_color_palette',
262
+ 'sm_color_palette_variation',
263
+ 'sm_color_primary',
264
+ 'sm_color_secondary',
265
+ 'sm_color_tertiary',
266
+ 'sm_dark_primary',
267
+ 'sm_dark_secondary',
268
+ 'sm_dark_tertiary',
269
+ 'sm_light_primary',
270
+ 'sm_light_secondary',
271
+ 'sm_light_tertiary',
272
+ 'sm_swap_colors',
273
+ 'sm_swap_dark_light',
274
+ 'sm_swap_colors_dark',
275
+ 'sm_swap_secondary_colors_dark',
276
+ 'sm_advanced_toggle',
277
  );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
278
 
279
+ $color_palettes_section_config = array(
280
+ 'title' => __( 'Colors', 'pixcustomify' ),
281
+ 'section_id' => 'sm_color_palettes_section',
282
+ 'priority' => 10,
283
+ 'options' => array(),
284
+ );
285
+ foreach ( $color_palettes_fields as $field_id ) {
286
+ if ( ! isset( $style_manager_section_config['options'][ $field_id ] ) ) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
287
  continue;
288
  }
289
 
290
+ if ( empty( $color_palettes_section_config['options'] ) ) {
291
+ $color_palettes_section_config['options'] = array( $field_id => $style_manager_section_config['options'][ $field_id ] );
292
+ } else {
293
+ $color_palettes_section_config['options'] = array_merge( $color_palettes_section_config['options'], array( $field_id => $style_manager_section_config['options'][ $field_id ] ) );
294
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
295
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
296
 
297
+ $config['panels']['style_manager_panel']['sections']['sm_color_palettes_section'] = $color_palettes_section_config;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
298
  }
299
 
300
+ // Maybe handle the font palettes.
301
+ if ( class_exists( 'Customify_Font_Palettes' ) && Customify_Font_Palettes::instance()->is_supported() ) {
302
 
303
+ $font_palettes_fields = array(
304
+ 'sm_font_palette',
305
+ 'sm_font_palette_variation',
306
+ 'sm_font_primary',
307
+ 'sm_font_secondary',
308
+ 'sm_font_body',
309
+ 'sm_swap_fonts',
310
+ 'sm_swap_primary_secondary_fonts',
 
 
 
 
 
 
 
 
 
 
 
 
 
311
  );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
312
 
313
+ $font_palettes_section_config = array(
314
+ 'title' => __( 'Fonts', 'pixcustomify' ),
315
+ 'section_id' => 'sm_font_palettes_section',
316
+ 'priority' => 20,
317
+ 'options' => array(),
318
+ );
319
+ foreach ( $font_palettes_fields as $field_id ) {
320
+ if ( ! isset( $style_manager_section_config['options'][ $field_id ] ) ) {
321
+ continue;
322
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
323
 
324
+ if ( empty( $font_palettes_section_config['options'] ) ) {
325
+ $font_palettes_section_config['options'] = array( $field_id => $style_manager_section_config['options'][ $field_id ] );
326
+ } else {
327
+ $font_palettes_section_config['options'] = array_merge( $font_palettes_section_config['options'], array( $field_id => $style_manager_section_config['options'][ $field_id ] ) );
328
+ }
329
+ }
 
 
330
 
331
+ $config['panels']['style_manager_panel']['sections']['sm_font_palettes_section'] = $font_palettes_section_config;
 
 
 
332
  }
333
 
334
+ // The Theme Options panel.
335
+ $config['panels']['theme_options_panel'] = array(
336
+ 'priority' => 23,
337
+ 'capability' => 'edit_theme_options',
338
+ 'panel_id' => 'theme_options_panel',
339
+ 'title' => __( 'Theme Options', 'pixcustomify' ),
340
+ 'description' => __( 'Advanced options to change your site look-and-feel on a detailed level.', 'pixcustomify' ),
341
+ 'sections' => $other_theme_sections_config,
 
 
 
 
 
 
342
  );
343
 
344
+ // Finally, remove the switch theme panel from the Customizer.
345
+ add_action( 'customize_register', array( $this, 'remove_switch_theme_panel' ), 10 );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
346
 
347
+ return $config;
348
  }
349
 
350
  /**
351
+ * Remove the switch/preview theme panel.
352
  *
353
+ * @since 1.7.4
 
 
 
 
 
 
 
 
 
354
  *
355
+ * @param WP_Customize_Manager $wp_customize
 
 
 
356
  */
357
+ public function remove_switch_theme_panel( $wp_customize ) {
358
+ $wp_customize->remove_panel( 'themes' );
 
 
 
 
 
 
 
 
359
  }
360
 
361
  /**
491
  $message = wp_kses_post( $_POST['message'] );
492
  }
493
 
494
+ $request_data = array(
495
  'site_url' => home_url( '/' ),
496
  'satisfaction_data' => array(
497
  'type' => $type,
498
  'rating' => $rating,
499
  'message' => $message,
500
  ),
 
 
 
 
 
 
 
 
501
  );
502
 
503
  // Send the feedback.
504
+ $response = $this->cloud_api->send_stats( $request_data, true );
505
  if ( is_wp_error( $response ) ) {
506
  wp_send_json_error( esc_html__( 'Sorry, something went wrong and we couldn\'t save your feedback.', 'customify' ) );
507
  }
533
  if ( is_null( self::$_instance ) ) {
534
  self::$_instance = new self( $parent );
535
  }
536
+
537
  return self::$_instance;
538
  } // End instance ()
539
 
557
  _doing_it_wrong( __FUNCTION__, esc_html( __( 'Cheatin&#8217; huh?' ) ), null );
558
  } // End __wakeup ()
559
  }
560
+
561
+ endif;
includes/class-customify-theme-configs.php ADDED
@@ -0,0 +1,378 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * This is the class that handles the overall logic for the theme configs.
4
+ *
5
+ * @see https://pixelgrade.com
6
+ * @author Pixelgrade
7
+ * @since 1.7.4
8
+ */
9
+
10
+ if ( ! defined( 'ABSPATH' ) ) {
11
+ exit; // Exit if accessed directly
12
+ }
13
+
14
+ if ( ! class_exists( 'Customify_Theme_Configs' ) ) :
15
+
16
+ class Customify_Theme_Configs {
17
+
18
+ /**
19
+ * Holds the only instance of this class.
20
+ * @var null|Customify_Theme_Configs
21
+ * @access protected
22
+ * @since 1.7.4
23
+ */
24
+ protected static $_instance = null;
25
+
26
+ /**
27
+ * The external theme config for the current active theme.
28
+ * @var array
29
+ * @access public
30
+ * @since 1.7.4
31
+ */
32
+ public $external_theme_config = null;
33
+
34
+ /**
35
+ * Constructor.
36
+ *
37
+ * @since 1.7.4
38
+ */
39
+ protected function __construct() {
40
+ $this->init();
41
+ }
42
+
43
+ /**
44
+ * Initialize this module.
45
+ *
46
+ * @since 1.7.4
47
+ */
48
+ public function init() {
49
+ // Hook up.
50
+ $this->add_hooks();
51
+ }
52
+
53
+ /**
54
+ * Initiate our hooks
55
+ *
56
+ * @since 1.7.4
57
+ */
58
+ public function add_hooks() {
59
+ /*
60
+ * Handle the external theme configuration logic. We use a late priority to be able to overwrite if we have to.
61
+ */
62
+ add_filter( 'customify_filter_fields', array( $this, 'maybe_activate_external_theme_config' ), 10, 1 );
63
+ add_filter( 'customify_filter_fields', array( $this, 'maybe_apply_external_theme_config' ), 100, 1 );
64
+ // Maybe the theme has instructed us to do things like removing sections or controls.
65
+ add_action( 'customize_register', array( $this, 'maybe_process_external_theme_config_extras' ), 11 );
66
+
67
+ /*
68
+ * Scripts enqueued in the Customizer.
69
+ */
70
+ add_action( 'customize_controls_init', array( $this, 'register_admin_customizer_scripts' ), 10 );
71
+ add_action( 'customize_controls_enqueue_scripts', array( $this, 'enqueue_admin_customizer_scripts' ), 10 );
72
+
73
+ /**
74
+ * Determine if we should output the theme root JSON in the Customizer for easier copy&paste to cloud.
75
+ */
76
+ if ( defined('CUSTOMIFY_SM_LOAD_THEME_ROOT_CONFIG') && true === CUSTOMIFY_SM_LOAD_THEME_ROOT_CONFIG ) {
77
+ add_filter( 'customize_controls_print_styles', array( $this, 'maybe_output_json_external_config' ), 0 );
78
+ }
79
+ }
80
+
81
+ /**
82
+ * Register Customizer admin scripts.
83
+ */
84
+ function register_admin_customizer_scripts() {
85
+
86
+ }
87
+
88
+ /**
89
+ * Enqueue Customizer admin scripts
90
+ */
91
+ function enqueue_admin_customizer_scripts() {
92
+ // If there is no style manager support, bail early.
93
+ if ( ! $this->is_supported() ) {
94
+ return;
95
+ }
96
+
97
+ // Enqueue the needed scripts, already registered.
98
+ }
99
+
100
+ /**
101
+ * Determine if Style Manager is supported.
102
+ *
103
+ * @since 1.7.4
104
+ *
105
+ * @return bool
106
+ */
107
+ public function is_supported() {
108
+ // For now we will only use the fact that Style Manager is supported.
109
+ return apply_filters( 'customify_theme_configs_are_supported', Customify_Style_Manager::instance()->is_supported() );
110
+ }
111
+
112
+ /**
113
+ * Get the themes configuration.
114
+ *
115
+ * @since 1.7.4
116
+ *
117
+ * @param bool $skip_cache Optional. Whether to use the cached config or fetch a new one.
118
+ *
119
+ * @return array
120
+ */
121
+ public function get_theme_configs( $skip_cache = false ) {
122
+ $theme_configs = array();
123
+
124
+ // Make sure that the Design Assets class is loaded.
125
+ require_once 'lib/class-customify-design-assets.php';
126
+
127
+ // Get the design assets data.
128
+ $design_assets = Customify_Design_Assets::instance()->get( $skip_cache );
129
+ if ( false !== $design_assets && ! empty( $design_assets['theme_configs'] ) ) {
130
+ $theme_configs = $design_assets['theme_configs'];
131
+ }
132
+
133
+ return apply_filters( 'customify_get_theme_configs', $theme_configs );
134
+ }
135
+
136
+ /**
137
+ * Maybe activate an external theme config.
138
+ *
139
+ * If the conditions are met, activate an external theme config by declaring support for the style manager and saving the config.
140
+ *
141
+ * @since 1.7.4
142
+ *
143
+ * @param array $config This holds required keys for the plugin config like 'opt-name', 'panels', 'settings'
144
+ * @return array
145
+ */
146
+ public function maybe_activate_external_theme_config( $config ) {
147
+ // If somebody else already declared support for the Style Manager, we stop and let them have it.
148
+ if ( $this->is_supported() ) {
149
+ return $config;
150
+ }
151
+
152
+ // First gather details about the current (parent) theme.
153
+ $theme = wp_get_theme( get_template() );
154
+ // Bail if for some strange reason we couldn't find the theme.
155
+ if ( ! $theme->exists() ) {
156
+ return $config;
157
+ }
158
+
159
+ // Now determine if we have a theme config for the current theme.
160
+ $theme_configs = $this->get_theme_configs();
161
+
162
+ // We will go through every theme config and determine it's match score
163
+ foreach ( $theme_configs as $hashid => $theme_config ) {
164
+ // Loose matching means that the theme doesn't have to match all the conditions.
165
+ $loose_match = false;
166
+ if ( ! empty( $theme_config['loose_match'] ) ) {
167
+ $loose_match = true;
168
+ }
169
+
170
+ $matches = 0;
171
+ $total = 0;
172
+ if ( ! empty( $theme_config['name'] ) && $theme_config['name'] == $theme->get('Name') ) {
173
+ $matches++;
174
+ $total++;
175
+ }
176
+ if ( ! empty( $theme_config['slug'] ) && $theme_config['slug'] == $theme->get_stylesheet() ) {
177
+ $matches++;
178
+ $total++;
179
+ }
180
+ if ( ! empty( $theme_config['txtd'] ) && $theme_config['txtd'] == $theme->get('TextDomain') ) {
181
+ $matches++;
182
+ $total++;
183
+ }
184
+
185
+ $theme_configs[ $hashid ]['match_score'] = 0;
186
+ if ( true === $loose_match ) {
187
+ $theme_configs[ $hashid ]['match_score'] = $matches;
188
+ } elseif( $matches === $total ) {
189
+ $theme_configs[ $hashid ]['match_score'] = $matches;
190
+ }
191
+ }
192
+
193
+ // Now we will order the theme configs by match scores, descending and get the highest matching candidate, if any.
194
+ $theme_configs = Customify_Array::array_orderby( $theme_configs, 'match_score', SORT_DESC );
195
+ $external_theme_config = array_shift( $theme_configs );
196
+ // If we've ended up with a theme config with a zero match score, bail.
197
+ if ( empty( $external_theme_config['match_score'] ) || empty( $external_theme_config['config']['sections'] ) ) {
198
+ return $config;
199
+ }
200
+
201
+ // Now we have a theme config to work with. Save it for later use.
202
+ $this->external_theme_config = $external_theme_config;
203
+
204
+ // Declare support for the Style Manager if there is such a section in the config
205
+ if ( isset( $external_theme_config['config']['sections']['style_manager_section'] ) ) {
206
+ add_theme_support( 'customizer_style_manager' );
207
+ }
208
+
209
+ return $config;
210
+ }
211
+
212
+ /**
213
+ * Maybe apply an external theme config.
214
+ *
215
+ * If the conditions are met, apply an external theme config. Right now we are only handling sections and their controls.
216
+ *
217
+ * @since 1.7.4
218
+ *
219
+ * @param array $config This holds required keys for the plugin config like 'opt-name', 'panels', 'settings'
220
+ * @return array
221
+ */
222
+ public function maybe_apply_external_theme_config( $config ) {
223
+ // Bail if we have no external theme config data.
224
+ if ( empty( $this->external_theme_config ) ) {
225
+ return $config;
226
+ }
227
+
228
+ // Apply the theme config.
229
+ // If we are dealing with the Customify default config, we need a clean slate, sort of.
230
+ if ( 'customify_defaults' === $config['opt-name'] ) {
231
+ // We will save the Style Manager config so we can merge with it. But the rest goes away.
232
+ $style_manager_section = array();
233
+ if ( isset( $config['sections']['style_manager_section'] ) ) {
234
+ $style_manager_section = $config['sections']['style_manager_section'];
235
+ }
236
+
237
+ $config['opt-name'] = get_template() . '_options';
238
+ if ( ! empty( $this->external_theme_config['config']['opt-name'] ) ) {
239
+ $config['opt-name'] = $this->external_theme_config['config']['opt-name'];
240
+ }
241
+
242
+ $config['sections'] = array(
243
+ 'style_manager_section' => $style_manager_section,
244
+ );
245
+ }
246
+
247
+ // Now merge things.
248
+ $config['sections'] = Customify_Array::array_merge_recursive_distinct( $config['sections'],$this->external_theme_config['config']['sections'] );
249
+
250
+ return $config;
251
+ }
252
+
253
+ /**
254
+ * Maybe process certain "commands" from the external theme config.
255
+ *
256
+ * Mainly things like removing sections, controls, etc.
257
+ *
258
+ * @since 1.7.4
259
+ *
260
+ * @param WP_Customize_Manager $wp_customize
261
+ */
262
+ public function maybe_process_external_theme_config_extras( $wp_customize ) {
263
+ // Bail if we have no external theme config data.
264
+ if ( empty( $this->external_theme_config ) ) {
265
+ return;
266
+ }
267
+
268
+ // Maybe remove panels
269
+ if ( ! empty( $this->external_theme_config['config']['remove_panels'] ) ) {
270
+ // Standardize it.
271
+ if ( is_string( $this->external_theme_config['config']['remove_panels'] ) ) {
272
+ $this->external_theme_config['config']['remove_panels'] = array( $this->external_theme_config['config']['remove_panels'] );
273
+ }
274
+
275
+ foreach ( $this->external_theme_config['config']['remove_panels'] as $panel_id ) {
276
+ $wp_customize->remove_panel( $panel_id );
277
+ }
278
+ }
279
+
280
+ // Maybe remove sections
281
+ if ( ! empty( $this->external_theme_config['config']['remove_sections'] ) ) {
282
+ // Standardize it.
283
+ if ( is_string( $this->external_theme_config['config']['remove_sections'] ) ) {
284
+ $this->external_theme_config['config']['remove_sections'] = array( $this->external_theme_config['config']['remove_sections'] );
285
+ }
286
+
287
+ foreach ( $this->external_theme_config['config']['remove_sections'] as $section_id ) {
288
+
289
+ if ( 'widgets' === $section_id ) {
290
+ global $wp_registered_sidebars;
291
+
292
+ foreach ( $wp_registered_sidebars as $widget => $settings ) {
293
+ $wp_customize->remove_section( 'sidebar-widgets-' . $widget );
294
+ }
295
+ continue;
296
+ }
297
+
298
+ $wp_customize->remove_section( $section_id );
299
+ }
300
+ }
301
+
302
+ // Maybe remove settings
303
+ if ( ! empty( $this->external_theme_config['config']['remove_settings'] ) ) {
304
+ // Standardize it.
305
+ if ( is_string( $this->external_theme_config['config']['remove_settings'] ) ) {
306
+ $this->external_theme_config['config']['remove_settings'] = array( $this->external_theme_config['config']['remove_settings'] );
307
+ }
308
+
309
+ foreach ( $this->external_theme_config['config']['remove_settings'] as $setting_id ) {
310
+ $wp_customize->remove_setting( $setting_id );
311
+ }
312
+ }
313
+
314
+ // Maybe remove controls
315
+ if ( ! empty( $this->external_theme_config['config']['remove_controls'] ) ) {
316
+ // Standardize it.
317
+ if ( is_string( $this->external_theme_config['config']['remove_controls'] ) ) {
318
+ $this->external_theme_config['config']['remove_controls'] = array( $this->external_theme_config['config']['remove_controls'] );
319
+ }
320
+
321
+ foreach ( $this->external_theme_config['config']['remove_controls'] as $control_id ) {
322
+ $wp_customize->remove_control( $control_id );
323
+ }
324
+ }
325
+ }
326
+
327
+ /**
328
+ * Output the JSON in the Customizer page source.
329
+ */
330
+ public function maybe_output_json_external_config() {
331
+ if ( ! empty( $this->external_theme_config['config'] ) ) {
332
+ // Also output the JSON in a special hidden div for easy copy pasting.
333
+ // Also remove any multiple tabs.
334
+ echo PHP_EOL . '<!--' . PHP_EOL . 'Just copy&paste this:' . PHP_EOL . PHP_EOL . trim( str_replace( '\t\t', '', json_encode( $this->external_theme_config['config'] ) ) ) . PHP_EOL . PHP_EOL . '-->' . PHP_EOL;
335
+ }
336
+ }
337
+
338
+ /**
339
+ * Main Customify_Theme_Configs Instance
340
+ *
341
+ * Ensures only one instance of Customify_Theme_Configs is loaded or can be loaded.
342
+ *
343
+ * @since 1.7.4
344
+ * @static
345
+ *
346
+ * @return Customify_Theme_Configs Main Customify_Theme_Configs instance
347
+ */
348
+ public static function instance() {
349
+
350
+ if ( is_null( self::$_instance ) ) {
351
+ self::$_instance = new self();
352
+ }
353
+
354
+ return self::$_instance;
355
+ } // End instance ()
356
+
357
+ /**
358
+ * Cloning is forbidden.
359
+ *
360
+ * @since 1.7.4
361
+ */
362
+ public function __clone() {
363
+
364
+ _doing_it_wrong( __FUNCTION__,esc_html( __( 'Cheatin&#8217; huh?' ) ), null );
365
+ } // End __clone ()
366
+
367
+ /**
368
+ * Unserializing instances of this class is forbidden.
369
+ *
370
+ * @since 1.7.4
371
+ */
372
+ public function __wakeup() {
373
+
374
+ _doing_it_wrong( __FUNCTION__, esc_html( __( 'Cheatin&#8217; huh?' ) ), null );
375
+ } // End __wakeup ()
376
+ }
377
+
378
+ endif;
includes/{class-customify-array.php → lib/class-customify-array.php} RENAMED
File without changes
includes/lib/class-customify-cloud-api.php ADDED
@@ -0,0 +1,199 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * This is the class that handles the communication with the cloud.
4
+ *
5
+ * @see https://pixelgrade.com
6
+ * @author Pixelgrade
7
+ * @since 1.7.4
8
+ */
9
+
10
+ if ( ! defined( 'ABSPATH' ) ) {
11
+ exit; // Exit if accessed directly
12
+ }
13
+
14
+ if ( ! class_exists( 'Customify_Cloud_Api' ) ) :
15
+
16
+ class Customify_Cloud_Api {
17
+
18
+ /**
19
+ * External REST API endpoints used for communicating with the Pixelgrade Cloud.
20
+ * @var array
21
+ * @access public
22
+ * @since 1.7.4
23
+ */
24
+ public static $externalApiEndpoints;
25
+
26
+ /**
27
+ * Constructor.
28
+ *
29
+ * @since 1.7.4
30
+ */
31
+ public function __construct() {
32
+
33
+ $this->init();
34
+ }
35
+
36
+ /**
37
+ * Initialize this module.
38
+ *
39
+ * @since 1.7.4
40
+ */
41
+ public function init() {
42
+ // Make sure our constants are in place, if not already defined.
43
+ defined( 'PIXELGRADE_CLOUD__API_BASE' ) || define( 'PIXELGRADE_CLOUD__API_BASE', 'https://cloud.pixelgrade.com/' );
44
+
45
+ // Save the external API endpoints in a easy to get property.
46
+ self::$externalApiEndpoints = apply_filters( 'customify_style_manager_external_api_endpoints', array(
47
+ 'cloud' => array(
48
+ 'getDesignAssets' => array(
49
+ 'method' => 'GET',
50
+ 'url' => PIXELGRADE_CLOUD__API_BASE . 'wp-json/pixcloud/v1/front/design_assets',
51
+ ),
52
+ 'stats' => array(
53
+ 'method' => 'POST',
54
+ 'url' => PIXELGRADE_CLOUD__API_BASE . 'wp-json/pixcloud/v1/front/stats',
55
+ ),
56
+ ),
57
+ ) );
58
+ }
59
+
60
+ /**
61
+ * Fetch the design assets data from the Pixelgrade Cloud.
62
+ *
63
+ * @since 1.7.4
64
+ *
65
+ * @return array|false
66
+ */
67
+ public function fetch_design_assets() {
68
+ $request_data = apply_filters( 'customify_pixelgrade_cloud_request_data', array(
69
+ 'site_url' => home_url('/'),
70
+ // We are only interested in data needed to identify the theme and eventually deliver only design assets suitable for it.
71
+ 'theme_data' => $this->get_active_theme_data(),
72
+ // We are only interested in data needed to identify the plugin version and eventually deliver design assets suitable for it.
73
+ 'site_data' => $this->get_site_data(),
74
+ ), $this );
75
+
76
+ $request_args = array(
77
+ 'method' => self::$externalApiEndpoints['cloud']['getDesignAssets']['method'],
78
+ 'timeout' => 4,
79
+ 'blocking' => true,
80
+ 'body' => $request_data,
81
+ 'sslverify' => false,
82
+ );
83
+ // Get the design assets from the cloud.
84
+ $response = wp_remote_request( self::$externalApiEndpoints['cloud']['getDesignAssets']['url'], $request_args );
85
+ // Bail in case of decode error or failure to retrieve data.
86
+ // We will return the data already available.
87
+ if ( is_wp_error( $response ) ) {
88
+ return false;
89
+ }
90
+ $response_data = json_decode( wp_remote_retrieve_body( $response ), true );
91
+ // Bail in case of decode error or failure to retrieve data.
92
+ // We will return the data already available.
93
+ if ( null === $response_data || empty( $response_data['data'] ) || empty( $response_data['code'] ) || 'success' !== $response_data['code'] ) {
94
+ return false;
95
+ }
96
+
97
+ return apply_filters( 'customify_style_manager_fetch_design_assets', $response_data['data'] );
98
+ }
99
+
100
+ /**
101
+ * Get the active theme data.
102
+ *
103
+ * @since 1.7.4
104
+ *
105
+ * @return array
106
+ */
107
+ public function get_active_theme_data() {
108
+ $theme_data = array();
109
+
110
+ $slug = basename( get_template_directory() );
111
+
112
+ $theme_data['slug'] = $slug;
113
+
114
+ // Get the current theme style.css data.
115
+ $current_theme = wp_get_theme( get_template() );
116
+ if ( ! empty( $current_theme ) && ! is_wp_error( $current_theme ) ) {
117
+ $theme_data['name'] = $current_theme->get('Name');
118
+ $theme_data['themeuri'] = $current_theme->get('ThemeURI');
119
+ $theme_data['version'] = $current_theme->get('Version');
120
+ $theme_data['textdomain'] = $current_theme->get('TextDomain');
121
+ }
122
+
123
+ // Maybe get the WUpdates theme info if it's a theme delivered from WUpdates.
124
+ $wupdates_ids = apply_filters( 'wupdates_gather_ids', array() );
125
+ if ( ! empty( $wupdates_ids[ $slug ] ) ) {
126
+ $theme_data['wupdates'] = $wupdates_ids[ $slug ];
127
+ }
128
+
129
+ return apply_filters( 'customify_style_manager_get_theme_data', $theme_data );
130
+ }
131
+
132
+ /**
133
+ * Get the site data.
134
+ *
135
+ * @since 1.7.4
136
+ *
137
+ * @return array
138
+ */
139
+ public function get_site_data() {
140
+ $site_data = array(
141
+ 'url' => home_url('/'),
142
+ 'is_ssl' => is_ssl(),
143
+ );
144
+
145
+ $site_data['wp'] = array(
146
+ 'version' => get_bloginfo('version'),
147
+ );
148
+
149
+ $site_data['customify'] = array(
150
+ 'version' => PixCustomifyPlugin()->get_version(),
151
+ );
152
+
153
+ return apply_filters( 'customify_style_manager_get_site_data', $site_data );
154
+ }
155
+
156
+ /**
157
+ * Send stats to the Pixelgrade Cloud.
158
+ *
159
+ * @since 1.7.4
160
+ *
161
+ * @param array $request_data The data to be sent.
162
+ * @param bool $blocking Optional. Whether this should be a blocking request. Defaults to false.
163
+ *
164
+ * @return array|false
165
+ */
166
+ public function send_stats( $request_data = array(), $blocking = false ) {
167
+ if ( empty( $request_data ) ) {
168
+ // This is what we send by default.
169
+ $request_data = array(
170
+ 'site_url' => home_url('/'),
171
+ // We are only interested in data needed to identify the theme and eventually deliver only design assets suitable for it.
172
+ 'theme_data' => $this->get_active_theme_data(),
173
+ // We are only interested in data needed to identify the plugin version and eventually deliver design assets suitable for it.
174
+ 'site_data' => $this->get_site_data(),
175
+ );
176
+ }
177
+
178
+ /**
179
+ * Filters request data sent to the cloud.
180
+ *
181
+ * @param array $request_data
182
+ * @param object $this @todo This argument is no longer needed and should be removed when Pixelgrade Care doesn't rely on it.
183
+ */
184
+ $request_data = apply_filters( 'customify_pixelgrade_cloud_request_data', $request_data, $this );
185
+
186
+ $request_args = array(
187
+ 'method' => self::$externalApiEndpoints['cloud']['stats']['method'],
188
+ 'timeout' => 5,
189
+ 'blocking' => $blocking,
190
+ 'body' => $request_data,
191
+ 'sslverify' => false,
192
+ );
193
+
194
+ // Make the request and return the response.
195
+ return wp_remote_request( self::$externalApiEndpoints['cloud']['stats']['url'], $request_args );
196
+ }
197
+ }
198
+
199
+ endif;
includes/lib/class-customify-design-assets.php ADDED
@@ -0,0 +1,240 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * This is the class that handles the overall logic for design assets.
4
+ *
5
+ * @see https://pixelgrade.com
6
+ * @author Pixelgrade
7
+ * @since 1.7.4
8
+ */
9
+
10
+ if ( ! defined( 'ABSPATH' ) ) {
11
+ exit; // Exit if accessed directly
12
+ }
13
+
14
+ if ( ! class_exists( 'Customify_Design_Assets' ) ) :
15
+
16
+ class Customify_Design_Assets {
17
+
18
+ /**
19
+ * Holds the only instance of this class.
20
+ * @var null|Customify_Design_Assets
21
+ * @access protected
22
+ * @since 1.7.4
23
+ */
24
+ protected static $_instance = null;
25
+
26
+ /**
27
+ * The current design assets config.
28
+ * @var array
29
+ * @access public
30
+ * @since 1.7.4
31
+ */
32
+ protected $design_assets = null;
33
+
34
+ /**
35
+ * The cloud API object used to communicate with the cloud.
36
+ * @var Customify_Cloud_Api
37
+ * @access public
38
+ * @since 1.7.4
39
+ */
40
+ protected $cloud_api = null;
41
+
42
+ /**
43
+ * Constructor.
44
+ *
45
+ * @since 1.7.4
46
+ */
47
+ private function __construct() {
48
+ $this->init();
49
+ }
50
+
51
+ /**
52
+ * Initialize this module.
53
+ *
54
+ * @since 1.7.4
55
+ */
56
+ public function init() {
57
+ /**
58
+ * Initialize the Cloud API logic.
59
+ */
60
+ require_once 'class-customify-cloud-api.php';
61
+ $this->cloud_api = new Customify_Cloud_Api();
62
+ }
63
+
64
+ /**
65
+ * Get the design assets configuration.
66
+ *
67
+ * @since 1.7.4
68
+ *
69
+ * @param bool $skip_cache Optional. Whether to use the cached config or fetch a new one.
70
+ *
71
+ * @return array
72
+ */
73
+ public function get( $skip_cache = false ) {
74
+ if ( ! is_null( $this->design_assets ) && false === $skip_cache ) {
75
+ return $this->design_assets;
76
+ }
77
+
78
+ $this->design_assets = $this->maybe_fetch( $skip_cache );
79
+
80
+ // Determine if we should use the config in the theme root and skip the external config entirely.
81
+ if ( defined('CUSTOMIFY_SM_LOAD_THEME_ROOT_CONFIG') && true === CUSTOMIFY_SM_LOAD_THEME_ROOT_CONFIG ) {
82
+ $this->design_assets = $this->maybe_load_theme_config_from_theme_root( $this->design_assets );
83
+ }
84
+
85
+ return apply_filters( 'customify_style_manager_get_design_assets', $this->design_assets );
86
+ }
87
+
88
+ /**
89
+ * Fetch the design assets data from the Pixelgrade Cloud.
90
+ *
91
+ * Caches the data for 12 hours. Use local defaults if not available.
92
+ *
93
+ * @since 1.7.4
94
+ *
95
+ * @param bool $skip_cache Optional. Whether to use the cached data or fetch a new one.
96
+ *
97
+ * @return array|false
98
+ */
99
+ protected function maybe_fetch( $skip_cache = false ) {
100
+ // First try and get the cached data
101
+ $data = get_option( $this->_get_cache_key() );
102
+
103
+ // For performance reasons, we will ONLY fetch remotely when in the WP ADMIN area or via an ADMIN AJAX call, regardless of settings.
104
+ if ( ! is_admin() ) {
105
+ return $data;
106
+ }
107
+
108
+ // Get the cache data expiration timestamp.
109
+ $expire_timestamp = get_option( $this->_get_cache_key() . '_timestamp' );
110
+
111
+ // We don't force skip the cache for AJAX requests for performance reasons.
112
+ if ( ! wp_doing_ajax() && defined('CUSTOMIFY_SM_ALWAYS_FETCH_DESIGN_ASSETS' ) && true === CUSTOMIFY_SM_ALWAYS_FETCH_DESIGN_ASSETS ) {
113
+ $skip_cache = true;
114
+ }
115
+
116
+ // The data isn't set, is expired or we were instructed to skip the cache; we need to fetch fresh data.
117
+ if ( true === $skip_cache || false === $data || false === $expire_timestamp || $expire_timestamp < time() ) {
118
+ // Fetch the design assets from the cloud.
119
+ $fetched_data = $this->cloud_api->fetch_design_assets();
120
+ // Bail in case of failure to retrieve data.
121
+ // We will return the data already available.
122
+ if ( false === $fetched_data ) {
123
+ return $data;
124
+ }
125
+
126
+ $data = $fetched_data;
127
+
128
+ // Cache the data in an option for 6 hours
129
+ update_option( $this->_get_cache_key() , $data, true );
130
+ update_option( $this->_get_cache_key() . '_timestamp' , time() + 6 * HOUR_IN_SECONDS, true );
131
+ }
132
+
133
+ return apply_filters( 'customify_style_manager_maybe_fetch_design_assets', $data );
134
+ }
135
+
136
+ /**
137
+ * Get the design assets cache key.
138
+ *
139
+ * @since 1.7.4
140
+ *
141
+ * @return string
142
+ */
143
+ private function _get_cache_key() {
144
+ return 'customify_style_manager_design_assets';
145
+ }
146
+
147
+ /**
148
+ * Include the customify "external" config file in the theme root and overwrite the existing theme configs.
149
+ *
150
+ * @since 1.7.4
151
+ *
152
+ * @param array $design_assets
153
+ *
154
+ * @return array
155
+ */
156
+ protected function maybe_load_theme_config_from_theme_root( $design_assets ) {
157
+ $file_name = 'customify_theme_root.php';
158
+
159
+ // First gather details about the current (parent) theme.
160
+ $theme = wp_get_theme( get_template() );
161
+ // Bail if for some strange reason we couldn't find the theme.
162
+ if ( ! $theme->exists() ) {
163
+ return $design_assets;
164
+ }
165
+
166
+ $file = trailingslashit( $theme->get_template_directory() ) . $file_name;
167
+ if ( ! file_exists( $file ) ) {
168
+ return $design_assets;
169
+ }
170
+
171
+ // We expect to get from the file include a $config variable with the entire Customify (partial) config.
172
+ include $file;
173
+
174
+ if ( ! isset( $config ) || ! is_array( $config ) || empty( $config['sections'] ) ) {
175
+ // Alert the developers that things are not alright.
176
+ _doing_it_wrong( __METHOD__, 'The Customify theme root config is not good - the `sections` entry is missing. Please check it! We will not apply it.', null );
177
+
178
+ return $design_assets;
179
+ }
180
+
181
+ // Construct the pseudo-external theme config.
182
+ // Start with a clean slate.
183
+ $design_assets['theme_configs'] = array();
184
+
185
+ $design_assets['theme_configs']['theme_root'] = array(
186
+ 'id' => 1,
187
+ 'name' => $theme->get( 'Name' ),
188
+ 'slug' => $theme->get_stylesheet(),
189
+ 'txtd' => $theme->get( 'TextDomain' ),
190
+ 'loose_match' => true,
191
+ 'config' => $config,
192
+ 'created' => date('Y-m-d H:i:s'),
193
+ 'last_modified' => date('Y-m-d H:i:s'),
194
+ 'hashid' => 'theme_root',
195
+ );
196
+
197
+ return $design_assets;
198
+ }
199
+
200
+ /**
201
+ * Main Customify_Design_Assets Instance
202
+ *
203
+ * Ensures only one instance of Customify_Design_Assets is loaded or can be loaded.
204
+ *
205
+ * @since 1.7.4
206
+ * @static
207
+ *
208
+ * @return Customify_Design_Assets Main Customify_Design_Assets instance
209
+ */
210
+ public static function instance() {
211
+
212
+ if ( is_null( self::$_instance ) ) {
213
+ self::$_instance = new self();
214
+ }
215
+
216
+ return self::$_instance;
217
+ } // End instance ()
218
+
219
+ /**
220
+ * Cloning is forbidden.
221
+ *
222
+ * @since 1.7.4
223
+ */
224
+ public function __clone() {
225
+
226
+ _doing_it_wrong( __FUNCTION__,esc_html( __( 'Cheatin&#8217; huh?' ) ), null );
227
+ } // End __clone ()
228
+
229
+ /**
230
+ * Unserializing instances of this class is forbidden.
231
+ *
232
+ * @since 1.7.4
233
+ */
234
+ public function __wakeup() {
235
+
236
+ _doing_it_wrong( __FUNCTION__, esc_html( __( 'Cheatin&#8217; huh?' ) ), null );
237
+ } // End __wakeup ()
238
+ }
239
+
240
+ endif;
js/ace/mode-plain_text.js CHANGED
File without changes
js/customizer.js CHANGED
@@ -41,7 +41,7 @@
41
  $( '.customify_select2' ).select2();
42
 
43
  setTimeout( function() {
44
- customifyFontSelect.init( this );
45
  }, 333 );
46
 
47
  prepare_typography_field();
@@ -62,7 +62,7 @@
62
  } );
63
 
64
  // for each range input add a value preview output
65
- $( '.accordion-section-content[id*="' + customify_settings.options_name + '"]' ).each( function() {
66
 
67
  // Initialize range fields logic
68
  customifyHandleRangeFields( this );
@@ -314,104 +314,70 @@
314
  }
315
  )();
316
 
317
- // Handle the Style Manager user feedback logic.
318
- var $styleManagerUserFeedbackModal = $('#style-manager-user-feedback-modal');
319
- if ( $styleManagerUserFeedbackModal.length ) {
320
- var $styleManagerUserFeedbackForm = $styleManagerUserFeedbackModal.find('form'),
321
- $styleManagerUserFeedbackCloseBtn = $styleManagerUserFeedbackModal.find('.close'),
322
- $styleManagerUserFeedbackFirstStep = $styleManagerUserFeedbackModal.find('.first-step'),
323
- $styleManagerUserFeedbackSecondStep = $styleManagerUserFeedbackModal.find('.second-step'),
324
- $styleManagerUserFeedbackThanksStep = $styleManagerUserFeedbackModal.find('.thanks-step'),
325
- $styleManagerUserFeedbackErrorStep = $styleManagerUserFeedbackModal.find('.error-step'),
326
- styleManagerUserFeedbackModalShown = false,
327
- styleManagerColorPaletteChanged = false;
328
-
329
- // Handle when to open the modal.
330
- api.bind('saved', function () {
331
- // We will only show the modal once per Customizer session.
332
- if (!styleManagerUserFeedbackModalShown && styleManagerColorPaletteChanged) {
333
- $('body').addClass('modal-open');
334
- styleManagerUserFeedbackModalShown = true;
335
  }
336
- });
337
-
338
- // Handle the color palette changed info update.
339
- const colorPaletteSetting = api( 'sm_color_palette' );
340
- if ( !_.isUndefined(colorPaletteSetting) ) {
341
- colorPaletteSetting.bind( function( new_value, old_value ) {
342
- if ( new_value != old_value ) {
343
- styleManagerColorPaletteChanged = true;
344
- }
345
- } )
 
 
 
 
 
 
346
  }
347
- const colorPaletteVariationSetting = api( 'sm_color_palette_variation' );
348
- if ( !_.isUndefined(colorPaletteVariationSetting) ) {
349
- colorPaletteVariationSetting.bind( function( new_value, old_value ) {
350
- if ( new_value != old_value ) {
351
- styleManagerColorPaletteChanged = true;
352
- }
353
- } )
354
  }
355
 
356
- // Handle the modal submit.
357
- $styleManagerUserFeedbackForm.on('submit', function (event) {
358
- event.preventDefault();
359
-
360
- let $form = $(event.target);
361
-
362
- let data = {
363
- action: 'customify_style_manager_user_feedback',
364
- nonce: customify_settings.style_manager_user_feedback_nonce,
365
- type: $form.find('input[name=type]').val(),
366
- rating: $form.find('input[name=rating]:checked').val(),
367
- message: $form.find('textarea[name=message]').val()
368
- };
369
-
370
- $.post(
371
- customify_settings.ajax_url,
372
- data,
373
- function (response) {
374
- if (true === response.success) {
375
- $styleManagerUserFeedbackFirstStep.hide();
376
- $styleManagerUserFeedbackSecondStep.hide();
377
- $styleManagerUserFeedbackThanksStep.show();
378
- $styleManagerUserFeedbackErrorStep.hide();
379
- } else {
380
- $styleManagerUserFeedbackFirstStep.hide();
381
- $styleManagerUserFeedbackSecondStep.hide();
382
- $styleManagerUserFeedbackThanksStep.hide();
383
- $styleManagerUserFeedbackErrorStep.show();
384
- }
385
- }
386
- );
387
- });
388
-
389
- $styleManagerUserFeedbackForm.find('input[name=rating]').on('change', function (event) {
390
- // Leave everything in working order
391
- setTimeout(function () {
392
- $styleManagerUserFeedbackSecondStep.show();
393
- }, 300);
394
-
395
- let rating = $styleManagerUserFeedbackForm.find('input[name=rating]:checked').val();
396
-
397
- $styleManagerUserFeedbackForm.find('.rating-placeholder').text(rating);
398
- });
399
-
400
- $styleManagerUserFeedbackCloseBtn.on('click', function (event) {
401
- event.preventDefault();
402
-
403
- $('body').removeClass('modal-open');
404
-
405
- // Leave everything in working order
406
- setTimeout(function () {
407
- $styleManagerUserFeedbackFirstStep.show();
408
- $styleManagerUserFeedbackSecondStep.hide();
409
- $styleManagerUserFeedbackThanksStep.hide();
410
- $styleManagerUserFeedbackErrorStep.hide();
411
- }, 300);
412
- });
413
- }
414
- } );
415
 
416
  const customifyHandleRangeFields = function( el ) {
417
 
@@ -1106,390 +1072,6 @@
1106
  }
1107
  )( jQuery );
1108
 
1109
- // This is for the Font control
1110
- var customifyFontSelect = (
1111
- function() {
1112
- const
1113
- wrapperSelector = '.font-options__wrapper',
1114
- valueHolderSelector = '.customify_font_values',
1115
- fontFamilySelector = '.customify_font_family',
1116
- fontWeightSelector = '.customify_font_weight',
1117
- fontSubsetsSelector = '.customify_font_subsets',
1118
- selectPlaceholder = "Select a font family",
1119
- weightPlaceholder = "Select a font weight",
1120
- subsetPlaceholder = "Extra Subsets";
1121
-
1122
- // We will use this to remember that we are self-updating the field from the subfields.
1123
- // We will save this info for each setting ID.
1124
- var updatingValue = {},
1125
- loadingValue = {};
1126
-
1127
- function init( wpapi ) {
1128
- let $fontFamilyFields = $( fontFamilySelector );
1129
-
1130
- // Initialize the select2 field for the font family
1131
- $fontFamilyFields.select2( {
1132
- placeholder: selectPlaceholder
1133
- } ).on( 'change', function( e ) {
1134
- let new_option = $( e.target ).find( 'option:selected' ),
1135
- wrapper = $( e.target ).closest( wrapperSelector );
1136
-
1137
- // Update the weight subfield with the new options given by the selected font family.
1138
- update_weight_field( new_option, wrapper );
1139
-
1140
- // Update the subset subfield with the new options given by the selected font family.
1141
- update_subset_field( new_option, wrapper );
1142
-
1143
- // Serialize subfield values and refresh the fonts in the preview window.
1144
- update_font_value( wrapper );
1145
- } );
1146
-
1147
- // Initialize the select2 field for the font weight
1148
- $( fontWeightSelector ).each( function( i, el ) {
1149
-
1150
- let select2_args = {
1151
- placeholder: weightPlaceholder
1152
- };
1153
-
1154
- // all this fuss is for the case when the font doesn't come with variants from PHP, like a theme_font
1155
- if ( this.options.length === 0 ) {
1156
- var wrapper = $( el ).closest( wrapperSelector ),
1157
- font = wrapper.find( fontFamilySelector ),
1158
- option = font[0].options[font[0].selectedIndex],
1159
- variants = maybeJsonParse( $( option ).data( 'variants' ) ),
1160
- data = [],
1161
- selecter_variants = $( el ).data( 'default' ) || null;
1162
-
1163
- if ( typeof variants === "undefined" ) {
1164
- $( this ).hide();
1165
- return;
1166
- }
1167
-
1168
- $.each( variants, function( index, weight ) {
1169
- let this_value = {
1170
- id: weight,
1171
- text: weight
1172
- };
1173
-
1174
- if ( selecter_variants !== null && weight == selecter_variants ) {
1175
- this_value.selected = true;
1176
- }
1177
-
1178
- data.push( this_value );
1179
- } );
1180
-
1181
- if ( data !== [] ) {
1182
- select2_args.data = data;
1183
- }
1184
- }
1185
-
1186
- $( this ).select2(
1187
- select2_args
1188
- ).on( 'change', function( e ) {
1189
- let wrapper = $( e.target ).closest( wrapperSelector );
1190
-
1191
- // Serialize subfield values and refresh the fonts in the preview window.
1192
- update_font_value( wrapper );
1193
- } );
1194
- } );
1195
-
1196
- // Initialize the select2 field for the font subsets
1197
- $( fontSubsetsSelector )
1198
- .select2( {
1199
- placeholder: subsetPlaceholder
1200
- } )
1201
- .on( 'change', function( e ) {
1202
- let wrapper = $( e.target ).closest( wrapperSelector );
1203
-
1204
- // Serialize subfield values and refresh the fonts in the preview window.
1205
- update_font_value( wrapper );
1206
- } );
1207
-
1208
- let rangers = $fontFamilyFields.parents( wrapperSelector ).find( 'input[type=range]' ),
1209
- selects = $fontFamilyFields.parents( wrapperSelector ).find( 'select' ).not( "select[class*=' select2'],select[class^='select2']" );
1210
-
1211
- // Initialize the all the regular selects in the font controls
1212
- if ( selects.length > 0 ) {
1213
- selects.on( 'change', function( e ) {
1214
- let wrapper = $( e.target ).closest( wrapperSelector );
1215
-
1216
- // Serialize subfield values and refresh the fonts in the preview window.
1217
- update_font_value( wrapper );
1218
- } );
1219
- }
1220
-
1221
- // Initialize the all the range fields in the font controls
1222
- if ( rangers.length > 0 ) {
1223
- rangers.on( 'change', function( e ) {
1224
- let wrapper = $( e.target ).closest( wrapperSelector );
1225
-
1226
- // Serialize subfield values and refresh the fonts in the preview window.
1227
- update_font_value( wrapper );
1228
-
1229
- wp.customize.previewer.send( 'font-changed' );
1230
- } );
1231
- }
1232
-
1233
- // When the previewer window is ready, render the fonts
1234
- var self = this;
1235
- wp.customize.previewer.bind( 'ready', function() {
1236
- self.render_fonts();
1237
- } );
1238
-
1239
- // Handle the reverse value direction, when the customize setting is updated and the subfields need to update their values.
1240
- $fontFamilyFields.each( function( i, el ) {
1241
- let wrapper = $( el ).closest( wrapperSelector ),
1242
- value_holder = wrapper.children( valueHolderSelector ),
1243
- setting_id = $( value_holder ).data( 'customize-setting-link' ),
1244
- setting = wp.customize( setting_id );
1245
-
1246
- setting.bind( function( newValue, oldValue ) {
1247
- if ( ! updatingValue[this.id] ) {
1248
- value_holder.val( newValue );
1249
-
1250
- load_font_value( wrapper );
1251
- }
1252
- } )
1253
- } )
1254
- }
1255
-
1256
- /**
1257
- * This function updates the data in font weight selector from the given <option> element
1258
- *
1259
- * @param option
1260
- * @param wraper
1261
- */
1262
- function update_weight_field( option, wraper ) {
1263
- let variants = $( option ).data( 'variants' ),
1264
- font_weights = wraper.find( fontWeightSelector ),
1265
- selected_variant = font_weights.data( 'default' ),
1266
- new_variants = [],
1267
- id = wraper.find( valueHolderSelector ).data( 'customizeSettingLink' );
1268
-
1269
- variants = maybeJsonParse( variants );
1270
-
1271
- if ( customify_settings.settings[id].load_all_weights || typeof variants === "undefined" || Object.keys( variants ).length < 2 ) {
1272
- font_weights.parent().hide();
1273
- } else {
1274
- font_weights.parent().show();
1275
- }
1276
-
1277
- // we need to turn the data array into a specific form like [{id:"id", text:"Text"}]
1278
- $.each( variants, function( index, variant ) {
1279
- new_variants[index] = {
1280
- 'id': variant,
1281
- 'text': variant
1282
- };
1283
-
1284
- if ( selected_variant == variant ) {
1285
- new_variants[index].selected = true;
1286
- }
1287
- } );
1288
-
1289
- // We need to clear the old select2 field and reinitialize it.
1290
- $( font_weights ).select2().empty();
1291
- $( font_weights ).select2( {
1292
- data: new_variants
1293
- } ).on( 'change', function( e ) {
1294
- let wrapper = $( e.target ).closest( wrapperSelector );
1295
-
1296
- // Serialize subfield values and refresh the fonts in the preview window.
1297
- update_font_value( wrapper );
1298
- } );
1299
- }
1300
-
1301
- /**
1302
- * This function updates the data in font subset selector from the given <option> element
1303
- * @param option
1304
- * @param wraper
1305
- */
1306
- function update_subset_field( option, wraper ) {
1307
- let subsets = $( option ).data( 'subsets' ),
1308
- font_subsets = wraper.find( fontSubsetsSelector ),
1309
- new_subsets = [],
1310
- type = $( option ).data( 'type' );
1311
-
1312
- if ( type !== 'google' ) {
1313
- font_subsets.parent().hide();
1314
- return;
1315
- }
1316
-
1317
- let current_value = wraper.children( valueHolderSelector ).val();
1318
-
1319
- current_value = maybeJsonParse( current_value );
1320
- if ( _.isUndefined( current_value.selected_subsets ) ) {
1321
- return;
1322
- }
1323
- current_value = current_value.selected_subsets;
1324
-
1325
- subsets = maybeJsonParse( subsets );
1326
-
1327
- if ( typeof subsets != 'undefined' && Object.keys( subsets ).length < 2 ) {
1328
- font_subsets.parent().hide();
1329
- } else {
1330
- font_subsets.parent().show();
1331
- }
1332
-
1333
- // we need to turn the data array into a specific form like [{id:"id", text:"Text"}]
1334
- $.each( subsets, function( index, subset ) {
1335
- new_subsets[index] = {
1336
- 'id': subset,
1337
- 'text': subset
1338
- };
1339
-
1340
- // current_subsets
1341
- if ( typeof current_value !== 'undefined' && current_value !== null && current_value.indexOf( subset ) !== - 1 ) {
1342
- new_subsets[index].selected = true;
1343
- }
1344
- } );
1345
-
1346
- // We need to clear the old select2 field and reinitialize it.
1347
- $( font_subsets ).select2().empty();
1348
- $( font_subsets ).select2( {
1349
- data: new_subsets
1350
- } ).on( 'change', function( e ) {
1351
- let wrapper = $( e.target ).closest( wrapperSelector );
1352
-
1353
- // Serialize subfield values and refresh the fonts in the preview window.
1354
- update_font_value( wrapper );
1355
- } );
1356
- }
1357
-
1358
- /**
1359
- * This function is a custom value serializer for our entire font field
1360
- * It collects values and saves them (encoded) into the `.customify_font_values` input's value
1361
- */
1362
- function update_font_value( wraper ) {
1363
- let options_list = $( wraper ).find( '.font-options__options-list' ),
1364
- inputs = options_list.find( '[data-field]' ),
1365
- value_holder = wraper.children( valueHolderSelector ),
1366
- setting_id = $( value_holder ).data( 'customize-setting-link' ),
1367
- setting = wp.customize( setting_id ),
1368
- newFontData = {};
1369
-
1370
- // If we are already self-updating this and we haven't finished, we need to stop here to prevent infinite loops
1371
- // This call might have come from a subfield detecting the change the triggering a further update_font_value()
1372
- if ( true === updatingValue[setting_id] ) {
1373
- return;
1374
- }
1375
-
1376
- // If we are loading this setting value and haven't finished, there is no point in updating it as this would cause infinite loops.
1377
- if ( true === loadingValue[setting_id] ) {
1378
- return;
1379
- }
1380
-
1381
- // Mark the fact that we are self-updating the field value
1382
- updatingValue[setting_id] = true;
1383
-
1384
- inputs.each( function( key, el ) {
1385
- let field = $( el ).data( 'field' ),
1386
- value = $( el ).val();
1387
-
1388
- if ( 'font_family' === field ) {
1389
- // the font family also holds the type
1390
- let selected_opt = $( el.options[el.selectedIndex] ),
1391
- type = selected_opt.data( 'type' ),
1392
- subsets = selected_opt.data( 'subsets' ),
1393
- variants = selected_opt.data( 'variants' );
1394
-
1395
- if ( ! _.isUndefined( type ) ) {
1396
- newFontData['type'] = type;
1397
- if ( type === 'theme_font' ) {
1398
- newFontData['src'] = selected_opt.data( 'src' );
1399
- }
1400
- }
1401
-
1402
- if ( ! _.isUndefined( variants ) ) {
1403
- newFontData['variants'] = maybeJsonParse( variants );
1404
- }
1405
-
1406
- if ( ! _.isUndefined( subsets ) ) {
1407
- newFontData['subsets'] = maybeJsonParse( subsets );
1408
- }
1409
- }
1410
-
1411
-
1412
- if ( ! _.isUndefined( field ) && ! _.isUndefined( value ) && ! _.isNull( value ) && value !== '' ) {
1413
- newFontData[field] = value;
1414
- }
1415
- } );
1416
-
1417
- // Serialize the newly gathered font data
1418
- let serializedNewFontData = encodeValues( newFontData );
1419
- // Set the serialized value in the hidden field.
1420
- value_holder.val( serializedNewFontData );
1421
- // Update also the Customizer setting value.
1422
- setting.set( serializedNewFontData );
1423
-
1424
-
1425
- // Finished with the field value self-updating.
1426
- updatingValue[setting_id] = false;
1427
-
1428
- return newFontData;
1429
- }
1430
-
1431
- /**
1432
- * This function is a reverse of update_font_value(), initializing the entire font field controls based on the value stored in the hidden input.
1433
- */
1434
- function load_font_value( wrapper ) {
1435
- let options_list = $( wrapper ).find( '.font-options__options-list' ),
1436
- inputs = options_list.find( '[data-field]' ),
1437
- value_holder = wrapper.children( valueHolderSelector ),
1438
- value = maybeJsonParse( value_holder.val() ),
1439
- setting_id = $( value_holder ).data( 'customize-setting-link' );
1440
-
1441
- // If we are already loading this setting value and haven't finished, there is no point in starting again.
1442
- if ( true === loadingValue[setting_id] ) {
1443
- return;
1444
- }
1445
-
1446
- // Mark the fact that we are loading the field value
1447
- loadingValue[setting_id] = true;
1448
-
1449
- inputs.each( function( key, el ) {
1450
- let field = $( el ).data( 'field' );
1451
-
1452
- // In the case of select2, only the original selects have the data field, thus excluding select2 created select DOM elements
1453
- if ( typeof field !== "undefined" && field !== "" && typeof value[field] !== "undefined" ) {
1454
- $( el ).val( value[field] ).trigger( 'change' );
1455
- }
1456
- } );
1457
-
1458
- // Finished with the field value loading.
1459
- loadingValue[setting_id] = false;
1460
- }
1461
-
1462
- var maybeJsonParse = function( value ) {
1463
- let parsed;
1464
-
1465
- //try and parse it, with decodeURIComponent
1466
- try {
1467
- parsed = JSON.parse( decodeURIComponent( value ) );
1468
- } catch ( e ) {
1469
-
1470
- // in case of an error, treat is as a string
1471
- parsed = value;
1472
- }
1473
-
1474
- return parsed;
1475
- };
1476
-
1477
- function encodeValues( obj ) {
1478
- return encodeURIComponent( JSON.stringify( obj ) );
1479
- }
1480
-
1481
- function render_fonts() {
1482
- $( '.customify_font_family' ).select2().trigger( 'change' )
1483
- }
1484
-
1485
- return {
1486
- render_fonts: render_fonts,
1487
- init: init,
1488
- update_font_value: update_font_value
1489
- };
1490
- }
1491
- )();
1492
-
1493
  var Queue = function() {
1494
  var lastPromise = null;
1495
  var queueDeferred = null;
@@ -1672,142 +1254,3 @@
1672
  };
1673
  }
1674
  )( jQuery, window, wp );
1675
-
1676
-
1677
- // Reverses a hex color to either black or white
1678
- function customifyInverseHexColorToBlackOrWhite( hex ) {
1679
- return customifyInverseHexColor( hex, true );
1680
- }
1681
-
1682
- // Taken from here: https://stackoverflow.com/a/35970186/6260836
1683
- function customifyInverseHexColor( hex, bw ) {
1684
- if ( hex.indexOf( '#' ) === 0 ) {
1685
- hex = hex.slice( 1 );
1686
- }
1687
- // convert 3-digit hex to 6-digits.
1688
- if ( hex.length === 3 ) {
1689
- hex = hex[0] + hex[0] + hex[1] + hex[1] + hex[2] + hex[2];
1690
- }
1691
- if ( hex.length !== 6 ) {
1692
- throw new Error( 'Invalid HEX color.' );
1693
- }
1694
- var r = parseInt( hex.slice( 0, 2 ), 16 ),
1695
- g = parseInt( hex.slice( 2, 4 ), 16 ),
1696
- b = parseInt( hex.slice( 4, 6 ), 16 );
1697
- if ( bw ) {
1698
- // http://stackoverflow.com/a/3943023/112731
1699
- return (
1700
- r * 0.299 + g * 0.587 + b * 0.114
1701
- ) > 186
1702
- ? '#000000'
1703
- : '#FFFFFF';
1704
- }
1705
- // invert color components
1706
- r = (
1707
- 255 - r
1708
- ).toString( 16 );
1709
- g = (
1710
- 255 - g
1711
- ).toString( 16 );
1712
- b = (
1713
- 255 - b
1714
- ).toString( 16 );
1715
- // pad each with zeros and return
1716
- return "#" + customifyPadZero( r ) + customifyPadZero( g ) + customifyPadZero( b );
1717
- }
1718
-
1719
- function customifyPadZero( str, len ) {
1720
- len = len || 2;
1721
- var zeros = new Array( len ).join( '0' );
1722
- return (
1723
- zeros + str
1724
- ).slice( - len );
1725
- }
1726
-
1727
- // Shading, Blending and Converting colors
1728
- // Taken from here: https://github.com/PimpTrizkit/PJs/wiki/12.-Shade,-Blend-and-Convert-a-Web-Color-(pSBC.js)
1729
- const pSBC = function( p, from, to ) {
1730
- if ( typeof(
1731
- p
1732
- ) != "number" || p < - 1 || p > 1 || typeof(
1733
- from
1734
- ) != "string" || (
1735
- from[0] != 'r' && from[0] != '#'
1736
- ) || (
1737
- to && typeof(
1738
- to
1739
- ) != "string"
1740
- ) ) {
1741
- return null;
1742
- } //ErrorCheck
1743
- if ( ! this.pSBCr ) {
1744
- this.pSBCr = ( d ) => {
1745
- let l = d.length, RGB = {};
1746
- if ( l > 9 ) {
1747
- d = d.split( "," );
1748
- if ( d.length < 3 || d.length > 4 ) {
1749
- return null;
1750
- }//ErrorCheck
1751
- RGB[0] = i( d[0].split( "(" )[1] ), RGB[1] = i( d[1] ), RGB[2] = i( d[2] ), RGB[3] = d[3] ? parseFloat( d[3] ) : - 1;
1752
- } else {
1753
- if ( l == 8 || l == 6 || l < 4 ) {
1754
- return null;
1755
- } //ErrorCheck
1756
- if ( l < 6 ) {
1757
- d = "#" + d[1] + d[1] + d[2] + d[2] + d[3] + d[3] + (
1758
- l > 4 ? d[4] + "" + d[4] : ""
1759
- );
1760
- } //3 or 4 digit
1761
- d = i( d.slice( 1 ), 16 ), RGB[0] = d >> 16 & 255, RGB[1] = d >> 8 & 255, RGB[2] = d & 255, RGB[3] = - 1;
1762
- if ( l == 9 || l == 5 ) {
1763
- RGB[3] = r( (
1764
- RGB[2] / 255
1765
- ) * 10000 ) / 10000, RGB[2] = RGB[1], RGB[1] = RGB[0], RGB[0] = d >> 24 & 255;
1766
- }
1767
- }
1768
- return RGB;
1769
- }
1770
- }
1771
- var i = parseInt, r = Math.round, h = from.length > 9, h = typeof(
1772
- to
1773
- ) == "string" ? to.length > 9 ? true : to == "c" ? ! h : false : h, b = p < 0, p = b ? p * - 1 : p,
1774
- to = to && to != "c" ? to : b ? "#000000" : "#FFFFFF", f = this.pSBCr( from ), t = this.pSBCr( to );
1775
- if ( ! f || ! t ) {
1776
- return null;
1777
- } //ErrorCheck
1778
- if ( h ) {
1779
- return "rgb" + (
1780
- f[3] > - 1 || t[3] > - 1 ? "a(" : "("
1781
- ) + r( (
1782
- t[0] - f[0]
1783
- ) * p + f[0] ) + "," + r( (
1784
- t[1] - f[1]
1785
- ) * p + f[1] ) + "," + r( (
1786
- t[2] - f[2]
1787
- ) * p + f[2] ) + (
1788
- f[3] < 0 && t[3] < 0 ? ")" : "," + (
1789
- f[3] > - 1 && t[3] > - 1 ? r( (
1790
- (
1791
- t[3] - f[3]
1792
- ) * p + f[3]
1793
- ) * 10000 ) / 10000 : t[3] < 0 ? f[3] : t[3]
1794
- ) + ")"
1795
- );
1796
- } else {
1797
- return "#" + (
1798
- 0x100000000 + r( (
1799
- t[0] - f[0]
1800
- ) * p + f[0] ) * 0x1000000 + r( (
1801
- t[1] - f[1]
1802
- ) * p + f[1] ) * 0x10000 + r( (
1803
- t[2] - f[2]
1804
- ) * p + f[2] ) * 0x100 + (
1805
- f[3] > - 1 && t[3] > - 1 ? r( (
1806
- (
1807
- t[3] - f[3]
1808
- ) * p + f[3]
1809
- ) * 255 ) : t[3] > - 1 ? r( t[3] * 255 ) : f[3] > - 1 ? r( f[3] * 255 ) : 255
1810
- )
1811
- ).toString( 16 ).slice( 1, f[3] > - 1 || t[3] > - 1 ? undefined : - 2 );
1812
- }
1813
- };
41
  $( '.customify_select2' ).select2();
42
 
43
  setTimeout( function() {
44
+ CustomifyFontSelectFields.init();
45
  }, 333 );
46
 
47
  prepare_typography_field();
62
  } );
63
 
64
  // for each range input add a value preview output
65
+ $( '.accordion-section-content[id*="' + customify_settings.options_name + '"], #sub-accordion-section-style_manager_section' ).each( function() {
66
 
67
  // Initialize range fields logic
68
  customifyHandleRangeFields( this );
314
  }
315
  )();
316
 
317
+ // Bind any connected fields, except those in the Style Manager.
318
+ // Those are handled by the appropriate Style Manager component (Color Palettes, Font Palettes, etc ).
319
+ bindConnectedFields();
320
+
321
+ } );
322
+
323
+ const getConnectedFieldsCallback = function( parent_setting_data, parent_setting_id ) {
324
+ return function( new_value, old_value ) {
325
+ _.each( parent_setting_data.connected_fields, function( connected_field_data ) {
326
+ if ( _.isUndefined( connected_field_data ) || _.isUndefined( connected_field_data.setting_id ) || ! _.isString( connected_field_data.setting_id ) ) {
327
+ return;
 
 
 
 
 
 
 
328
  }
329
+ const setting = wp.customize( connected_field_data.setting_id );
330
+ if ( _.isUndefined( setting ) ) {
331
+ return;
332
+ }
333
+ setting.set( new_value );
334
+ } );
335
+ }
336
+ };
337
+
338
+ const bindConnectedFields = function() {
339
+ _.each( wp.customize.settings.settings, function( parent_setting_data, parent_setting_id ) {
340
+ // We don't want to handle the binding of the Style Manager settings
341
+ if ( typeof ColorPalettes !== "undefined"
342
+ && typeof ColorPalettes.masterSettingIds !== "undefined"
343
+ && _.contains( ColorPalettes.masterSettingIds, parent_setting_id ) ) {
344
+ return;
345
  }
346
+ if ( typeof FontPalettes !== "undefined"
347
+ && typeof FontPalettes.masterSettingIds !== "undefined"
348
+ && _.contains( FontPalettes.masterSettingIds, parent_setting_id ) ) {
349
+ return;
 
 
 
350
  }
351
 
352
+ let parent_setting = wp.customize( parent_setting_id );
353
+ if ( typeof parent_setting_data.connected_fields !== "undefined" ) {
354
+ connectedFieldsCallbacks[parent_setting_id] = getConnectedFieldsCallback( parent_setting_data, parent_setting_id );
355
+ parent_setting.bind( connectedFieldsCallbacks[parent_setting_id] );
356
+ }
357
+ } );
358
+ };
359
+
360
+ const unbindConnectedFields = function() {
361
+ _.each( wp.customize.settings.settings, function( parent_setting_data, parent_setting_id ) {
362
+ // We don't want to handle the binding of the Style Manager settings
363
+ if ( typeof ColorPalettes !== "undefined"
364
+ && typeof ColorPalettes.masterSettingIds !== "undefined"
365
+ && _.contains( ColorPalettes.masterSettingIds, parent_setting_id ) ) {
366
+ return;
367
+ }
368
+ if ( typeof FontPalettes !== "undefined"
369
+ && typeof FontPalettes.masterSettingIds !== "undefined"
370
+ && _.contains( FontPalettes.masterSettingIds, parent_setting_id ) ) {
371
+ return;
372
+ }
373
+
374
+ let parent_setting = wp.customize( parent_setting_id );
375
+ if ( typeof parent_setting_data.connected_fields !== "undefined" && typeof connectedFieldsCallbacks[parent_setting_id] !== "undefined" ) {
376
+ parent_setting.unbind( connectedFieldsCallbacks[parent_setting_id] );
377
+ }
378
+ delete connectedFieldsCallbacks[parent_setting_id];
379
+ } );
380
+ };
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
381
 
382
  const customifyHandleRangeFields = function( el ) {
383
 
1072
  }
1073
  )( jQuery );
1074
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1075
  var Queue = function() {
1076
  var lastPromise = null;
1077
  var queueDeferred = null;
1254
  };
1255
  }
1256
  )( jQuery, window, wp );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
js/customizer/color-palettes-variations.js ADDED
@@ -0,0 +1,68 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ window.colorPalettesVariations = {
2
+ 'light': {
3
+ 'sm_color_primary': ['sm_color_primary'],
4
+ 'sm_color_secondary': ['sm_color_secondary'],
5
+ 'sm_color_tertiary': ['sm_color_tertiary'],
6
+ 'sm_dark_primary': ['sm_dark_primary'],
7
+ 'sm_dark_secondary': ['sm_dark_secondary'],
8
+ 'sm_dark_tertiary': ['sm_dark_tertiary'],
9
+ 'sm_light_primary': ['sm_light_primary'],
10
+ 'sm_light_secondary': ['sm_light_secondary'],
11
+ 'sm_light_tertiary': ['sm_light_tertiary'],
12
+ },
13
+ 'dark': {
14
+ 'sm_color_primary': ['sm_color_primary'],
15
+ 'sm_color_secondary': ['sm_color_secondary'],
16
+ 'sm_color_tertiary': ['sm_color_tertiary'],
17
+ 'sm_dark_primary': ['sm_light_primary'],
18
+ 'sm_dark_secondary': ['sm_light_secondary'],
19
+ 'sm_dark_tertiary': ['sm_light_tertiary'],
20
+ 'sm_light_primary': ['sm_dark_primary'],
21
+ 'sm_light_secondary': ['sm_dark_secondary'],
22
+ 'sm_light_tertiary': ['sm_dark_tertiary'],
23
+ },
24
+ 'colorful': {
25
+ 'sm_color_primary': ['sm_light_primary'],
26
+ 'sm_color_secondary': ['sm_light_secondary'],
27
+ 'sm_color_tertiary': ['sm_light_tertiary'],
28
+ 'sm_dark_primary': [],
29
+ 'sm_dark_secondary': [],
30
+ 'sm_dark_tertiary': [],
31
+ 'sm_light_primary': ['sm_color_primary', 'sm_dark_primary'],
32
+ 'sm_light_secondary': ['sm_color_secondary', 'sm_dark_secondary'],
33
+ 'sm_light_tertiary': ['sm_color_tertiary', 'sm_dark_tertiary'],
34
+ },
35
+ 'dark_alt': {
36
+ 'sm_color_primary': ['sm_light_primary'],
37
+ 'sm_color_secondary': ['sm_light_secondary'],
38
+ 'sm_color_tertiary': ['sm_light_tertiary'],
39
+ 'sm_dark_primary': ['sm_color_primary'],
40
+ 'sm_dark_secondary': ['sm_color_secondary'],
41
+ 'sm_dark_tertiary': ['sm_color_tertiary'],
42
+ 'sm_light_primary': ['sm_dark_primary'],
43
+ 'sm_light_secondary': ['sm_dark_secondary'],
44
+ 'sm_light_tertiary': ['sm_dark_tertiary'],
45
+ },
46
+ 'colorful_alt': {
47
+ 'sm_color_primary': ['sm_dark_primary'],
48
+ 'sm_color_secondary': ['sm_dark_secondary'],
49
+ 'sm_color_tertiary': ['sm_dark_tertiary'],
50
+ 'sm_dark_primary': ['sm_light_primary'],
51
+ 'sm_dark_secondary': ['sm_light_secondary'],
52
+ 'sm_dark_tertiary': ['sm_light_tertiary'],
53
+ 'sm_light_primary': ['sm_color_primary'],
54
+ 'sm_light_secondary': ['sm_color_secondary'],
55
+ 'sm_light_tertiary': ['sm_color_tertiary'],
56
+ },
57
+ 'light_alt': {
58
+ 'sm_color_primary': ['sm_dark_primary'],
59
+ 'sm_color_secondary': ['sm_dark_secondary'],
60
+ 'sm_color_tertiary': ['sm_dark_tertiary'],
61
+ 'sm_dark_primary': ['sm_color_primary'],
62
+ 'sm_dark_secondary': ['sm_color_secondary'],
63
+ 'sm_dark_tertiary': ['sm_color_tertiary'],
64
+ 'sm_light_primary': ['sm_light_primary'],
65
+ 'sm_light_secondary': ['sm_light_secondary'],
66
+ 'sm_light_tertiary': ['sm_light_tertiary'],
67
+ },
68
+ };
js/customizer/color-palettes.js ADDED
@@ -0,0 +1,521 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ let ColorPalettes = ( function( $, exports, wp ) {
2
+
3
+ const defaultVariation = 'light';
4
+ const masterSettingIds = [
5
+ "sm_color_primary",
6
+ "sm_color_secondary",
7
+ "sm_color_tertiary",
8
+ "sm_dark_primary",
9
+ "sm_dark_secondary",
10
+ "sm_dark_tertiary",
11
+ "sm_light_primary",
12
+ "sm_light_secondary",
13
+ "sm_light_tertiary"
14
+ ];
15
+
16
+ // const master_color_selector = '#_customize-input-sm_dark_color_master_slider_control';
17
+ // const primary_color_selector = '#_customize-input-sm_dark_color_primary_slider_control';
18
+ // const secondary_color_selector = '#_customize-input-sm_dark_color_secondary_slider_control';
19
+ // const tertiary_color_selector = '#_customize-input-sm_dark_color_tertiary_slider_control';
20
+ // const color_dispersion_selector = '#_customize-input-sm_colors_dispersion_control';
21
+ // const color_focus_point_selector = '#_customize-input-sm_colors_focus_point_control';
22
+ // const color_sliders_selector = primary_color_selector + ', ' + secondary_color_selector + ', ' + tertiary_color_selector;
23
+ // const all_sliders_selector = color_sliders_selector + ', ' + color_dispersion_selector + ', ' + color_focus_point_selector;
24
+
25
+
26
+ const initializePalettes = () => {
27
+ // Cache initial settings configuration to be able to update connected fields on variation change.
28
+ if ( typeof window.settingsClone === "undefined" ) {
29
+ window.settingsClone = $.extend(true, {}, wp.customize.settings.settings);
30
+ }
31
+
32
+ // Create a stack of callbacks bound to parent settings to be able to unbind them
33
+ // when altering the connected_fields attribute.
34
+ if ( typeof window.connectedFieldsCallbacks === "undefined" ) {
35
+ window.connectedFieldsCallbacks = {};
36
+ }
37
+ };
38
+
39
+ const hexDigits = ["0","1","2","3","4","5","6","7","8","9","a","b","c","d","e","f"];
40
+
41
+ function rgb2hex(rgb) {
42
+ rgb = rgb.match(/^rgb\((\d+),\s*(\d+),\s*(\d+)\)$/);
43
+ return "#" + hex(rgb[1]) + hex(rgb[2]) + hex(rgb[3]);
44
+ }
45
+
46
+ function hex(x) {
47
+ return isNaN(x) ? "00" : hexDigits[(x - x % 16) / 16] + hexDigits[x % 16];
48
+ }
49
+
50
+ const updateCurrentPalette = ( label ) => {
51
+ const $palette = $( '.c-color-palette' );
52
+
53
+ if ( ! $palette.length ) {
54
+ return;
55
+ }
56
+
57
+ const $current = $palette.find( '.colors.current' );
58
+ const $next = $palette.find( '.colors.next' );
59
+
60
+ label = label || 'Custom Style';
61
+ $palette.find( '.c-color-palette__name' ).text( label );
62
+
63
+ // apply the last animate set of colors to the "current" color palette
64
+ _.each( masterSettingIds, function( setting_id ) {
65
+ const color = $next.find( '.' + setting_id ).css( 'color' );
66
+ $current.find( '.color.' + setting_id ).css( 'color', color );
67
+ $palette.find( 'input.' + setting_id ).val( rgb2hex( color ) );
68
+ });
69
+
70
+ // removing the "animate" class will put the "next" color palette out view
71
+ // so we can update the colors in it
72
+ $palette.removeClass( 'animate' );
73
+
74
+ // update the colors in the "next" palette with the new values
75
+ _.each( masterSettingIds, function( setting_id ) {
76
+ const setting = wp.customize( setting_id );
77
+
78
+ if ( typeof setting !== "undefined" ) {
79
+ $next.find( '.' + setting_id ).css( 'color', setting() );
80
+ }
81
+ });
82
+
83
+ // trigger transition to new color palette
84
+ setTimeout(function() {
85
+ $palette.addClass( 'animate' );
86
+ var color = $next.first( ':visible' ).css( 'color' );
87
+ $palette.find( '.c-color-palette__control' ).css( 'color', color );
88
+ });
89
+ };
90
+
91
+ const resetSettings = settings => {
92
+ _.each( settings, function( setting_id ) {
93
+ const setting = wp.customize( setting_id );
94
+
95
+ if ( typeof setting !== "undefined" ) {
96
+ let value = setting();
97
+ setting.set( value + "ff" );
98
+ setting.set( value );
99
+ }
100
+ });
101
+ };
102
+
103
+ const getConnectedFieldsCallback = function( parent_setting_data, parent_setting_id ) {
104
+ return function( new_value, old_value ) {
105
+ _.each( parent_setting_data.connected_fields, function( connected_field_data ) {
106
+ if ( _.isUndefined( connected_field_data ) || _.isUndefined( connected_field_data.setting_id ) || ! _.isString( connected_field_data.setting_id ) ) {
107
+ return;
108
+ }
109
+ const setting = wp.customize( connected_field_data.setting_id );
110
+ if ( _.isUndefined( setting ) ) {
111
+ return;
112
+ }
113
+ setting.set( new_value );
114
+ } );
115
+ }
116
+ };
117
+
118
+ const bindConnectedFields = function() {
119
+ _.each( masterSettingIds, function( parent_setting_id ) {
120
+ if ( typeof wp.customize.settings.settings[parent_setting_id] !== "undefined" ) {
121
+ let parent_setting_data = wp.customize.settings.settings[parent_setting_id];
122
+ let parent_setting = wp.customize(parent_setting_id);
123
+
124
+ if (typeof parent_setting_data.connected_fields !== "undefined") {
125
+ connectedFieldsCallbacks[parent_setting_id] = getConnectedFieldsCallback(parent_setting_data, parent_setting_id);
126
+ parent_setting.bind(connectedFieldsCallbacks[parent_setting_id]);
127
+ }
128
+ }
129
+ } );
130
+ };
131
+
132
+ const unbindConnectedFields = function() {
133
+ _.each( masterSettingIds, function( parent_setting_id ) {
134
+ if ( typeof wp.customize.settings.settings[parent_setting_id] !== "undefined" ) {
135
+ let parent_setting_data = wp.customize.settings.settings[parent_setting_id];
136
+ let parent_setting = wp.customize(parent_setting_id);
137
+
138
+ if (typeof parent_setting_data.connected_fields !== "undefined" && typeof connectedFieldsCallbacks[parent_setting_id] !== "undefined") {
139
+ parent_setting.unbind(connectedFieldsCallbacks[parent_setting_id]);
140
+ }
141
+ delete connectedFieldsCallbacks[parent_setting_id];
142
+ }
143
+ } );
144
+ };
145
+
146
+ // alter connected fields of the master colors controls depending on the selected palette variation
147
+ const getCurrentVariation = () => {
148
+ const setting = wp.customize( 'sm_color_palette_variation' );
149
+
150
+ if ( _.isUndefined( setting ) ) {
151
+ return defaultVariation;
152
+ }
153
+
154
+ const variation = setting();
155
+
156
+ if ( ! window.colorPalettesVariations.hasOwnProperty( variation ) ) {
157
+ return defaultVariation;
158
+ }
159
+
160
+ return variation;
161
+ };
162
+
163
+ const createCurrentPaletteControls = () => {
164
+ const $palette = $( '.c-color-palette' );
165
+ const $fields = $palette.find( '.c-color-palette__fields' ).find( 'input' );
166
+
167
+ if ( ! $palette.length ) {
168
+ return;
169
+ }
170
+
171
+ const $colors = $palette.find( '.colors.next .color' );
172
+
173
+ $colors.each( ( i, obj ) => {
174
+ const $obj = $( obj );
175
+ const setting_id = $obj.data( 'setting' );
176
+ const $input = $fields.filter( '.' + setting_id );
177
+ const setting = wp.customize( setting_id );
178
+
179
+ $obj.data( 'target', $input );
180
+
181
+ $input.iris( {
182
+ change: ( event, ui ) => {
183
+ const lastColor = setting();
184
+ const currentColor = ui.color.toString();
185
+
186
+ if ( 'sm_color_primary' === $obj.data( 'setting' ) ) {
187
+ $( '.c-color-palette__control' ).css( 'color', currentColor );
188
+ }
189
+
190
+ if ( lastColor !== currentColor ) {
191
+ $obj.css( 'color', currentColor );
192
+ setting.set( currentColor );
193
+ $palette.find( '.c-color-palette__name' ).text( 'Custom Style' );
194
+ }
195
+ }
196
+ } );
197
+
198
+ $obj.find( '.iris-picker' ).on( 'click', function( e ) {
199
+ e.stopPropagation();
200
+ e.preventDefault();
201
+ } );
202
+
203
+ $obj.on( 'click', ( e ) => {
204
+ e.stopPropagation();
205
+ e.preventDefault();
206
+
207
+ if ( $input.is( ':visible' ) ) {
208
+ $input.iris( 'hide' );
209
+ $input.hide();
210
+ $colors.removeClass( 'active inactive' );
211
+ } else {
212
+ $colors.not( $obj ).each( function( i, obj ) {
213
+ $( obj ).data( 'target' ).not( $input ).hide();
214
+ } );
215
+ $input.show().focus();
216
+ }
217
+ } );
218
+
219
+ $input.on( 'click', ( e ) => {
220
+ e.stopPropagation();
221
+ e.preventDefault();
222
+ } );
223
+
224
+ $input.on( 'focus', ( e ) => {
225
+
226
+ $colors.each( ( i, obj ) => {
227
+ $( obj ).data( 'target' ).not( $input ).iris( 'hide' );
228
+ } );
229
+
230
+ $colors.not( $obj ).addClass( 'inactive' ).removeClass( 'active' );
231
+ $obj.addClass( 'active' ).removeClass( 'inactive' );
232
+
233
+ $colors.not( $obj ).each( function( i, obj ) {
234
+ $( obj ).data( 'target' ).iris( 'hide' );
235
+ } );
236
+
237
+ const $iris = $input.next( '.iris-picker' );
238
+ const paletteWidth = $palette.outerWidth();
239
+ const $visibleColors = $colors.filter( ':visible' );
240
+ const index = $visibleColors.index( $obj );
241
+
242
+ $iris.css( 'left', ( paletteWidth - 200 ) * index / ( $visibleColors.length - 1 ) );
243
+
244
+ $input.iris( 'color', $obj.css( 'color' ) );
245
+ $input.iris( 'show' );
246
+ } );
247
+ } );
248
+
249
+ $( 'body' ).on( 'click', function() {
250
+ $colors.removeClass( 'active inactive' );
251
+ $colors.each( function( i, obj ) {
252
+ const $input = $( obj ).data( 'target' );
253
+
254
+ $input.iris( 'hide' );
255
+ $input.hide();
256
+ } );
257
+ } );
258
+ };
259
+
260
+ const onPaletteChange = function() {
261
+ const $label = $( this ).next( 'label' ).clone();
262
+ let label;
263
+
264
+ $label.find( '.preview__letter' ).remove();
265
+ label = $label.text();
266
+ $label.remove();
267
+
268
+ $( this ).trigger( 'customify:preset-change' );
269
+ updateCurrentPalette( label );
270
+ // buildColorMatrix();
271
+ };
272
+
273
+ const buildColorMatrix = () => {
274
+ const $matrix = $( '.sm_color_matrix' );
275
+
276
+ if ( ! $matrix.children().length ) {
277
+ _.each( masterSettingIds, function( setting_id ) {
278
+ const $bucket = $( '<div class="' + setting_id + '">' ).appendTo( $matrix );
279
+ } );
280
+ }
281
+
282
+ _.each( masterSettingIds, function( setting_id ) {
283
+ const $bucket = $matrix.children( '.' + setting_id );
284
+ const color = wp.customize( setting_id )();
285
+ let classes = [];
286
+
287
+ $bucket.css( 'color', color );
288
+
289
+ _.each( wp.customize.settings.settings[setting_id]['connected_fields'], function( connected_field ) {
290
+ const field_id = connected_field.setting_id;
291
+ const fieldClassName = field_id.replace( '[', '_' ).replace( ']', '' );
292
+ classes.push( fieldClassName );
293
+
294
+ if ( ! $bucket.children( '.' + fieldClassName ).length ) {
295
+ const $color = $( '<div title="' + field_id + '" class="' + fieldClassName + '">' ).appendTo( $bucket );
296
+ }
297
+ } );
298
+
299
+ let className = '.' + classes.join( ', .' );
300
+
301
+ if ( classes.length ) {
302
+ $bucket.children().not( className ).remove();
303
+ } else {
304
+ $bucket.children().remove();
305
+ }
306
+ });
307
+ };
308
+
309
+ const toggleVisibleOptions = ( settings ) => {
310
+ let optionsToShow = [];
311
+
312
+ _.each( masterSettingIds, function( settingId ) {
313
+ const connectedFields = settings[settingId]['connected_fields'];
314
+ if ( ! _.isUndefined( connectedFields ) && connectedFields.length ) {
315
+ optionsToShow.push( settingId );
316
+ }
317
+ } );
318
+
319
+ if ( optionsToShow.length ) {
320
+ let optionsSelector = '.' + optionsToShow.join(', .');
321
+ $( '.c-color-palette .color' ).addClass( 'hidden' ).filter( optionsSelector ).removeClass( 'hidden' );
322
+ }
323
+ };
324
+
325
+ const alterFields = ( settings, swapMap ) => {
326
+
327
+ var newSettings = JSON.parse(JSON.stringify(settings));
328
+ var oldSettings = JSON.parse(JSON.stringify(settings));
329
+
330
+ _.each( swapMap, function( fromArray, to ) {
331
+ if ( typeof newSettings[to] !== "undefined" ) {
332
+ let newConnectedFields = [];
333
+ if ( fromArray instanceof Array ) {
334
+ _.each( fromArray, function( from ) {
335
+ let oldConnectedFields;
336
+ if ( _.isUndefined( oldSettings[from]['connected_fields'] ) ) {
337
+ oldSettings[from]['connected_fields'] = [];
338
+ }
339
+ oldConnectedFields = Object.values( oldSettings[from]['connected_fields'] );
340
+ newConnectedFields = newConnectedFields.concat( oldConnectedFields );
341
+ } );
342
+ }
343
+ newSettings[to]['connected_fields'] = Object.keys( newConnectedFields ).map( function(key) {
344
+ return newConnectedFields[key];
345
+ });
346
+ }
347
+ } );
348
+ return _.clone(newSettings);
349
+ };
350
+
351
+ const moveConnectedFields = ( oldSettings, from, to, ratio ) => {
352
+
353
+ let settings = _.clone( oldSettings );
354
+
355
+ if ( ! _.isUndefined( settings[to] ) && ! _.isUndefined( settings[from] ) ) {
356
+
357
+ if ( _.isUndefined( settings[from]['connected_fields'] ) ) {
358
+ settings[from]['connected_fields'] = [];
359
+ }
360
+
361
+ if ( _.isUndefined( settings[to]['connected_fields'] ) ) {
362
+ settings[to]['connected_fields'] = [];
363
+ }
364
+
365
+ const oldFromConnectedFields = Object.values( settings[from]['connected_fields'] );
366
+ const oldToConnectedFields = Object.values( settings[to]['connected_fields'] );
367
+ const oldConnectedFields = oldToConnectedFields.concat( oldFromConnectedFields );
368
+ const count = ratio * oldConnectedFields.length;
369
+
370
+ let newToConnectedFields = oldConnectedFields.slice( 0, count );
371
+ let newFromConnectedFields = oldConnectedFields.slice( count );
372
+
373
+ newToConnectedFields = Object.keys( newToConnectedFields ).map( function(key) {
374
+ return newToConnectedFields[key];
375
+ });
376
+ newToConnectedFields = Object.keys( newToConnectedFields ).map( function(key) {
377
+ return newToConnectedFields[key];
378
+ });
379
+
380
+ settings[to]['connected_fields'] = newToConnectedFields;
381
+ settings[from]['connected_fields'] = newFromConnectedFields;
382
+ }
383
+
384
+ return settings;
385
+ };
386
+
387
+ const disperseColorConnectedFields = ( oldSettings, dispersion, focus ) => {
388
+
389
+ let settings = _.clone(oldSettings);
390
+
391
+ if ( _.isUndefined( settings['sm_color_primary']['connected_fields'] ) ) {
392
+ settings['sm_color_primary']['connected_fields'] = [];
393
+ }
394
+
395
+ if ( _.isUndefined( settings['sm_color_secondary']['connected_fields'] ) ) {
396
+ settings['sm_color_secondary']['connected_fields'] = [];
397
+ }
398
+
399
+ if ( _.isUndefined( settings['sm_color_tertiary']['connected_fields'] ) ) {
400
+ settings['sm_color_tertiary']['connected_fields'] = [];
401
+ }
402
+
403
+ const primaryConnectedFields = Object.values( settings['sm_color_primary']['connected_fields'] );
404
+ const secondaryConnectedFields = Object.values( settings['sm_color_secondary']['connected_fields'] );
405
+ const tertiaryConnectedFields = Object.values( settings['sm_color_tertiary']['connected_fields'] );
406
+
407
+ // A1 A2 A3 A4
408
+ // |--- primary ---|-- secondary --|-- tertiary --|
409
+ // B1 B2
410
+ // |----- focus -----|
411
+
412
+ const b1 = Math.max(0, focus - dispersion / 2 );
413
+ const b2 = Math.min(1, focus + dispersion / 2 );
414
+ const a1 = 0;
415
+ const a2 = 0.334;
416
+ const a3 = 0.667;
417
+ const a4 = 1;
418
+
419
+ const primaryWidth = b1 > a2 || b2 < a1 ? 0 : Math.min(a2, b2) - Math.max(a1, b1);
420
+ const secondaryWidth = b1 > a3 || b2 < a2 ? 0 : Math.min(a3, b2) - Math.max(a2, b1);
421
+ const tertiaryWidth = b1 > a4 || b2 < a3 ? 0 : Math.min(a4, b2) - Math.max(a3, b1);
422
+
423
+ const totalWidth = primaryWidth + secondaryWidth + tertiaryWidth;
424
+ const connectedFields = primaryConnectedFields.concat( secondaryConnectedFields ).concat( tertiaryConnectedFields );
425
+ const primaryFieldsCount = Math.round(connectedFields.length * primaryWidth / totalWidth);
426
+ const secondaryFieldsCount = Math.round(connectedFields.length * secondaryWidth / totalWidth);
427
+
428
+ let newPrimaryConnectedFields = connectedFields.slice(0, primaryFieldsCount);
429
+ let newSecondaryConnectedFields = connectedFields.slice(primaryFieldsCount, primaryFieldsCount + secondaryFieldsCount);
430
+ let newTertiaryConnectedFields = connectedFields.slice(primaryFieldsCount + secondaryFieldsCount);
431
+
432
+ newPrimaryConnectedFields = Object.keys( newPrimaryConnectedFields ).map( function(key) {
433
+ return newPrimaryConnectedFields[key];
434
+ });
435
+ newSecondaryConnectedFields = Object.keys( newSecondaryConnectedFields ).map( function(key) {
436
+ return newSecondaryConnectedFields[key];
437
+ });
438
+ newTertiaryConnectedFields = Object.keys( newTertiaryConnectedFields ).map( function(key) {
439
+ return newTertiaryConnectedFields[key];
440
+ });
441
+
442
+ settings['sm_color_primary']['connected_fields'] = newPrimaryConnectedFields;
443
+ settings['sm_color_secondary']['connected_fields'] = newSecondaryConnectedFields;
444
+ settings['sm_color_tertiary']['connected_fields'] = newTertiaryConnectedFields;
445
+
446
+ return settings;
447
+ };
448
+
449
+ const reloadConnectedFields = () => {
450
+ const variation = getCurrentVariation();
451
+ // const primaryRatio = $( primary_color_selector ).val() / 100;
452
+ // const secondaryRatio = $( secondary_color_selector ).val() / 100;
453
+ // const tertiaryRatio = $( tertiary_color_selector ).val() / 100;
454
+ // const colorDispersion = $( color_dispersion_selector ).val() / 100;
455
+ // const focusPoint = $( color_focus_point_selector ).val() / 100;
456
+
457
+ let tempSettings = JSON.parse(JSON.stringify(window.settingsClone));
458
+
459
+ unbindConnectedFields();
460
+
461
+ // tempSettings = moveConnectedFields( tempSettings, 'sm_dark_primary', 'sm_color_primary', primaryRatio );
462
+ // tempSettings = moveConnectedFields( tempSettings, 'sm_dark_secondary', 'sm_color_secondary', secondaryRatio );
463
+ // tempSettings = moveConnectedFields( tempSettings, 'sm_dark_tertiary', 'sm_color_tertiary', tertiaryRatio );
464
+ // tempSettings = disperseColorConnectedFields( tempSettings, colorDispersion, focusPoint );
465
+
466
+ tempSettings = alterFields( tempSettings, colorPalettesVariations[variation] );
467
+
468
+ toggleVisibleOptions( tempSettings );
469
+
470
+ wp.customize.settings.settings = tempSettings;
471
+
472
+ bindConnectedFields();
473
+ // buildColorMatrix();
474
+ resetSettings( masterSettingIds );
475
+ };
476
+
477
+ const bindEvents = () => {
478
+ const paletteControlSelector = '.c-color-palette__control';
479
+ const $paletteControl = $( paletteControlSelector );
480
+ const variation = getCurrentVariation();
481
+
482
+ $paletteControl.removeClass( 'active' );
483
+ $paletteControl.filter( '.variation-' + variation ).addClass( 'active' );
484
+
485
+ $( 'body' ).on( 'click', paletteControlSelector, function() {
486
+ let $obj = $( this ),
487
+ $target = $( $obj.data( 'target' ) );
488
+
489
+ $obj.siblings( paletteControlSelector ).removeClass( 'active' );
490
+ $obj.addClass( 'active' );
491
+ $target.prop( 'checked', true ).trigger( 'change' );
492
+ } );
493
+
494
+ // when variation is changed reload connected fields from cached version of customizer settings config
495
+ $( document ).on( 'change', '[name="_customize-radio-sm_color_palette_variation_control"]', reloadConnectedFields );
496
+
497
+ //
498
+ $( document ).on( 'click', '.customify_preset.color_palette input', onPaletteChange );
499
+
500
+ // $( all_sliders_selector ).on( 'input', reloadConnectedFields );
501
+
502
+ // $( master_color_selector ).on( 'input', function() {
503
+ // const masterValue = $( master_color_selector ).val();
504
+ // $( color_sliders_selector ).val( masterValue ).trigger( 'input' );
505
+ // } );
506
+ };
507
+
508
+ wp.customize.bind( 'ready', function() {
509
+ initializePalettes();
510
+ createCurrentPaletteControls();
511
+ updateCurrentPalette();
512
+ reloadConnectedFields();
513
+ // buildColorMatrix();
514
+ bindEvents();
515
+ } );
516
+
517
+ return {
518
+ masterSettingIds: masterSettingIds
519
+ };
520
+
521
+ } )( jQuery, window, wp );
js/customizer/customify-palette-variations.js CHANGED
@@ -1,30 +1,30 @@
1
  window.variations = {
2
  'light': {
3
- 'sm_color_primary': ['sm_color_primary'],
4
- 'sm_color_secondary': ['sm_color_secondary'],
5
- 'sm_color_tertiary': ['sm_color_tertiary'],
6
- 'sm_dark_primary': ['sm_dark_primary'],
7
- 'sm_dark_secondary': ['sm_dark_secondary'],
8
- 'sm_dark_tertiary': ['sm_dark_tertiary'],
9
- 'sm_light_primary': ['sm_light_primary'],
10
- 'sm_light_secondary': ['sm_light_secondary'],
11
- 'sm_light_tertiary': ['sm_light_tertiary'],
12
  },
13
  'dark': {
14
- 'sm_color_primary': ['sm_color_primary'],
15
- 'sm_color_secondary': ['sm_color_secondary'],
16
- 'sm_color_tertiary': ['sm_color_tertiary'],
17
- 'sm_dark_primary': ['sm_light_primary'],
18
- 'sm_dark_secondary': ['sm_light_secondary'],
19
- 'sm_dark_tertiary': ['sm_light_tertiary'],
20
- 'sm_light_primary': ['sm_dark_primary'],
21
- 'sm_light_secondary': ['sm_dark_secondary'],
22
- 'sm_light_tertiary': ['sm_dark_tertiary'],
23
  },
24
  'colorful': {
25
- 'sm_color_primary': ['sm_light_primary'],
26
- 'sm_color_secondary': ['sm_light_secondary'],
27
- 'sm_color_tertiary': ['sm_light_tertiary'],
28
  'sm_dark_primary': [],
29
  'sm_dark_secondary': [],
30
  'sm_dark_tertiary': [],
@@ -33,36 +33,36 @@ window.variations = {
33
  'sm_light_tertiary': ['sm_color_tertiary', 'sm_dark_tertiary'],
34
  },
35
  'dark_alt': {
36
- 'sm_color_primary': ['sm_light_primary'],
37
- 'sm_color_secondary': ['sm_light_secondary'],
38
- 'sm_color_tertiary': ['sm_light_tertiary'],
39
- 'sm_dark_primary': ['sm_color_primary'],
40
- 'sm_dark_secondary': ['sm_color_secondary'],
41
- 'sm_dark_tertiary': ['sm_color_tertiary'],
42
- 'sm_light_primary': ['sm_dark_primary'],
43
- 'sm_light_secondary': ['sm_dark_secondary'],
44
- 'sm_light_tertiary': ['sm_dark_tertiary'],
45
  },
46
  'colorful_alt': {
47
- 'sm_color_primary': ['sm_dark_primary'],
48
- 'sm_color_secondary': ['sm_dark_secondary'],
49
- 'sm_color_tertiary': ['sm_dark_tertiary'],
50
- 'sm_dark_primary': ['sm_light_primary'],
51
- 'sm_dark_secondary': ['sm_light_secondary'],
52
- 'sm_dark_tertiary': ['sm_light_tertiary'],
53
- 'sm_light_primary': ['sm_color_primary'],
54
- 'sm_light_secondary': ['sm_color_secondary'],
55
- 'sm_light_tertiary': ['sm_color_tertiary'],
56
  },
57
  'light_alt': {
58
- 'sm_color_primary': ['sm_dark_primary'],
59
- 'sm_color_secondary': ['sm_dark_secondary'],
60
- 'sm_color_tertiary': ['sm_dark_tertiary'],
61
- 'sm_dark_primary': ['sm_color_primary'],
62
- 'sm_dark_secondary': ['sm_color_secondary'],
63
- 'sm_dark_tertiary': ['sm_color_tertiary'],
64
- 'sm_light_primary': ['sm_light_primary'],
65
- 'sm_light_secondary': ['sm_light_secondary'],
66
- 'sm_light_tertiary': ['sm_light_tertiary'],
67
  },
68
  };
1
  window.variations = {
2
  'light': {
3
+ 'sm_color_primary': 'sm_color_primary',
4
+ 'sm_color_secondary': 'sm_color_secondary',
5
+ 'sm_color_tertiary': 'sm_color_tertiary',
6
+ 'sm_dark_primary': 'sm_dark_primary',
7
+ 'sm_dark_secondary': 'sm_dark_secondary',
8
+ 'sm_dark_tertiary': 'sm_dark_tertiary',
9
+ 'sm_light_primary': 'sm_light_primary',
10
+ 'sm_light_secondary': 'sm_light_secondary',
11
+ 'sm_light_tertiary': 'sm_light_tertiary',
12
  },
13
  'dark': {
14
+ 'sm_color_primary': 'sm_color_primary',
15
+ 'sm_color_secondary': 'sm_color_secondary',
16
+ 'sm_color_tertiary': 'sm_color_tertiary',
17
+ 'sm_dark_primary': 'sm_light_primary',
18
+ 'sm_dark_secondary': 'sm_light_secondary',
19
+ 'sm_dark_tertiary': 'sm_light_tertiary',
20
+ 'sm_light_primary': 'sm_dark_primary',
21
+ 'sm_light_secondary': 'sm_dark_secondary',
22
+ 'sm_light_tertiary': 'sm_dark_tertiary',
23
  },
24
  'colorful': {
25
+ 'sm_color_primary': 'sm_light_primary',
26
+ 'sm_color_secondary': 'sm_light_secondary',
27
+ 'sm_color_tertiary': 'sm_light_tertiary',
28
  'sm_dark_primary': [],
29
  'sm_dark_secondary': [],
30
  'sm_dark_tertiary': [],
33
  'sm_light_tertiary': ['sm_color_tertiary', 'sm_dark_tertiary'],
34
  },
35
  'dark_alt': {
36
+ 'sm_color_primary': 'sm_light_primary',
37
+ 'sm_color_secondary': 'sm_light_secondary',
38
+ 'sm_color_tertiary': 'sm_light_tertiary',
39
+ 'sm_dark_primary': 'sm_color_primary',
40
+ 'sm_dark_secondary': 'sm_color_secondary',
41
+ 'sm_dark_tertiary': 'sm_color_tertiary',
42
+ 'sm_light_primary': 'sm_dark_primary',
43
+ 'sm_light_secondary': 'sm_dark_secondary',
44
+ 'sm_light_tertiary': 'sm_dark_tertiary',
45
  },
46
  'colorful_alt': {
47
+ 'sm_color_primary': 'sm_dark_primary',
48
+ 'sm_color_secondary': 'sm_dark_secondary',
49
+ 'sm_color_tertiary': 'sm_dark_tertiary',
50
+ 'sm_dark_primary': 'sm_light_primary',
51
+ 'sm_dark_secondary': 'sm_light_secondary',
52
+ 'sm_dark_tertiary': 'sm_light_tertiary',
53
+ 'sm_light_primary': 'sm_color_primary',
54
+ 'sm_light_secondary': 'sm_color_secondary',
55
+ 'sm_light_tertiary': 'sm_color_tertiary',
56
  },
57
  'light_alt': {
58
+ 'sm_color_primary': 'sm_dark_primary',
59
+ 'sm_color_secondary': 'sm_dark_secondary',
60
+ 'sm_color_tertiary': 'sm_dark_tertiary',
61
+ 'sm_dark_primary': 'sm_color_primary',
62
+ 'sm_dark_secondary': 'sm_color_secondary',
63
+ 'sm_dark_tertiary': 'sm_color_tertiary',
64
+ 'sm_light_primary': 'sm_light_primary',
65
+ 'sm_light_secondary': 'sm_light_secondary',
66
+ 'sm_light_tertiary': 'sm_light_tertiary',
67
  },
68
  };
js/customizer/customify-palettes.js CHANGED
@@ -21,17 +21,6 @@
21
  window.connectedFieldsCallbacks = {};
22
  };
23
 
24
- const hexDigits = new Array("0","1","2","3","4","5","6","7","8","9","a","b","c","d","e","f");
25
-
26
- function rgb2hex(rgb) {
27
- rgb = rgb.match(/^rgb\((\d+),\s*(\d+),\s*(\d+)\)$/);
28
- return "#" + hex(rgb[1]) + hex(rgb[2]) + hex(rgb[3]);
29
- }
30
-
31
- function hex(x) {
32
- return isNaN(x) ? "00" : hexDigits[(x - x % 16) / 16] + hexDigits[x % 16];
33
- }
34
-
35
  const updateCurrentPalette = ( label ) => {
36
  const $palette = $( '.c-palette' );
37
 
@@ -48,8 +37,7 @@
48
  // apply the last animate set of colors to the "current" color palette
49
  _.each( settings, function( setting_id ) {
50
  const color = $next.find( '.' + setting_id ).css( 'color' );
51
- $current.find( '.color.' + setting_id ).css( 'color', color );
52
- $palette.find( 'input.' + setting_id ).val( rgb2hex( color ) );
53
  });
54
 
55
  // removing the "animate" class will put the "next" color palette out view
@@ -94,12 +82,10 @@
94
  };
95
 
96
  const alterConnectedFields = swapMap => {
97
- let optionsToShow = [];
98
  _.each( swapMap, function( fromArray, to ) {
99
  if ( typeof wp.customize.settings.settings[to] !== "undefined" ) {
100
  let newConnectedFields = [];
101
  if ( fromArray instanceof Array ) {
102
-
103
  _.each( fromArray, function( from ) {
104
  if ( typeof window.settingsClone[from] !== "undefined" ) {
105
  let oldConnectedFields;
@@ -113,18 +99,12 @@
113
  newConnectedFields = Object.keys( newConnectedFields ).map( function(key) {
114
  return newConnectedFields[key];
115
  });
 
 
116
  }
117
  wp.customize.settings.settings[to]['connected_fields'] = newConnectedFields;
118
-
119
-
120
- if ( fromArray instanceof Array && fromArray.length && newConnectedFields.length ) {
121
- optionsToShow.push( to );
122
- }
123
  }
124
  } );
125
-
126
- let optionsSelector = '.' + optionsToShow.join( ', .' );
127
- $( '.c-palette .color' ).addClass( 'hidden' ).filter( optionsSelector ).removeClass( 'hidden' );
128
  };
129
 
130
  const resetSettings = settings => {
@@ -191,11 +171,11 @@
191
  unbindConnectedFields();
192
  alterConnectedFields( variations[variation] );
193
  bindConnectedFields();
 
194
  };
195
 
196
  const createCurrentPaletteControls = () => {
197
  const $palette = $( '.c-palette' );
198
- const $fields = $palette.find( '.c-palette__fields' ).find( 'input' );
199
 
200
  if ( ! $palette.length ) {
201
  return;
@@ -206,12 +186,9 @@
206
  $colors.each( ( i, obj ) => {
207
  const $obj = $( obj );
208
  const setting_id = $obj.data( 'setting' );
209
- const $input = $fields.filter( '.' + setting_id );
210
  const setting = wp.customize( setting_id );
211
 
212
- $obj.data( 'target', $input );
213
-
214
- $input.iris( {
215
  change: ( event, ui ) => {
216
  const lastColor = setting();
217
  const currentColor = ui.color.toString();
@@ -233,60 +210,32 @@
233
  e.preventDefault();
234
  } );
235
 
236
- $obj.on( 'click', ( e ) => {
237
  e.stopPropagation();
238
  e.preventDefault();
239
 
240
- if ( $input.is( ':visible' ) ) {
241
- $input.iris( 'hide' );
242
- $input.hide();
243
- $colors.removeClass( 'active inactive' );
244
- } else {
245
- $colors.not( $obj ).each( function( i, obj ) {
246
- $( obj ).data( 'target' ).not( $input ).hide();
247
- } );
248
- $input.show().focus();
249
- }
250
- } );
251
-
252
- $input.on( 'click', ( e ) => {
253
- e.stopPropagation();
254
- e.preventDefault();
255
- } );
256
-
257
- $input.on( 'focus', ( e ) => {
258
-
259
- $colors.each( ( i, obj ) => {
260
- $( obj ).data( 'target' ).not( $input ).iris( 'hide' );
261
- } );
262
 
263
- $colors.not( $obj ).addClass( 'inactive' ).removeClass( 'active' );
264
- $obj.addClass( 'active' ).removeClass( 'inactive' );
 
265
 
266
- $colors.not( $obj ).each( function( i, obj ) {
267
- $( obj ).data( 'target' ).iris( 'hide' );
268
- } );
269
 
270
- const $iris = $input.next( '.iris-picker' );
271
- const paletteWidth = $palette.outerWidth();
272
- const $visibleColors = $colors.filter( ':visible' );
273
- const index = $visibleColors.index( $obj );
274
-
275
- $iris.css( 'left', ( paletteWidth - 200 ) * index / ( $visibleColors.length - 1 ) );
276
 
277
- $input.iris( 'color', $obj.css( 'color' ) );
278
- $input.iris( 'show' );
279
  } );
280
  } );
281
 
282
  $( 'body' ).on( 'click', function() {
283
- $colors.removeClass( 'active inactive' );
284
- $colors.each( function( i, obj ) {
285
- const $input = $( obj ).data( 'target' );
286
-
287
- $input.iris( 'hide' );
288
- $input.hide();
289
- } );
290
  } );
291
  };
292
 
@@ -305,16 +254,12 @@
305
  const handleColorPalettes = () => {
306
  initializeColorPalettes();
307
  createCurrentPaletteControls();
308
- reloadConnectedFields();
309
  updateCurrentPalette();
310
  bindVariationChange();
311
 
312
  // when variation is changed reload connected fields from cached version of customizer settings config
313
- $( document ).on( 'change', '[name="_customize-radio-sm_color_palette_variation_control"]', function() {
314
- reloadConnectedFields();
315
- resetSettings( settings );
316
- });
317
-
318
  $( document ).on( 'click', '.customify_preset.color_palette input', onPaletteChange );
319
  };
320
 
21
  window.connectedFieldsCallbacks = {};
22
  };
23
 
 
 
 
 
 
 
 
 
 
 
 
24
  const updateCurrentPalette = ( label ) => {
25
  const $palette = $( '.c-palette' );
26
 
37
  // apply the last animate set of colors to the "current" color palette
38
  _.each( settings, function( setting_id ) {
39
  const color = $next.find( '.' + setting_id ).css( 'color' );
40
+ $current.find( '.' + setting_id ).css( 'color', color );
 
41
  });
42
 
43
  // removing the "animate" class will put the "next" color palette out view
82
  };
83
 
84
  const alterConnectedFields = swapMap => {
 
85
  _.each( swapMap, function( fromArray, to ) {
86
  if ( typeof wp.customize.settings.settings[to] !== "undefined" ) {
87
  let newConnectedFields = [];
88
  if ( fromArray instanceof Array ) {
 
89
  _.each( fromArray, function( from ) {
90
  if ( typeof window.settingsClone[from] !== "undefined" ) {
91
  let oldConnectedFields;
99
  newConnectedFields = Object.keys( newConnectedFields ).map( function(key) {
100
  return newConnectedFields[key];
101
  });
102
+ } else {
103
+ newConnectedFields = window.settingsClone[fromArray]['connected_fields'];
104
  }
105
  wp.customize.settings.settings[to]['connected_fields'] = newConnectedFields;
 
 
 
 
 
106
  }
107
  } );
 
 
 
108
  };
109
 
110
  const resetSettings = settings => {
171
  unbindConnectedFields();
172
  alterConnectedFields( variations[variation] );
173
  bindConnectedFields();
174
+ resetSettings( settings );
175
  };
176
 
177
  const createCurrentPaletteControls = () => {
178
  const $palette = $( '.c-palette' );
 
179
 
180
  if ( ! $palette.length ) {
181
  return;
186
  $colors.each( ( i, obj ) => {
187
  const $obj = $( obj );
188
  const setting_id = $obj.data( 'setting' );
 
189
  const setting = wp.customize( setting_id );
190
 
191
+ $obj.iris( {
 
 
192
  change: ( event, ui ) => {
193
  const lastColor = setting();
194
  const currentColor = ui.color.toString();
210
  e.preventDefault();
211
  } );
212
 
213
+ $obj.on( 'click', ( e ) => {
214
  e.stopPropagation();
215
  e.preventDefault();
216
 
217
+ const hidden = ! $obj.find( '.iris-picker' ).is( ":visible" );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
218
 
219
+ if ( hidden ) {
220
+ $colors.not( $obj ).addClass( 'inactive' ).iris( 'hide' );
221
+ $obj.removeClass( 'inactive' );
222
 
223
+ const $iris = $obj.find( '.iris-picker' );
224
+ const paletteWidth = $palette.outerWidth();
225
+ const irisWidth = $iris.outerWidth();
226
 
227
+ $iris.css( 'left', ( paletteWidth - irisWidth ) * i / ( $colors.length - 1 ) );
228
+ } else {
229
+ $colors.removeClass( 'inactive' );
230
+ }
 
 
231
 
232
+ $obj.iris( 'color', $obj.css( 'color' ) );
233
+ $obj.iris( 'toggle' );
234
  } );
235
  } );
236
 
237
  $( 'body' ).on( 'click', function() {
238
+ $colors.removeClass( 'inactive' ).iris( 'hide' );
 
 
 
 
 
 
239
  } );
240
  };
241
 
254
  const handleColorPalettes = () => {
255
  initializeColorPalettes();
256
  createCurrentPaletteControls();
257
+ reloadConnectedFields();
258
  updateCurrentPalette();
259
  bindVariationChange();
260
 
261
  // when variation is changed reload connected fields from cached version of customizer settings config
262
+ $( document ).on( 'change', '[name="_customize-radio-sm_color_palette_variation_control"]', reloadConnectedFields );
 
 
 
 
263
  $( document ).on( 'click', '.customify_preset.color_palette input', onPaletteChange );
264
  };
265
 
js/customizer/font-palettes-variations.js ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ window.fontPalettesVariations = {
2
+ 'light': {
3
+
4
+ },
5
+ 'regular': {
6
+
7
+ },
8
+ 'big': {
9
+
10
+ }
11
+ };
js/customizer/font-palettes.js ADDED
@@ -0,0 +1,350 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ let FontPalettes = ( function( $, exports, wp ) {
2
+
3
+ const masterSettingIds = [
4
+ 'sm_font_primary',
5
+ 'sm_font_secondary',
6
+ 'sm_font_body'
7
+ ];
8
+
9
+ const defaultFontType = 'google';
10
+
11
+ const initializePalettes = () => {
12
+ // Cache initial settings configuration to be able to update connected fields on variation change.
13
+ if ( typeof window.settingsClone === "undefined" ) {
14
+ window.settingsClone = $.extend(true, {}, wp.customize.settings.settings);
15
+ }
16
+
17
+ // Create a stack of callbacks bound to parent settings to be able to unbind them
18
+ // when altering the connected_fields attribute.
19
+ if ( typeof window.connectedFieldsCallbacks === "undefined" ) {
20
+ window.connectedFieldsCallbacks = {};
21
+ }
22
+ };
23
+
24
+ const updateCurrentPalette = ( label ) => {
25
+ const $palette = $( '.c-font-palette' );
26
+
27
+ if ( ! $palette.length ) {
28
+ return;
29
+ }
30
+
31
+ const $current = $palette.find( '.fonts.current' );
32
+ const $next = $palette.find( '.fonts.next' );
33
+
34
+ label = label || 'Custom Style';
35
+ $palette.find( '.c-font-palette__name' ).text( label );
36
+
37
+ // apply the last animate set of fonts to the "current" font palette
38
+ _.each( masterSettingIds, function( setting_id ) {
39
+ const font = $next.find( '.' + setting_id ).css( 'font' );
40
+ $current.find( '.' + setting_id ).css( 'font', font );
41
+ });
42
+
43
+ // removing the "animate" class will put the "next" font palette out view
44
+ // so we can update the fonts in it
45
+ $palette.removeClass( 'animate' );
46
+
47
+ // update the fonts in the "next" palette with the new values
48
+ _.each( masterSettingIds, function( setting_id ) {
49
+ const setting = wp.customize( setting_id );
50
+
51
+ if ( typeof setting !== "undefined" ) {
52
+ $next.find( '.' + setting_id ).css( 'font', setting() );
53
+ }
54
+ });
55
+
56
+ // trigger transition to new font palette
57
+ setTimeout(function() {
58
+ $palette.addClass( 'animate' );
59
+ $palette.find( '.c-font-palette__control' ).css( 'font', wp.customize( 'sm_font_primary' )() );
60
+ });
61
+ };
62
+
63
+ const bindVariationChange = () => {
64
+ const paletteControlSelector = '.c-font-palette__control';
65
+ const $paletteControl = $( paletteControlSelector );
66
+ const variation = wp.customize( 'sm_font_palette_variation' )();
67
+
68
+ if ( _.isUndefined( variation ) || ! $paletteControl.length ) {
69
+ return;
70
+ }
71
+
72
+ $paletteControl.removeClass( 'active' );
73
+ $paletteControl.filter( '.variation-' + variation ).addClass( 'active' );
74
+ $( 'body' ).on( 'click', paletteControlSelector, function() {
75
+ let $obj = $( this ),
76
+ $target = $( $obj.data( 'target' ) );
77
+
78
+ $obj.siblings( paletteControlSelector ).removeClass( 'active' );
79
+ $obj.addClass( 'active' );
80
+ $target.prop( 'checked', true ).trigger( 'change' );
81
+ } );
82
+ };
83
+
84
+ const alterConnectedFields = swapMap => {
85
+ let optionsToShow = [];
86
+ _.each( swapMap, function( fromArray, to ) {
87
+ if ( typeof wp.customize.settings.settings[to] !== "undefined" ) {
88
+ let newConnectedFields = [];
89
+ if ( fromArray instanceof Array ) {
90
+
91
+ _.each( fromArray, function( from ) {
92
+ if ( typeof window.settingsClone[from] !== "undefined" ) {
93
+ let oldConnectedFields;
94
+ if ( ! _.isUndefined( window.settingsClone[from]['connected_fields'] ) ) {
95
+ oldConnectedFields = Object.values( window.settingsClone[from]['connected_fields'] );
96
+ newConnectedFields = newConnectedFields.concat( oldConnectedFields );
97
+ }
98
+ }
99
+ } );
100
+
101
+ newConnectedFields = Object.keys( newConnectedFields ).map( function(key) {
102
+ return newConnectedFields[key];
103
+ });
104
+ }
105
+ wp.customize.settings.settings[to]['connected_fields'] = newConnectedFields;
106
+
107
+
108
+ if ( fromArray instanceof Array && fromArray.length && newConnectedFields.length ) {
109
+ optionsToShow.push( to );
110
+ }
111
+ }
112
+ } );
113
+
114
+ if ( optionsToShow.length ) {
115
+ let optionsSelector = '.' + optionsToShow.join(', .');
116
+ $('.c-font-palette .font').addClass('hidden').filter(optionsSelector).removeClass('hidden');
117
+ }
118
+ };
119
+
120
+ const resetSettings = settings => {
121
+ _.each( settings, function( setting_id ) {
122
+ const setting = wp.customize( setting_id );
123
+
124
+ if ( typeof setting !== "undefined" ) {
125
+ let value = setting();
126
+ setting.set( value + "ff" );
127
+ setting.set( value );
128
+ }
129
+ });
130
+ };
131
+
132
+ const getConnectedFieldsCallback = function (parent_setting_data, parent_setting_id) {
133
+ return function (new_value, old_value) {
134
+ _.each(parent_setting_data.connected_fields, function (connected_field_data) {
135
+ if (_.isUndefined(connected_field_data) || _.isUndefined(connected_field_data.setting_id) || !_.isString(connected_field_data.setting_id) || _.isUndefined(parent_setting_data.fonts_logic)) {
136
+ return;
137
+ }
138
+
139
+ let setting = wp.customize(connected_field_data.setting_id);
140
+ if (_.isUndefined(setting)) {
141
+ return;
142
+ }
143
+
144
+ /* ======================
145
+ * Process the font logic for the master (parent) font control to get the value that should be applied to the connected (font) fields.
146
+ */
147
+ let newFontData = {};
148
+ let fonts_logic = parent_setting_data.fonts_logic;
149
+
150
+ /* ===========
151
+ * We need to determine the 6 subfields values to be able to determine the value of the font field.
152
+ */
153
+
154
+ // The font type is straight forward as it comes directly from the parent field font logic configuration.
155
+ if (typeof fonts_logic.type !== "undefined") {
156
+ newFontData['type'] = fonts_logic.type;
157
+ } else {
158
+ // We use the default
159
+ newFontData['type'] = defaultFontType;
160
+ }
161
+
162
+ // The font family is straight forward as it comes directly from the parent field font logic configuration.
163
+ if (typeof fonts_logic.font_family !== "undefined") {
164
+ newFontData['font_family'] = fonts_logic.font_family;
165
+ }
166
+
167
+ // The selected variants (subsets) also come straight from the font logic right now.
168
+ if (typeof fonts_logic.font_weights !== "undefined") {
169
+ newFontData['variants'] = fonts_logic.font_weights;
170
+ }
171
+
172
+ if (typeof connected_field_data.font_size !== "undefined" && false !== connected_field_data.font_size) {
173
+ newFontData['font_size'] = connected_field_data.font_size;
174
+
175
+ // The font weight (selected_variants), letter spacing and text transform all come together from the font styles (intervals).
176
+ // We just need to find the one that best matches the connected field given font size (if given).
177
+ // Please bear in mind that we expect the font logic styles to be preprocessed, without any overlapping and using numerical keys.
178
+ if (typeof fonts_logic.font_styles !== "undefined" && _.isArray( fonts_logic.font_styles ) && fonts_logic.font_styles.length > 0) {
179
+ let idx = 0;
180
+ while ( idx < fonts_logic.font_styles.length-1 &&
181
+ typeof fonts_logic.font_styles[idx].end !== "undefined" &&
182
+ fonts_logic.font_styles[idx].end <= connected_field_data.font_size.value ) {
183
+ idx++;
184
+ }
185
+
186
+ // We will apply what we've got.
187
+ if (typeof fonts_logic.font_styles[idx].font_weight !== "undefined") {
188
+ newFontData['selected_variants'] = fonts_logic.font_styles[idx].font_weight;
189
+ }
190
+ if (typeof fonts_logic.font_styles[idx].letter_spacing !== "undefined") {
191
+ newFontData['letter_spacing'] = fonts_logic.font_styles[idx].letter_spacing;
192
+ }
193
+ if (typeof fonts_logic.font_styles[idx].text_transform !== "undefined") {
194
+ newFontData['text_transform'] = fonts_logic.font_styles[idx].text_transform;
195
+ }
196
+ }
197
+
198
+ // The line height is determined by getting the value of the polynomial function determined by points.
199
+ if ( typeof fonts_logic.font_size_to_line_height_points !== "undefined" && _.isArray(fonts_logic.font_size_to_line_height_points)) {
200
+ let f = interpolatingPolynomial(fonts_logic.font_size_to_line_height_points);
201
+ newFontData['line_height'] = { value: Number(f(connected_field_data.font_size.value)).toPrecision(2) };
202
+ }
203
+ }
204
+
205
+ let serializedNewFontData = CustomifyFontSelectFields.encodeValues(newFontData);
206
+ setting.set(serializedNewFontData);
207
+ });
208
+ }
209
+ };
210
+
211
+ // Neville's algorithm for polynomial interpolation.
212
+ const interpolatingPolynomial = function (points) {
213
+ let n = points.length - 1, p;
214
+
215
+ p = function (i, j, x) {
216
+ if (i === j) {
217
+ return points[i][1];
218
+ }
219
+
220
+ return ((points[j][0] - x) * p(i, j - 1, x) +
221
+ (x - points[i][0]) * p(i + 1, j, x)) /
222
+ (points[j][0] - points[i][0]);
223
+ };
224
+
225
+ return function (x) {
226
+ if (points.length === 0) {
227
+ return 0;
228
+ }
229
+ return p(0, n, x);
230
+ };
231
+ };
232
+
233
+ const bindConnectedFields = function() {
234
+ _.each( masterSettingIds, function( parent_setting_id ) {
235
+ if ( typeof wp.customize.settings.settings[parent_setting_id] !== "undefined" ) {
236
+ let parent_setting_data = wp.customize.settings.settings[parent_setting_id];
237
+ let parent_setting = wp.customize( parent_setting_id );
238
+
239
+ if ( typeof parent_setting_data.connected_fields !== "undefined" ) {
240
+ connectedFieldsCallbacks[parent_setting_id] = getConnectedFieldsCallback( parent_setting_data, parent_setting_id );
241
+ parent_setting.bind( connectedFieldsCallbacks[parent_setting_id] );
242
+ }
243
+ }
244
+ } );
245
+ };
246
+
247
+ const unbindConnectedFields = function() {
248
+ _.each( masterSettingIds, function( parent_setting_id ) {
249
+ if ( typeof wp.customize.settings.settings[parent_setting_id] !== "undefined" ) {
250
+ let parent_setting_data = wp.customize.settings.settings[parent_setting_id];
251
+ let parent_setting = wp.customize(parent_setting_id);
252
+
253
+ if (typeof parent_setting_data.connected_fields !== "undefined" && typeof connectedFieldsCallbacks[parent_setting_id] !== "undefined") {
254
+ parent_setting.unbind(connectedFieldsCallbacks[parent_setting_id]);
255
+ }
256
+ delete connectedFieldsCallbacks[parent_setting_id];
257
+ }
258
+ } );
259
+ };
260
+
261
+ // Alter connected fields of the master fonts controls depending on the selected palette variation.
262
+ const reloadConnectedFields = () => {
263
+ const setting = wp.customize( 'sm_font_palette_variation' );
264
+
265
+ if ( _.isUndefined( setting ) ) {
266
+ return;
267
+ }
268
+
269
+ const variation = setting();
270
+
271
+ if ( ! window.fontPalettesVariations.hasOwnProperty( variation ) ) {
272
+ return;
273
+ }
274
+
275
+ unbindConnectedFields();
276
+ alterConnectedFields( fontPalettesVariations[variation] );
277
+ bindConnectedFields();
278
+ };
279
+
280
+ const createCurrentPaletteControls = () => {
281
+ let $palette = $( '.c-font-palette' );
282
+
283
+ if ( ! $palette.length ) {
284
+ return;
285
+ }
286
+
287
+ let $fonts = $palette.find( '.fonts.next .font' );
288
+ };
289
+
290
+ const onPaletteChange = function() {
291
+ let $label = $( this ).next( 'label' ).clone();
292
+ let label;
293
+
294
+ $label.find( '.preview__letter' ).remove();
295
+ label = $label.text();
296
+ $label.remove();
297
+
298
+ // Take the fonts config for each setting and distribute it to each (master) setting.
299
+ let data = $( this ).data( 'fonts_logic' );
300
+ if ( ! _.isUndefined( data ) ) {
301
+ $.each( data, function( setting_id, config ) {
302
+ set_field_fonts_logic_config( setting_id, config );
303
+ } );
304
+ }
305
+
306
+ // In case this palette has values (options) attached to it, let it happen.
307
+ $( this ).trigger( 'customify:preset-change' );
308
+ updateCurrentPalette( label );
309
+ };
310
+
311
+ const set_field_fonts_logic_config = function( setting_id, config ) {
312
+ wp.customize.settings.settings[setting_id].fonts_logic = config;
313
+
314
+ // We also need to trigger a fake setting value change since the master font controls don't usually hold a (usable) value.
315
+ let setting = wp.customize( setting_id );
316
+ if ( _.isUndefined( setting ) ) {
317
+ return;
318
+ }
319
+
320
+ // We will set the entire config as the master font field value just because it ensures us that,
321
+ // when new info arrives, the setting callbacks will be fired (.set() doesn't do anything if the new value is the same as the old).
322
+ // Also some entries will be used to set the master font subfields (mainly font family).
323
+ // This value is not used in any other way!
324
+ let serializedNewFontData = CustomifyFontSelectFields.encodeValues(config);
325
+ setting.set(serializedNewFontData);
326
+ };
327
+
328
+ const handlePalettes = () => {
329
+ initializePalettes();
330
+ createCurrentPaletteControls();
331
+ reloadConnectedFields();
332
+ updateCurrentPalette();
333
+ bindVariationChange();
334
+
335
+ // when variation is changed reload connected fields from cached version of customizer settings config
336
+ $( document ).on( 'change', '[name="_customize-radio-sm_font_palette_variation_control"]', function() {
337
+ reloadConnectedFields();
338
+ resetSettings( masterSettingIds );
339
+ });
340
+
341
+ $( document ).on( 'click', '.customify_preset.font_palette input', onPaletteChange );
342
+ };
343
+
344
+ wp.customize.bind( 'ready', handlePalettes );
345
+
346
+ return {
347
+ masterSettingIds: masterSettingIds
348
+ };
349
+
350
+ } )( jQuery, window, wp );
js/customizer/font-select-fields.js ADDED
@@ -0,0 +1,449 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // This is for the Customizer Font control
2
+ let CustomifyFontSelectFields = ( function( $, exports, wp ) {
3
+ const
4
+ wrapperSelector = '.font-options__wrapper',
5
+ valueHolderSelector = '.customify_font_values',
6
+ fontFamilySelector = '.customify_font_family',
7
+ fontWeightSelector = '.customify_font_weight',
8
+ fontSubsetsSelector = '.customify_font_subsets',
9
+ selectPlaceholder = "Select a font family",
10
+ weightPlaceholder = "Select a font weight",
11
+ subsetPlaceholder = "Extra Subsets";
12
+
13
+ // We will use this to remember that we are self-updating the field from the subfields.
14
+ // We will save this info for each setting ID.
15
+ var updatingValue = {},
16
+ loadingValue = {};
17
+
18
+ function init() {
19
+ let $fontFamilyFields = $( fontFamilySelector );
20
+
21
+ // Initialize the select2 field for the font family
22
+ $fontFamilyFields.select2( {
23
+ placeholder: selectPlaceholder
24
+ } ).on( 'change', function( e ) {
25
+ let new_option = $( e.target ).find( 'option:selected' ),
26
+ wrapper = $( e.target ).closest( wrapperSelector );
27
+
28
+ // Update the weight subfield with the new options given by the selected font family.
29
+ updateWeightField( new_option, wrapper );
30
+
31
+ // Update the subset subfield with the new options given by the selected font family.
32
+ updateSubsetField( new_option, wrapper );
33
+
34
+ // Serialize subfield values and refresh the fonts in the preview window.
35
+ selfUpdateValue( wrapper );
36
+ } );
37
+
38
+ // Initialize the select2 field for the font weight
39
+ $( fontWeightSelector ).each( function( i, el ) {
40
+
41
+ let select2_args = {
42
+ placeholder: weightPlaceholder
43
+ };
44
+
45
+ // all this fuss is for the case when the font doesn't come with variants from PHP, like a theme_font
46
+ if ( this.options.length === 0 ) {
47
+ let wrapper = $( el ).closest( wrapperSelector ),
48
+ font = wrapper.find( fontFamilySelector ),
49
+ option = font[0].options[font[0].selectedIndex],
50
+ variants = maybeJsonParse( $( option ).data( 'variants' ) ),
51
+ data = [],
52
+ selecter_variants = $( el ).data( 'default' ) || null;
53
+
54
+ if ( typeof variants === "undefined" ) {
55
+ $( this ).hide();
56
+ return;
57
+ }
58
+
59
+ $.each( variants, function( index, weight ) {
60
+ let this_value = {
61
+ id: weight,
62
+ text: weight
63
+ };
64
+
65
+ if ( selecter_variants !== null && weight == selecter_variants ) {
66
+ this_value.selected = true;
67
+ }
68
+
69
+ data.push( this_value );
70
+ } );
71
+
72
+ if ( data !== [] ) {
73
+ select2_args.data = data;
74
+ }
75
+ }
76
+
77
+ $( this ).select2(
78
+ select2_args
79
+ ).on( 'change', function( e ) {
80
+ let wrapper = $( e.target ).closest( wrapperSelector );
81
+
82
+ // Serialize subfield values and refresh the fonts in the preview window.
83
+ selfUpdateValue( wrapper );
84
+ } );
85
+ } );
86
+
87
+ // Initialize the select2 field for the font subsets
88
+ $( fontSubsetsSelector )
89
+ .select2( {
90
+ placeholder: subsetPlaceholder
91
+ } )
92
+ .on( 'change', function( e ) {
93
+ let wrapper = $( e.target ).closest( wrapperSelector );
94
+
95
+ // Serialize subfield values and refresh the fonts in the preview window.
96
+ selfUpdateValue( wrapper );
97
+ } );
98
+
99
+ let rangers = $fontFamilyFields.parents( wrapperSelector ).find( 'input[type=range]' ),
100
+ selects = $fontFamilyFields.parents( wrapperSelector ).find( 'select' ).not( "select[class*=' select2'],select[class^='select2']" );
101
+
102
+ // Initialize the all the regular selects in the font controls
103
+ if ( selects.length > 0 ) {
104
+ selects.on( 'change', function( e ) {
105
+ let wrapper = $( e.target ).closest( wrapperSelector );
106
+
107
+ // Serialize subfield values and refresh the fonts in the preview window.
108
+ selfUpdateValue( wrapper );
109
+ } );
110
+ }
111
+
112
+ // Initialize the all the range fields in the font controls
113
+ if ( rangers.length > 0 ) {
114
+ rangers.on( 'change', function( e ) {
115
+ let wrapper = $( e.target ).closest( wrapperSelector );
116
+
117
+ // Serialize subfield values and refresh the fonts in the preview window.
118
+ selfUpdateValue( wrapper );
119
+
120
+ wp.customize.previewer.send( 'font-changed' );
121
+ } );
122
+ }
123
+
124
+ // When the previewer window is ready, render the fonts
125
+ var self = this;
126
+ wp.customize.previewer.bind( 'ready', function() {
127
+ self.renderFonts();
128
+ } );
129
+
130
+ // Handle the reverse value direction, when the customize setting is updated and the subfields need to update their values.
131
+ $fontFamilyFields.each( function( i, el ) {
132
+ let wrapper = $( el ).closest( wrapperSelector ),
133
+ value_holder = wrapper.children( valueHolderSelector ),
134
+ setting_id = $( value_holder ).data( 'customize-setting-link' ),
135
+ setting = wp.customize( setting_id );
136
+
137
+ setting.bind( function( newValue, oldValue ) {
138
+ if ( ! updatingValue[this.id] ) {
139
+ value_holder.val( newValue );
140
+
141
+ loadFontValue( wrapper );
142
+ }
143
+ } )
144
+ } )
145
+ }
146
+
147
+ /**
148
+ * This function updates the data in font weight selector from the given <option> element
149
+ *
150
+ * @param option
151
+ * @param wraper
152
+ */
153
+ function updateWeightField( option, wraper ) {
154
+ let variants = $( option ).data( 'variants' ),
155
+ font_weights = wraper.find( fontWeightSelector ),
156
+ selected_variant = font_weights.val() ? font_weights.val() : font_weights.data( 'default' ),
157
+ new_variants = [],
158
+ id = wraper.find( valueHolderSelector ).data( 'customizeSettingLink' );
159
+
160
+ variants = maybeJsonParse( variants );
161
+
162
+ if ( customify_settings.settings[id].load_all_weights || typeof variants === "undefined" || Object.keys( variants ).length < 2 || font_weights.data('disabled') !== undefined ) {
163
+ font_weights.parent().hide();
164
+ } else {
165
+ font_weights.parent().show();
166
+ }
167
+
168
+ // we need to turn the data array into a specific form like [{id:"id", text:"Text"}]
169
+ $.each( variants, function( index, variant ) {
170
+ new_variants[index] = {
171
+ 'id': variant,
172
+ 'text': variant
173
+ };
174
+
175
+ if ( selected_variant == variant ) {
176
+ new_variants[index].selected = true;
177
+ }
178
+ } );
179
+
180
+ // We need to clear the old select2 field and reinitialize it.
181
+ $( font_weights ).select2().empty();
182
+ $( font_weights ).select2( {
183
+ data: new_variants
184
+ } ).on( 'change', function( e ) {
185
+ let wrapper = $( e.target ).closest( wrapperSelector );
186
+
187
+ // Serialize subfield values and refresh the fonts in the preview window.
188
+ selfUpdateValue( wrapper );
189
+ } );
190
+ }
191
+
192
+ /**
193
+ * This function updates the data in font subset selector from the given <option> element
194
+ * @param option
195
+ * @param wraper
196
+ */
197
+ function updateSubsetField( option, wraper ) {
198
+ let subsets = $( option ).data( 'subsets' ),
199
+ font_subsets = wraper.find( fontSubsetsSelector ),
200
+ new_subsets = [],
201
+ type = $( option ).data( 'type' );
202
+
203
+ if ( type !== 'google' ) {
204
+ font_subsets.parent().hide();
205
+ return;
206
+ }
207
+
208
+ let current_value = wraper.children( valueHolderSelector ).val();
209
+
210
+ current_value = maybeJsonParse( current_value );
211
+ if ( _.isUndefined( current_value.selected_subsets ) ) {
212
+ return;
213
+ }
214
+ current_value = current_value.selected_subsets;
215
+
216
+ subsets = maybeJsonParse( subsets );
217
+
218
+ if ( typeof subsets !== "undefined" && Object.keys( subsets ).length < 2 || font_subsets.data('disabled') !== undefined ) {
219
+ font_subsets.parent().hide();
220
+ } else {
221
+ font_subsets.parent().show();
222
+ }
223
+
224
+ // we need to turn the data array into a specific form like [{id:"id", text:"Text"}]
225
+ $.each( subsets, function( index, subset ) {
226
+ new_subsets[index] = {
227
+ 'id': subset,
228
+ 'text': subset
229
+ };
230
+
231
+ // current_subsets
232
+ if ( typeof current_value !== "undefined" && current_value !== null && current_value.indexOf( subset ) !== - 1 ) {
233
+ new_subsets[index].selected = true;
234
+ }
235
+ } );
236
+
237
+ // We need to clear the old select2 field and reinitialize it.
238
+ $( font_subsets ).select2().empty();
239
+ $( font_subsets ).select2( {
240
+ data: new_subsets
241
+ } ).on( 'change', function( e ) {
242
+ let wrapper = $( e.target ).closest( wrapperSelector );
243
+
244
+ // Serialize subfield values and refresh the fonts in the preview window.
245
+ selfUpdateValue( wrapper );
246
+ } );
247
+ }
248
+
249
+ function getValue( wrapper ) {
250
+ let value_holder = wrapper.children( valueHolderSelector );
251
+
252
+ if ( value_holder.length ) {
253
+ return maybeJsonParse( value_holder.val() );
254
+ }
255
+
256
+ return [];
257
+ }
258
+
259
+ function updateValue( wrapper, value ) {
260
+ let value_holder = wrapper.children( valueHolderSelector ),
261
+ setting_id = $( value_holder ).data( 'customize-setting-link' ),
262
+ setting = wp.customize( setting_id );
263
+
264
+ if ( ! value_holder.length ) {
265
+ return;
266
+ }
267
+
268
+ if ( _.isArrayLikeObject( value ) ) {
269
+ value = encodeValues( value );
270
+ }
271
+
272
+ // Set the serialized value in the hidden field.
273
+ value_holder.val( value );
274
+ // Update also the Customizer setting value.
275
+ setting.set( value );
276
+ }
277
+
278
+ /**
279
+ * This function is a custom value serializer for our entire font field
280
+ * It collects values and saves them (encoded) into the `.customify_font_values` input's value
281
+ */
282
+ function selfUpdateValue( wrapper ) {
283
+ let options_list = $( wrapper ).find( '.font-options__options-list' ),
284
+ inputs = options_list.find( '[data-field]' ),
285
+ value_holder = wrapper.children( valueHolderSelector ),
286
+ setting_id = $( value_holder ).data( 'customize-setting-link' ),
287
+ setting = wp.customize( setting_id ),
288
+ newFontData = {};
289
+
290
+ // If we are already self-updating this and we haven't finished, we need to stop here to prevent infinite loops
291
+ // This call might have come from a subfield detecting the change the triggering a further update_font_value()
292
+ if ( true === updatingValue[setting_id] ) {
293
+ return;
294
+ }
295
+
296
+ // If we are loading this setting value and haven't finished, there is no point in updating it as this would cause infinite loops.
297
+ if ( true === loadingValue[setting_id] ) {
298
+ return;
299
+ }
300
+
301
+ // Mark the fact that we are self-updating the field value
302
+ updatingValue[setting_id] = true;
303
+
304
+ inputs.each( function( key, el ) {
305
+ let field = $( el ).data( 'field' ),
306
+ value = $( el ).val();
307
+
308
+ if ( 'font_family' === field ) {
309
+ // the font family also holds the type
310
+ let selected_opt = $( el.options[el.selectedIndex] ),
311
+ type = selected_opt.data( 'type' ),
312
+ subsets = selected_opt.data( 'subsets' ),
313
+ variants = selected_opt.data( 'variants' );
314
+
315
+ if ( ! _.isUndefined( type ) ) {
316
+ newFontData['type'] = type;
317
+ if ( type === 'theme_font' ) {
318
+ newFontData['src'] = selected_opt.data( 'src' );
319
+ }
320
+ }
321
+
322
+ if ( ! _.isUndefined( variants ) ) {
323
+ newFontData['variants'] = maybeJsonParse( variants );
324
+ }
325
+
326
+ if ( ! _.isUndefined( subsets ) ) {
327
+ newFontData['subsets'] = maybeJsonParse( subsets );
328
+ }
329
+ }
330
+
331
+ if ( ! _.isUndefined( field ) && ! _.isUndefined( value ) && ! _.isNull( value ) && value !== '' ) {
332
+ newFontData[field] = value;
333
+ }
334
+ } );
335
+
336
+ // Serialize the newly gathered font data
337
+ let serializedNewFontData = encodeValues( newFontData );
338
+ // Set the serialized value in the hidden field.
339
+ value_holder.val( serializedNewFontData );
340
+ // Update also the Customizer setting value.
341
+ setting.set( serializedNewFontData );
342
+
343
+
344
+ // Finished with the field value self-updating.
345
+ updatingValue[setting_id] = false;
346
+
347
+ return newFontData;
348
+ }
349
+
350
+ /**
351
+ * This function is a reverse of update_font_value(), initializing the entire font field controls based on the value stored in the hidden input.
352
+ */
353
+ function loadFontValue( wrapper ) {
354
+ let options_list = $( wrapper ).find( '.font-options__options-list' ),
355
+ inputs = options_list.find( '[data-field]' ),
356
+ value_holder = wrapper.children( valueHolderSelector ),
357
+ value = maybeJsonParse( value_holder.val() ),
358
+ setting_id = $( value_holder ).data( 'customize-setting-link' );
359
+
360
+ // If we are already loading this setting value and haven't finished, there is no point in starting again.
361
+ if ( true === loadingValue[setting_id] ) {
362
+ return;
363
+ }
364
+
365
+ // Mark the fact that we are loading the field value
366
+ loadingValue[setting_id] = true;
367
+
368
+ inputs.each( function( key, el ) {
369
+ let field = $( el ).data( 'field' );
370
+
371
+ // In the case of select2, only the original selects have the data field, thus excluding select2 created select DOM elements
372
+ if ( typeof field !== "undefined" && field !== "" && typeof value[field] !== "undefined" ) {
373
+ // If the value contains also the unit (it is not a number) we need to split it and change the subfield accordingly.
374
+ let cleanValue = value[field],
375
+ unit = '';
376
+ // We will do this only for numerical fields.
377
+ if ( _.contains( ['letter_spacing','line_height', 'font_size'], field ) && isNaN( cleanValue ) ) {
378
+ // If we have a standardized value field (as array), use that.
379
+ if ( typeof cleanValue.value !== "undefined" ) {
380
+ if ( typeof cleanValue.unit !== "undefined" ) {
381
+ unit = cleanValue.unit;
382
+ }
383
+
384
+ cleanValue = cleanValue.value;
385
+ } else {
386
+ // Treat the case when the value is a string.
387
+ let matches = cleanValue.match(/^([\d.\-+]+)(.+)/i);
388
+ if (matches !== null && typeof matches[1] !== "undefined") {
389
+ cleanValue = matches[1];
390
+ unit = matches[2];
391
+ }
392
+ }
393
+ }
394
+
395
+ if ( unit !== '' ) {
396
+ $( el ).attr( 'unit', unit );
397
+ }
398
+
399
+ // If this field has a min/max attribute we need to make sure that those attributes allow for the value we are trying to impose.
400
+ // But only for numerical values.
401
+ if ( ! isNaN( cleanValue ) ) {
402
+ if ( $(el).attr('min') && $(el).attr('min') > cleanValue ) {
403
+ $(el).attr('min', cleanValue );
404
+ }
405
+ if ( $(el).attr('max') && $(el).attr('max') < cleanValue ) {
406
+ $(el).attr('max', cleanValue );
407
+ }
408
+ }
409
+
410
+ $( el ).val( cleanValue ).trigger( 'change' );
411
+ }
412
+ } );
413
+
414
+ // Finished with the field value loading.
415
+ loadingValue[setting_id] = false;
416
+ }
417
+
418
+ const maybeJsonParse = function( value ) {
419
+ let parsed;
420
+
421
+ //try and parse it, with decodeURIComponent
422
+ try {
423
+ parsed = JSON.parse( decodeURIComponent( value ) );
424
+ } catch ( e ) {
425
+
426
+ // in case of an error, treat is as a string
427
+ parsed = value;
428
+ }
429
+
430
+ return parsed;
431
+ };
432
+
433
+ const encodeValues = function( obj ) {
434
+ return encodeURIComponent( JSON.stringify( obj ) );
435
+ };
436
+
437
+ const renderFonts = function() {
438
+ $( '.customify_font_family' ).select2().trigger( 'change' )
439
+ };
440
+
441
+ return {
442
+ renderFonts: renderFonts,
443
+ init: init,
444
+ getValue: getValue,
445
+ updateValue: updateValue,
446
+ selfUpdateValue: selfUpdateValue,
447
+ encodeValues: encodeValues,
448
+ };
449
+ } )( jQuery, window, wp );
js/customizer/scale-iframe.js ADDED
@@ -0,0 +1,55 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ( function( $, exports, wp ) {
2
+ const api = wp.customize;
3
+ const $window = $( window );
4
+ const $previewIframe = $( '.wp-full-overlay' );
5
+
6
+ const scaleIframe = function() {
7
+
8
+ // remove CSS properties that may have been previously added
9
+ $previewIframe.find( 'iframe' ).css( {
10
+ width: '',
11
+ height: '',
12
+ transformOrigin: '',
13
+ transform: ''
14
+ } );
15
+
16
+ // scaling of the site preview should be done only in desktop preview mode
17
+ if ( api.previewedDevice.get() !== 'desktop' ) {
18
+ return;
19
+ }
20
+
21
+ const iframeWidth = $previewIframe.width();
22
+ const windowWidth = $window.width();
23
+ const windowHeight = $window.height();
24
+
25
+ // get the ratio between the site preview and actual browser width
26
+ const scale = windowWidth / iframeWidth;
27
+
28
+ // for an accurate preview at resolutions where media queries may intervene
29
+ // increase the width of the iframe and use CSS transforms to scale it back down
30
+ if ( iframeWidth > 720 && iframeWidth < 1100 ) {
31
+ $previewIframe.find( 'iframe' ).css( {
32
+ width: iframeWidth * scale,
33
+ height: windowHeight * scale,
34
+ transformOrigin: 'left top',
35
+ transform: 'scale(' + 1 / scale + ')'
36
+ } );
37
+ }
38
+ };
39
+
40
+ wp.customize.bind( 'ready', function() {
41
+
42
+ wp.customize.previewer.bind( 'synced', function() {
43
+ scaleIframe();
44
+
45
+ api.previewedDevice.bind( scaleIframe );
46
+ $window.on( 'resize', scaleIframe );
47
+ } );
48
+
49
+ $( '.collapse-sidebar' ).on( 'click', function() {
50
+ setTimeout( scaleIframe, 300 );
51
+ } );
52
+
53
+ } );
54
+
55
+ } )( jQuery, window, wp );
js/customizer/style-manager.js ADDED
@@ -0,0 +1,158 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ (
2
+ function( $, exports, wp ) {
3
+ var api = wp.customize;
4
+ var $window = $( window );
5
+
6
+ wp.customize.bind( 'ready', function() {
7
+
8
+ // Handle the Style Manager user feedback logic.
9
+ var $styleManagerUserFeedbackModal = $('#style-manager-user-feedback-modal');
10
+ if ( $styleManagerUserFeedbackModal.length ) {
11
+ var $styleManagerUserFeedbackForm = $styleManagerUserFeedbackModal.find('form'),
12
+ $styleManagerUserFeedbackCloseBtn = $styleManagerUserFeedbackModal.find('.close'),
13
+ $styleManagerUserFeedbackFirstStep = $styleManagerUserFeedbackModal.find('.first-step'),
14
+ $styleManagerUserFeedbackSecondStep = $styleManagerUserFeedbackModal.find('.second-step'),
15
+ $styleManagerUserFeedbackThanksStep = $styleManagerUserFeedbackModal.find('.thanks-step'),
16
+ $styleManagerUserFeedbackErrorStep = $styleManagerUserFeedbackModal.find('.error-step'),
17
+ styleManagerUserFeedbackModalShown = false,
18
+ styleManagerColorPaletteChanged = false;
19
+
20
+ // Handle when to open the modal.
21
+ api.bind('saved', function () {
22
+ // We will only show the modal once per Customizer session.
23
+ if (!styleManagerUserFeedbackModalShown && styleManagerColorPaletteChanged) {
24
+ $('body').addClass('modal-open');
25
+ styleManagerUserFeedbackModalShown = true;
26
+ }
27
+ });
28
+
29
+ // Handle the color palette changed info update.
30
+ const colorPaletteSetting = api( 'sm_color_palette' );
31
+ if ( !_.isUndefined(colorPaletteSetting) ) {
32
+ colorPaletteSetting.bind( function( new_value, old_value ) {
33
+ if ( new_value != old_value ) {
34
+ styleManagerColorPaletteChanged = true;
35
+ }
36
+ } )
37
+ }
38
+ const colorPaletteVariationSetting = api( 'sm_color_palette_variation' );
39
+ if ( !_.isUndefined(colorPaletteVariationSetting) ) {
40
+ colorPaletteVariationSetting.bind( function( new_value, old_value ) {
41
+ if ( new_value != old_value ) {
42
+ styleManagerColorPaletteChanged = true;
43
+ }
44
+ } )
45
+ }
46
+
47
+ // Handle the modal submit.
48
+ $styleManagerUserFeedbackForm.on('submit', function (event) {
49
+ event.preventDefault();
50
+
51
+ let $form = $(event.target);
52
+
53
+ let data = {
54
+ action: 'customify_style_manager_user_feedback',
55
+ nonce: customify_settings.style_manager_user_feedback_nonce,
56
+ type: $form.find('input[name=type]').val(),
57
+ rating: $form.find('input[name=rating]:checked').val(),
58
+ message: $form.find('textarea[name=message]').val()
59
+ };
60
+
61
+ $.post(
62
+ customify_settings.ajax_url,
63
+ data,
64
+ function (response) {
65
+ if (true === response.success) {
66
+ $styleManagerUserFeedbackFirstStep.hide();
67
+ $styleManagerUserFeedbackSecondStep.hide();
68
+ $styleManagerUserFeedbackThanksStep.show();
69
+ $styleManagerUserFeedbackErrorStep.hide();
70
+ } else {
71
+ $styleManagerUserFeedbackFirstStep.hide();
72
+ $styleManagerUserFeedbackSecondStep.hide();
73
+ $styleManagerUserFeedbackThanksStep.hide();
74
+ $styleManagerUserFeedbackErrorStep.show();
75
+ }
76
+ }
77
+ );
78
+ });
79
+
80
+ $styleManagerUserFeedbackForm.find('input[name=rating]').on('change', function (event) {
81
+ // Leave everything in working order
82
+ setTimeout(function () {
83
+ $styleManagerUserFeedbackSecondStep.show();
84
+ }, 300);
85
+
86
+ let rating = $styleManagerUserFeedbackForm.find('input[name=rating]:checked').val();
87
+
88
+ $styleManagerUserFeedbackForm.find('.rating-placeholder').text(rating);
89
+ });
90
+
91
+ $styleManagerUserFeedbackCloseBtn.on('click', function (event) {
92
+ event.preventDefault();
93
+
94
+ $('body').removeClass('modal-open');
95
+
96
+ // Leave everything in working order
97
+ setTimeout(function () {
98
+ $styleManagerUserFeedbackFirstStep.show();
99
+ $styleManagerUserFeedbackSecondStep.hide();
100
+ $styleManagerUserFeedbackThanksStep.hide();
101
+ $styleManagerUserFeedbackErrorStep.hide();
102
+ }, 300);
103
+ });
104
+ }
105
+ } );
106
+ }
107
+ )( jQuery, window, wp );
108
+
109
+
110
+ // Reverses a hex color to either black or white
111
+ function customifyInverseHexColorToBlackOrWhite( hex ) {
112
+ return customifyInverseHexColor( hex, true );
113
+ }
114
+
115
+ // Taken from here: https://stackoverflow.com/a/35970186/6260836
116
+ function customifyInverseHexColor( hex, bw ) {
117
+ if ( hex.indexOf( '#' ) === 0 ) {
118
+ hex = hex.slice( 1 );
119
+ }
120
+ // convert 3-digit hex to 6-digits.
121
+ if ( hex.length === 3 ) {
122
+ hex = hex[0] + hex[0] + hex[1] + hex[1] + hex[2] + hex[2];
123
+ }
124
+ if ( hex.length !== 6 ) {
125
+ throw new Error( 'Invalid HEX color.' );
126
+ }
127
+ var r = parseInt( hex.slice( 0, 2 ), 16 ),
128
+ g = parseInt( hex.slice( 2, 4 ), 16 ),
129
+ b = parseInt( hex.slice( 4, 6 ), 16 );
130
+ if ( bw ) {
131
+ // http://stackoverflow.com/a/3943023/112731
132
+ return (
133
+ r * 0.299 + g * 0.587 + b * 0.114
134
+ ) > 186
135
+ ? '#000000'
136
+ : '#FFFFFF';
137
+ }
138
+ // invert color components
139
+ r = (
140
+ 255 - r
141
+ ).toString( 16 );
142
+ g = (
143
+ 255 - g
144
+ ).toString( 16 );
145
+ b = (
146
+ 255 - b
147
+ ).toString( 16 );
148
+ // pad each with zeros and return
149
+ return "#" + customifyPadZero( r ) + customifyPadZero( g ) + customifyPadZero( b );
150
+ }
151
+
152
+ function customifyPadZero( str, len ) {
153
+ len = len || 2;
154
+ var zeros = new Array( len ).join( '0' );
155
+ return (
156
+ zeros + str
157
+ ).slice( - len );
158
+ }
js/customizer/swap-values.js ADDED
@@ -0,0 +1,45 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ( function( $, exports, wp ) {
2
+
3
+ function swap_values( setting_one, setting_two ) {
4
+ var color_primary = wp.customize( setting_one )();
5
+ var color_secondary = wp.customize( setting_two )();
6
+
7
+ wp.customize( setting_one ).set( color_secondary );
8
+ wp.customize( setting_two ).set( color_primary );
9
+ }
10
+
11
+ wp.customize.bind( 'ready', function() {
12
+ const $document = $( document );
13
+
14
+ $document.on( 'click', '[data-action="sm_swap_colors"]', function( e ) {
15
+ e.preventDefault();
16
+ swap_values( 'sm_color_primary', 'sm_color_secondary' );
17
+ } );
18
+
19
+ $document.on( 'click', '[data-action="sm_swap_dark_light"]', function( e ) {
20
+ e.preventDefault();
21
+ swap_values( 'sm_dark_primary', 'sm_light_primary' );
22
+ swap_values( 'sm_dark_secondary', 'sm_light_secondary' );
23
+ swap_values( 'sm_dark_tertiary', 'sm_light_tertiary' );
24
+ } );
25
+
26
+ $document.on( 'click', '[data-action="sm_swap_colors_dark"]', function( e ) {
27
+ e.preventDefault();
28
+ swap_values( 'sm_color_primary', 'sm_dark_primary' );
29
+ swap_values( 'sm_color_secondary', 'sm_dark_secondary' );
30
+ swap_values( 'sm_color_tertiary', 'sm_dark_tertiary' );
31
+ } );
32
+
33
+ $document.on( 'click', '[data-action="sm_swap_secondary_colors_dark"]', function( e ) {
34
+ e.preventDefault();
35
+ swap_values( 'sm_color_secondary', 'sm_dark_secondary' );
36
+ } );
37
+
38
+ $document.on( 'click', '[data-action="sm_toggle_advanced_settings"]', function( e ) {
39
+ e.preventDefault();
40
+ $( '#sub-accordion-section-sm_color_palettes_section' ).toggleClass( 'advanced' );
41
+ } );
42
+
43
+ } );
44
+
45
+ } )( jQuery, window, wp );
js/customizer_preview.js CHANGED
@@ -1,6 +1,6 @@
1
  ;(function ($, window, document, undefined) {
2
 
3
- var fonts_cache = [];
4
 
5
  $(document).ready(function () {
6
  var api = parent.wp.customize,
@@ -15,25 +15,27 @@
15
  setting.bind(function (to) {
16
  let $values = maybeJsonParse(to);
17
 
18
- if (typeof $values.font_family !== "undefined") {
19
- maybeLoadFontFamily($values);
20
- }
 
21
 
22
- let vls = get_CSS_values(this.id, $values),
23
- CSS = get_CSS_code(this.id, vls),
24
- field_style = $('#customify_font_output_for_' + el.html_safe_option_id);
25
 
26
- field_style.html(CSS);
 
27
  });
28
  });
29
 
30
- } else if (typeof wp_settings[key] !== "undefined" && typeof el.css !== "undefined" && typeof el.live !== 'undefined' && el.live === true) {
31
  api(key, function (setting) {
32
 
33
  setting.bind(function (to) {
34
 
35
  $.each(el.css, function (counter, property_config) {
36
- var properties = [];
37
 
38
  properties[property_config.property] = property_config.selector;
39
  if (typeof property_config.callback_filter !== "undefined") {
@@ -101,34 +103,34 @@
101
 
102
  function load_webfont_once() {
103
  if (typeof WebFont === "undefined") {
104
- var tk = document.createElement('script');
105
  tk.src = '//ajax.googleapis.com/ajax/libs/webfont/1/webfont.js';
106
  tk.type = 'text/javascript';
107
- var s = document.getElementsByTagName('script')[0];
108
  s.parentNode.insertBefore(tk, s);
109
  }
110
  }
111
 
112
- var get_CSS_values = function (ID, $values) {
113
 
114
- var store = {};
115
 
116
- if (typeof $values.font_family !== "undefined") {
117
- store['font-family'] = $values.font_family;
118
  }
119
 
120
- if (typeof $values.selected_variants !== "undefined") {
121
 
122
- var variants = null;
123
 
124
- if (typeof $values.selected_variants !== "undefined" && $values.selected_variants !== null) {
125
- variants = $values.selected_variants;
126
- } else if (typeof $values.variants !== "undefined" && typeof $values.variants[0] !== "undefined") {
127
- variants = $values.variants[0];
128
  }
129
 
130
  // google fonts also have the italic string inside, split that
131
- if (variants !== null && variants.indexOf('italic') !== -1) {
132
  store['font-style'] = 'italic';
133
  variants = variants.replace('italic', '');
134
  }
@@ -142,52 +144,94 @@
142
  }
143
  }
144
 
145
- if (typeof $values.font_size !== "undefined") {
146
- store['font-size'] = $values.font_size + get_field_unit(ID, 'font-size');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
147
  }
148
 
149
- if (typeof $values.letter_spacing !== "undefined") {
150
- store['letter-spacing'] = $values.letter_spacing + get_field_unit(ID, 'letter-spacing');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
151
  }
152
 
153
- if (typeof $values.line_height !== "undefined") {
154
- store['line-height'] = $values.line_height + get_field_unit(ID, 'line-height');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
155
  }
156
 
157
- if (typeof $values.text_align !== "undefined") {
158
- store['text-align'] = $values.text_align;
159
  }
160
 
161
- if (typeof $values.text_transform !== "undefined") {
162
- store['text-transform'] = $values.text_transform;
163
  }
164
- if (typeof $values.text_decoration !== "undefined") {
165
- store['text-decoration'] = $values.text_decoration;
166
  }
167
 
168
  return store;
169
  };
170
 
171
- var get_CSS_code = function (ID, $values) {
172
 
173
- var field = customify_settings.settings[ID];
174
- var output = '';
175
 
176
  if (typeof window !== "undefined" && typeof field.callback !== "undefined" && typeof window[field.callback] === "function") {
177
- output = window[field.callback]($values, field);
178
  } else {
179
  output = field.selector + "{\n";
180
- $.each($values, function (k, v) {
181
  output += k + ': ' + v + ";\n";
182
- })
183
  output += "}\n";
184
  }
185
 
186
  return output;
187
  };
188
 
189
- var get_field_unit = function (ID, field) {
190
- var unit = 'px';
191
  if (typeof customify_settings.settings[ID] === "undefined" || typeof customify_settings.settings[ID].fields[field] === "undefined") {
192
  return unit;
193
  }
@@ -198,18 +242,23 @@
198
  // in case of an associative array
199
  return customify_settings.settings[ID].fields[field][3];
200
  }
201
- }
202
 
203
- var maybeLoadFontFamily = function (font) {
204
 
205
  if (typeof WebFont === "undefined") {
206
- var tk = document.createElement('script');
207
  tk.src = '//ajax.googleapis.com/ajax/libs/webfont/1/webfont.js';
208
  tk.type = 'text/javascript';
209
- var s = document.getElementsByTagName('script')[0];
210
  s.parentNode.insertBefore(tk, s);
211
  }
212
 
 
 
 
 
 
213
  if (font.type === 'theme_font') {
214
  WebFont.load({
215
  custom: {
@@ -218,16 +267,20 @@
218
  }
219
  });
220
  } else if (font.type === 'google') {
221
- var family = font.font_family,
222
  variants = null,
223
  subsets = null;
224
 
225
  if (typeof font.variants !== "undefined") {
226
  variants = maybeJsonParse(font.variants);
227
 
 
 
 
 
228
  $.each(variants, function (k, v) {
229
 
230
- if (k === "0") {
231
  family = family + ':';
232
  }
233
 
@@ -280,10 +333,14 @@
280
  } else {
281
  // else what?
282
  }
283
- }
 
 
 
284
 
285
- var maybeJsonParse = function (value) {
286
- var parsed;
 
287
 
288
  //try and parse it, with decodeURIComponent
289
  try {
1
  ;(function ($, window, document, undefined) {
2
 
3
+ const fonts_cache = [];
4
 
5
  $(document).ready(function () {
6
  var api = parent.wp.customize,
15
  setting.bind(function (to) {
16
  let $values = maybeJsonParse(to);
17
 
18
+ if (typeof $values !== "undefined" ) {
19
+ if (typeof $values.font_family !== "undefined") {
20
+ maybeLoadFontFamily($values);
21
+ }
22
 
23
+ let vls = get_CSS_values(this.id, $values),
24
+ CSS = get_CSS_code(this.id, vls),
25
+ field_style = $('#customify_font_output_for_' + el.html_safe_option_id);
26
 
27
+ field_style.html(CSS);
28
+ }
29
  });
30
  });
31
 
32
+ } else if (typeof wp_settings !== "undefined" && typeof wp_settings[key] !== "undefined" && typeof el.css !== "undefined" && typeof el.live !== 'undefined' && el.live === true) {
33
  api(key, function (setting) {
34
 
35
  setting.bind(function (to) {
36
 
37
  $.each(el.css, function (counter, property_config) {
38
+ let properties = [];
39
 
40
  properties[property_config.property] = property_config.selector;
41
  if (typeof property_config.callback_filter !== "undefined") {
103
 
104
  function load_webfont_once() {
105
  if (typeof WebFont === "undefined") {
106
+ let tk = document.createElement('script');
107
  tk.src = '//ajax.googleapis.com/ajax/libs/webfont/1/webfont.js';
108
  tk.type = 'text/javascript';
109
+ let s = document.getElementsByTagName('script')[0];
110
  s.parentNode.insertBefore(tk, s);
111
  }
112
  }
113
 
114
+ const get_CSS_values = function (ID, values) {
115
 
116
+ let store = {};
117
 
118
+ if (typeof values.font_family !== "undefined") {
119
+ store['font-family'] = values.font_family;
120
  }
121
 
122
+ if (typeof values.selected_variants !== "undefined") {
123
 
124
+ let variants = null;
125
 
126
+ if (typeof values.selected_variants !== "undefined" && values.selected_variants !== null) {
127
+ variants = values.selected_variants;
128
+ } else if (typeof values.variants !== "undefined" && typeof values.variants[0] !== "undefined") {
129
+ variants = values.variants[0];
130
  }
131
 
132
  // google fonts also have the italic string inside, split that
133
+ if (variants !== null && _.isString( variants ) && variants.indexOf('italic') !== -1) {
134
  store['font-style'] = 'italic';
135
  variants = variants.replace('italic', '');
136
  }
144
  }
145
  }
146
 
147
+ if (typeof values.font_size !== "undefined") {
148
+ store['font-size'] = values.font_size;
149
+ // If the value already contains a unit (is not numeric), go with that.
150
+ if ( isNaN(values.font_size) ) {
151
+ // If we have a standardized value field (as array), use that.
152
+ if ( typeof values.font_size.value !== "undefined" ) {
153
+ store['font-size'] = values.font_size.value;
154
+ if ( typeof values.font_size.unit !== "undefined" ) {
155
+ store['font-size'] += values.font_size.unit;
156
+ }
157
+ } else {
158
+ store['font-size'] += get_field_unit(ID, 'font-size');
159
+ }
160
+ } else {
161
+ store['font-size'] += get_field_unit(ID, 'font-size');
162
+ }
163
  }
164
 
165
+ if (typeof values.letter_spacing !== "undefined") {
166
+ store['letter-spacing'] = values.letter_spacing;
167
+ // If the value already contains a unit (is not numeric), go with that.
168
+ if ( isNaN(values.letter_spacing) ) {
169
+ // If we have a standardized value field (as array), use that.
170
+ if ( typeof values.letter_spacing.value !== "undefined" ) {
171
+ store['letter-spacing'] = values.letter_spacing.value;
172
+ if ( typeof values.letter_spacing.unit !== "undefined" ) {
173
+ store['letter-spacing'] += values.letter_spacing.unit;
174
+ }
175
+ } else {
176
+ store['letter-spacing'] += get_field_unit(ID, 'letter-spacing');
177
+ }
178
+ } else {
179
+ store['letter-spacing'] += get_field_unit(ID, 'letter-spacing');
180
+ }
181
  }
182
 
183
+ if (typeof values.line_height !== "undefined") {
184
+ store['line-height'] = values.line_height;
185
+ // If the value already contains a unit (is not numeric), go with that.
186
+ if ( isNaN(values.line_height) ) {
187
+ // If we have a standardized value field (as array), use that.
188
+ if ( typeof values.line_height.value !== "undefined" ) {
189
+ store['line-height'] = values.line_height.value;
190
+ if ( typeof values.line_height.unit !== "undefined" ) {
191
+ store['line-height'] += values.line_height.unit;
192
+ }
193
+ } else {
194
+ store['line-height'] += get_field_unit(ID, 'line-height');
195
+ }
196
+ } else {
197
+ store['line-height'] += get_field_unit(ID, 'line-height');
198
+ }
199
  }
200
 
201
+ if (typeof values.text_align !== "undefined") {
202
+ store['text-align'] = values.text_align;
203
  }
204
 
205
+ if (typeof values.text_transform !== "undefined") {
206
+ store['text-transform'] = values.text_transform;
207
  }
208
+ if (typeof values.text_decoration !== "undefined") {
209
+ store['text-decoration'] = values.text_decoration;
210
  }
211
 
212
  return store;
213
  };
214
 
215
+ const get_CSS_code = function (ID, values) {
216
 
217
+ let field = customify_settings.settings[ID];
218
+ let output = '';
219
 
220
  if (typeof window !== "undefined" && typeof field.callback !== "undefined" && typeof window[field.callback] === "function") {
221
+ output = window[field.callback](values, field);
222
  } else {
223
  output = field.selector + "{\n";
224
+ $.each(values, function (k, v) {
225
  output += k + ': ' + v + ";\n";
226
+ });
227
  output += "}\n";
228
  }
229
 
230
  return output;
231
  };
232
 
233
+ const get_field_unit = function (ID, field) {
234
+ let unit = '';
235
  if (typeof customify_settings.settings[ID] === "undefined" || typeof customify_settings.settings[ID].fields[field] === "undefined") {
236
  return unit;
237
  }
242
  // in case of an associative array
243
  return customify_settings.settings[ID].fields[field][3];
244
  }
245
+ };
246
 
247
+ const maybeLoadFontFamily = function (font) {
248
 
249
  if (typeof WebFont === "undefined") {
250
+ let tk = document.createElement('script');
251
  tk.src = '//ajax.googleapis.com/ajax/libs/webfont/1/webfont.js';
252
  tk.type = 'text/javascript';
253
+ let s = document.getElementsByTagName('script')[0];
254
  s.parentNode.insertBefore(tk, s);
255
  }
256
 
257
+ // If the font type is not defined, we assume is a Google font.
258
+ if ( typeof font.type === "undefined" ) {
259
+ font.type = 'google';
260
+ }
261
+
262
  if (font.type === 'theme_font') {
263
  WebFont.load({
264
  custom: {
267
  }
268
  });
269
  } else if (font.type === 'google') {
270
+ let family = font.font_family,
271
  variants = null,
272
  subsets = null;
273
 
274
  if (typeof font.variants !== "undefined") {
275
  variants = maybeJsonParse(font.variants);
276
 
277
+ if ( typeof variants === "string" || typeof variants === "number") {
278
+ variants = [ variants ];
279
+ }
280
+
281
  $.each(variants, function (k, v) {
282
 
283
+ if (k == 0) {
284
  family = family + ':';
285
  }
286
 
333
  } else {
334
  // else what?
335
  }
336
+ };
337
+
338
+ const maybeJsonParse = function (value) {
339
+ let parsed;
340
 
341
+ if ( typeof value !== "string" ) {
342
+ return value;
343
+ }
344
 
345
  //try and parse it, with decodeURIComponent
346
  try {
package-lock.json DELETED
@@ -1,4776 +0,0 @@
1
- {
2
- "name": "customify",
3
- "requires": true,
4
- "lockfileVersion": 1,
5
- "dependencies": {
6
- "abbrev": {
7
- "version": "1.1.1",
8
- "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz",
9
- "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==",
10
- "dev": true
11
- },
12
- "ajv": {
13
- "version": "5.3.0",
14
- "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.3.0.tgz",
15
- "integrity": "sha1-RBT/dKUIecII7l/cgm4ywwNUnto=",
16
- "dev": true,
17
- "requires": {
18
- "co": "^4.6.0",
19
- "fast-deep-equal": "^1.0.0",
20
- "fast-json-stable-stringify": "^2.0.0",
21
- "json-schema-traverse": "^0.3.0"
22
- }
23
- },
24
- "amdefine": {
25
- "version": "1.0.1",
26
- "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz",
27
- "integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=",
28
- "dev": true
29
- },
30
- "ansi-regex": {
31
- "version": "2.1.1",
32
- "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
33
- "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=",
34
- "dev": true
35
- },
36
- "ansi-styles": {
37
- "version": "2.2.1",
38
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz",
39
- "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=",
40
- "dev": true
41
- },
42
- "aproba": {
43
- "version": "1.2.0",
44
- "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz",
45
- "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==",
46
- "dev": true
47
- },
48
- "archy": {
49
- "version": "1.0.0",
50
- "resolved": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz",
51
- "integrity": "sha1-+cjBN1fMHde8N5rHeyxipcKGjEA=",
52
- "dev": true
53
- },
54
- "are-we-there-yet": {
55
- "version": "1.1.4",
56
- "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.4.tgz",
57
- "integrity": "sha1-u13KOCu5TwXhUZQ3PRb9O6HKEQ0=",
58
- "dev": true,
59
- "requires": {
60
- "delegates": "^1.0.0",
61
- "readable-stream": "^2.0.6"
62
- },
63
- "dependencies": {
64
- "isarray": {
65
- "version": "1.0.0",
66
- "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
67
- "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
68
- "dev": true
69
- },
70
- "readable-stream": {
71
- "version": "2.3.3",
72
- "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz",
73
- "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==",
74
- "dev": true,
75
- "requires": {
76
- "core-util-is": "~1.0.0",
77
- "inherits": "~2.0.3",
78
- "isarray": "~1.0.0",
79
- "process-nextick-args": "~1.0.6",
80
- "safe-buffer": "~5.1.1",
81
- "string_decoder": "~1.0.3",
82
- "util-deprecate": "~1.0.1"
83
- }
84
- },
85
- "string_decoder": {
86
- "version": "1.0.3",
87
- "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz",
88
- "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==",
89
- "dev": true,
90
- "requires": {
91
- "safe-buffer": "~5.1.0"
92
- }
93
- }
94
- }
95
- },
96
- "argparse": {
97
- "version": "1.0.9",
98
- "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.9.tgz",
99
- "integrity": "sha1-c9g7wmP4bpf4zE9rrhsOkKfSLIY=",
100
- "dev": true,
101
- "requires": {
102
- "sprintf-js": "~1.0.2"
103
- }
104
- },
105
- "arr-diff": {
106
- "version": "2.0.0",
107
- "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-2.0.0.tgz",
108
- "integrity": "sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8=",
109
- "dev": true,
110
- "requires": {
111
- "arr-flatten": "^1.0.1"
112
- }
113
- },
114
- "arr-flatten": {
115
- "version": "1.1.0",
116
- "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz",
117
- "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==",
118
- "dev": true
119
- },
120
- "array-differ": {
121
- "version": "1.0.0",
122
- "resolved": "https://registry.npmjs.org/array-differ/-/array-differ-1.0.0.tgz",
123
- "integrity": "sha1-7/UuN1gknTO+QCuLuOVkuytdQDE=",
124
- "dev": true
125
- },
126
- "array-each": {
127
- "version": "1.0.1",
128
- "resolved": "https://registry.npmjs.org/array-each/-/array-each-1.0.1.tgz",
129
- "integrity": "sha1-p5SvDAWrF1KEbudTofIRoFugxE8=",
130
- "dev": true
131
- },
132
- "array-find-index": {
133
- "version": "1.0.2",
134
- "resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz",
135
- "integrity": "sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E=",
136
- "dev": true
137
- },
138
- "array-slice": {
139
- "version": "1.0.0",
140
- "resolved": "https://registry.npmjs.org/array-slice/-/array-slice-1.0.0.tgz",
141
- "integrity": "sha1-5zA08A3MH0CHYAj9IP6ud71LfC8=",
142
- "dev": true
143
- },
144
- "array-union": {
145
- "version": "1.0.2",
146
- "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz",
147
- "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=",
148
- "dev": true,
149
- "requires": {
150
- "array-uniq": "^1.0.1"
151
- }
152
- },
153
- "array-uniq": {
154
- "version": "1.0.3",
155
- "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz",
156
- "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=",
157
- "dev": true
158
- },
159
- "array-unique": {
160
- "version": "0.2.1",
161
- "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz",
162
- "integrity": "sha1-odl8yvy8JiXMcPrc6zalDFiwGlM=",
163
- "dev": true
164
- },
165
- "asn1": {
166
- "version": "0.2.3",
167
- "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.3.tgz",
168
- "integrity": "sha1-2sh4dxPJlmhJ/IGAd36+nB3fO4Y=",
169
- "dev": true
170
- },
171
- "assert-plus": {
172
- "version": "1.0.0",
173
- "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
174
- "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=",
175
- "dev": true
176
- },
177
- "async-foreach": {
178
- "version": "0.1.3",
179
- "resolved": "https://registry.npmjs.org/async-foreach/-/async-foreach-0.1.3.tgz",
180
- "integrity": "sha1-NhIfhFwFeBct5Bmpfb6x0W7DRUI=",
181
- "dev": true
182
- },
183
- "asynckit": {
184
- "version": "0.4.0",
185
- "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
186
- "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=",
187
- "dev": true
188
- },
189
- "autoprefixer-core": {
190
- "version": "3.1.2",
191
- "resolved": "https://registry.npmjs.org/autoprefixer-core/-/autoprefixer-core-3.1.2.tgz",
192
- "integrity": "sha1-reXOni2dcbt//DHWlvpeh66+tjQ=",
193
- "dev": true,
194
- "requires": {
195
- "caniuse-db": "^1.0.30000006",
196
- "postcss": "~2.2.5"
197
- }
198
- },
199
- "aws-sign2": {
200
- "version": "0.7.0",
201
- "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz",
202
- "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=",
203
- "dev": true
204
- },
205
- "aws4": {
206
- "version": "1.6.0",
207
- "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.6.0.tgz",
208
- "integrity": "sha1-g+9cqGCysy5KDe7e6MdxudtXRx4=",
209
- "dev": true
210
- },
211
- "balanced-match": {
212
- "version": "1.0.0",
213
- "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
214
- "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=",
215
- "dev": true
216
- },
217
- "bcrypt-pbkdf": {
218
- "version": "1.0.1",
219
- "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.1.tgz",
220
- "integrity": "sha1-Y7xdy2EzG5K8Bf1SiVPDNGKgb40=",
221
- "dev": true,
222
- "optional": true,
223
- "requires": {
224
- "tweetnacl": "^0.14.3"
225
- }
226
- },
227
- "beeper": {
228
- "version": "1.1.1",
229
- "resolved": "https://registry.npmjs.org/beeper/-/beeper-1.1.1.tgz",
230
- "integrity": "sha1-5tXqjF2tABMEpwsiY4RH9pyy+Ak=",
231
- "dev": true
232
- },
233
- "binaryextensions": {
234
- "version": "1.0.1",
235
- "resolved": "https://registry.npmjs.org/binaryextensions/-/binaryextensions-1.0.1.tgz",
236
- "integrity": "sha1-HmN0iLNbWL2l9HdL+WpSEqjJB1U=",
237
- "dev": true
238
- },
239
- "block-stream": {
240
- "version": "0.0.9",
241
- "resolved": "https://registry.npmjs.org/block-stream/-/block-stream-0.0.9.tgz",
242
- "integrity": "sha1-E+v+d4oDIFz+A3UUgeu0szAMEmo=",
243
- "dev": true,
244
- "requires": {
245
- "inherits": "~2.0.0"
246
- }
247
- },
248
- "bluebird": {
249
- "version": "3.5.1",
250
- "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.1.tgz",
251
- "integrity": "sha512-MKiLiV+I1AA596t9w1sQJ8jkiSr5+ZKi0WKrYGUn6d1Fx+Ij4tIj+m2WMQSGczs5jZVxV339chE8iwk6F64wjA==",
252
- "dev": true
253
- },
254
- "boom": {
255
- "version": "4.3.1",
256
- "resolved": "https://registry.npmjs.org/boom/-/boom-4.3.1.tgz",
257
- "integrity": "sha1-T4owBctKfjiJ90kDD9JbluAdLjE=",
258
- "dev": true,
259
- "requires": {
260
- "hoek": "4.x.x"
261
- }
262
- },
263
- "brace-expansion": {
264
- "version": "1.1.8",
265
- "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.8.tgz",
266
- "integrity": "sha1-wHshHHyVLsH479Uad+8NHTmQopI=",
267
- "dev": true,
268
- "requires": {
269
- "balanced-match": "^1.0.0",
270
- "concat-map": "0.0.1"
271
- }
272
- },
273
- "braces": {
274
- "version": "1.8.5",
275
- "resolved": "https://registry.npmjs.org/braces/-/braces-1.8.5.tgz",
276
- "integrity": "sha1-uneWLhLf+WnWt2cR6RS3N4V79qc=",
277
- "dev": true,
278
- "requires": {
279
- "expand-range": "^1.8.1",
280
- "preserve": "^0.2.0",
281
- "repeat-element": "^1.1.2"
282
- }
283
- },
284
- "bufferstreams": {
285
- "version": "1.0.1",
286
- "resolved": "https://registry.npmjs.org/bufferstreams/-/bufferstreams-1.0.1.tgz",
287
- "integrity": "sha1-z7GtlWjTujz+k1upq92VLeiKqyo=",
288
- "dev": true,
289
- "requires": {
290
- "readable-stream": "^1.0.33"
291
- }
292
- },
293
- "builtin-modules": {
294
- "version": "1.1.1",
295
- "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz",
296
- "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=",
297
- "dev": true
298
- },
299
- "camelcase": {
300
- "version": "2.1.1",
301
- "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz",
302
- "integrity": "sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8=",
303
- "dev": true
304
- },
305
- "camelcase-keys": {
306
- "version": "2.1.0",
307
- "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-2.1.0.tgz",
308
- "integrity": "sha1-MIvur/3ygRkFHvodkyITyRuPkuc=",
309
- "dev": true,
310
- "requires": {
311
- "camelcase": "^2.0.0",
312
- "map-obj": "^1.0.0"
313
- }
314
- },
315
- "caniuse-db": {
316
- "version": "1.0.30000766",
317
- "resolved": "https://registry.npmjs.org/caniuse-db/-/caniuse-db-1.0.30000766.tgz",
318
- "integrity": "sha1-TJEao3R/ATiEUvpLknt4/PFDBoA=",
319
- "dev": true
320
- },
321
- "caseless": {
322
- "version": "0.12.0",
323
- "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz",
324
- "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=",
325
- "dev": true
326
- },
327
- "chalk": {
328
- "version": "1.1.3",
329
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
330
- "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
331
- "dev": true,
332
- "requires": {
333
- "ansi-styles": "^2.2.1",
334
- "escape-string-regexp": "^1.0.2",
335
- "has-ansi": "^2.0.0",
336
- "strip-ansi": "^3.0.0",
337
- "supports-color": "^2.0.0"
338
- }
339
- },
340
- "clean-css": {
341
- "version": "3.4.28",
342
- "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-3.4.28.tgz",
343
- "integrity": "sha1-vxlF6C/ICPVWlebd6uwBQA79A/8=",
344
- "dev": true,
345
- "requires": {
346
- "commander": "2.8.x",
347
- "source-map": "0.4.x"
348
- },
349
- "dependencies": {
350
- "commander": {
351
- "version": "2.8.1",
352
- "resolved": "https://registry.npmjs.org/commander/-/commander-2.8.1.tgz",
353
- "integrity": "sha1-Br42f+v9oMMwqh4qBy09yXYkJdQ=",
354
- "dev": true,
355
- "requires": {
356
- "graceful-readlink": ">= 1.0.0"
357
- }
358
- },
359
- "source-map": {
360
- "version": "0.4.4",
361
- "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz",
362
- "integrity": "sha1-66T12pwNyZneaAMti092FzZSA2s=",
363
- "dev": true,
364
- "requires": {
365
- "amdefine": ">=0.0.4"
366
- }
367
- }
368
- }
369
- },
370
- "cliui": {
371
- "version": "3.2.0",
372
- "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz",
373
- "integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=",
374
- "dev": true,
375
- "requires": {
376
- "string-width": "^1.0.1",
377
- "strip-ansi": "^3.0.1",
378
- "wrap-ansi": "^2.0.0"
379
- }
380
- },
381
- "clone": {
382
- "version": "1.0.3",
383
- "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.3.tgz",
384
- "integrity": "sha1-KY1+IjFmD0DAA8LtMUDezz9TCF8=",
385
- "dev": true
386
- },
387
- "clone-stats": {
388
- "version": "0.0.1",
389
- "resolved": "https://registry.npmjs.org/clone-stats/-/clone-stats-0.0.1.tgz",
390
- "integrity": "sha1-uI+UqCzzi4eR1YBG6kAprYjKmdE=",
391
- "dev": true
392
- },
393
- "co": {
394
- "version": "4.6.0",
395
- "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz",
396
- "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=",
397
- "dev": true
398
- },
399
- "code-point-at": {
400
- "version": "1.1.0",
401
- "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz",
402
- "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=",
403
- "dev": true
404
- },
405
- "color-convert": {
406
- "version": "1.9.1",
407
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.1.tgz",
408
- "integrity": "sha512-mjGanIiwQJskCC18rPR6OmrZ6fm2Lc7PeGFYwCmy5J34wC6F1PzdGL6xeMfmgicfYcNLGuVFA3WzXtIDCQSZxQ==",
409
- "dev": true,
410
- "requires": {
411
- "color-name": "^1.1.1"
412
- }
413
- },
414
- "color-name": {
415
- "version": "1.1.3",
416
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
417
- "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=",
418
- "dev": true
419
- },
420
- "colors": {
421
- "version": "0.6.2",
422
- "resolved": "https://registry.npmjs.org/colors/-/colors-0.6.2.tgz",
423
- "integrity": "sha1-JCP+ZnisDF2uiFLl0OW+CMmXq8w=",
424
- "dev": true
425
- },
426
- "combined-stream": {
427
- "version": "1.0.5",
428
- "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.5.tgz",
429
- "integrity": "sha1-k4NwpXtKUd6ix3wV1cX9+JUWQAk=",
430
- "dev": true,
431
- "requires": {
432
- "delayed-stream": "~1.0.0"
433
- }
434
- },
435
- "commander": {
436
- "version": "2.11.0",
437
- "resolved": "https://registry.npmjs.org/commander/-/commander-2.11.0.tgz",
438
- "integrity": "sha512-b0553uYA5YAEGgyYIGYROzKQ7X5RAqedkfjiZxwi0kL1g3bOaBNNZfYkzt/CL0umgD5wc9Jec2FbB98CjkMRvQ==",
439
- "dev": true
440
- },
441
- "concat-map": {
442
- "version": "0.0.1",
443
- "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
444
- "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=",
445
- "dev": true
446
- },
447
- "config-chain": {
448
- "version": "1.1.11",
449
- "resolved": "https://registry.npmjs.org/config-chain/-/config-chain-1.1.11.tgz",
450
- "integrity": "sha1-q6CXR9++TD5w52am5BWG4YWfxvI=",
451
- "dev": true,
452
- "requires": {
453
- "ini": "^1.3.4",
454
- "proto-list": "~1.2.1"
455
- }
456
- },
457
- "console-control-strings": {
458
- "version": "1.1.0",
459
- "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz",
460
- "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=",
461
- "dev": true
462
- },
463
- "core-util-is": {
464
- "version": "1.0.2",
465
- "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
466
- "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=",
467
- "dev": true
468
- },
469
- "cosmiconfig": {
470
- "version": "2.2.2",
471
- "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-2.2.2.tgz",
472
- "integrity": "sha512-GiNXLwAFPYHy25XmTPpafYvn3CLAkJ8FLsscq78MQd1Kh0OU6Yzhn4eV2MVF4G9WEQZoWEGltatdR+ntGPMl5A==",
473
- "dev": true,
474
- "requires": {
475
- "is-directory": "^0.3.1",
476
- "js-yaml": "^3.4.3",
477
- "minimist": "^1.2.0",
478
- "object-assign": "^4.1.0",
479
- "os-homedir": "^1.0.1",
480
- "parse-json": "^2.2.0",
481
- "require-from-string": "^1.1.0"
482
- }
483
- },
484
- "cross-spawn": {
485
- "version": "3.0.1",
486
- "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-3.0.1.tgz",
487
- "integrity": "sha1-ElYDfsufDF9549bvE14wdwGEuYI=",
488
- "dev": true,
489
- "requires": {
490
- "lru-cache": "^4.0.1",
491
- "which": "^1.2.9"
492
- },
493
- "dependencies": {
494
- "lru-cache": {
495
- "version": "4.1.1",
496
- "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.1.tgz",
497
- "integrity": "sha512-q4spe4KTfsAS1SUHLO0wz8Qiyf1+vMIAgpRYioFYDMNqKfHQbg+AVDH3i4fvpl71/P1L0dBl+fQi+P37UYf0ew==",
498
- "dev": true,
499
- "requires": {
500
- "pseudomap": "^1.0.2",
501
- "yallist": "^2.1.2"
502
- }
503
- }
504
- }
505
- },
506
- "cryptiles": {
507
- "version": "3.1.2",
508
- "resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-3.1.2.tgz",
509
- "integrity": "sha1-qJ+7Ig9c4l7FboxKqKT9e1sNKf4=",
510
- "dev": true,
511
- "requires": {
512
- "boom": "5.x.x"
513
- },
514
- "dependencies": {
515
- "boom": {
516
- "version": "5.2.0",
517
- "resolved": "https://registry.npmjs.org/boom/-/boom-5.2.0.tgz",
518
- "integrity": "sha512-Z5BTk6ZRe4tXXQlkqftmsAUANpXmuwlsF5Oov8ThoMbQRzdGTA1ngYRW160GexgOgjsFOKJz0LYhoNi+2AMBUw==",
519
- "dev": true,
520
- "requires": {
521
- "hoek": "4.x.x"
522
- }
523
- }
524
- }
525
- },
526
- "css-parse": {
527
- "version": "1.7.0",
528
- "resolved": "https://registry.npmjs.org/css-parse/-/css-parse-1.7.0.tgz",
529
- "integrity": "sha1-Mh9s9zeCpv91ERE5D8BeLGV9jJs=",
530
- "dev": true
531
- },
532
- "csscomb": {
533
- "version": "3.1.8",
534
- "resolved": "https://registry.npmjs.org/csscomb/-/csscomb-3.1.8.tgz",
535
- "integrity": "sha1-qKc4iE9Am6817JRhr8UuHHW9I6I=",
536
- "dev": true,
537
- "requires": {
538
- "commander": "2.0.0",
539
- "csscomb-core": "3.0.0-3.1",
540
- "gonzales-pe": "3.0.0-28",
541
- "vow": "0.4.4"
542
- },
543
- "dependencies": {
544
- "commander": {
545
- "version": "2.0.0",
546
- "resolved": "https://registry.npmjs.org/commander/-/commander-2.0.0.tgz",
547
- "integrity": "sha1-0bhvkB+LZL2UG96tr5JFMDk76Sg=",
548
- "dev": true
549
- }
550
- }
551
- },
552
- "csscomb-core": {
553
- "version": "3.0.0-3.1",
554
- "resolved": "https://registry.npmjs.org/csscomb-core/-/csscomb-core-3.0.0-3.1.tgz",
555
- "integrity": "sha1-tBHI18/g3z8v4d+E0b1kpvAEbGg=",
556
- "dev": true,
557
- "requires": {
558
- "gonzales-pe": "3.0.0-28",
559
- "minimatch": "0.2.12",
560
- "vow": "0.4.4",
561
- "vow-fs": "0.3.2"
562
- },
563
- "dependencies": {
564
- "minimatch": {
565
- "version": "0.2.12",
566
- "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-0.2.12.tgz",
567
- "integrity": "sha1-6oKgEqxmLH3fqhRPHBR+aUb12vs=",
568
- "dev": true,
569
- "requires": {
570
- "lru-cache": "2",
571
- "sigmund": "~1.0.0"
572
- }
573
- }
574
- }
575
- },
576
- "currently-unhandled": {
577
- "version": "0.4.1",
578
- "resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz",
579
- "integrity": "sha1-mI3zP+qxke95mmE2nddsF635V+o=",
580
- "dev": true,
581
- "requires": {
582
- "array-find-index": "^1.0.1"
583
- }
584
- },
585
- "dashdash": {
586
- "version": "1.14.1",
587
- "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz",
588
- "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=",
589
- "dev": true,
590
- "requires": {
591
- "assert-plus": "^1.0.0"
592
- }
593
- },
594
- "dateformat": {
595
- "version": "2.2.0",
596
- "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-2.2.0.tgz",
597
- "integrity": "sha1-QGXiATz5+5Ft39gu+1Bq1MZ2kGI=",
598
- "dev": true
599
- },
600
- "decamelize": {
601
- "version": "1.2.0",
602
- "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz",
603
- "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=",
604
- "dev": true
605
- },
606
- "defaults": {
607
- "version": "1.0.3",
608
- "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.3.tgz",
609
- "integrity": "sha1-xlYFHpgX2f8I7YgUd/P+QBnz730=",
610
- "dev": true,
611
- "requires": {
612
- "clone": "^1.0.2"
613
- }
614
- },
615
- "del": {
616
- "version": "3.0.0",
617
- "resolved": "https://registry.npmjs.org/del/-/del-3.0.0.tgz",
618
- "integrity": "sha1-U+z2mf/LyzljdpGrE7rxYIGXZuU=",
619
- "dev": true,
620
- "requires": {
621
- "globby": "^6.1.0",
622
- "is-path-cwd": "^1.0.0",
623
- "is-path-in-cwd": "^1.0.0",
624
- "p-map": "^1.1.1",
625
- "pify": "^3.0.0",
626
- "rimraf": "^2.2.8"
627
- }
628
- },
629
- "delayed-stream": {
630
- "version": "1.0.0",
631
- "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
632
- "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=",
633
- "dev": true
634
- },
635
- "delegates": {
636
- "version": "1.0.0",
637
- "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz",
638
- "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=",
639
- "dev": true
640
- },
641
- "deprecated": {
642
- "version": "0.0.1",
643
- "resolved": "https://registry.npmjs.org/deprecated/-/deprecated-0.0.1.tgz",
644
- "integrity": "sha1-+cmvVGSvoeepcUWKi97yqpTVuxk=",
645
- "dev": true
646
- },
647
- "detect-file": {
648
- "version": "0.1.0",
649
- "resolved": "https://registry.npmjs.org/detect-file/-/detect-file-0.1.0.tgz",
650
- "integrity": "sha1-STXe39lIhkjgBrASlWbpOGcR6mM=",
651
- "dev": true,
652
- "requires": {
653
- "fs-exists-sync": "^0.1.0"
654
- }
655
- },
656
- "duplexer": {
657
- "version": "0.1.1",
658
- "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.1.tgz",
659
- "integrity": "sha1-rOb/gIwc5mtX0ev5eXessCM0z8E=",
660
- "dev": true
661
- },
662
- "duplexer2": {
663
- "version": "0.0.2",
664
- "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.0.2.tgz",
665
- "integrity": "sha1-xhTc9n4vsUmVqRcR5aYX6KYKMds=",
666
- "dev": true,
667
- "requires": {
668
- "readable-stream": "~1.1.9"
669
- }
670
- },
671
- "ecc-jsbn": {
672
- "version": "0.1.1",
673
- "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz",
674
- "integrity": "sha1-D8c6ntXw1Tw4GTOYUj735UN3dQU=",
675
- "dev": true,
676
- "optional": true,
677
- "requires": {
678
- "jsbn": "~0.1.0"
679
- }
680
- },
681
- "editorconfig": {
682
- "version": "0.13.3",
683
- "resolved": "https://registry.npmjs.org/editorconfig/-/editorconfig-0.13.3.tgz",
684
- "integrity": "sha512-WkjsUNVCu+ITKDj73QDvi0trvpdDWdkDyHybDGSXPfekLCqwmpD7CP7iPbvBgosNuLcI96XTDwNa75JyFl7tEQ==",
685
- "dev": true,
686
- "requires": {
687
- "bluebird": "^3.0.5",
688
- "commander": "^2.9.0",
689
- "lru-cache": "^3.2.0",
690
- "semver": "^5.1.0",
691
- "sigmund": "^1.0.1"
692
- },
693
- "dependencies": {
694
- "lru-cache": {
695
- "version": "3.2.0",
696
- "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-3.2.0.tgz",
697
- "integrity": "sha1-cXibO39Tmb7IVl3aOKow0qCX7+4=",
698
- "dev": true,
699
- "requires": {
700
- "pseudomap": "^1.0.1"
701
- }
702
- },
703
- "semver": {
704
- "version": "5.4.1",
705
- "resolved": "https://registry.npmjs.org/semver/-/semver-5.4.1.tgz",
706
- "integrity": "sha512-WfG/X9+oATh81XtllIo/I8gOiY9EXRdv1cQdyykeXK17YcUW3EXUAi2To4pcH6nZtJPr7ZOpM5OMyWJZm+8Rsg==",
707
- "dev": true
708
- }
709
- }
710
- },
711
- "end-of-stream": {
712
- "version": "0.1.5",
713
- "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-0.1.5.tgz",
714
- "integrity": "sha1-jhdyBsPICDfYVjLouTWd/osvbq8=",
715
- "dev": true,
716
- "requires": {
717
- "once": "~1.3.0"
718
- },
719
- "dependencies": {
720
- "once": {
721
- "version": "1.3.3",
722
- "resolved": "https://registry.npmjs.org/once/-/once-1.3.3.tgz",
723
- "integrity": "sha1-suJhVXzkwxTsgwTz+oJmPkKXyiA=",
724
- "dev": true,
725
- "requires": {
726
- "wrappy": "1"
727
- }
728
- }
729
- }
730
- },
731
- "error-ex": {
732
- "version": "1.3.1",
733
- "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.1.tgz",
734
- "integrity": "sha1-+FWobOYa3E6GIcPNoh56dhLDqNw=",
735
- "dev": true,
736
- "requires": {
737
- "is-arrayish": "^0.2.1"
738
- }
739
- },
740
- "es6-promise": {
741
- "version": "4.1.1",
742
- "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.1.1.tgz",
743
- "integrity": "sha512-OaU1hHjgJf+b0NzsxCg7NdIYERD6Hy/PEmFLTjw+b65scuisG3Kt4QoTvJ66BBkPZ581gr0kpoVzKnxniM8nng==",
744
- "dev": true
745
- },
746
- "escape-string-regexp": {
747
- "version": "1.0.5",
748
- "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
749
- "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=",
750
- "dev": true
751
- },
752
- "esprima": {
753
- "version": "4.0.0",
754
- "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.0.tgz",
755
- "integrity": "sha512-oftTcaMu/EGrEIu904mWteKIv8vMuOgGYo7EhVJJN00R/EED9DCua/xxHRdYnKtcECzVg7xOWhflvJMnqcFZjw==",
756
- "dev": true
757
- },
758
- "event-stream": {
759
- "version": "3.0.20",
760
- "resolved": "https://registry.npmjs.org/event-stream/-/event-stream-3.0.20.tgz",
761
- "integrity": "sha1-A4u7LqnqkDhbJvvBhU0LU58qvqM=",
762
- "dev": true,
763
- "requires": {
764
- "duplexer": "~0.1.1",
765
- "from": "~0",
766
- "map-stream": "~0.0.3",
767
- "pause-stream": "0.0.11",
768
- "split": "0.2",
769
- "stream-combiner": "~0.0.3",
770
- "through": "~2.3.1"
771
- }
772
- },
773
- "expand-brackets": {
774
- "version": "0.1.5",
775
- "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-0.1.5.tgz",
776
- "integrity": "sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s=",
777
- "dev": true,
778
- "requires": {
779
- "is-posix-bracket": "^0.1.0"
780
- }
781
- },
782
- "expand-range": {
783
- "version": "1.8.2",
784
- "resolved": "https://registry.npmjs.org/expand-range/-/expand-range-1.8.2.tgz",
785
- "integrity": "sha1-opnv/TNf4nIeuujiV+x5ZE/IUzc=",
786
- "dev": true,
787
- "requires": {
788
- "fill-range": "^2.1.0"
789
- }
790
- },
791
- "expand-tilde": {
792
- "version": "1.2.2",
793
- "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-1.2.2.tgz",
794
- "integrity": "sha1-C4HrqJflo9MdHD0QL48BRB5VlEk=",
795
- "dev": true,
796
- "requires": {
797
- "os-homedir": "^1.0.1"
798
- }
799
- },
800
- "extend": {
801
- "version": "3.0.1",
802
- "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.1.tgz",
803
- "integrity": "sha1-p1Xqe8Gt/MWjHOfnYtuq3F5jZEQ=",
804
- "dev": true
805
- },
806
- "extglob": {
807
- "version": "0.3.2",
808
- "resolved": "https://registry.npmjs.org/extglob/-/extglob-0.3.2.tgz",
809
- "integrity": "sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE=",
810
- "dev": true,
811
- "requires": {
812
- "is-extglob": "^1.0.0"
813
- }
814
- },
815
- "extsprintf": {
816
- "version": "1.3.0",
817
- "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz",
818
- "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=",
819
- "dev": true
820
- },
821
- "fancy-log": {
822
- "version": "1.3.0",
823
- "resolved": "https://registry.npmjs.org/fancy-log/-/fancy-log-1.3.0.tgz",
824
- "integrity": "sha1-Rb4X0Cu5kX1gzP/UmVyZnmyMmUg=",
825
- "dev": true,
826
- "requires": {
827
- "chalk": "^1.1.1",
828
- "time-stamp": "^1.0.0"
829
- }
830
- },
831
- "fast-deep-equal": {
832
- "version": "1.0.0",
833
- "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.0.0.tgz",
834
- "integrity": "sha1-liVqO8l1WV6zbYLpkp0GDYk0Of8=",
835
- "dev": true
836
- },
837
- "fast-json-stable-stringify": {
838
- "version": "2.0.0",
839
- "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz",
840
- "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=",
841
- "dev": true
842
- },
843
- "filename-regex": {
844
- "version": "2.0.1",
845
- "resolved": "https://registry.npmjs.org/filename-regex/-/filename-regex-2.0.1.tgz",
846
- "integrity": "sha1-wcS5vuPglyXdsQa3XB4wH+LxiyY=",
847
- "dev": true
848
- },
849
- "fill-range": {
850
- "version": "2.2.3",
851
- "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-2.2.3.tgz",
852
- "integrity": "sha1-ULd9/X5Gm8dJJHCWNpn+eoSFpyM=",
853
- "dev": true,
854
- "requires": {
855
- "is-number": "^2.1.0",
856
- "isobject": "^2.0.0",
857
- "randomatic": "^1.1.3",
858
- "repeat-element": "^1.1.2",
859
- "repeat-string": "^1.5.2"
860
- }
861
- },
862
- "find-index": {
863
- "version": "0.1.1",
864
- "resolved": "https://registry.npmjs.org/find-index/-/find-index-0.1.1.tgz",
865
- "integrity": "sha1-Z101iyyjiS15Whq0cjL4tuLg3eQ=",
866
- "dev": true
867
- },
868
- "find-up": {
869
- "version": "1.1.2",
870
- "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz",
871
- "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=",
872
- "dev": true,
873
- "requires": {
874
- "path-exists": "^2.0.0",
875
- "pinkie-promise": "^2.0.0"
876
- }
877
- },
878
- "findup": {
879
- "version": "0.1.5",
880
- "resolved": "https://registry.npmjs.org/findup/-/findup-0.1.5.tgz",
881
- "integrity": "sha1-itkpozk7rGJ5V6fl3kYjsGsOLOs=",
882
- "dev": true,
883
- "requires": {
884
- "colors": "~0.6.0-1",
885
- "commander": "~2.1.0"
886
- },
887
- "dependencies": {
888
- "commander": {
889
- "version": "2.1.0",
890
- "resolved": "https://registry.npmjs.org/commander/-/commander-2.1.0.tgz",
891
- "integrity": "sha1-0SG7roYNmZKj1Re6lvVliOR8Z4E=",
892
- "dev": true
893
- }
894
- }
895
- },
896
- "findup-sync": {
897
- "version": "0.4.3",
898
- "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-0.4.3.tgz",
899
- "integrity": "sha1-QAQ5Kee8YK3wt/SCfExudaDeyhI=",
900
- "dev": true,
901
- "requires": {
902
- "detect-file": "^0.1.0",
903
- "is-glob": "^2.0.1",
904
- "micromatch": "^2.3.7",
905
- "resolve-dir": "^0.1.0"
906
- }
907
- },
908
- "fined": {
909
- "version": "1.1.0",
910
- "resolved": "https://registry.npmjs.org/fined/-/fined-1.1.0.tgz",
911
- "integrity": "sha1-s33IRLdqL15wgeiE98CuNE8VNHY=",
912
- "dev": true,
913
- "requires": {
914
- "expand-tilde": "^2.0.2",
915
- "is-plain-object": "^2.0.3",
916
- "object.defaults": "^1.1.0",
917
- "object.pick": "^1.2.0",
918
- "parse-filepath": "^1.0.1"
919
- },
920
- "dependencies": {
921
- "expand-tilde": {
922
- "version": "2.0.2",
923
- "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-2.0.2.tgz",
924
- "integrity": "sha1-l+gBqgUt8CRU3kawK/YhZCzchQI=",
925
- "dev": true,
926
- "requires": {
927
- "homedir-polyfill": "^1.0.1"
928
- }
929
- }
930
- }
931
- },
932
- "first-chunk-stream": {
933
- "version": "1.0.0",
934
- "resolved": "https://registry.npmjs.org/first-chunk-stream/-/first-chunk-stream-1.0.0.tgz",
935
- "integrity": "sha1-Wb+1DNkF9g18OUzT2ayqtOatk04=",
936
- "dev": true
937
- },
938
- "flagged-respawn": {
939
- "version": "0.3.2",
940
- "resolved": "https://registry.npmjs.org/flagged-respawn/-/flagged-respawn-0.3.2.tgz",
941
- "integrity": "sha1-/xke3c1wiKZ1smEP/8l2vpuAdLU=",
942
- "dev": true
943
- },
944
- "for-in": {
945
- "version": "1.0.2",
946
- "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz",
947
- "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=",
948
- "dev": true
949
- },
950
- "for-own": {
951
- "version": "0.1.5",
952
- "resolved": "https://registry.npmjs.org/for-own/-/for-own-0.1.5.tgz",
953
- "integrity": "sha1-UmXGgaTylNq78XyVCbZ2OqhFEM4=",
954
- "dev": true,
955
- "requires": {
956
- "for-in": "^1.0.1"
957
- }
958
- },
959
- "forever-agent": {
960
- "version": "0.6.1",
961
- "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz",
962
- "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=",
963
- "dev": true
964
- },
965
- "form-data": {
966
- "version": "2.3.1",
967
- "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.1.tgz",
968
- "integrity": "sha1-b7lPvXGIUwbXPRXMSX/kzE7NRL8=",
969
- "dev": true,
970
- "requires": {
971
- "asynckit": "^0.4.0",
972
- "combined-stream": "^1.0.5",
973
- "mime-types": "^2.1.12"
974
- }
975
- },
976
- "from": {
977
- "version": "0.1.7",
978
- "resolved": "https://registry.npmjs.org/from/-/from-0.1.7.tgz",
979
- "integrity": "sha1-g8YK/Fi5xWmXAH7Rp2izqzA6RP4=",
980
- "dev": true
981
- },
982
- "fs-exists-sync": {
983
- "version": "0.1.0",
984
- "resolved": "https://registry.npmjs.org/fs-exists-sync/-/fs-exists-sync-0.1.0.tgz",
985
- "integrity": "sha1-mC1ok6+RjnLQjeyehnP/K1qNat0=",
986
- "dev": true
987
- },
988
- "fs.realpath": {
989
- "version": "1.0.0",
990
- "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
991
- "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=",
992
- "dev": true
993
- },
994
- "fstream": {
995
- "version": "1.0.11",
996
- "resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.11.tgz",
997
- "integrity": "sha1-XB+x8RdHcRTwYyoOtLcbPLD9MXE=",
998
- "dev": true,
999
- "requires": {
1000
- "graceful-fs": "^4.1.2",
1001
- "inherits": "~2.0.0",
1002
- "mkdirp": ">=0.5 0",
1003
- "rimraf": "2"
1004
- },
1005
- "dependencies": {
1006
- "graceful-fs": {
1007
- "version": "4.1.11",
1008
- "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz",
1009
- "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=",
1010
- "dev": true
1011
- }
1012
- }
1013
- },
1014
- "gauge": {
1015
- "version": "2.7.4",
1016
- "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz",
1017
- "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=",
1018
- "dev": true,
1019
- "requires": {
1020
- "aproba": "^1.0.3",
1021
- "console-control-strings": "^1.0.0",
1022
- "has-unicode": "^2.0.0",
1023
- "object-assign": "^4.1.0",
1024
- "signal-exit": "^3.0.0",
1025
- "string-width": "^1.0.1",
1026
- "strip-ansi": "^3.0.1",
1027
- "wide-align": "^1.1.0"
1028
- }
1029
- },
1030
- "gaze": {
1031
- "version": "0.5.2",
1032
- "resolved": "https://registry.npmjs.org/gaze/-/gaze-0.5.2.tgz",
1033
- "integrity": "sha1-QLcJU30k0dRXZ9takIaJ3+aaxE8=",
1034
- "dev": true,
1035
- "requires": {
1036
- "globule": "~0.1.0"
1037
- }
1038
- },
1039
- "get-caller-file": {
1040
- "version": "1.0.2",
1041
- "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.2.tgz",
1042
- "integrity": "sha1-9wLmMSfn4jHBYKgMFVSstw1QR+U=",
1043
- "dev": true
1044
- },
1045
- "get-stdin": {
1046
- "version": "4.0.1",
1047
- "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz",
1048
- "integrity": "sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4=",
1049
- "dev": true
1050
- },
1051
- "getpass": {
1052
- "version": "0.1.7",
1053
- "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz",
1054
- "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=",
1055
- "dev": true,
1056
- "requires": {
1057
- "assert-plus": "^1.0.0"
1058
- }
1059
- },
1060
- "glob": {
1061
- "version": "7.1.2",
1062
- "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz",
1063
- "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==",
1064
- "dev": true,
1065
- "requires": {
1066
- "fs.realpath": "^1.0.0",
1067
- "inflight": "^1.0.4",
1068
- "inherits": "2",
1069
- "minimatch": "^3.0.4",
1070
- "once": "^1.3.0",
1071
- "path-is-absolute": "^1.0.0"
1072
- }
1073
- },
1074
- "glob-base": {
1075
- "version": "0.3.0",
1076
- "resolved": "https://registry.npmjs.org/glob-base/-/glob-base-0.3.0.tgz",
1077
- "integrity": "sha1-27Fk9iIbHAscz4Kuoyi0l98Oo8Q=",
1078
- "dev": true,
1079
- "requires": {
1080
- "glob-parent": "^2.0.0",
1081
- "is-glob": "^2.0.0"
1082
- }
1083
- },
1084
- "glob-parent": {
1085
- "version": "2.0.0",
1086
- "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-2.0.0.tgz",
1087
- "integrity": "sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg=",
1088
- "dev": true,
1089
- "requires": {
1090
- "is-glob": "^2.0.0"
1091
- }
1092
- },
1093
- "glob-stream": {
1094
- "version": "3.1.18",
1095
- "resolved": "https://registry.npmjs.org/glob-stream/-/glob-stream-3.1.18.tgz",
1096
- "integrity": "sha1-kXCl8St5Awb9/lmPMT+PeVT9FDs=",
1097
- "dev": true,
1098
- "requires": {
1099
- "glob": "^4.3.1",
1100
- "glob2base": "^0.0.12",
1101
- "minimatch": "^2.0.1",
1102
- "ordered-read-streams": "^0.1.0",
1103
- "through2": "^0.6.1",
1104
- "unique-stream": "^1.0.0"
1105
- },
1106
- "dependencies": {
1107
- "glob": {
1108
- "version": "4.5.3",
1109
- "resolved": "https://registry.npmjs.org/glob/-/glob-4.5.3.tgz",
1110
- "integrity": "sha1-xstz0yJsHv7wTePFbQEvAzd+4V8=",
1111
- "dev": true,
1112
- "requires": {
1113
- "inflight": "^1.0.4",
1114
- "inherits": "2",
1115
- "minimatch": "^2.0.1",
1116
- "once": "^1.3.0"
1117
- }
1118
- },
1119
- "minimatch": {
1120
- "version": "2.0.10",
1121
- "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-2.0.10.tgz",
1122
- "integrity": "sha1-jQh8OcazjAAbl/ynzm0OHoCvusc=",
1123
- "dev": true,
1124
- "requires": {
1125
- "brace-expansion": "^1.0.0"
1126
- }
1127
- },
1128
- "readable-stream": {
1129
- "version": "1.0.34",
1130
- "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz",
1131
- "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=",
1132
- "dev": true,
1133
- "requires": {
1134
- "core-util-is": "~1.0.0",
1135
- "inherits": "~2.0.1",
1136
- "isarray": "0.0.1",
1137
- "string_decoder": "~0.10.x"
1138
- }
1139
- },
1140
- "through2": {
1141
- "version": "0.6.5",
1142
- "resolved": "https://registry.npmjs.org/through2/-/through2-0.6.5.tgz",
1143
- "integrity": "sha1-QaucZ7KdVyCQcUEOHXp6lozTrUg=",
1144
- "dev": true,
1145
- "requires": {
1146
- "readable-stream": ">=1.0.33-1 <1.1.0-0",
1147
- "xtend": ">=4.0.0 <4.1.0-0"
1148
- }
1149
- }
1150
- }
1151
- },
1152
- "glob-watcher": {
1153
- "version": "0.0.6",
1154
- "resolved": "https://registry.npmjs.org/glob-watcher/-/glob-watcher-0.0.6.tgz",
1155
- "integrity": "sha1-uVtKjfdLOcgymLDAXJeLTZo7cQs=",
1156
- "dev": true,
1157
- "requires": {
1158
- "gaze": "^0.5.1"
1159
- }
1160
- },
1161
- "glob2base": {
1162
- "version": "0.0.12",
1163
- "resolved": "https://registry.npmjs.org/glob2base/-/glob2base-0.0.12.tgz",
1164
- "integrity": "sha1-nUGbPijxLoOjYhZKJ3BVkiycDVY=",
1165
- "dev": true,
1166
- "requires": {
1167
- "find-index": "^0.1.1"
1168
- }
1169
- },
1170
- "global-modules": {
1171
- "version": "0.2.3",
1172
- "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-0.2.3.tgz",
1173
- "integrity": "sha1-6lo77ULG1s6ZWk+KEmm12uIjgo0=",
1174
- "dev": true,
1175
- "requires": {
1176
- "global-prefix": "^0.1.4",
1177
- "is-windows": "^0.2.0"
1178
- }
1179
- },
1180
- "global-prefix": {
1181
- "version": "0.1.5",
1182
- "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-0.1.5.tgz",
1183
- "integrity": "sha1-jTvGuNo8qBEqFg2NSW/wRiv+948=",
1184
- "dev": true,
1185
- "requires": {
1186
- "homedir-polyfill": "^1.0.0",
1187
- "ini": "^1.3.4",
1188
- "is-windows": "^0.2.0",
1189
- "which": "^1.2.12"
1190
- }
1191
- },
1192
- "globby": {
1193
- "version": "6.1.0",
1194
- "resolved": "https://registry.npmjs.org/globby/-/globby-6.1.0.tgz",
1195
- "integrity": "sha1-9abXDoOV4hyFj7BInWTfAkJNUGw=",
1196
- "dev": true,
1197
- "requires": {
1198
- "array-union": "^1.0.1",
1199
- "glob": "^7.0.3",
1200
- "object-assign": "^4.0.1",
1201
- "pify": "^2.0.0",
1202
- "pinkie-promise": "^2.0.0"
1203
- },
1204
- "dependencies": {
1205
- "pify": {
1206
- "version": "2.3.0",
1207
- "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
1208
- "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=",
1209
- "dev": true
1210
- }
1211
- }
1212
- },
1213
- "globule": {
1214
- "version": "0.1.0",
1215
- "resolved": "https://registry.npmjs.org/globule/-/globule-0.1.0.tgz",
1216
- "integrity": "sha1-2cjt3h2nnRJaFRt5UzuXhnY0auU=",
1217
- "dev": true,
1218
- "requires": {
1219
- "glob": "~3.1.21",
1220
- "lodash": "~1.0.1",
1221
- "minimatch": "~0.2.11"
1222
- },
1223
- "dependencies": {
1224
- "glob": {
1225
- "version": "3.1.21",
1226
- "resolved": "https://registry.npmjs.org/glob/-/glob-3.1.21.tgz",
1227
- "integrity": "sha1-0p4KBV3qUTj00H7UDomC6DwgZs0=",
1228
- "dev": true,
1229
- "requires": {
1230
- "graceful-fs": "~1.2.0",
1231
- "inherits": "1",
1232
- "minimatch": "~0.2.11"
1233
- }
1234
- },
1235
- "graceful-fs": {
1236
- "version": "1.2.3",
1237
- "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-1.2.3.tgz",
1238
- "integrity": "sha1-FaSAaldUfLLS2/J/QuiajDRRs2Q=",
1239
- "dev": true
1240
- },
1241
- "inherits": {
1242
- "version": "1.0.2",
1243
- "resolved": "https://registry.npmjs.org/inherits/-/inherits-1.0.2.tgz",
1244
- "integrity": "sha1-ykMJ2t7mtUzAuNJH6NfHoJdb3Js=",
1245
- "dev": true
1246
- },
1247
- "minimatch": {
1248
- "version": "0.2.14",
1249
- "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-0.2.14.tgz",
1250
- "integrity": "sha1-x054BXT2PG+aCQ6Q775u9TpqdWo=",
1251
- "dev": true,
1252
- "requires": {
1253
- "lru-cache": "2",
1254
- "sigmund": "~1.0.0"
1255
- }
1256
- }
1257
- }
1258
- },
1259
- "glogg": {
1260
- "version": "1.0.0",
1261
- "resolved": "https://registry.npmjs.org/glogg/-/glogg-1.0.0.tgz",
1262
- "integrity": "sha1-f+DxmfV6yQbPUS/urY+Q7kooT8U=",
1263
- "dev": true,
1264
- "requires": {
1265
- "sparkles": "^1.0.0"
1266
- }
1267
- },
1268
- "gonzales-pe": {
1269
- "version": "3.0.0-28",
1270
- "resolved": "https://registry.npmjs.org/gonzales-pe/-/gonzales-pe-3.0.0-28.tgz",
1271
- "integrity": "sha1-3VC0HdFbaCooxA5fD/IAeQGsYr0=",
1272
- "dev": true
1273
- },
1274
- "graceful-fs": {
1275
- "version": "3.0.11",
1276
- "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-3.0.11.tgz",
1277
- "integrity": "sha1-dhPHeKGv6mLyXGMKCG1/Osu92Bg=",
1278
- "dev": true,
1279
- "requires": {
1280
- "natives": "^1.1.0"
1281
- }
1282
- },
1283
- "graceful-readlink": {
1284
- "version": "1.0.1",
1285
- "resolved": "https://registry.npmjs.org/graceful-readlink/-/graceful-readlink-1.0.1.tgz",
1286
- "integrity": "sha1-TK+tdrxi8C+gObL5Tpo906ORpyU=",
1287
- "dev": true
1288
- },
1289
- "growly": {
1290
- "version": "1.3.0",
1291
- "resolved": "https://registry.npmjs.org/growly/-/growly-1.3.0.tgz",
1292
- "integrity": "sha1-8QdIy+dq+WS3yWyTxrzCivEgwIE=",
1293
- "dev": true
1294
- },
1295
- "gulp": {
1296
- "version": "3.9.1",
1297
- "resolved": "https://registry.npmjs.org/gulp/-/gulp-3.9.1.tgz",
1298
- "integrity": "sha1-VxzkWSjdQK9lFPxAEYZgFsE4RbQ=",
1299
- "dev": true,
1300
- "requires": {
1301
- "archy": "^1.0.0",
1302
- "chalk": "^1.0.0",
1303
- "deprecated": "^0.0.1",
1304
- "gulp-util": "^3.0.0",
1305
- "interpret": "^1.0.0",
1306
- "liftoff": "^2.1.0",
1307
- "minimist": "^1.1.0",
1308
- "orchestrator": "^0.3.0",
1309
- "pretty-hrtime": "^1.0.0",
1310
- "semver": "^4.1.0",
1311
- "tildify": "^1.0.0",
1312
- "v8flags": "^2.0.2",
1313
- "vinyl-fs": "^0.3.0"
1314
- }
1315
- },
1316
- "gulp-autoprefixer": {
1317
- "version": "1.0.1",
1318
- "resolved": "https://registry.npmjs.org/gulp-autoprefixer/-/gulp-autoprefixer-1.0.1.tgz",
1319
- "integrity": "sha1-5CsA1Zcz3aRMPyAd0h5Ny02oRzM=",
1320
- "dev": true,
1321
- "requires": {
1322
- "autoprefixer-core": "^3.0.1",
1323
- "gulp-util": "^3.0.0",
1324
- "object-assign": "^1.0.0",
1325
- "through2": "^0.6.2",
1326
- "vinyl-sourcemaps-apply": "^0.1.3"
1327
- },
1328
- "dependencies": {
1329
- "object-assign": {
1330
- "version": "1.0.0",
1331
- "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-1.0.0.tgz",
1332
- "integrity": "sha1-5l3Idm07R7S4MHRlyDEdoDCwcKY=",
1333
- "dev": true
1334
- },
1335
- "readable-stream": {
1336
- "version": "1.0.34",
1337
- "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz",
1338
- "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=",
1339
- "dev": true,
1340
- "requires": {
1341
- "core-util-is": "~1.0.0",
1342
- "inherits": "~2.0.1",
1343
- "isarray": "0.0.1",
1344
- "string_decoder": "~0.10.x"
1345
- }
1346
- },
1347
- "through2": {
1348
- "version": "0.6.5",
1349
- "resolved": "https://registry.npmjs.org/through2/-/through2-0.6.5.tgz",
1350
- "integrity": "sha1-QaucZ7KdVyCQcUEOHXp6lozTrUg=",
1351
- "dev": true,
1352
- "requires": {
1353
- "readable-stream": ">=1.0.33-1 <1.1.0-0",
1354
- "xtend": ">=4.0.0 <4.1.0-0"
1355
- }
1356
- }
1357
- }
1358
- },
1359
- "gulp-beautify": {
1360
- "version": "2.0.1",
1361
- "resolved": "https://registry.npmjs.org/gulp-beautify/-/gulp-beautify-2.0.1.tgz",
1362
- "integrity": "sha1-1bfBTQAgMrpa6mFvAt1cktnmV+w=",
1363
- "dev": true,
1364
- "requires": {
1365
- "js-beautify": "^1.5.10",
1366
- "rcloader": "^0.2.1",
1367
- "through2": "^2.0.0"
1368
- }
1369
- },
1370
- "gulp-combine-media-queries": {
1371
- "version": "0.2.0",
1372
- "resolved": "https://registry.npmjs.org/gulp-combine-media-queries/-/gulp-combine-media-queries-0.2.0.tgz",
1373
- "integrity": "sha1-uuA/s8qBKdkJbAyT/k3rVfPLQR8=",
1374
- "dev": true,
1375
- "requires": {
1376
- "css-parse": "~1.7.0",
1377
- "gulp-util": "~2.2.14",
1378
- "lodash.defaults": "~2.4.1",
1379
- "through2": "~0.4.1"
1380
- },
1381
- "dependencies": {
1382
- "ansi-regex": {
1383
- "version": "0.2.1",
1384
- "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-0.2.1.tgz",
1385
- "integrity": "sha1-DY6UaWej2BQ/k+JOKYUl/BsiNfk=",
1386
- "dev": true
1387
- },
1388
- "ansi-styles": {
1389
- "version": "1.1.0",
1390
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-1.1.0.tgz",
1391
- "integrity": "sha1-6uy/Zs1waIJ2Cy9GkVgrj1XXp94=",
1392
- "dev": true
1393
- },
1394
- "chalk": {
1395
- "version": "0.5.1",
1396
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-0.5.1.tgz",
1397
- "integrity": "sha1-Zjs6ZItotV0EaQ1JFnqoN4WPIXQ=",
1398
- "dev": true,
1399
- "requires": {
1400
- "ansi-styles": "^1.1.0",
1401
- "escape-string-regexp": "^1.0.0",
1402
- "has-ansi": "^0.1.0",
1403
- "strip-ansi": "^0.3.0",
1404
- "supports-color": "^0.2.0"
1405
- }
1406
- },
1407
- "dateformat": {
1408
- "version": "1.0.12",
1409
- "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-1.0.12.tgz",
1410
- "integrity": "sha1-nxJLZ1lMk3/3BpMuSmQsyo27/uk=",
1411
- "dev": true,
1412
- "requires": {
1413
- "get-stdin": "^4.0.1",
1414
- "meow": "^3.3.0"
1415
- }
1416
- },
1417
- "gulp-util": {
1418
- "version": "2.2.20",
1419
- "resolved": "https://registry.npmjs.org/gulp-util/-/gulp-util-2.2.20.tgz",
1420
- "integrity": "sha1-1xRuVyiRC9jwR6awseVJvCLb1kw=",
1421
- "dev": true,
1422
- "requires": {
1423
- "chalk": "^0.5.0",
1424
- "dateformat": "^1.0.7-1.2.3",
1425
- "lodash._reinterpolate": "^2.4.1",
1426
- "lodash.template": "^2.4.1",
1427
- "minimist": "^0.2.0",
1428
- "multipipe": "^0.1.0",
1429
- "through2": "^0.5.0",
1430
- "vinyl": "^0.2.1"
1431
- },
1432
- "dependencies": {
1433
- "through2": {
1434
- "version": "0.5.1",
1435
- "resolved": "https://registry.npmjs.org/through2/-/through2-0.5.1.tgz",
1436
- "integrity": "sha1-390BLrnHAOIyP9M084rGIqs3Lac=",
1437
- "dev": true,
1438
- "requires": {
1439
- "readable-stream": "~1.0.17",
1440
- "xtend": "~3.0.0"
1441
- }
1442
- }
1443
- }
1444
- },
1445
- "has-ansi": {
1446
- "version": "0.1.0",
1447
- "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-0.1.0.tgz",
1448
- "integrity": "sha1-hPJlqujA5qiKEtcCKJS3VoiUxi4=",
1449
- "dev": true,
1450
- "requires": {
1451
- "ansi-regex": "^0.2.0"
1452
- }
1453
- },
1454
- "lodash._reinterpolate": {
1455
- "version": "2.4.1",
1456
- "resolved": "https://registry.npmjs.org/lodash._reinterpolate/-/lodash._reinterpolate-2.4.1.tgz",
1457
- "integrity": "sha1-TxInqlqHEfxjL1sHofRgequLMiI=",
1458
- "dev": true
1459
- },
1460
- "lodash.escape": {
1461
- "version": "2.4.1",
1462
- "resolved": "https://registry.npmjs.org/lodash.escape/-/lodash.escape-2.4.1.tgz",
1463
- "integrity": "sha1-LOEsXghNsKV92l5dHu659dF1o7Q=",
1464
- "dev": true,
1465
- "requires": {
1466
- "lodash._escapehtmlchar": "~2.4.1",
1467
- "lodash._reunescapedhtml": "~2.4.1",
1468
- "lodash.keys": "~2.4.1"
1469
- }
1470
- },
1471
- "lodash.isobject": {
1472
- "version": "2.4.1",
1473
- "resolved": "https://registry.npmjs.org/lodash.isobject/-/lodash.isobject-2.4.1.tgz",
1474
- "integrity": "sha1-Wi5H/mmVPx7mMafrof5k0tBlWPU=",
1475
- "dev": true,
1476
- "requires": {
1477
- "lodash._objecttypes": "~2.4.1"
1478
- }
1479
- },
1480
- "lodash.keys": {
1481
- "version": "2.4.1",
1482
- "resolved": "https://registry.npmjs.org/lodash.keys/-/lodash.keys-2.4.1.tgz",
1483
- "integrity": "sha1-SN6kbfj/djKxDXBrissmWR4rNyc=",
1484
- "dev": true,
1485
- "requires": {
1486
- "lodash._isnative": "~2.4.1",
1487
- "lodash._shimkeys": "~2.4.1",
1488
- "lodash.isobject": "~2.4.1"
1489
- }
1490
- },
1491
- "lodash.template": {
1492
- "version": "2.4.1",
1493
- "resolved": "https://registry.npmjs.org/lodash.template/-/lodash.template-2.4.1.tgz",
1494
- "integrity": "sha1-nmEQB+32KRKal0qzxIuBez4c8g0=",
1495
- "dev": true,
1496
- "requires": {
1497
- "lodash._escapestringchar": "~2.4.1",
1498
- "lodash._reinterpolate": "~2.4.1",
1499
- "lodash.defaults": "~2.4.1",
1500
- "lodash.escape": "~2.4.1",
1501
- "lodash.keys": "~2.4.1",
1502
- "lodash.templatesettings": "~2.4.1",
1503
- "lodash.values": "~2.4.1"
1504
- }
1505
- },
1506
- "lodash.templatesettings": {
1507
- "version": "2.4.1",
1508
- "resolved": "https://registry.npmjs.org/lodash.templatesettings/-/lodash.templatesettings-2.4.1.tgz",
1509
- "integrity": "sha1-6nbHXRHrhtTb6JqDiTu4YZKaxpk=",
1510
- "dev": true,
1511
- "requires": {
1512
- "lodash._reinterpolate": "~2.4.1",
1513
- "lodash.escape": "~2.4.1"
1514
- }
1515
- },
1516
- "minimist": {
1517
- "version": "0.2.0",
1518
- "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.2.0.tgz",
1519
- "integrity": "sha1-Tf/lJdriuGTGbC4jxicdev3s784=",
1520
- "dev": true
1521
- },
1522
- "readable-stream": {
1523
- "version": "1.0.34",
1524
- "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz",
1525
- "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=",
1526
- "dev": true,
1527
- "requires": {
1528
- "core-util-is": "~1.0.0",
1529
- "inherits": "~2.0.1",
1530
- "isarray": "0.0.1",
1531
- "string_decoder": "~0.10.x"
1532
- }
1533
- },
1534
- "strip-ansi": {
1535
- "version": "0.3.0",
1536
- "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-0.3.0.tgz",
1537
- "integrity": "sha1-JfSOoiynkYfzF0pNuHWTR7sSYiA=",
1538
- "dev": true,
1539
- "requires": {
1540
- "ansi-regex": "^0.2.1"
1541
- }
1542
- },
1543
- "supports-color": {
1544
- "version": "0.2.0",
1545
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-0.2.0.tgz",
1546
- "integrity": "sha1-2S3iaU6z9nMjlz1649i1W0wiGQo=",
1547
- "dev": true
1548
- },
1549
- "through2": {
1550
- "version": "0.4.2",
1551
- "resolved": "https://registry.npmjs.org/through2/-/through2-0.4.2.tgz",
1552
- "integrity": "sha1-2/WGYDEVHsg1K7bE22SiKSqEC5s=",
1553
- "dev": true,
1554
- "requires": {
1555
- "readable-stream": "~1.0.17",
1556
- "xtend": "~2.1.1"
1557
- },
1558
- "dependencies": {
1559
- "xtend": {
1560
- "version": "2.1.2",
1561
- "resolved": "https://registry.npmjs.org/xtend/-/xtend-2.1.2.tgz",
1562
- "integrity": "sha1-bv7MKk2tjmlixJAbM3znuoe10os=",
1563
- "dev": true,
1564
- "requires": {
1565
- "object-keys": "~0.4.0"
1566
- }
1567
- }
1568
- }
1569
- },
1570
- "vinyl": {
1571
- "version": "0.2.3",
1572
- "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-0.2.3.tgz",
1573
- "integrity": "sha1-vKk4IJWC7FpJrVOKAPofEl5RMlI=",
1574
- "dev": true,
1575
- "requires": {
1576
- "clone-stats": "~0.0.1"
1577
- }
1578
- },
1579
- "xtend": {
1580
- "version": "3.0.0",
1581
- "resolved": "https://registry.npmjs.org/xtend/-/xtend-3.0.0.tgz",
1582
- "integrity": "sha1-XM50B7r2Qsunvs2laBEcST9ZZlo=",
1583
- "dev": true
1584
- }
1585
- }
1586
- },
1587
- "gulp-concat": {
1588
- "version": "2.1.7",
1589
- "resolved": "https://registry.npmjs.org/gulp-concat/-/gulp-concat-2.1.7.tgz",
1590
- "integrity": "sha1-biJ9dBeDXYiwg7xEuLTUG7fkElU=",
1591
- "dev": true,
1592
- "requires": {
1593
- "gulp-util": "~2.2.5",
1594
- "through": "~2.3.4"
1595
- },
1596
- "dependencies": {
1597
- "ansi-regex": {
1598
- "version": "0.2.1",
1599
- "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-0.2.1.tgz",
1600
- "integrity": "sha1-DY6UaWej2BQ/k+JOKYUl/BsiNfk=",
1601
- "dev": true
1602
- },
1603
- "ansi-styles": {
1604
- "version": "1.1.0",
1605
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-1.1.0.tgz",
1606
- "integrity": "sha1-6uy/Zs1waIJ2Cy9GkVgrj1XXp94=",
1607
- "dev": true
1608
- },
1609
- "chalk": {
1610
- "version": "0.5.1",
1611
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-0.5.1.tgz",
1612
- "integrity": "sha1-Zjs6ZItotV0EaQ1JFnqoN4WPIXQ=",
1613
- "dev": true,
1614
- "requires": {
1615
- "ansi-styles": "^1.1.0",
1616
- "escape-string-regexp": "^1.0.0",
1617
- "has-ansi": "^0.1.0",
1618
- "strip-ansi": "^0.3.0",
1619
- "supports-color": "^0.2.0"
1620
- }
1621
- },
1622
- "dateformat": {
1623
- "version": "1.0.12",
1624
- "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-1.0.12.tgz",
1625
- "integrity": "sha1-nxJLZ1lMk3/3BpMuSmQsyo27/uk=",
1626
- "dev": true,
1627
- "requires": {
1628
- "get-stdin": "^4.0.1",
1629
- "meow": "^3.3.0"
1630
- }
1631
- },
1632
- "gulp-util": {
1633
- "version": "2.2.20",
1634
- "resolved": "https://registry.npmjs.org/gulp-util/-/gulp-util-2.2.20.tgz",
1635
- "integrity": "sha1-1xRuVyiRC9jwR6awseVJvCLb1kw=",
1636
- "dev": true,
1637
- "requires": {
1638
- "chalk": "^0.5.0",
1639
- "dateformat": "^1.0.7-1.2.3",
1640
- "lodash._reinterpolate": "^2.4.1",
1641
- "lodash.template": "^2.4.1",
1642
- "minimist": "^0.2.0",
1643
- "multipipe": "^0.1.0",
1644
- "through2": "^0.5.0",
1645
- "vinyl": "^0.2.1"
1646
- }
1647
- },
1648
- "has-ansi": {
1649
- "version": "0.1.0",
1650
- "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-0.1.0.tgz",
1651
- "integrity": "sha1-hPJlqujA5qiKEtcCKJS3VoiUxi4=",
1652
- "dev": true,
1653
- "requires": {
1654
- "ansi-regex": "^0.2.0"
1655
- }
1656
- },
1657
- "lodash._reinterpolate": {
1658
- "version": "2.4.1",
1659
- "resolved": "https://registry.npmjs.org/lodash._reinterpolate/-/lodash._reinterpolate-2.4.1.tgz",
1660
- "integrity": "sha1-TxInqlqHEfxjL1sHofRgequLMiI=",
1661
- "dev": true
1662
- },
1663
- "lodash.escape": {
1664
- "version": "2.4.1",
1665
- "resolved": "https://registry.npmjs.org/lodash.escape/-/lodash.escape-2.4.1.tgz",
1666
- "integrity": "sha1-LOEsXghNsKV92l5dHu659dF1o7Q=",
1667
- "dev": true,
1668
- "requires": {
1669
- "lodash._escapehtmlchar": "~2.4.1",
1670
- "lodash._reunescapedhtml": "~2.4.1",
1671
- "lodash.keys": "~2.4.1"
1672
- }
1673
- },
1674
- "lodash.isobject": {
1675
- "version": "2.4.1",
1676
- "resolved": "https://registry.npmjs.org/lodash.isobject/-/lodash.isobject-2.4.1.tgz",
1677
- "integrity": "sha1-Wi5H/mmVPx7mMafrof5k0tBlWPU=",
1678
- "dev": true,
1679
- "requires": {
1680
- "lodash._objecttypes": "~2.4.1"
1681
- }
1682
- },
1683
- "lodash.keys": {
1684
- "version": "2.4.1",
1685
- "resolved": "https://registry.npmjs.org/lodash.keys/-/lodash.keys-2.4.1.tgz",
1686
- "integrity": "sha1-SN6kbfj/djKxDXBrissmWR4rNyc=",
1687
- "dev": true,
1688
- "requires": {
1689
- "lodash._isnative": "~2.4.1",
1690
- "lodash._shimkeys": "~2.4.1",
1691
- "lodash.isobject": "~2.4.1"
1692
- }
1693
- },
1694
- "lodash.template": {
1695
- "version": "2.4.1",
1696
- "resolved": "https://registry.npmjs.org/lodash.template/-/lodash.template-2.4.1.tgz",
1697
- "integrity": "sha1-nmEQB+32KRKal0qzxIuBez4c8g0=",
1698
- "dev": true,
1699
- "requires": {
1700
- "lodash._escapestringchar": "~2.4.1",
1701
- "lodash._reinterpolate": "~2.4.1",
1702
- "lodash.defaults": "~2.4.1",
1703
- "lodash.escape": "~2.4.1",
1704
- "lodash.keys": "~2.4.1",
1705
- "lodash.templatesettings": "~2.4.1",
1706
- "lodash.values": "~2.4.1"
1707
- }
1708
- },
1709
- "lodash.templatesettings": {
1710
- "version": "2.4.1",
1711
- "resolved": "https://registry.npmjs.org/lodash.templatesettings/-/lodash.templatesettings-2.4.1.tgz",
1712
- "integrity": "sha1-6nbHXRHrhtTb6JqDiTu4YZKaxpk=",
1713
- "dev": true,
1714
- "requires": {
1715
- "lodash._reinterpolate": "~2.4.1",
1716
- "lodash.escape": "~2.4.1"
1717
- }
1718
- },
1719
- "minimist": {
1720
- "version": "0.2.0",
1721
- "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.2.0.tgz",
1722
- "integrity": "sha1-Tf/lJdriuGTGbC4jxicdev3s784=",
1723
- "dev": true
1724
- },
1725
- "readable-stream": {
1726
- "version": "1.0.34",
1727
- "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz",
1728
- "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=",
1729
- "dev": true,
1730
- "requires": {
1731
- "core-util-is": "~1.0.0",
1732
- "inherits": "~2.0.1",
1733
- "isarray": "0.0.1",
1734
- "string_decoder": "~0.10.x"
1735
- }
1736
- },
1737
- "strip-ansi": {
1738
- "version": "0.3.0",
1739
- "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-0.3.0.tgz",
1740
- "integrity": "sha1-JfSOoiynkYfzF0pNuHWTR7sSYiA=",
1741
- "dev": true,
1742
- "requires": {
1743
- "ansi-regex": "^0.2.1"
1744
- }
1745
- },
1746
- "supports-color": {
1747
- "version": "0.2.0",
1748
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-0.2.0.tgz",
1749
- "integrity": "sha1-2S3iaU6z9nMjlz1649i1W0wiGQo=",
1750
- "dev": true
1751
- },
1752
- "through2": {
1753
- "version": "0.5.1",
1754
- "resolved": "https://registry.npmjs.org/through2/-/through2-0.5.1.tgz",
1755
- "integrity": "sha1-390BLrnHAOIyP9M084rGIqs3Lac=",
1756
- "dev": true,
1757
- "requires": {
1758
- "readable-stream": "~1.0.17",
1759
- "xtend": "~3.0.0"
1760
- }
1761
- },
1762
- "vinyl": {
1763
- "version": "0.2.3",
1764
- "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-0.2.3.tgz",
1765
- "integrity": "sha1-vKk4IJWC7FpJrVOKAPofEl5RMlI=",
1766
- "dev": true,
1767
- "requires": {
1768
- "clone-stats": "~0.0.1"
1769
- }
1770
- },
1771
- "xtend": {
1772
- "version": "3.0.0",
1773
- "resolved": "https://registry.npmjs.org/xtend/-/xtend-3.0.0.tgz",
1774
- "integrity": "sha1-XM50B7r2Qsunvs2laBEcST9ZZlo=",
1775
- "dev": true
1776
- }
1777
- }
1778
- },
1779
- "gulp-csscomb": {
1780
- "version": "3.0.8",
1781
- "resolved": "https://registry.npmjs.org/gulp-csscomb/-/gulp-csscomb-3.0.8.tgz",
1782
- "integrity": "sha1-3zSCSlgKTH0zUcHo67ateh1aibc=",
1783
- "dev": true,
1784
- "requires": {
1785
- "csscomb": "^3.1.7",
1786
- "gulp-util": "^3.0.7",
1787
- "through2": "^2.0.1"
1788
- }
1789
- },
1790
- "gulp-exec": {
1791
- "version": "2.0.1",
1792
- "resolved": "https://registry.npmjs.org/gulp-exec/-/gulp-exec-2.0.1.tgz",
1793
- "integrity": "sha1-/jCSqQb5iNC+cmSkv/JKKt37dWo=",
1794
- "dev": true,
1795
- "requires": {
1796
- "gulp-util": "^2.2.14",
1797
- "through2": "^0.4.1"
1798
- },
1799
- "dependencies": {
1800
- "ansi-regex": {
1801
- "version": "0.2.1",
1802
- "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-0.2.1.tgz",
1803
- "integrity": "sha1-DY6UaWej2BQ/k+JOKYUl/BsiNfk=",
1804
- "dev": true
1805
- },
1806
- "ansi-styles": {
1807
- "version": "1.1.0",
1808
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-1.1.0.tgz",
1809
- "integrity": "sha1-6uy/Zs1waIJ2Cy9GkVgrj1XXp94=",
1810
- "dev": true
1811
- },
1812
- "chalk": {
1813
- "version": "0.5.1",
1814
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-0.5.1.tgz",
1815
- "integrity": "sha1-Zjs6ZItotV0EaQ1JFnqoN4WPIXQ=",
1816
- "dev": true,
1817
- "requires": {
1818
- "ansi-styles": "^1.1.0",
1819
- "escape-string-regexp": "^1.0.0",
1820
- "has-ansi": "^0.1.0",
1821
- "strip-ansi": "^0.3.0",
1822
- "supports-color": "^0.2.0"
1823
- }
1824
- },
1825
- "dateformat": {
1826
- "version": "1.0.12",
1827
- "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-1.0.12.tgz",
1828
- "integrity": "sha1-nxJLZ1lMk3/3BpMuSmQsyo27/uk=",
1829
- "dev": true,
1830
- "requires": {
1831
- "get-stdin": "^4.0.1",
1832
- "meow": "^3.3.0"
1833
- }
1834
- },
1835
- "gulp-util": {
1836
- "version": "2.2.20",
1837
- "resolved": "https://registry.npmjs.org/gulp-util/-/gulp-util-2.2.20.tgz",
1838
- "integrity": "sha1-1xRuVyiRC9jwR6awseVJvCLb1kw=",
1839
- "dev": true,
1840
- "requires": {
1841
- "chalk": "^0.5.0",
1842
- "dateformat": "^1.0.7-1.2.3",
1843
- "lodash._reinterpolate": "^2.4.1",
1844
- "lodash.template": "^2.4.1",
1845
- "minimist": "^0.2.0",
1846
- "multipipe": "^0.1.0",
1847
- "through2": "^0.5.0",
1848
- "vinyl": "^0.2.1"
1849
- },
1850
- "dependencies": {
1851
- "through2": {
1852
- "version": "0.5.1",
1853
- "resolved": "https://registry.npmjs.org/through2/-/through2-0.5.1.tgz",
1854
- "integrity": "sha1-390BLrnHAOIyP9M084rGIqs3Lac=",
1855
- "dev": true,
1856
- "requires": {
1857
- "readable-stream": "~1.0.17",
1858
- "xtend": "~3.0.0"
1859
- }
1860
- }
1861
- }
1862
- },
1863
- "has-ansi": {
1864
- "version": "0.1.0",
1865
- "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-0.1.0.tgz",
1866
- "integrity": "sha1-hPJlqujA5qiKEtcCKJS3VoiUxi4=",
1867
- "dev": true,
1868
- "requires": {
1869
- "ansi-regex": "^0.2.0"
1870
- }
1871
- },
1872
- "lodash._reinterpolate": {
1873
- "version": "2.4.1",
1874
- "resolved": "https://registry.npmjs.org/lodash._reinterpolate/-/lodash._reinterpolate-2.4.1.tgz",
1875
- "integrity": "sha1-TxInqlqHEfxjL1sHofRgequLMiI=",
1876
- "dev": true
1877
- },
1878
- "lodash.escape": {
1879
- "version": "2.4.1",
1880
- "resolved": "https://registry.npmjs.org/lodash.escape/-/lodash.escape-2.4.1.tgz",
1881
- "integrity": "sha1-LOEsXghNsKV92l5dHu659dF1o7Q=",
1882
- "dev": true,
1883
- "requires": {
1884
- "lodash._escapehtmlchar": "~2.4.1",
1885
- "lodash._reunescapedhtml": "~2.4.1",
1886
- "lodash.keys": "~2.4.1"
1887
- }
1888
- },
1889
- "lodash.isobject": {
1890
- "version": "2.4.1",
1891
- "resolved": "https://registry.npmjs.org/lodash.isobject/-/lodash.isobject-2.4.1.tgz",
1892
- "integrity": "sha1-Wi5H/mmVPx7mMafrof5k0tBlWPU=",
1893
- "dev": true,
1894
- "requires": {
1895
- "lodash._objecttypes": "~2.4.1"
1896
- }
1897
- },
1898
- "lodash.keys": {
1899
- "version": "2.4.1",
1900
- "resolved": "https://registry.npmjs.org/lodash.keys/-/lodash.keys-2.4.1.tgz",
1901
- "integrity": "sha1-SN6kbfj/djKxDXBrissmWR4rNyc=",
1902
- "dev": true,
1903
- "requires": {
1904
- "lodash._isnative": "~2.4.1",
1905
- "lodash._shimkeys": "~2.4.1",
1906
- "lodash.isobject": "~2.4.1"
1907
- }
1908
- },
1909
- "lodash.template": {
1910
- "version": "2.4.1",
1911
- "resolved": "https://registry.npmjs.org/lodash.template/-/lodash.template-2.4.1.tgz",
1912
- "integrity": "sha1-nmEQB+32KRKal0qzxIuBez4c8g0=",
1913
- "dev": true,
1914
- "requires": {
1915
- "lodash._escapestringchar": "~2.4.1",
1916
- "lodash._reinterpolate": "~2.4.1",
1917
- "lodash.defaults": "~2.4.1",
1918
- "lodash.escape": "~2.4.1",
1919
- "lodash.keys": "~2.4.1",
1920
- "lodash.templatesettings": "~2.4.1",
1921
- "lodash.values": "~2.4.1"
1922
- }
1923
- },
1924
- "lodash.templatesettings": {
1925
- "version": "2.4.1",
1926
- "resolved": "https://registry.npmjs.org/lodash.templatesettings/-/lodash.templatesettings-2.4.1.tgz",
1927
- "integrity": "sha1-6nbHXRHrhtTb6JqDiTu4YZKaxpk=",
1928
- "dev": true,
1929
- "requires": {
1930
- "lodash._reinterpolate": "~2.4.1",
1931
- "lodash.escape": "~2.4.1"
1932
- }
1933
- },
1934
- "minimist": {
1935
- "version": "0.2.0",
1936
- "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.2.0.tgz",
1937
- "integrity": "sha1-Tf/lJdriuGTGbC4jxicdev3s784=",
1938
- "dev": true
1939
- },
1940
- "readable-stream": {
1941
- "version": "1.0.34",
1942
- "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz",
1943
- "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=",
1944
- "dev": true,
1945
- "requires": {
1946
- "core-util-is": "~1.0.0",
1947
- "inherits": "~2.0.1",
1948
- "isarray": "0.0.1",
1949
- "string_decoder": "~0.10.x"
1950
- }
1951
- },
1952
- "strip-ansi": {
1953
- "version": "0.3.0",
1954
- "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-0.3.0.tgz",
1955
- "integrity": "sha1-JfSOoiynkYfzF0pNuHWTR7sSYiA=",
1956
- "dev": true,
1957
- "requires": {
1958
- "ansi-regex": "^0.2.1"
1959
- }
1960
- },
1961
- "supports-color": {
1962
- "version": "0.2.0",
1963
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-0.2.0.tgz",
1964
- "integrity": "sha1-2S3iaU6z9nMjlz1649i1W0wiGQo=",
1965
- "dev": true
1966
- },
1967
- "through2": {
1968
- "version": "0.4.2",
1969
- "resolved": "https://registry.npmjs.org/through2/-/through2-0.4.2.tgz",
1970
- "integrity": "sha1-2/WGYDEVHsg1K7bE22SiKSqEC5s=",
1971
- "dev": true,
1972
- "requires": {
1973
- "readable-stream": "~1.0.17",
1974
- "xtend": "~2.1.1"
1975
- },
1976
- "dependencies": {
1977
- "xtend": {
1978
- "version": "2.1.2",
1979
- "resolved": "https://registry.npmjs.org/xtend/-/xtend-2.1.2.tgz",
1980
- "integrity": "sha1-bv7MKk2tjmlixJAbM3znuoe10os=",
1981
- "dev": true,
1982
- "requires": {
1983
- "object-keys": "~0.4.0"
1984
- }
1985
- }
1986
- }
1987
- },
1988
- "vinyl": {
1989
- "version": "0.2.3",
1990
- "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-0.2.3.tgz",
1991
- "integrity": "sha1-vKk4IJWC7FpJrVOKAPofEl5RMlI=",
1992
- "dev": true,
1993
- "requires": {
1994
- "clone-stats": "~0.0.1"
1995
- }
1996
- },
1997
- "xtend": {
1998
- "version": "3.0.0",
1999
- "resolved": "https://registry.npmjs.org/xtend/-/xtend-3.0.0.tgz",
2000
- "integrity": "sha1-XM50B7r2Qsunvs2laBEcST9ZZlo=",
2001
- "dev": true
2002
- }
2003
- }
2004
- },
2005
- "gulp-ignore": {
2006
- "version": "2.0.2",
2007
- "resolved": "https://registry.npmjs.org/gulp-ignore/-/gulp-ignore-2.0.2.tgz",
2008
- "integrity": "sha1-XC6ioKRALgq0orzRLv2SlTRNePI=",
2009
- "dev": true,
2010
- "requires": {
2011
- "gulp-match": "^1.0.3",
2012
- "through2": "^2.0.1"
2013
- }
2014
- },
2015
- "gulp-match": {
2016
- "version": "1.0.3",
2017
- "resolved": "https://registry.npmjs.org/gulp-match/-/gulp-match-1.0.3.tgz",
2018
- "integrity": "sha1-kcfA1/Kb7NZgbVfYCn+Hdqh6uo4=",
2019
- "dev": true,
2020
- "requires": {
2021
- "minimatch": "^3.0.3"
2022
- }
2023
- },
2024
- "gulp-minify-css": {
2025
- "version": "1.2.4",
2026
- "resolved": "https://registry.npmjs.org/gulp-minify-css/-/gulp-minify-css-1.2.4.tgz",
2027
- "integrity": "sha1-thZJV2Auon+eWtiCJ2ld0gV3jAY=",
2028
- "dev": true,
2029
- "requires": {
2030
- "clean-css": "^3.3.3",
2031
- "gulp-util": "^3.0.5",
2032
- "object-assign": "^4.0.1",
2033
- "readable-stream": "^2.0.0",
2034
- "vinyl-bufferstream": "^1.0.1",
2035
- "vinyl-sourcemaps-apply": "^0.2.0"
2036
- },
2037
- "dependencies": {
2038
- "isarray": {
2039
- "version": "1.0.0",
2040
- "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
2041
- "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
2042
- "dev": true
2043
- },
2044
- "readable-stream": {
2045
- "version": "2.3.3",
2046
- "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz",
2047
- "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==",
2048
- "dev": true,
2049
- "requires": {
2050
- "core-util-is": "~1.0.0",
2051
- "inherits": "~2.0.3",
2052
- "isarray": "~1.0.0",
2053
- "process-nextick-args": "~1.0.6",
2054
- "safe-buffer": "~5.1.1",
2055
- "string_decoder": "~1.0.3",
2056
- "util-deprecate": "~1.0.1"
2057
- }
2058
- },
2059
- "source-map": {
2060
- "version": "0.5.7",
2061
- "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
2062
- "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=",
2063
- "dev": true
2064
- },
2065
- "string_decoder": {
2066
- "version": "1.0.3",
2067
- "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz",
2068
- "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==",
2069
- "dev": true,
2070
- "requires": {
2071
- "safe-buffer": "~5.1.0"
2072
- }
2073
- },
2074
- "vinyl-sourcemaps-apply": {
2075
- "version": "0.2.1",
2076
- "resolved": "https://registry.npmjs.org/vinyl-sourcemaps-apply/-/vinyl-sourcemaps-apply-0.2.1.tgz",
2077
- "integrity": "sha1-q2VJ1h0XLCsbh75cUI0jnI74dwU=",
2078
- "dev": true,
2079
- "requires": {
2080
- "source-map": "^0.5.1"
2081
- }
2082
- }
2083
- }
2084
- },
2085
- "gulp-notify": {
2086
- "version": "3.0.0",
2087
- "resolved": "https://registry.npmjs.org/gulp-notify/-/gulp-notify-3.0.0.tgz",
2088
- "integrity": "sha1-oEuK+azb5OY8hFZ4zgw9MGlMWaM=",
2089
- "dev": true,
2090
- "requires": {
2091
- "gulp-util": "^3.0.8",
2092
- "lodash.template": "^4.4.0",
2093
- "node-notifier": "^5.0.1",
2094
- "node.extend": "^1.1.6",
2095
- "through2": "^2.0.3"
2096
- },
2097
- "dependencies": {
2098
- "lodash.template": {
2099
- "version": "4.4.0",
2100
- "resolved": "https://registry.npmjs.org/lodash.template/-/lodash.template-4.4.0.tgz",
2101
- "integrity": "sha1-5zoDhcg1VZF0bgILmWecaQ5o+6A=",
2102
- "dev": true,
2103
- "requires": {
2104
- "lodash._reinterpolate": "~3.0.0",
2105
- "lodash.templatesettings": "^4.0.0"
2106
- }
2107
- },
2108
- "lodash.templatesettings": {
2109
- "version": "4.1.0",
2110
- "resolved": "https://registry.npmjs.org/lodash.templatesettings/-/lodash.templatesettings-4.1.0.tgz",
2111
- "integrity": "sha1-K01OlbpEDZFf8IvImeRVNmZxMxY=",
2112
- "dev": true,
2113
- "requires": {
2114
- "lodash._reinterpolate": "~3.0.0"
2115
- }
2116
- }
2117
- }
2118
- },
2119
- "gulp-postcss": {
2120
- "version": "7.0.0",
2121
- "resolved": "https://registry.npmjs.org/gulp-postcss/-/gulp-postcss-7.0.0.tgz",
2122
- "integrity": "sha1-z7YqGfqUf4vmfOnsronOuVnwz5M=",
2123
- "dev": true,
2124
- "requires": {
2125
- "gulp-util": "^3.0.8",
2126
- "postcss": "^6.0.0",
2127
- "postcss-load-config": "^1.2.0",
2128
- "vinyl-sourcemaps-apply": "^0.2.1"
2129
- },
2130
- "dependencies": {
2131
- "ansi-styles": {
2132
- "version": "3.2.0",
2133
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz",
2134
- "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==",
2135
- "dev": true,
2136
- "requires": {
2137
- "color-convert": "^1.9.0"
2138
- }
2139
- },
2140
- "chalk": {
2141
- "version": "2.3.0",
2142
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.0.tgz",
2143
- "integrity": "sha512-Az5zJR2CBujap2rqXGaJKaPHyJ0IrUimvYNX+ncCy8PJP4ltOGTrHUIo097ZaL2zMeKYpiCdqDvS6zdrTFok3Q==",
2144
- "dev": true,
2145
- "requires": {
2146
- "ansi-styles": "^3.1.0",
2147
- "escape-string-regexp": "^1.0.5",
2148
- "supports-color": "^4.0.0"
2149
- }
2150
- },
2151
- "postcss": {
2152
- "version": "6.0.14",
2153
- "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.14.tgz",
2154
- "integrity": "sha512-NJ1z0f+1offCgadPhz+DvGm5Mkci+mmV5BqD13S992o0Xk9eElxUfPPF+t2ksH5R/17gz4xVK8KWocUQ5o3Rog==",
2155
- "dev": true,
2156
- "requires": {
2157
- "chalk": "^2.3.0",
2158
- "source-map": "^0.6.1",
2159
- "supports-color": "^4.4.0"
2160
- }
2161
- },
2162
- "source-map": {
2163
- "version": "0.6.1",
2164
- "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
2165
- "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
2166
- "dev": true
2167
- },
2168
- "supports-color": {
2169
- "version": "4.5.0",
2170
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz",
2171
- "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=",
2172
- "dev": true,
2173
- "requires": {
2174
- "has-flag": "^2.0.0"
2175
- }
2176
- },
2177
- "vinyl-sourcemaps-apply": {
2178
- "version": "0.2.1",
2179
- "resolved": "https://registry.npmjs.org/vinyl-sourcemaps-apply/-/vinyl-sourcemaps-apply-0.2.1.tgz",
2180
- "integrity": "sha1-q2VJ1h0XLCsbh75cUI0jnI74dwU=",
2181
- "dev": true,
2182
- "requires": {
2183
- "source-map": "^0.5.1"
2184
- },
2185
- "dependencies": {
2186
- "source-map": {
2187
- "version": "0.5.7",
2188
- "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
2189
- "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=",
2190
- "dev": true
2191
- }
2192
- }
2193
- }
2194
- }
2195
- },
2196
- "gulp-rename": {
2197
- "version": "1.2.2",
2198
- "resolved": "https://registry.npmjs.org/gulp-rename/-/gulp-rename-1.2.2.tgz",
2199
- "integrity": "sha1-OtRCh2PwXidk3sHGfYaNsnVoeBc=",
2200
- "dev": true
2201
- },
2202
- "gulp-replace": {
2203
- "version": "0.4.0",
2204
- "resolved": "https://registry.npmjs.org/gulp-replace/-/gulp-replace-0.4.0.tgz",
2205
- "integrity": "sha1-4ivJwD6dBRsyiBzFib0+jE5UFoo=",
2206
- "dev": true,
2207
- "requires": {
2208
- "event-stream": "~3.0.18",
2209
- "istextorbinary": "~1.0.0",
2210
- "replacestream": "0.1.3"
2211
- }
2212
- },
2213
- "gulp-sass": {
2214
- "version": "3.1.0",
2215
- "resolved": "https://registry.npmjs.org/gulp-sass/-/gulp-sass-3.1.0.tgz",
2216
- "integrity": "sha1-U9xLaKH13f5EJKtMJHZVJpqLdLc=",
2217
- "dev": true,
2218
- "requires": {
2219
- "gulp-util": "^3.0",
2220
- "lodash.clonedeep": "^4.3.2",
2221
- "node-sass": "^4.2.0",
2222
- "through2": "^2.0.0",
2223
- "vinyl-sourcemaps-apply": "^0.2.0"
2224
- },
2225
- "dependencies": {
2226
- "source-map": {
2227
- "version": "0.5.7",
2228
- "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
2229
- "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=",
2230
- "dev": true
2231
- },
2232
- "vinyl-sourcemaps-apply": {
2233
- "version": "0.2.1",
2234
- "resolved": "https://registry.npmjs.org/vinyl-sourcemaps-apply/-/vinyl-sourcemaps-apply-0.2.1.tgz",
2235
- "integrity": "sha1-q2VJ1h0XLCsbh75cUI0jnI74dwU=",
2236
- "dev": true,
2237
- "requires": {
2238
- "source-map": "^0.5.1"
2239
- }
2240
- }
2241
- }
2242
- },
2243
- "gulp-util": {
2244
- "version": "3.0.8",
2245
- "resolved": "https://registry.npmjs.org/gulp-util/-/gulp-util-3.0.8.tgz",
2246
- "integrity": "sha1-AFTh50RQLifATBh8PsxQXdVLu08=",
2247
- "dev": true,
2248
- "requires": {
2249
- "array-differ": "^1.0.0",
2250
- "array-uniq": "^1.0.2",
2251
- "beeper": "^1.0.0",
2252
- "chalk": "^1.0.0",
2253
- "dateformat": "^2.0.0",
2254
- "fancy-log": "^1.1.0",
2255
- "gulplog": "^1.0.0",
2256
- "has-gulplog": "^0.1.0",
2257
- "lodash._reescape": "^3.0.0",
2258
- "lodash._reevaluate": "^3.0.0",
2259
- "lodash._reinterpolate": "^3.0.0",
2260
- "lodash.template": "^3.0.0",
2261
- "minimist": "^1.1.0",
2262
- "multipipe": "^0.1.2",
2263
- "object-assign": "^3.0.0",
2264
- "replace-ext": "0.0.1",
2265
- "through2": "^2.0.0",
2266
- "vinyl": "^0.5.0"
2267
- },
2268
- "dependencies": {
2269
- "object-assign": {
2270
- "version": "3.0.0",
2271
- "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-3.0.0.tgz",
2272
- "integrity": "sha1-m+3VygiXlJvKR+f/QIBi1Un1h/I=",
2273
- "dev": true
2274
- }
2275
- }
2276
- },
2277
- "gulplog": {
2278
- "version": "1.0.0",
2279
- "resolved": "https://registry.npmjs.org/gulplog/-/gulplog-1.0.0.tgz",
2280
- "integrity": "sha1-4oxNRdBey77YGDY86PnFkmIp/+U=",
2281
- "dev": true,
2282
- "requires": {
2283
- "glogg": "^1.0.0"
2284
- }
2285
- },
2286
- "har-schema": {
2287
- "version": "2.0.0",
2288
- "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz",
2289
- "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=",
2290
- "dev": true
2291
- },
2292
- "har-validator": {
2293
- "version": "5.0.3",
2294
- "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.0.3.tgz",
2295
- "integrity": "sha1-ukAsJmGU8VlW7xXg/PJCmT9qff0=",
2296
- "dev": true,
2297
- "requires": {
2298
- "ajv": "^5.1.0",
2299
- "har-schema": "^2.0.0"
2300
- }
2301
- },
2302
- "has-ansi": {
2303
- "version": "2.0.0",
2304
- "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz",
2305
- "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=",
2306
- "dev": true,
2307
- "requires": {
2308
- "ansi-regex": "^2.0.0"
2309
- }
2310
- },
2311
- "has-flag": {
2312
- "version": "2.0.0",
2313
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz",
2314
- "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=",
2315
- "dev": true
2316
- },
2317
- "has-gulplog": {
2318
- "version": "0.1.0",
2319
- "resolved": "https://registry.npmjs.org/has-gulplog/-/has-gulplog-0.1.0.tgz",
2320
- "integrity": "sha1-ZBTIKRNpfaUVkDl9r7EvIpZ4Ec4=",
2321
- "dev": true,
2322
- "requires": {
2323
- "sparkles": "^1.0.0"
2324
- }
2325
- },
2326
- "has-unicode": {
2327
- "version": "2.0.1",
2328
- "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz",
2329
- "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=",
2330
- "dev": true
2331
- },
2332
- "hawk": {
2333
- "version": "6.0.2",
2334
- "resolved": "https://registry.npmjs.org/hawk/-/hawk-6.0.2.tgz",
2335
- "integrity": "sha512-miowhl2+U7Qle4vdLqDdPt9m09K6yZhkLDTWGoUiUzrQCn+mHHSmfJgAyGaLRZbPmTqfFFjRV1QWCW0VWUJBbQ==",
2336
- "dev": true,
2337
- "requires": {
2338
- "boom": "4.x.x",
2339
- "cryptiles": "3.x.x",
2340
- "hoek": "4.x.x",
2341
- "sntp": "2.x.x"
2342
- }
2343
- },
2344
- "hoek": {
2345
- "version": "4.2.0",
2346
- "resolved": "https://registry.npmjs.org/hoek/-/hoek-4.2.0.tgz",
2347
- "integrity": "sha512-v0XCLxICi9nPfYrS9RL8HbYnXi9obYAeLbSP00BmnZwCK9+Ih9WOjoZ8YoHCoav2csqn4FOz4Orldsy2dmDwmQ==",
2348
- "dev": true
2349
- },
2350
- "homedir-polyfill": {
2351
- "version": "1.0.1",
2352
- "resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.1.tgz",
2353
- "integrity": "sha1-TCu8inWJmP7r9e1oWA921GdotLw=",
2354
- "dev": true,
2355
- "requires": {
2356
- "parse-passwd": "^1.0.0"
2357
- }
2358
- },
2359
- "hosted-git-info": {
2360
- "version": "2.5.0",
2361
- "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.5.0.tgz",
2362
- "integrity": "sha512-pNgbURSuab90KbTqvRPsseaTxOJCZBD0a7t+haSN33piP9cCM4l0CqdzAif2hUqm716UovKB2ROmiabGAKVXyg==",
2363
- "dev": true
2364
- },
2365
- "http-signature": {
2366
- "version": "1.2.0",
2367
- "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz",
2368
- "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=",
2369
- "dev": true,
2370
- "requires": {
2371
- "assert-plus": "^1.0.0",
2372
- "jsprim": "^1.2.2",
2373
- "sshpk": "^1.7.0"
2374
- }
2375
- },
2376
- "in-publish": {
2377
- "version": "2.0.0",
2378
- "resolved": "https://registry.npmjs.org/in-publish/-/in-publish-2.0.0.tgz",
2379
- "integrity": "sha1-4g/146KvwmkDILbcVSaCqcf631E=",
2380
- "dev": true
2381
- },
2382
- "indent-string": {
2383
- "version": "2.1.0",
2384
- "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-2.1.0.tgz",
2385
- "integrity": "sha1-ji1INIdCEhtKghi3oTfppSBJ3IA=",
2386
- "dev": true,
2387
- "requires": {
2388
- "repeating": "^2.0.0"
2389
- }
2390
- },
2391
- "inflight": {
2392
- "version": "1.0.6",
2393
- "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
2394
- "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
2395
- "dev": true,
2396
- "requires": {
2397
- "once": "^1.3.0",
2398
- "wrappy": "1"
2399
- }
2400
- },
2401
- "inherits": {
2402
- "version": "2.0.3",
2403
- "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
2404
- "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=",
2405
- "dev": true
2406
- },
2407
- "ini": {
2408
- "version": "1.3.4",
2409
- "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.4.tgz",
2410
- "integrity": "sha1-BTfLedr1m1mhpRff9wbIbsA5Fi4=",
2411
- "dev": true
2412
- },
2413
- "interpret": {
2414
- "version": "1.0.4",
2415
- "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.0.4.tgz",
2416
- "integrity": "sha1-ggzdWIuGj/sZGoCVBtbJyPISsbA=",
2417
- "dev": true
2418
- },
2419
- "invert-kv": {
2420
- "version": "1.0.0",
2421
- "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz",
2422
- "integrity": "sha1-EEqOSqym09jNFXqO+L+rLXo//bY=",
2423
- "dev": true
2424
- },
2425
- "is": {
2426
- "version": "3.2.1",
2427
- "resolved": "https://registry.npmjs.org/is/-/is-3.2.1.tgz",
2428
- "integrity": "sha1-0Kwq1V63sL7JJqUmb2xmKqqD3KU=",
2429
- "dev": true
2430
- },
2431
- "is-absolute": {
2432
- "version": "0.2.6",
2433
- "resolved": "https://registry.npmjs.org/is-absolute/-/is-absolute-0.2.6.tgz",
2434
- "integrity": "sha1-IN5p89uULvLYe5wto28XIjWxtes=",
2435
- "dev": true,
2436
- "requires": {
2437
- "is-relative": "^0.2.1",
2438
- "is-windows": "^0.2.0"
2439
- }
2440
- },
2441
- "is-arrayish": {
2442
- "version": "0.2.1",
2443
- "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz",
2444
- "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=",
2445
- "dev": true
2446
- },
2447
- "is-buffer": {
2448
- "version": "1.1.6",
2449
- "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz",
2450
- "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==",
2451
- "dev": true
2452
- },
2453
- "is-builtin-module": {
2454
- "version": "1.0.0",
2455
- "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-1.0.0.tgz",
2456
- "integrity": "sha1-VAVy0096wxGfj3bDDLwbHgN6/74=",
2457
- "dev": true,
2458
- "requires": {
2459
- "builtin-modules": "^1.0.0"
2460
- }
2461
- },
2462
- "is-directory": {
2463
- "version": "0.3.1",
2464
- "resolved": "https://registry.npmjs.org/is-directory/-/is-directory-0.3.1.tgz",
2465
- "integrity": "sha1-YTObbyR1/Hcv2cnYP1yFddwVSuE=",
2466
- "dev": true
2467
- },
2468
- "is-dotfile": {
2469
- "version": "1.0.3",
2470
- "resolved": "https://registry.npmjs.org/is-dotfile/-/is-dotfile-1.0.3.tgz",
2471
- "integrity": "sha1-pqLzL/0t+wT1yiXs0Pa4PPeYoeE=",
2472
- "dev": true
2473
- },
2474
- "is-equal-shallow": {
2475
- "version": "0.1.3",
2476
- "resolved": "https://registry.npmjs.org/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz",
2477
- "integrity": "sha1-IjgJj8Ih3gvPpdnqxMRdY4qhxTQ=",
2478
- "dev": true,
2479
- "requires": {
2480
- "is-primitive": "^2.0.0"
2481
- }
2482
- },
2483
- "is-extendable": {
2484
- "version": "0.1.1",
2485
- "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz",
2486
- "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=",
2487
- "dev": true
2488
- },
2489
- "is-extglob": {
2490
- "version": "1.0.0",
2491
- "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz",
2492
- "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=",
2493
- "dev": true
2494
- },
2495
- "is-finite": {
2496
- "version": "1.0.2",
2497
- "resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.0.2.tgz",
2498
- "integrity": "sha1-zGZ3aVYCvlUO8R6LSqYwU0K20Ko=",
2499
- "dev": true,
2500
- "requires": {
2501
- "number-is-nan": "^1.0.0"
2502
- }
2503
- },
2504
- "is-fullwidth-code-point": {
2505
- "version": "1.0.0",
2506
- "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz",
2507
- "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=",
2508
- "dev": true,
2509
- "requires": {
2510
- "number-is-nan": "^1.0.0"
2511
- }
2512
- },
2513
- "is-glob": {
2514
- "version": "2.0.1",
2515
- "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz",
2516
- "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=",
2517
- "dev": true,
2518
- "requires": {
2519
- "is-extglob": "^1.0.0"
2520
- }
2521
- },
2522
- "is-number": {
2523
- "version": "2.1.0",
2524
- "resolved": "https://registry.npmjs.org/is-number/-/is-number-2.1.0.tgz",
2525
- "integrity": "sha1-Afy7s5NGOlSPL0ZszhbezknbkI8=",
2526
- "dev": true,
2527
- "requires": {
2528
- "kind-of": "^3.0.2"
2529
- }
2530
- },
2531
- "is-path-cwd": {
2532
- "version": "1.0.0",
2533
- "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-1.0.0.tgz",
2534
- "integrity": "sha1-0iXsIxMuie3Tj9p2dHLmLmXxEG0=",
2535
- "dev": true
2536
- },
2537
- "is-path-in-cwd": {
2538
- "version": "1.0.0",
2539
- "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-1.0.0.tgz",
2540
- "integrity": "sha1-ZHdYK4IU1gI0YJRWcAO+ip6sBNw=",
2541
- "dev": true,
2542
- "requires": {
2543
- "is-path-inside": "^1.0.0"
2544
- }
2545
- },
2546
- "is-path-inside": {
2547
- "version": "1.0.0",
2548
- "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-1.0.0.tgz",
2549
- "integrity": "sha1-/AbloWg/vaE95mev9xe7wQpI838=",
2550
- "dev": true,
2551
- "requires": {
2552
- "path-is-inside": "^1.0.1"
2553
- }
2554
- },
2555
- "is-plain-object": {
2556
- "version": "2.0.4",
2557
- "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz",
2558
- "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==",
2559
- "dev": true,
2560
- "requires": {
2561
- "isobject": "^3.0.1"
2562
- },
2563
- "dependencies": {
2564
- "isobject": {
2565
- "version": "3.0.1",
2566
- "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
2567
- "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=",
2568
- "dev": true
2569
- }
2570
- }
2571
- },
2572
- "is-posix-bracket": {
2573
- "version": "0.1.1",
2574
- "resolved": "https://registry.npmjs.org/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz",
2575
- "integrity": "sha1-MzTceXdDaOkvAW5vvAqI9c1ua8Q=",
2576
- "dev": true
2577
- },
2578
- "is-primitive": {
2579
- "version": "2.0.0",
2580
- "resolved": "https://registry.npmjs.org/is-primitive/-/is-primitive-2.0.0.tgz",
2581
- "integrity": "sha1-IHurkWOEmcB7Kt8kCkGochADRXU=",
2582
- "dev": true
2583
- },
2584
- "is-relative": {
2585
- "version": "0.2.1",
2586
- "resolved": "https://registry.npmjs.org/is-relative/-/is-relative-0.2.1.tgz",
2587
- "integrity": "sha1-0n9MfVFtF1+2ENuEu+7yPDvJeqU=",
2588
- "dev": true,
2589
- "requires": {
2590
- "is-unc-path": "^0.1.1"
2591
- }
2592
- },
2593
- "is-typedarray": {
2594
- "version": "1.0.0",
2595
- "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz",
2596
- "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=",
2597
- "dev": true
2598
- },
2599
- "is-unc-path": {
2600
- "version": "0.1.2",
2601
- "resolved": "https://registry.npmjs.org/is-unc-path/-/is-unc-path-0.1.2.tgz",
2602
- "integrity": "sha1-arBTpyVzwQJQ/0FqOBTDUXivObk=",
2603
- "dev": true,
2604
- "requires": {
2605
- "unc-path-regex": "^0.1.0"
2606
- }
2607
- },
2608
- "is-utf8": {
2609
- "version": "0.2.1",
2610
- "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz",
2611
- "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=",
2612
- "dev": true
2613
- },
2614
- "is-windows": {
2615
- "version": "0.2.0",
2616
- "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-0.2.0.tgz",
2617
- "integrity": "sha1-3hqm1j6indJIc3tp8f+LgALSEIw=",
2618
- "dev": true
2619
- },
2620
- "isarray": {
2621
- "version": "0.0.1",
2622
- "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
2623
- "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=",
2624
- "dev": true
2625
- },
2626
- "isexe": {
2627
- "version": "2.0.0",
2628
- "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
2629
- "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=",
2630
- "dev": true
2631
- },
2632
- "isobject": {
2633
- "version": "2.1.0",
2634
- "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz",
2635
- "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=",
2636
- "dev": true,
2637
- "requires": {
2638
- "isarray": "1.0.0"
2639
- },
2640
- "dependencies": {
2641
- "isarray": {
2642
- "version": "1.0.0",
2643
- "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
2644
- "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
2645
- "dev": true
2646
- }
2647
- }
2648
- },
2649
- "isstream": {
2650
- "version": "0.1.2",
2651
- "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz",
2652
- "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=",
2653
- "dev": true
2654
- },
2655
- "istextorbinary": {
2656
- "version": "1.0.2",
2657
- "resolved": "https://registry.npmjs.org/istextorbinary/-/istextorbinary-1.0.2.tgz",
2658
- "integrity": "sha1-rOGTVNGpoBc+/rEITOD4ewrX3s8=",
2659
- "dev": true,
2660
- "requires": {
2661
- "binaryextensions": "~1.0.0",
2662
- "textextensions": "~1.0.0"
2663
- }
2664
- },
2665
- "js-base64": {
2666
- "version": "2.1.9",
2667
- "resolved": "https://registry.npmjs.org/js-base64/-/js-base64-2.1.9.tgz",
2668
- "integrity": "sha1-8OgK4DmkvWVLXygfyT8EqRSn/M4=",
2669
- "dev": true
2670
- },
2671
- "js-beautify": {
2672
- "version": "1.7.4",
2673
- "resolved": "https://registry.npmjs.org/js-beautify/-/js-beautify-1.7.4.tgz",
2674
- "integrity": "sha512-6YX1g+lIl0/JDxjFFbgj7fz6i0bWFa2Hdc7PfGqFhynaEiYe1NJ3R1nda0VGaRiGU82OllR+EGDoWFpGr3k5Kg==",
2675
- "dev": true,
2676
- "requires": {
2677
- "config-chain": "~1.1.5",
2678
- "editorconfig": "^0.13.2",
2679
- "mkdirp": "~0.5.0",
2680
- "nopt": "~3.0.1"
2681
- }
2682
- },
2683
- "js-yaml": {
2684
- "version": "3.10.0",
2685
- "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.10.0.tgz",
2686
- "integrity": "sha512-O2v52ffjLa9VeM43J4XocZE//WT9N0IiwDa3KSHH7Tu8CtH+1qM8SIZvnsTh6v+4yFy5KUY3BHUVwjpfAWsjIA==",
2687
- "dev": true,
2688
- "requires": {
2689
- "argparse": "^1.0.7",
2690
- "esprima": "^4.0.0"
2691
- }
2692
- },
2693
- "jsbn": {
2694
- "version": "0.1.1",
2695
- "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz",
2696
- "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=",
2697
- "dev": true,
2698
- "optional": true
2699
- },
2700
- "json-schema": {
2701
- "version": "0.2.3",
2702
- "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz",
2703
- "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=",
2704
- "dev": true
2705
- },
2706
- "json-schema-traverse": {
2707
- "version": "0.3.1",
2708
- "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz",
2709
- "integrity": "sha1-NJptRMU6Ud6JtAgFxdXlm0F9M0A=",
2710
- "dev": true
2711
- },
2712
- "json-stringify-safe": {
2713
- "version": "5.0.1",
2714
- "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz",
2715
- "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=",
2716
- "dev": true
2717
- },
2718
- "jsprim": {
2719
- "version": "1.4.1",
2720
- "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz",
2721
- "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=",
2722
- "dev": true,
2723
- "requires": {
2724
- "assert-plus": "1.0.0",
2725
- "extsprintf": "1.3.0",
2726
- "json-schema": "0.2.3",
2727
- "verror": "1.10.0"
2728
- }
2729
- },
2730
- "kind-of": {
2731
- "version": "3.2.2",
2732
- "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
2733
- "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
2734
- "dev": true,
2735
- "requires": {
2736
- "is-buffer": "^1.1.5"
2737
- }
2738
- },
2739
- "lcid": {
2740
- "version": "1.0.0",
2741
- "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz",
2742
- "integrity": "sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU=",
2743
- "dev": true,
2744
- "requires": {
2745
- "invert-kv": "^1.0.0"
2746
- }
2747
- },
2748
- "liftoff": {
2749
- "version": "2.3.0",
2750
- "resolved": "https://registry.npmjs.org/liftoff/-/liftoff-2.3.0.tgz",
2751
- "integrity": "sha1-qY8v9nGD2Lp8+soQVIvX/wVQs4U=",
2752
- "dev": true,
2753
- "requires": {
2754
- "extend": "^3.0.0",
2755
- "findup-sync": "^0.4.2",
2756
- "fined": "^1.0.1",
2757
- "flagged-respawn": "^0.3.2",
2758
- "lodash.isplainobject": "^4.0.4",
2759
- "lodash.isstring": "^4.0.1",
2760
- "lodash.mapvalues": "^4.4.0",
2761
- "rechoir": "^0.6.2",
2762
- "resolve": "^1.1.7"
2763
- }
2764
- },
2765
- "load-json-file": {
2766
- "version": "1.1.0",
2767
- "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz",
2768
- "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=",
2769
- "dev": true,
2770
- "requires": {
2771
- "graceful-fs": "^4.1.2",
2772
- "parse-json": "^2.2.0",
2773
- "pify": "^2.0.0",
2774
- "pinkie-promise": "^2.0.0",
2775
- "strip-bom": "^2.0.0"
2776
- },
2777
- "dependencies": {
2778
- "graceful-fs": {
2779
- "version": "4.1.11",
2780
- "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz",
2781
- "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=",
2782
- "dev": true
2783
- },
2784
- "pify": {
2785
- "version": "2.3.0",
2786
- "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
2787
- "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=",
2788
- "dev": true
2789
- },
2790
- "strip-bom": {
2791
- "version": "2.0.0",
2792
- "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz",
2793
- "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=",
2794
- "dev": true,
2795
- "requires": {
2796
- "is-utf8": "^0.2.0"
2797
- }
2798
- }
2799
- }
2800
- },
2801
- "lodash": {
2802
- "version": "1.0.2",
2803
- "resolved": "https://registry.npmjs.org/lodash/-/lodash-1.0.2.tgz",
2804
- "integrity": "sha1-j1dWDIO1n8JwvT1WG2kAQ0MOJVE=",
2805
- "dev": true
2806
- },
2807
- "lodash._basecopy": {
2808
- "version": "3.0.1",
2809
- "resolved": "https://registry.npmjs.org/lodash._basecopy/-/lodash._basecopy-3.0.1.tgz",
2810
- "integrity": "sha1-jaDmqHbPNEwK2KVIghEd08XHyjY=",
2811
- "dev": true
2812
- },
2813
- "lodash._basetostring": {
2814
- "version": "3.0.1",
2815
- "resolved": "https://registry.npmjs.org/lodash._basetostring/-/lodash._basetostring-3.0.1.tgz",
2816
- "integrity": "sha1-0YYdh3+CSlL2aYMtyvPuFVZqB9U=",
2817
- "dev": true
2818
- },
2819
- "lodash._basevalues": {
2820
- "version": "3.0.0",
2821
- "resolved": "https://registry.npmjs.org/lodash._basevalues/-/lodash._basevalues-3.0.0.tgz",
2822
- "integrity": "sha1-W3dXYoAr3j0yl1A+JjAIIP32Ybc=",
2823
- "dev": true
2824
- },
2825
- "lodash._escapehtmlchar": {
2826
- "version": "2.4.1",
2827
- "resolved": "https://registry.npmjs.org/lodash._escapehtmlchar/-/lodash._escapehtmlchar-2.4.1.tgz",
2828
- "integrity": "sha1-32fDu2t+jh6DGrSL+geVuSr+iZ0=",
2829
- "dev": true,
2830
- "requires": {
2831
- "lodash._htmlescapes": "~2.4.1"
2832
- }
2833
- },
2834
- "lodash._escapestringchar": {
2835
- "version": "2.4.1",
2836
- "resolved": "https://registry.npmjs.org/lodash._escapestringchar/-/lodash._escapestringchar-2.4.1.tgz",
2837
- "integrity": "sha1-7P4iYYoq3lC/7qQ5N+Ud9m8O23I=",
2838
- "dev": true
2839
- },
2840
- "lodash._getnative": {
2841
- "version": "3.9.1",
2842
- "resolved": "https://registry.npmjs.org/lodash._getnative/-/lodash._getnative-3.9.1.tgz",
2843
- "integrity": "sha1-VwvH3t5G1hzc3mh9ZdPuy6o6r/U=",
2844
- "dev": true
2845
- },
2846
- "lodash._htmlescapes": {
2847
- "version": "2.4.1",
2848
- "resolved": "https://registry.npmjs.org/lodash._htmlescapes/-/lodash._htmlescapes-2.4.1.tgz",
2849
- "integrity": "sha1-MtFL8IRLbeb4tioFG09nwii2JMs=",
2850
- "dev": true
2851
- },
2852
- "lodash._isiterateecall": {
2853
- "version": "3.0.9",
2854
- "resolved": "https://registry.npmjs.org/lodash._isiterateecall/-/lodash._isiterateecall-3.0.9.tgz",
2855
- "integrity": "sha1-UgOte6Ql+uhCRg5pbbnPPmqsBXw=",
2856
- "dev": true
2857
- },
2858
- "lodash._isnative": {
2859
- "version": "2.4.1",
2860
- "resolved": "https://registry.npmjs.org/lodash._isnative/-/lodash._isnative-2.4.1.tgz",
2861
- "integrity": "sha1-PqZAS3hKe+g2x7V1gOHN95sUgyw=",
2862
- "dev": true
2863
- },
2864
- "lodash._objecttypes": {
2865
- "version": "2.4.1",
2866
- "resolved": "https://registry.npmjs.org/lodash._objecttypes/-/lodash._objecttypes-2.4.1.tgz",
2867
- "integrity": "sha1-fAt/admKH3ZSn4kLDNsbTf7BHBE=",
2868
- "dev": true
2869
- },
2870
- "lodash._reescape": {
2871
- "version": "3.0.0",
2872
- "resolved": "https://registry.npmjs.org/lodash._reescape/-/lodash._reescape-3.0.0.tgz",
2873
- "integrity": "sha1-Kx1vXf4HyKNVdT5fJ/rH8c3hYWo=",
2874
- "dev": true
2875
- },
2876
- "lodash._reevaluate": {
2877
- "version": "3.0.0",
2878
- "resolved": "https://registry.npmjs.org/lodash._reevaluate/-/lodash._reevaluate-3.0.0.tgz",
2879
- "integrity": "sha1-WLx0xAZklTrgsSTYBpltrKQx4u0=",
2880
- "dev": true
2881
- },
2882
- "lodash._reinterpolate": {
2883
- "version": "3.0.0",
2884
- "resolved": "https://registry.npmjs.org/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz",
2885
- "integrity": "sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0=",
2886
- "dev": true
2887
- },
2888
- "lodash._reunescapedhtml": {
2889
- "version": "2.4.1",
2890
- "resolved": "https://registry.npmjs.org/lodash._reunescapedhtml/-/lodash._reunescapedhtml-2.4.1.tgz",
2891
- "integrity": "sha1-dHxPxAED6zu4oJduVx96JlnpO6c=",
2892
- "dev": true,
2893
- "requires": {
2894
- "lodash._htmlescapes": "~2.4.1",
2895
- "lodash.keys": "~2.4.1"
2896
- },
2897
- "dependencies": {
2898
- "lodash.isobject": {
2899
- "version": "2.4.1",
2900
- "resolved": "https://registry.npmjs.org/lodash.isobject/-/lodash.isobject-2.4.1.tgz",
2901
- "integrity": "sha1-Wi5H/mmVPx7mMafrof5k0tBlWPU=",
2902
- "dev": true,
2903
- "requires": {
2904
- "lodash._objecttypes": "~2.4.1"
2905
- }
2906
- },
2907
- "lodash.keys": {
2908
- "version": "2.4.1",
2909
- "resolved": "https://registry.npmjs.org/lodash.keys/-/lodash.keys-2.4.1.tgz",
2910
- "integrity": "sha1-SN6kbfj/djKxDXBrissmWR4rNyc=",
2911
- "dev": true,
2912
- "requires": {
2913
- "lodash._isnative": "~2.4.1",
2914
- "lodash._shimkeys": "~2.4.1",
2915
- "lodash.isobject": "~2.4.1"
2916
- }
2917
- }
2918
- }
2919
- },
2920
- "lodash._root": {
2921
- "version": "3.0.1",
2922
- "resolved": "https://registry.npmjs.org/lodash._root/-/lodash._root-3.0.1.tgz",
2923
- "integrity": "sha1-+6HEUkwZ7ppfgTa0YJ8BfPTe1pI=",
2924
- "dev": true
2925
- },
2926
- "lodash._shimkeys": {
2927
- "version": "2.4.1",
2928
- "resolved": "https://registry.npmjs.org/lodash._shimkeys/-/lodash._shimkeys-2.4.1.tgz",
2929
- "integrity": "sha1-bpzJZm/wgfC1psl4uD4kLmlJ0gM=",
2930
- "dev": true,
2931
- "requires": {
2932
- "lodash._objecttypes": "~2.4.1"
2933
- }
2934
- },
2935
- "lodash.assign": {
2936
- "version": "4.2.0",
2937
- "resolved": "https://registry.npmjs.org/lodash.assign/-/lodash.assign-4.2.0.tgz",
2938
- "integrity": "sha1-DZnzzNem0mHRm9rrkkUAXShYCOc=",
2939
- "dev": true
2940
- },
2941
- "lodash.clonedeep": {
2942
- "version": "4.5.0",
2943
- "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz",
2944
- "integrity": "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=",
2945
- "dev": true
2946
- },
2947
- "lodash.defaults": {
2948
- "version": "2.4.1",
2949
- "resolved": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-2.4.1.tgz",
2950
- "integrity": "sha1-p+iIXwXmiFEUS24SqPNngCa8TFQ=",
2951
- "dev": true,
2952
- "requires": {
2953
- "lodash._objecttypes": "~2.4.1",
2954
- "lodash.keys": "~2.4.1"
2955
- },
2956
- "dependencies": {
2957
- "lodash.isobject": {
2958
- "version": "2.4.1",
2959
- "resolved": "https://registry.npmjs.org/lodash.isobject/-/lodash.isobject-2.4.1.tgz",
2960
- "integrity": "sha1-Wi5H/mmVPx7mMafrof5k0tBlWPU=",
2961
- "dev": true,
2962
- "requires": {
2963
- "lodash._objecttypes": "~2.4.1"
2964
- }
2965
- },
2966
- "lodash.keys": {
2967
- "version": "2.4.1",
2968
- "resolved": "https://registry.npmjs.org/lodash.keys/-/lodash.keys-2.4.1.tgz",
2969
- "integrity": "sha1-SN6kbfj/djKxDXBrissmWR4rNyc=",
2970
- "dev": true,
2971
- "requires": {
2972
- "lodash._isnative": "~2.4.1",
2973
- "lodash._shimkeys": "~2.4.1",
2974
- "lodash.isobject": "~2.4.1"
2975
- }
2976
- }
2977
- }
2978
- },
2979
- "lodash.escape": {
2980
- "version": "3.2.0",
2981
- "resolved": "https://registry.npmjs.org/lodash.escape/-/lodash.escape-3.2.0.tgz",
2982
- "integrity": "sha1-mV7g3BjBtIzJLv+ucaEKq1tIdpg=",
2983
- "dev": true,
2984
- "requires": {
2985
- "lodash._root": "^3.0.0"
2986
- }
2987
- },
2988
- "lodash.isarguments": {
2989
- "version": "3.1.0",
2990
- "resolved": "https://registry.npmjs.org/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz",
2991
- "integrity": "sha1-L1c9hcaiQon/AGY7SRwdM4/zRYo=",
2992
- "dev": true
2993
- },
2994
- "lodash.isarray": {
2995
- "version": "3.0.4",
2996
- "resolved": "https://registry.npmjs.org/lodash.isarray/-/lodash.isarray-3.0.4.tgz",
2997
- "integrity": "sha1-eeTriMNqgSKvhvhEqpvNhRtfu1U=",
2998
- "dev": true
2999
- },
3000
- "lodash.isobject": {
3001
- "version": "3.0.2",
3002
- "resolved": "https://registry.npmjs.org/lodash.isobject/-/lodash.isobject-3.0.2.tgz",
3003
- "integrity": "sha1-PI+41bW/S/kK4G4U8qUwpO2TXh0=",
3004
- "dev": true
3005
- },
3006
- "lodash.isplainobject": {
3007
- "version": "4.0.6",
3008
- "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz",
3009
- "integrity": "sha1-fFJqUtibRcRcxpC4gWO+BJf1UMs=",
3010
- "dev": true
3011
- },
3012
- "lodash.isstring": {
3013
- "version": "4.0.1",
3014
- "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz",
3015
- "integrity": "sha1-1SfftUVuynzJu5XV2ur4i6VKVFE=",
3016
- "dev": true
3017
- },
3018
- "lodash.keys": {
3019
- "version": "3.1.2",
3020
- "resolved": "https://registry.npmjs.org/lodash.keys/-/lodash.keys-3.1.2.tgz",
3021
- "integrity": "sha1-TbwEcrFWvlCgsoaFXRvQsMZWCYo=",
3022
- "dev": true,
3023
- "requires": {
3024
- "lodash._getnative": "^3.0.0",
3025
- "lodash.isarguments": "^3.0.0",
3026
- "lodash.isarray": "^3.0.0"
3027
- }
3028
- },
3029
- "lodash.mapvalues": {
3030
- "version": "4.6.0",
3031
- "resolved": "https://registry.npmjs.org/lodash.mapvalues/-/lodash.mapvalues-4.6.0.tgz",
3032
- "integrity": "sha1-G6+lAF3p3W9PJmaMMMo3IwzJaJw=",
3033
- "dev": true
3034
- },
3035
- "lodash.merge": {
3036
- "version": "4.6.0",
3037
- "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.0.tgz",
3038
- "integrity": "sha1-aYhLoUSsM/5plzemCG3v+t0PicU=",
3039
- "dev": true
3040
- },
3041
- "lodash.mergewith": {
3042
- "version": "4.6.0",
3043
- "resolved": "https://registry.npmjs.org/lodash.mergewith/-/lodash.mergewith-4.6.0.tgz",
3044
- "integrity": "sha1-FQzwoWeR9ZA7iJHqsVRgknS96lU=",
3045
- "dev": true
3046
- },
3047
- "lodash.restparam": {
3048
- "version": "3.6.1",
3049
- "resolved": "https://registry.npmjs.org/lodash.restparam/-/lodash.restparam-3.6.1.tgz",
3050
- "integrity": "sha1-k2pOMJ7zMKdkXtQUWYbIWuWyCAU=",
3051
- "dev": true
3052
- },
3053
- "lodash.template": {
3054
- "version": "3.6.2",
3055
- "resolved": "https://registry.npmjs.org/lodash.template/-/lodash.template-3.6.2.tgz",
3056
- "integrity": "sha1-+M3sxhaaJVvpCYrosMU9N4kx0U8=",
3057
- "dev": true,
3058
- "requires": {
3059
- "lodash._basecopy": "^3.0.0",
3060
- "lodash._basetostring": "^3.0.0",
3061
- "lodash._basevalues": "^3.0.0",
3062
- "lodash._isiterateecall": "^3.0.0",
3063
- "lodash._reinterpolate": "^3.0.0",
3064
- "lodash.escape": "^3.0.0",
3065
- "lodash.keys": "^3.0.0",
3066
- "lodash.restparam": "^3.0.0",
3067
- "lodash.templatesettings": "^3.0.0"
3068
- }
3069
- },
3070
- "lodash.templatesettings": {
3071
- "version": "3.1.1",
3072
- "resolved": "https://registry.npmjs.org/lodash.templatesettings/-/lodash.templatesettings-3.1.1.tgz",
3073
- "integrity": "sha1-+zB4RHU7Zrnxr6VOJix0UwfbqOU=",
3074
- "dev": true,
3075
- "requires": {
3076
- "lodash._reinterpolate": "^3.0.0",
3077
- "lodash.escape": "^3.0.0"
3078
- }
3079
- },
3080
- "lodash.values": {
3081
- "version": "2.4.1",
3082
- "resolved": "https://registry.npmjs.org/lodash.values/-/lodash.values-2.4.1.tgz",
3083
- "integrity": "sha1-q/UUQ2s8twUAFieXjLzzCxKA7qQ=",
3084
- "dev": true,
3085
- "requires": {
3086
- "lodash.keys": "~2.4.1"
3087
- },
3088
- "dependencies": {
3089
- "lodash.isobject": {
3090
- "version": "2.4.1",
3091
- "resolved": "https://registry.npmjs.org/lodash.isobject/-/lodash.isobject-2.4.1.tgz",
3092
- "integrity": "sha1-Wi5H/mmVPx7mMafrof5k0tBlWPU=",
3093
- "dev": true,
3094
- "requires": {
3095
- "lodash._objecttypes": "~2.4.1"
3096
- }
3097
- },
3098
- "lodash.keys": {
3099
- "version": "2.4.1",
3100
- "resolved": "https://registry.npmjs.org/lodash.keys/-/lodash.keys-2.4.1.tgz",
3101
- "integrity": "sha1-SN6kbfj/djKxDXBrissmWR4rNyc=",
3102
- "dev": true,
3103
- "requires": {
3104
- "lodash._isnative": "~2.4.1",
3105
- "lodash._shimkeys": "~2.4.1",
3106
- "lodash.isobject": "~2.4.1"
3107
- }
3108
- }
3109
- }
3110
- },
3111
- "loud-rejection": {
3112
- "version": "1.6.0",
3113
- "resolved": "https://registry.npmjs.org/loud-rejection/-/loud-rejection-1.6.0.tgz",
3114
- "integrity": "sha1-W0b4AUft7leIcPCG0Eghz5mOVR8=",
3115
- "dev": true,
3116
- "requires": {
3117
- "currently-unhandled": "^0.4.1",
3118
- "signal-exit": "^3.0.0"
3119
- }
3120
- },
3121
- "lru-cache": {
3122
- "version": "2.7.3",
3123
- "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-2.7.3.tgz",
3124
- "integrity": "sha1-bUUk6LlV+V1PW1iFHOId1y+06VI=",
3125
- "dev": true
3126
- },
3127
- "map-cache": {
3128
- "version": "0.2.2",
3129
- "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz",
3130
- "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=",
3131
- "dev": true
3132
- },
3133
- "map-obj": {
3134
- "version": "1.0.1",
3135
- "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz",
3136
- "integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0=",
3137
- "dev": true
3138
- },
3139
- "map-stream": {
3140
- "version": "0.0.7",
3141
- "resolved": "https://registry.npmjs.org/map-stream/-/map-stream-0.0.7.tgz",
3142
- "integrity": "sha1-ih8HiW2CsQkmvTdEokIACfiJdKg=",
3143
- "dev": true
3144
- },
3145
- "meow": {
3146
- "version": "3.7.0",
3147
- "resolved": "https://registry.npmjs.org/meow/-/meow-3.7.0.tgz",
3148
- "integrity": "sha1-cstmi0JSKCkKu/qFaJJYcwioAfs=",
3149
- "dev": true,
3150
- "requires": {
3151
- "camelcase-keys": "^2.0.0",
3152
- "decamelize": "^1.1.2",
3153
- "loud-rejection": "^1.0.0",
3154
- "map-obj": "^1.0.1",
3155
- "minimist": "^1.1.3",
3156
- "normalize-package-data": "^2.3.4",
3157
- "object-assign": "^4.0.1",
3158
- "read-pkg-up": "^1.0.1",
3159
- "redent": "^1.0.0",
3160
- "trim-newlines": "^1.0.0"
3161
- }
3162
- },
3163
- "micromatch": {
3164
- "version": "2.3.11",
3165
- "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-2.3.11.tgz",
3166
- "integrity": "sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU=",
3167
- "dev": true,
3168
- "requires": {
3169
- "arr-diff": "^2.0.0",
3170
- "array-unique": "^0.2.1",
3171
- "braces": "^1.8.2",
3172
- "expand-brackets": "^0.1.4",
3173
- "extglob": "^0.3.1",
3174
- "filename-regex": "^2.0.0",
3175
- "is-extglob": "^1.0.0",
3176
- "is-glob": "^2.0.1",
3177
- "kind-of": "^3.0.2",
3178
- "normalize-path": "^2.0.1",
3179
- "object.omit": "^2.0.0",
3180
- "parse-glob": "^3.0.4",
3181
- "regex-cache": "^0.4.2"
3182
- }
3183
- },
3184
- "mime-db": {
3185
- "version": "1.30.0",
3186
- "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.30.0.tgz",
3187
- "integrity": "sha1-dMZD2i3Z1qRTmZY0ZbJtXKfXHwE=",
3188
- "dev": true
3189
- },
3190
- "mime-types": {
3191
- "version": "2.1.17",
3192
- "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.17.tgz",
3193
- "integrity": "sha1-Cdejk/A+mVp5+K+Fe3Cp4KsWVXo=",
3194
- "dev": true,
3195
- "requires": {
3196
- "mime-db": "~1.30.0"
3197
- }
3198
- },
3199
- "minimatch": {
3200
- "version": "3.0.4",
3201
- "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
3202
- "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
3203
- "dev": true,
3204
- "requires": {
3205
- "brace-expansion": "^1.1.7"
3206
- }
3207
- },
3208
- "minimist": {
3209
- "version": "1.2.0",
3210
- "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
3211
- "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
3212
- "dev": true
3213
- },
3214
- "mkdirp": {
3215
- "version": "0.5.1",
3216
- "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz",
3217
- "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=",
3218
- "dev": true,
3219
- "requires": {
3220
- "minimist": "0.0.8"
3221
- },
3222
- "dependencies": {
3223
- "minimist": {
3224
- "version": "0.0.8",
3225
- "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz",
3226
- "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=",
3227
- "dev": true
3228
- }
3229
- }
3230
- },
3231
- "multipipe": {
3232
- "version": "0.1.2",
3233
- "resolved": "https://registry.npmjs.org/multipipe/-/multipipe-0.1.2.tgz",
3234
- "integrity": "sha1-Ko8t33Du1WTf8tV/HhoTfZ8FB4s=",
3235
- "dev": true,
3236
- "requires": {
3237
- "duplexer2": "0.0.2"
3238
- }
3239
- },
3240
- "nan": {
3241
- "version": "2.8.0",
3242
- "resolved": "https://registry.npmjs.org/nan/-/nan-2.8.0.tgz",
3243
- "integrity": "sha1-7XFfP+neArV6XmJS2QqWZ14fCFo=",
3244
- "dev": true
3245
- },
3246
- "natives": {
3247
- "version": "1.1.0",
3248
- "resolved": "https://registry.npmjs.org/natives/-/natives-1.1.0.tgz",
3249
- "integrity": "sha1-6f+EFBimsux6SV6TmYT3jxY+bjE=",
3250
- "dev": true
3251
- },
3252
- "node-gyp": {
3253
- "version": "3.6.2",
3254
- "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-3.6.2.tgz",
3255
- "integrity": "sha1-m/vlRWIoYoSDjnUOrAUpWFP6HGA=",
3256
- "dev": true,
3257
- "requires": {
3258
- "fstream": "^1.0.0",
3259
- "glob": "^7.0.3",
3260
- "graceful-fs": "^4.1.2",
3261
- "minimatch": "^3.0.2",
3262
- "mkdirp": "^0.5.0",
3263
- "nopt": "2 || 3",
3264
- "npmlog": "0 || 1 || 2 || 3 || 4",
3265
- "osenv": "0",
3266
- "request": "2",
3267
- "rimraf": "2",
3268
- "semver": "~5.3.0",
3269
- "tar": "^2.0.0",
3270
- "which": "1"
3271
- },
3272
- "dependencies": {
3273
- "graceful-fs": {
3274
- "version": "4.1.11",
3275
- "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz",
3276
- "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=",
3277
- "dev": true
3278
- },
3279
- "semver": {
3280
- "version": "5.3.0",
3281
- "resolved": "https://registry.npmjs.org/semver/-/semver-5.3.0.tgz",
3282
- "integrity": "sha1-myzl094C0XxgEq0yaqa00M9U+U8=",
3283
- "dev": true
3284
- }
3285
- }
3286
- },
3287
- "node-notifier": {
3288
- "version": "5.1.2",
3289
- "resolved": "https://registry.npmjs.org/node-notifier/-/node-notifier-5.1.2.tgz",
3290
- "integrity": "sha1-L6nhJgX6EACdRFSdb82KY93g5P8=",
3291
- "dev": true,
3292
- "requires": {
3293
- "growly": "^1.3.0",
3294
- "semver": "^5.3.0",
3295
- "shellwords": "^0.1.0",
3296
- "which": "^1.2.12"
3297
- },
3298
- "dependencies": {
3299
- "semver": {
3300
- "version": "5.4.1",
3301
- "resolved": "https://registry.npmjs.org/semver/-/semver-5.4.1.tgz",
3302
- "integrity": "sha512-WfG/X9+oATh81XtllIo/I8gOiY9EXRdv1cQdyykeXK17YcUW3EXUAi2To4pcH6nZtJPr7ZOpM5OMyWJZm+8Rsg==",
3303
- "dev": true
3304
- }
3305
- }
3306
- },
3307
- "node-sass": {
3308
- "version": "4.6.1",
3309
- "resolved": "https://registry.npmjs.org/node-sass/-/node-sass-4.6.1.tgz",
3310
- "integrity": "sha512-0zQQ7tjEK5W8RfW9LiQrkzfo7uLZ0QtZGV69rdKn5cFzdweHLJ14lR6xLPvI6UimkXMO8m0qDsXwUCNdnqV3sA==",
3311
- "dev": true,
3312
- "requires": {
3313
- "async-foreach": "^0.1.3",
3314
- "chalk": "^1.1.1",
3315
- "cross-spawn": "^3.0.0",
3316
- "gaze": "^1.0.0",
3317
- "get-stdin": "^4.0.1",
3318
- "glob": "^7.0.3",
3319
- "in-publish": "^2.0.0",
3320
- "lodash.assign": "^4.2.0",
3321
- "lodash.clonedeep": "^4.3.2",
3322
- "lodash.mergewith": "^4.6.0",
3323
- "meow": "^3.7.0",
3324
- "mkdirp": "^0.5.1",
3325
- "nan": "^2.3.2",
3326
- "node-gyp": "^3.3.1",
3327
- "npmlog": "^4.0.0",
3328
- "request": "^2.79.0",
3329
- "sass-graph": "^2.2.4",
3330
- "stdout-stream": "^1.4.0"
3331
- },
3332
- "dependencies": {
3333
- "gaze": {
3334
- "version": "1.1.2",
3335
- "resolved": "https://registry.npmjs.org/gaze/-/gaze-1.1.2.tgz",
3336
- "integrity": "sha1-hHIkZ3rbiHDWeSV+0ziP22HkAQU=",
3337
- "dev": true,
3338
- "requires": {
3339
- "globule": "^1.0.0"
3340
- }
3341
- },
3342
- "globule": {
3343
- "version": "1.2.0",
3344
- "resolved": "https://registry.npmjs.org/globule/-/globule-1.2.0.tgz",
3345
- "integrity": "sha1-HcScaCLdnoovoAuiopUAboZkvQk=",
3346
- "dev": true,
3347
- "requires": {
3348
- "glob": "~7.1.1",
3349
- "lodash": "~4.17.4",
3350
- "minimatch": "~3.0.2"
3351
- }
3352
- },
3353
- "lodash": {
3354
- "version": "4.17.4",
3355
- "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz",
3356
- "integrity": "sha1-eCA6TRwyiuHYbcpkYONptX9AVa4=",
3357
- "dev": true
3358
- }
3359
- }
3360
- },
3361
- "node-uuid": {
3362
- "version": "1.4.0",
3363
- "resolved": "https://registry.npmjs.org/node-uuid/-/node-uuid-1.4.0.tgz",
3364
- "integrity": "sha1-B/myM3Vy/2J1x3Xh1IUT86RdemU=",
3365
- "dev": true
3366
- },
3367
- "node.extend": {
3368
- "version": "1.1.6",
3369
- "resolved": "https://registry.npmjs.org/node.extend/-/node.extend-1.1.6.tgz",
3370
- "integrity": "sha1-p7iCyC1sk6SGOlUEvV3o7IYli5Y=",
3371
- "dev": true,
3372
- "requires": {
3373
- "is": "^3.1.0"
3374
- }
3375
- },
3376
- "nopt": {
3377
- "version": "3.0.6",
3378
- "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz",
3379
- "integrity": "sha1-xkZdvwirzU2zWTF/eaxopkayj/k=",
3380
- "dev": true,
3381
- "requires": {
3382
- "abbrev": "1"
3383
- }
3384
- },
3385
- "normalize-package-data": {
3386
- "version": "2.4.0",
3387
- "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.4.0.tgz",
3388
- "integrity": "sha512-9jjUFbTPfEy3R/ad/2oNbKtW9Hgovl5O1FvFWKkKblNXoN/Oou6+9+KKohPK13Yc3/TyunyWhJp6gvRNR/PPAw==",
3389
- "dev": true,
3390
- "requires": {
3391
- "hosted-git-info": "^2.1.4",
3392
- "is-builtin-module": "^1.0.0",
3393
- "semver": "2 || 3 || 4 || 5",
3394
- "validate-npm-package-license": "^3.0.1"
3395
- }
3396
- },
3397
- "normalize-path": {
3398
- "version": "2.1.1",
3399
- "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz",
3400
- "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=",
3401
- "dev": true,
3402
- "requires": {
3403
- "remove-trailing-separator": "^1.0.1"
3404
- }
3405
- },
3406
- "npmlog": {
3407
- "version": "4.1.2",
3408
- "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz",
3409
- "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==",
3410
- "dev": true,
3411
- "requires": {
3412
- "are-we-there-yet": "~1.1.2",
3413
- "console-control-strings": "~1.1.0",
3414
- "gauge": "~2.7.3",
3415
- "set-blocking": "~2.0.0"
3416
- }
3417
- },
3418
- "number-is-nan": {
3419
- "version": "1.0.1",
3420
- "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz",
3421
- "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=",
3422
- "dev": true
3423
- },
3424
- "oauth-sign": {
3425
- "version": "0.8.2",
3426
- "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.8.2.tgz",
3427
- "integrity": "sha1-Rqarfwrq2N6unsBWV4C31O/rnUM=",
3428
- "dev": true
3429
- },
3430
- "object-assign": {
3431
- "version": "4.1.1",
3432
- "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
3433
- "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=",
3434
- "dev": true
3435
- },
3436
- "object-keys": {
3437
- "version": "0.4.0",
3438
- "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-0.4.0.tgz",
3439
- "integrity": "sha1-KKaq50KN0sOpLz2V8hM13SBOAzY=",
3440
- "dev": true
3441
- },
3442
- "object.defaults": {
3443
- "version": "1.1.0",
3444
- "resolved": "https://registry.npmjs.org/object.defaults/-/object.defaults-1.1.0.tgz",
3445
- "integrity": "sha1-On+GgzS0B96gbaFtiNXNKeQ1/s8=",
3446
- "dev": true,
3447
- "requires": {
3448
- "array-each": "^1.0.1",
3449
- "array-slice": "^1.0.0",
3450
- "for-own": "^1.0.0",
3451
- "isobject": "^3.0.0"
3452
- },
3453
- "dependencies": {
3454
- "for-own": {
3455
- "version": "1.0.0",
3456
- "resolved": "https://registry.npmjs.org/for-own/-/for-own-1.0.0.tgz",
3457
- "integrity": "sha1-xjMy9BXO3EsE2/5wz4NklMU8tEs=",
3458
- "dev": true,
3459
- "requires": {
3460
- "for-in": "^1.0.1"
3461
- }
3462
- },
3463
- "isobject": {
3464
- "version": "3.0.1",
3465
- "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
3466
- "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=",
3467
- "dev": true
3468
- }
3469
- }
3470
- },
3471
- "object.omit": {
3472
- "version": "2.0.1",
3473
- "resolved": "https://registry.npmjs.org/object.omit/-/object.omit-2.0.1.tgz",
3474
- "integrity": "sha1-Gpx0SCnznbuFjHbKNXmuKlTr0fo=",
3475
- "dev": true,
3476
- "requires": {
3477
- "for-own": "^0.1.4",
3478
- "is-extendable": "^0.1.1"
3479
- }
3480
- },
3481
- "object.pick": {
3482
- "version": "1.3.0",
3483
- "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz",
3484
- "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=",
3485
- "dev": true,
3486
- "requires": {
3487
- "isobject": "^3.0.1"
3488
- },
3489
- "dependencies": {
3490
- "isobject": {
3491
- "version": "3.0.1",
3492
- "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
3493
- "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=",
3494
- "dev": true
3495
- }
3496
- }
3497
- },
3498
- "once": {
3499
- "version": "1.4.0",
3500
- "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
3501
- "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
3502
- "dev": true,
3503
- "requires": {
3504
- "wrappy": "1"
3505
- }
3506
- },
3507
- "orchestrator": {
3508
- "version": "0.3.8",
3509
- "resolved": "https://registry.npmjs.org/orchestrator/-/orchestrator-0.3.8.tgz",
3510
- "integrity": "sha1-FOfp4nZPcxX7rBhOUGx6pt+UrX4=",
3511
- "dev": true,
3512
- "requires": {
3513
- "end-of-stream": "~0.1.5",
3514
- "sequencify": "~0.0.7",
3515
- "stream-consume": "~0.1.0"
3516
- }
3517
- },
3518
- "ordered-read-streams": {
3519
- "version": "0.1.0",
3520
- "resolved": "https://registry.npmjs.org/ordered-read-streams/-/ordered-read-streams-0.1.0.tgz",
3521
- "integrity": "sha1-/VZamvjrRHO6abbtijQ1LLVS8SY=",
3522
- "dev": true
3523
- },
3524
- "os-homedir": {
3525
- "version": "1.0.2",
3526
- "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz",
3527
- "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=",
3528
- "dev": true
3529
- },
3530
- "os-locale": {
3531
- "version": "1.4.0",
3532
- "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz",
3533
- "integrity": "sha1-IPnxeuKe00XoveWDsT0gCYA8FNk=",
3534
- "dev": true,
3535
- "requires": {
3536
- "lcid": "^1.0.0"
3537
- }
3538
- },
3539
- "os-tmpdir": {
3540
- "version": "1.0.2",
3541
- "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz",
3542
- "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=",
3543
- "dev": true
3544
- },
3545
- "osenv": {
3546
- "version": "0.1.4",
3547
- "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.4.tgz",
3548
- "integrity": "sha1-Qv5tWVPfBsgGS+bxdsPQWqqjRkQ=",
3549
- "dev": true,
3550
- "requires": {
3551
- "os-homedir": "^1.0.0",
3552
- "os-tmpdir": "^1.0.0"
3553
- }
3554
- },
3555
- "p-map": {
3556
- "version": "1.2.0",
3557
- "resolved": "https://registry.npmjs.org/p-map/-/p-map-1.2.0.tgz",
3558
- "integrity": "sha512-r6zKACMNhjPJMTl8KcFH4li//gkrXWfbD6feV8l6doRHlzljFWGJ2AP6iKaCJXyZmAUMOPtvbW7EXkbWO/pLEA==",
3559
- "dev": true
3560
- },
3561
- "parse-filepath": {
3562
- "version": "1.0.1",
3563
- "resolved": "https://registry.npmjs.org/parse-filepath/-/parse-filepath-1.0.1.tgz",
3564
- "integrity": "sha1-FZ1hVdQ5BNFsEO9piRHaHpGWm3M=",
3565
- "dev": true,
3566
- "requires": {
3567
- "is-absolute": "^0.2.3",
3568
- "map-cache": "^0.2.0",
3569
- "path-root": "^0.1.1"
3570
- }
3571
- },
3572
- "parse-glob": {
3573
- "version": "3.0.4",
3574
- "resolved": "https://registry.npmjs.org/parse-glob/-/parse-glob-3.0.4.tgz",
3575
- "integrity": "sha1-ssN2z7EfNVE7rdFz7wu246OIORw=",
3576
- "dev": true,
3577
- "requires": {
3578
- "glob-base": "^0.3.0",
3579
- "is-dotfile": "^1.0.0",
3580
- "is-extglob": "^1.0.0",
3581
- "is-glob": "^2.0.0"
3582
- }
3583
- },
3584
- "parse-json": {
3585
- "version": "2.2.0",
3586
- "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz",
3587
- "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=",
3588
- "dev": true,
3589
- "requires": {
3590
- "error-ex": "^1.2.0"
3591
- }
3592
- },
3593
- "parse-passwd": {
3594
- "version": "1.0.0",
3595
- "resolved": "https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz",
3596
- "integrity": "sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY=",
3597
- "dev": true
3598
- },
3599
- "path-exists": {
3600
- "version": "2.1.0",
3601
- "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz",
3602
- "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=",
3603
- "dev": true,
3604
- "requires": {
3605
- "pinkie-promise": "^2.0.0"
3606
- }
3607
- },
3608
- "path-is-absolute": {
3609
- "version": "1.0.1",
3610
- "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
3611
- "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=",
3612
- "dev": true
3613
- },
3614
- "path-is-inside": {
3615
- "version": "1.0.2",
3616
- "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz",
3617
- "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=",
3618
- "dev": true
3619
- },
3620
- "path-parse": {
3621
- "version": "1.0.5",
3622
- "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.5.tgz",
3623
- "integrity": "sha1-PBrfhx6pzWyUMbbqK9dKD/BVxME=",
3624
- "dev": true
3625
- },
3626
- "path-root": {
3627
- "version": "0.1.1",
3628
- "resolved": "https://registry.npmjs.org/path-root/-/path-root-0.1.1.tgz",
3629
- "integrity": "sha1-mkpoFMrBwM1zNgqV8yCDyOpHRbc=",
3630
- "dev": true,
3631
- "requires": {
3632
- "path-root-regex": "^0.1.0"
3633
- }
3634
- },
3635
- "path-root-regex": {
3636
- "version": "0.1.2",
3637
- "resolved": "https://registry.npmjs.org/path-root-regex/-/path-root-regex-0.1.2.tgz",
3638
- "integrity": "sha1-v8zcjfWxLcUsi0PsONGNcsBLqW0=",
3639
- "dev": true
3640
- },
3641
- "path-type": {
3642
- "version": "1.1.0",
3643
- "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz",
3644
- "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=",
3645
- "dev": true,
3646
- "requires": {
3647
- "graceful-fs": "^4.1.2",
3648
- "pify": "^2.0.0",
3649
- "pinkie-promise": "^2.0.0"
3650
- },
3651
- "dependencies": {
3652
- "graceful-fs": {
3653
- "version": "4.1.11",
3654
- "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz",
3655
- "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=",
3656
- "dev": true
3657
- },
3658
- "pify": {
3659
- "version": "2.3.0",
3660
- "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
3661
- "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=",
3662
- "dev": true
3663
- }
3664
- }
3665
- },
3666
- "pause-stream": {
3667
- "version": "0.0.11",
3668
- "resolved": "https://registry.npmjs.org/pause-stream/-/pause-stream-0.0.11.tgz",
3669
- "integrity": "sha1-/lo0sMvOErWqaitAPuLnO2AvFEU=",
3670
- "dev": true,
3671
- "requires": {
3672
- "through": "~2.3"
3673
- }
3674
- },
3675
- "performance-now": {
3676
- "version": "2.1.0",
3677
- "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz",
3678
- "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=",
3679
- "dev": true
3680
- },
3681
- "pify": {
3682
- "version": "3.0.0",
3683
- "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz",
3684
- "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=",
3685
- "dev": true
3686
- },
3687
- "pinkie": {
3688
- "version": "2.0.4",
3689
- "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz",
3690
- "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=",
3691
- "dev": true
3692
- },
3693
- "pinkie-promise": {
3694
- "version": "2.0.1",
3695
- "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz",
3696
- "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=",
3697
- "dev": true,
3698
- "requires": {
3699
- "pinkie": "^2.0.0"
3700
- }
3701
- },
3702
- "postcss": {
3703
- "version": "2.2.6",
3704
- "resolved": "https://registry.npmjs.org/postcss/-/postcss-2.2.6.tgz",
3705
- "integrity": "sha1-wENE4kSeRYa5Vfvkp093CA2EVx8=",
3706
- "dev": true,
3707
- "requires": {
3708
- "js-base64": "~2.1.5",
3709
- "source-map": "~0.1.40"
3710
- }
3711
- },
3712
- "postcss-load-config": {
3713
- "version": "1.2.0",
3714
- "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-1.2.0.tgz",
3715
- "integrity": "sha1-U56a/J3chiASHr+djDZz4M5Q0oo=",
3716
- "dev": true,
3717
- "requires": {
3718
- "cosmiconfig": "^2.1.0",
3719
- "object-assign": "^4.1.0",
3720
- "postcss-load-options": "^1.2.0",
3721
- "postcss-load-plugins": "^2.3.0"
3722
- }
3723
- },
3724
- "postcss-load-options": {
3725
- "version": "1.2.0",
3726
- "resolved": "https://registry.npmjs.org/postcss-load-options/-/postcss-load-options-1.2.0.tgz",
3727
- "integrity": "sha1-sJixVZ3awt8EvAuzdfmaXP4rbYw=",
3728
- "dev": true,
3729
- "requires": {
3730
- "cosmiconfig": "^2.1.0",
3731
- "object-assign": "^4.1.0"
3732
- }
3733
- },
3734
- "postcss-load-plugins": {
3735
- "version": "2.3.0",
3736
- "resolved": "https://registry.npmjs.org/postcss-load-plugins/-/postcss-load-plugins-2.3.0.tgz",
3737
- "integrity": "sha1-dFdoEWWZrKLwCfrUJrABdQSdjZI=",
3738
- "dev": true,
3739
- "requires": {
3740
- "cosmiconfig": "^2.1.1",
3741
- "object-assign": "^4.1.0"
3742
- }
3743
- },
3744
- "preserve": {
3745
- "version": "0.2.0",
3746
- "resolved": "https://registry.npmjs.org/preserve/-/preserve-0.2.0.tgz",
3747
- "integrity": "sha1-gV7R9uvGWSb4ZbMQwHE7yzMVzks=",
3748
- "dev": true
3749
- },
3750
- "pretty-hrtime": {
3751
- "version": "1.0.3",
3752
- "resolved": "https://registry.npmjs.org/pretty-hrtime/-/pretty-hrtime-1.0.3.tgz",
3753
- "integrity": "sha1-t+PqQkNaTJsnWdmeDyAesZWALuE=",
3754
- "dev": true
3755
- },
3756
- "process-nextick-args": {
3757
- "version": "1.0.7",
3758
- "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz",
3759
- "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=",
3760
- "dev": true
3761
- },
3762
- "proto-list": {
3763
- "version": "1.2.4",
3764
- "resolved": "https://registry.npmjs.org/proto-list/-/proto-list-1.2.4.tgz",
3765
- "integrity": "sha1-IS1b/hMYMGpCD2QCuOJv85ZHqEk=",
3766
- "dev": true
3767
- },
3768
- "pseudomap": {
3769
- "version": "1.0.2",
3770
- "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz",
3771
- "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=",
3772
- "dev": true
3773
- },
3774
- "punycode": {
3775
- "version": "1.4.1",
3776
- "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz",
3777
- "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=",
3778
- "dev": true
3779
- },
3780
- "qs": {
3781
- "version": "6.5.1",
3782
- "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.1.tgz",
3783
- "integrity": "sha512-eRzhrN1WSINYCDCbrz796z37LOe3m5tmW7RQf6oBntukAG1nmovJvhnwHHRMAfeoItc1m2Hk02WER2aQ/iqs+A==",
3784
- "dev": true
3785
- },
3786
- "randomatic": {
3787
- "version": "1.1.7",
3788
- "resolved": "https://registry.npmjs.org/randomatic/-/randomatic-1.1.7.tgz",
3789
- "integrity": "sha512-D5JUjPyJbaJDkuAazpVnSfVkLlpeO3wDlPROTMLGKG1zMFNFRgrciKo1ltz/AzNTkqE0HzDx655QOL51N06how==",
3790
- "dev": true,
3791
- "requires": {
3792
- "is-number": "^3.0.0",
3793
- "kind-of": "^4.0.0"
3794
- },
3795
- "dependencies": {
3796
- "is-number": {
3797
- "version": "3.0.0",
3798
- "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz",
3799
- "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=",
3800
- "dev": true,
3801
- "requires": {
3802
- "kind-of": "^3.0.2"
3803
- },
3804
- "dependencies": {
3805
- "kind-of": {
3806
- "version": "3.2.2",
3807
- "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
3808
- "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
3809
- "dev": true,
3810
- "requires": {
3811
- "is-buffer": "^1.1.5"
3812
- }
3813
- }
3814
- }
3815
- },
3816
- "kind-of": {
3817
- "version": "4.0.0",
3818
- "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz",
3819
- "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=",
3820
- "dev": true,
3821
- "requires": {
3822
- "is-buffer": "^1.1.5"
3823
- }
3824
- }
3825
- }
3826
- },
3827
- "rcfinder": {
3828
- "version": "0.1.9",
3829
- "resolved": "https://registry.npmjs.org/rcfinder/-/rcfinder-0.1.9.tgz",
3830
- "integrity": "sha1-8+gPOH3fmugK4wpBADKWQuroERU=",
3831
- "dev": true,
3832
- "requires": {
3833
- "lodash.clonedeep": "^4.3.2"
3834
- }
3835
- },
3836
- "rcloader": {
3837
- "version": "0.2.2",
3838
- "resolved": "https://registry.npmjs.org/rcloader/-/rcloader-0.2.2.tgz",
3839
- "integrity": "sha1-WNIpi0YtC5v9ITPSoex0+9cFxxc=",
3840
- "dev": true,
3841
- "requires": {
3842
- "lodash.assign": "^4.2.0",
3843
- "lodash.isobject": "^3.0.2",
3844
- "lodash.merge": "^4.6.0",
3845
- "rcfinder": "^0.1.6"
3846
- }
3847
- },
3848
- "read-pkg": {
3849
- "version": "1.1.0",
3850
- "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz",
3851
- "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=",
3852
- "dev": true,
3853
- "requires": {
3854
- "load-json-file": "^1.0.0",
3855
- "normalize-package-data": "^2.3.2",
3856
- "path-type": "^1.0.0"
3857
- }
3858
- },
3859
- "read-pkg-up": {
3860
- "version": "1.0.1",
3861
- "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz",
3862
- "integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=",
3863
- "dev": true,
3864
- "requires": {
3865
- "find-up": "^1.0.0",
3866
- "read-pkg": "^1.0.0"
3867
- }
3868
- },
3869
- "readable-stream": {
3870
- "version": "1.1.14",
3871
- "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz",
3872
- "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=",
3873
- "dev": true,
3874
- "requires": {
3875
- "core-util-is": "~1.0.0",
3876
- "inherits": "~2.0.1",
3877
- "isarray": "0.0.1",
3878
- "string_decoder": "~0.10.x"
3879
- }
3880
- },
3881
- "rechoir": {
3882
- "version": "0.6.2",
3883
- "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz",
3884
- "integrity": "sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q=",
3885
- "dev": true,
3886
- "requires": {
3887
- "resolve": "^1.1.6"
3888
- }
3889
- },
3890
- "redent": {
3891
- "version": "1.0.0",
3892
- "resolved": "https://registry.npmjs.org/redent/-/redent-1.0.0.tgz",
3893
- "integrity": "sha1-z5Fqsf1fHxbfsggi3W7H9zDCr94=",
3894
- "dev": true,
3895
- "requires": {
3896
- "indent-string": "^2.1.0",
3897
- "strip-indent": "^1.0.1"
3898
- }
3899
- },
3900
- "regex-cache": {
3901
- "version": "0.4.4",
3902
- "resolved": "https://registry.npmjs.org/regex-cache/-/regex-cache-0.4.4.tgz",
3903
- "integrity": "sha512-nVIZwtCjkC9YgvWkpM55B5rBhBYRZhAaJbgcFYXXsHnbZ9UZI9nnVWYZpBlCqv9ho2eZryPnWrZGsOdPwVWXWQ==",
3904
- "dev": true,
3905
- "requires": {
3906
- "is-equal-shallow": "^0.1.3"
3907
- }
3908
- },
3909
- "remove-trailing-separator": {
3910
- "version": "1.1.0",
3911
- "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz",
3912
- "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=",
3913
- "dev": true
3914
- },
3915
- "repeat-element": {
3916
- "version": "1.1.2",
3917
- "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.2.tgz",
3918
- "integrity": "sha1-7wiaF40Ug7quTZPrmLT55OEdmQo=",
3919
- "dev": true
3920
- },
3921
- "repeat-string": {
3922
- "version": "1.6.1",
3923
- "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz",
3924
- "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=",
3925
- "dev": true
3926
- },
3927
- "repeating": {
3928
- "version": "2.0.1",
3929
- "resolved": "https://registry.npmjs.org/repeating/-/repeating-2.0.1.tgz",
3930
- "integrity": "sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo=",
3931
- "dev": true,
3932
- "requires": {
3933
- "is-finite": "^1.0.0"
3934
- }
3935
- },
3936
- "replace-ext": {
3937
- "version": "0.0.1",
3938
- "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-0.0.1.tgz",
3939
- "integrity": "sha1-KbvZIHinOfC8zitO5B6DeVNSKSQ=",
3940
- "dev": true
3941
- },
3942
- "replacestream": {
3943
- "version": "0.1.3",
3944
- "resolved": "https://registry.npmjs.org/replacestream/-/replacestream-0.1.3.tgz",
3945
- "integrity": "sha1-4BjTo3ckYAzNDABZkNiiG3tU/zQ=",
3946
- "dev": true,
3947
- "requires": {
3948
- "through": "~2.3.4"
3949
- }
3950
- },
3951
- "request": {
3952
- "version": "2.83.0",
3953
- "resolved": "https://registry.npmjs.org/request/-/request-2.83.0.tgz",
3954
- "integrity": "sha512-lR3gD69osqm6EYLk9wB/G1W/laGWjzH90t1vEa2xuxHD5KUrSzp9pUSfTm+YC5Nxt2T8nMPEvKlhbQayU7bgFw==",
3955
- "dev": true,
3956
- "requires": {
3957
- "aws-sign2": "~0.7.0",
3958
- "aws4": "^1.6.0",
3959
- "caseless": "~0.12.0",
3960
- "combined-stream": "~1.0.5",
3961
- "extend": "~3.0.1",
3962
- "forever-agent": "~0.6.1",
3963
- "form-data": "~2.3.1",
3964
- "har-validator": "~5.0.3",
3965
- "hawk": "~6.0.2",
3966
- "http-signature": "~1.2.0",
3967
- "is-typedarray": "~1.0.0",
3968
- "isstream": "~0.1.2",
3969
- "json-stringify-safe": "~5.0.1",
3970
- "mime-types": "~2.1.17",
3971
- "oauth-sign": "~0.8.2",
3972
- "performance-now": "^2.1.0",
3973
- "qs": "~6.5.1",
3974
- "safe-buffer": "^5.1.1",
3975
- "stringstream": "~0.0.5",
3976
- "tough-cookie": "~2.3.3",
3977
- "tunnel-agent": "^0.6.0",
3978
- "uuid": "^3.1.0"
3979
- }
3980
- },
3981
- "require-directory": {
3982
- "version": "2.1.1",
3983
- "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
3984
- "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=",
3985
- "dev": true
3986
- },
3987
- "require-from-string": {
3988
- "version": "1.2.1",
3989
- "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-1.2.1.tgz",
3990
- "integrity": "sha1-UpyczvJzgK3+yaL5ZbZJu+5jZBg=",
3991
- "dev": true
3992
- },
3993
- "require-main-filename": {
3994
- "version": "1.0.1",
3995
- "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz",
3996
- "integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE=",
3997
- "dev": true
3998
- },
3999
- "resolve": {
4000
- "version": "1.5.0",
4001
- "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.5.0.tgz",
4002
- "integrity": "sha512-hgoSGrc3pjzAPHNBg+KnFcK2HwlHTs/YrAGUr6qgTVUZmXv1UEXXl0bZNBKMA9fud6lRYFdPGz0xXxycPzmmiw==",
4003
- "dev": true,
4004
- "requires": {
4005
- "path-parse": "^1.0.5"
4006
- }
4007
- },
4008
- "resolve-dir": {
4009
- "version": "0.1.1",
4010
- "resolved": "https://registry.npmjs.org/resolve-dir/-/resolve-dir-0.1.1.tgz",
4011
- "integrity": "sha1-shklmlYC+sXFxJatiUpujMQwJh4=",
4012
- "dev": true,
4013
- "requires": {
4014
- "expand-tilde": "^1.2.2",
4015
- "global-modules": "^0.2.3"
4016
- }
4017
- },
4018
- "rimraf": {
4019
- "version": "2.6.2",
4020
- "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz",
4021
- "integrity": "sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==",
4022
- "dev": true,
4023
- "requires": {
4024
- "glob": "^7.0.5"
4025
- }
4026
- },
4027
- "rtlcss": {
4028
- "version": "2.2.1",
4029
- "resolved": "https://registry.npmjs.org/rtlcss/-/rtlcss-2.2.1.tgz",
4030
- "integrity": "sha512-JjQ5DlrmwiItAjlmhoxrJq5ihgZcE0wMFxt7S17bIrt4Lw0WwKKFk+viRhvodB/0falyG/5fiO043ZDh6/aqTw==",
4031
- "dev": true,
4032
- "requires": {
4033
- "chalk": "^2.3.0",
4034
- "findup": "^0.1.5",
4035
- "mkdirp": "^0.5.1",
4036
- "postcss": "^6.0.14",
4037
- "strip-json-comments": "^2.0.0"
4038
- },
4039
- "dependencies": {
4040
- "ansi-styles": {
4041
- "version": "3.2.0",
4042
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz",
4043
- "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==",
4044
- "dev": true,
4045
- "requires": {
4046
- "color-convert": "^1.9.0"
4047
- }
4048
- },
4049
- "chalk": {
4050
- "version": "2.3.0",
4051
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.0.tgz",
4052
- "integrity": "sha512-Az5zJR2CBujap2rqXGaJKaPHyJ0IrUimvYNX+ncCy8PJP4ltOGTrHUIo097ZaL2zMeKYpiCdqDvS6zdrTFok3Q==",
4053
- "dev": true,
4054
- "requires": {
4055
- "ansi-styles": "^3.1.0",
4056
- "escape-string-regexp": "^1.0.5",
4057
- "supports-color": "^4.0.0"
4058
- }
4059
- },
4060
- "postcss": {
4061
- "version": "6.0.14",
4062
- "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.14.tgz",
4063
- "integrity": "sha512-NJ1z0f+1offCgadPhz+DvGm5Mkci+mmV5BqD13S992o0Xk9eElxUfPPF+t2ksH5R/17gz4xVK8KWocUQ5o3Rog==",
4064
- "dev": true,
4065
- "requires": {
4066
- "chalk": "^2.3.0",
4067
- "source-map": "^0.6.1",
4068
- "supports-color": "^4.4.0"
4069
- }
4070
- },
4071
- "source-map": {
4072
- "version": "0.6.1",
4073
- "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
4074
- "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
4075
- "dev": true
4076
- },
4077
- "supports-color": {
4078
- "version": "4.5.0",
4079
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz",
4080
- "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=",
4081
- "dev": true,
4082
- "requires": {
4083
- "has-flag": "^2.0.0"
4084
- }
4085
- }
4086
- }
4087
- },
4088
- "safe-buffer": {
4089
- "version": "5.1.1",
4090
- "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz",
4091
- "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==",
4092
- "dev": true
4093
- },
4094
- "sass-graph": {
4095
- "version": "2.2.4",
4096
- "resolved": "https://registry.npmjs.org/sass-graph/-/sass-graph-2.2.4.tgz",
4097
- "integrity": "sha1-E/vWPNHK8JCLn9k0dq1DpR0eC0k=",
4098
- "dev": true,
4099
- "requires": {
4100
- "glob": "^7.0.0",
4101
- "lodash": "^4.0.0",
4102
- "scss-tokenizer": "^0.2.3",
4103
- "yargs": "^7.0.0"
4104
- },
4105
- "dependencies": {
4106
- "lodash": {
4107
- "version": "4.17.4",
4108
- "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz",
4109
- "integrity": "sha1-eCA6TRwyiuHYbcpkYONptX9AVa4=",
4110
- "dev": true
4111
- }
4112
- }
4113
- },
4114
- "scss-tokenizer": {
4115
- "version": "0.2.3",
4116
- "resolved": "https://registry.npmjs.org/scss-tokenizer/-/scss-tokenizer-0.2.3.tgz",
4117
- "integrity": "sha1-jrBtualyMzOCTT9VMGQRSYR85dE=",
4118
- "dev": true,
4119
- "requires": {
4120
- "js-base64": "^2.1.8",
4121
- "source-map": "^0.4.2"
4122
- },
4123
- "dependencies": {
4124
- "source-map": {
4125
- "version": "0.4.4",
4126
- "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz",
4127
- "integrity": "sha1-66T12pwNyZneaAMti092FzZSA2s=",
4128
- "dev": true,
4129
- "requires": {
4130
- "amdefine": ">=0.0.4"
4131
- }
4132
- }
4133
- }
4134
- },
4135
- "semver": {
4136
- "version": "4.3.6",
4137
- "resolved": "https://registry.npmjs.org/semver/-/semver-4.3.6.tgz",
4138
- "integrity": "sha1-MAvG4OhjdPe6YQaLWx7NV/xlMto=",
4139
- "dev": true
4140
- },
4141
- "sequencify": {
4142
- "version": "0.0.7",
4143
- "resolved": "https://registry.npmjs.org/sequencify/-/sequencify-0.0.7.tgz",
4144
- "integrity": "sha1-kM/xnQLgcCf9dn9erT57ldHnOAw=",
4145
- "dev": true
4146
- },
4147
- "set-blocking": {
4148
- "version": "2.0.0",
4149
- "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz",
4150
- "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=",
4151
- "dev": true
4152
- },
4153
- "shellwords": {
4154
- "version": "0.1.1",
4155
- "resolved": "https://registry.npmjs.org/shellwords/-/shellwords-0.1.1.tgz",
4156
- "integrity": "sha512-vFwSUfQvqybiICwZY5+DAWIPLKsWO31Q91JSKl3UYv+K5c2QRPzn0qzec6QPu1Qc9eHYItiP3NdJqNVqetYAww==",
4157
- "dev": true
4158
- },
4159
- "sigmund": {
4160
- "version": "1.0.1",
4161
- "resolved": "https://registry.npmjs.org/sigmund/-/sigmund-1.0.1.tgz",
4162
- "integrity": "sha1-P/IfGYytIXX587eBhT/ZTQ0ZtZA=",
4163
- "dev": true
4164
- },
4165
- "signal-exit": {
4166
- "version": "3.0.2",
4167
- "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz",
4168
- "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=",
4169
- "dev": true
4170
- },
4171
- "sntp": {
4172
- "version": "2.1.0",
4173
- "resolved": "https://registry.npmjs.org/sntp/-/sntp-2.1.0.tgz",
4174
- "integrity": "sha512-FL1b58BDrqS3A11lJ0zEdnJ3UOKqVxawAkF3k7F0CVN7VQ34aZrV+G8BZ1WC9ZL7NyrwsW0oviwsWDgRuVYtJg==",
4175
- "dev": true,
4176
- "requires": {
4177
- "hoek": "4.x.x"
4178
- }
4179
- },
4180
- "source-map": {
4181
- "version": "0.1.43",
4182
- "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.1.43.tgz",
4183
- "integrity": "sha1-wkvBRspRfBRx9drL4lcbK3+eM0Y=",
4184
- "dev": true,
4185
- "requires": {
4186
- "amdefine": ">=0.0.4"
4187
- }
4188
- },
4189
- "sparkles": {
4190
- "version": "1.0.0",
4191
- "resolved": "https://registry.npmjs.org/sparkles/-/sparkles-1.0.0.tgz",
4192
- "integrity": "sha1-Gsu/tZJDbRC76PeFt8xvgoFQEsM=",
4193
- "dev": true
4194
- },
4195
- "spdx-correct": {
4196
- "version": "1.0.2",
4197
- "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-1.0.2.tgz",
4198
- "integrity": "sha1-SzBz2TP/UfORLwOsVRlJikFQ20A=",
4199
- "dev": true,
4200
- "requires": {
4201
- "spdx-license-ids": "^1.0.2"
4202
- }
4203
- },
4204
- "spdx-expression-parse": {
4205
- "version": "1.0.4",
4206
- "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-1.0.4.tgz",
4207
- "integrity": "sha1-m98vIOH0DtRH++JzJmGR/O1RYmw=",
4208
- "dev": true
4209
- },
4210
- "spdx-license-ids": {
4211
- "version": "1.2.2",
4212
- "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-1.2.2.tgz",
4213
- "integrity": "sha1-yd96NCRZSt5r0RkA1ZZpbcBrrFc=",
4214
- "dev": true
4215
- },
4216
- "split": {
4217
- "version": "0.2.10",
4218
- "resolved": "https://registry.npmjs.org/split/-/split-0.2.10.tgz",
4219
- "integrity": "sha1-Zwl8YB1pfOE2j0GPBs0gHPBSGlc=",
4220
- "dev": true,
4221
- "requires": {
4222
- "through": "2"
4223
- }
4224
- },
4225
- "sprintf-js": {
4226
- "version": "1.0.3",
4227
- "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
4228
- "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=",
4229
- "dev": true
4230
- },
4231
- "sshpk": {
4232
- "version": "1.13.1",
4233
- "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.13.1.tgz",
4234
- "integrity": "sha1-US322mKHFEMW3EwY/hzx2UBzm+M=",
4235
- "dev": true,
4236
- "requires": {
4237
- "asn1": "~0.2.3",
4238
- "assert-plus": "^1.0.0",
4239
- "bcrypt-pbkdf": "^1.0.0",
4240
- "dashdash": "^1.12.0",
4241
- "ecc-jsbn": "~0.1.1",
4242
- "getpass": "^0.1.1",
4243
- "jsbn": "~0.1.0",
4244
- "tweetnacl": "~0.14.0"
4245
- }
4246
- },
4247
- "stdout-stream": {
4248
- "version": "1.4.0",
4249
- "resolved": "https://registry.npmjs.org/stdout-stream/-/stdout-stream-1.4.0.tgz",
4250
- "integrity": "sha1-osfIWH5U2UJ+qe2zrD8s1SLfN4s=",
4251
- "dev": true,
4252
- "requires": {
4253
- "readable-stream": "^2.0.1"
4254
- },
4255
- "dependencies": {
4256
- "isarray": {
4257
- "version": "1.0.0",
4258
- "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
4259
- "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
4260
- "dev": true
4261
- },
4262
- "readable-stream": {
4263
- "version": "2.3.3",
4264
- "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz",
4265
- "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==",
4266
- "dev": true,
4267
- "requires": {
4268
- "core-util-is": "~1.0.0",
4269
- "inherits": "~2.0.3",
4270
- "isarray": "~1.0.0",
4271
- "process-nextick-args": "~1.0.6",
4272
- "safe-buffer": "~5.1.1",
4273
- "string_decoder": "~1.0.3",
4274
- "util-deprecate": "~1.0.1"
4275
- }
4276
- },
4277
- "string_decoder": {
4278
- "version": "1.0.3",
4279
- "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz",
4280
- "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==",
4281
- "dev": true,
4282
- "requires": {
4283
- "safe-buffer": "~5.1.0"
4284
- }
4285
- }
4286
- }
4287
- },
4288
- "stream-combiner": {
4289
- "version": "0.0.4",
4290
- "resolved": "https://registry.npmjs.org/stream-combiner/-/stream-combiner-0.0.4.tgz",
4291
- "integrity": "sha1-TV5DPBhSYd3mI8o/RMWGvPXErRQ=",
4292
- "dev": true,
4293
- "requires": {
4294
- "duplexer": "~0.1.1"
4295
- }
4296
- },
4297
- "stream-consume": {
4298
- "version": "0.1.0",
4299
- "resolved": "https://registry.npmjs.org/stream-consume/-/stream-consume-0.1.0.tgz",
4300
- "integrity": "sha1-pB6tGm1ggc63n2WwYZAbbY89HQ8=",
4301
- "dev": true
4302
- },
4303
- "string-width": {
4304
- "version": "1.0.2",
4305
- "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz",
4306
- "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=",
4307
- "dev": true,
4308
- "requires": {
4309
- "code-point-at": "^1.0.0",
4310
- "is-fullwidth-code-point": "^1.0.0",
4311
- "strip-ansi": "^3.0.0"
4312
- }
4313
- },
4314
- "string_decoder": {
4315
- "version": "0.10.31",
4316
- "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz",
4317
- "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=",
4318
- "dev": true
4319
- },
4320
- "stringstream": {
4321
- "version": "0.0.5",
4322
- "resolved": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.5.tgz",
4323
- "integrity": "sha1-TkhM1N5aC7vuGORjB3EKioFiGHg=",
4324
- "dev": true
4325
- },
4326
- "strip-ansi": {
4327
- "version": "3.0.1",
4328
- "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
4329
- "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
4330
- "dev": true,
4331
- "requires": {
4332
- "ansi-regex": "^2.0.0"
4333
- }
4334
- },
4335
- "strip-bom": {
4336
- "version": "1.0.0",
4337
- "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-1.0.0.tgz",
4338
- "integrity": "sha1-hbiGLzhEtabV7IRnqTWYFzo295Q=",
4339
- "dev": true,
4340
- "requires": {
4341
- "first-chunk-stream": "^1.0.0",
4342
- "is-utf8": "^0.2.0"
4343
- }
4344
- },
4345
- "strip-indent": {
4346
- "version": "1.0.1",
4347
- "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-1.0.1.tgz",
4348
- "integrity": "sha1-DHlipq3vp7vUrDZkYKY4VSrhoKI=",
4349
- "dev": true,
4350
- "requires": {
4351
- "get-stdin": "^4.0.1"
4352
- }
4353
- },
4354
- "strip-json-comments": {
4355
- "version": "2.0.1",
4356
- "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz",
4357
- "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=",
4358
- "dev": true
4359
- },
4360
- "supports-color": {
4361
- "version": "2.0.0",
4362
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
4363
- "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=",
4364
- "dev": true
4365
- },
4366
- "tar": {
4367
- "version": "2.2.1",
4368
- "resolved": "https://registry.npmjs.org/tar/-/tar-2.2.1.tgz",
4369
- "integrity": "sha1-jk0qJWwOIYXGsYrWlK7JaLg8sdE=",
4370
- "dev": true,
4371
- "requires": {
4372
- "block-stream": "*",
4373
- "fstream": "^1.0.2",
4374
- "inherits": "2"
4375
- }
4376
- },
4377
- "textextensions": {
4378
- "version": "1.0.2",
4379
- "resolved": "https://registry.npmjs.org/textextensions/-/textextensions-1.0.2.tgz",
4380
- "integrity": "sha1-ZUhjk+4fK7A5pgy7oFsLaL2VAdI=",
4381
- "dev": true
4382
- },
4383
- "through": {
4384
- "version": "2.3.8",
4385
- "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz",
4386
- "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=",
4387
- "dev": true
4388
- },
4389
- "through2": {
4390
- "version": "2.0.3",
4391
- "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.3.tgz",
4392
- "integrity": "sha1-AARWmzfHx0ujnEPzzteNGtlBQL4=",
4393
- "dev": true,
4394
- "requires": {
4395
- "readable-stream": "^2.1.5",
4396
- "xtend": "~4.0.1"
4397
- },
4398
- "dependencies": {
4399
- "isarray": {
4400
- "version": "1.0.0",
4401
- "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
4402
- "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
4403
- "dev": true
4404
- },
4405
- "readable-stream": {
4406
- "version": "2.3.3",
4407
- "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz",
4408
- "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==",
4409
- "dev": true,
4410
- "requires": {
4411
- "core-util-is": "~1.0.0",
4412
- "inherits": "~2.0.3",
4413
- "isarray": "~1.0.0",
4414
- "process-nextick-args": "~1.0.6",
4415
- "safe-buffer": "~5.1.1",
4416
- "string_decoder": "~1.0.3",
4417
- "util-deprecate": "~1.0.1"
4418
- }
4419
- },
4420
- "string_decoder": {
4421
- "version": "1.0.3",
4422
- "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz",
4423
- "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==",
4424
- "dev": true,
4425
- "requires": {
4426
- "safe-buffer": "~5.1.0"
4427
- }
4428
- }
4429
- }
4430
- },
4431
- "tildify": {
4432
- "version": "1.2.0",
4433
- "resolved": "https://registry.npmjs.org/tildify/-/tildify-1.2.0.tgz",
4434
- "integrity": "sha1-3OwD9V3Km3qj5bBPIYF+tW5jWIo=",
4435
- "dev": true,
4436
- "requires": {
4437
- "os-homedir": "^1.0.0"
4438
- }
4439
- },
4440
- "time-stamp": {
4441
- "version": "1.1.0",
4442
- "resolved": "https://registry.npmjs.org/time-stamp/-/time-stamp-1.1.0.tgz",
4443
- "integrity": "sha1-dkpaEa9QVhkhsTPztE5hhofg9cM=",
4444
- "dev": true
4445
- },
4446
- "tough-cookie": {
4447
- "version": "2.3.3",
4448
- "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.3.tgz",
4449
- "integrity": "sha1-C2GKVWW23qkL80JdBNVe3EdadWE=",
4450
- "dev": true,
4451
- "requires": {
4452
- "punycode": "^1.4.1"
4453
- }
4454
- },
4455
- "trim-newlines": {
4456
- "version": "1.0.0",
4457
- "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-1.0.0.tgz",
4458
- "integrity": "sha1-WIeWa7WCpFA6QetST301ARgVphM=",
4459
- "dev": true
4460
- },
4461
- "tunnel-agent": {
4462
- "version": "0.6.0",
4463
- "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz",
4464
- "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=",
4465
- "dev": true,
4466
- "requires": {
4467
- "safe-buffer": "^5.0.1"
4468
- }
4469
- },
4470
- "tweetnacl": {
4471
- "version": "0.14.5",
4472
- "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz",
4473
- "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=",
4474
- "dev": true,
4475
- "optional": true
4476
- },
4477
- "unc-path-regex": {
4478
- "version": "0.1.2",
4479
- "resolved": "https://registry.npmjs.org/unc-path-regex/-/unc-path-regex-0.1.2.tgz",
4480
- "integrity": "sha1-5z3T17DXxe2G+6xrCufYxqadUPo=",
4481
- "dev": true
4482
- },
4483
- "unique-stream": {
4484
- "version": "1.0.0",
4485
- "resolved": "https://registry.npmjs.org/unique-stream/-/unique-stream-1.0.0.tgz",
4486
- "integrity": "sha1-1ZpKdUJ0R9mqbJHnAmP40mpLEEs=",
4487
- "dev": true
4488
- },
4489
- "user-home": {
4490
- "version": "1.1.1",
4491
- "resolved": "https://registry.npmjs.org/user-home/-/user-home-1.1.1.tgz",
4492
- "integrity": "sha1-K1viOjK2Onyd640PKNSFcko98ZA=",
4493
- "dev": true
4494
- },
4495
- "util-deprecate": {
4496
- "version": "1.0.2",
4497
- "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
4498
- "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=",
4499
- "dev": true
4500
- },
4501
- "uuid": {
4502
- "version": "3.1.0",
4503
- "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.1.0.tgz",
4504
- "integrity": "sha512-DIWtzUkw04M4k3bf1IcpS2tngXEL26YUD2M0tMDUpnUrz2hgzUBlD55a4FjdLGPvfHxS6uluGWvaVEqgBcVa+g==",
4505
- "dev": true
4506
- },
4507
- "v8flags": {
4508
- "version": "2.1.1",
4509
- "resolved": "https://registry.npmjs.org/v8flags/-/v8flags-2.1.1.tgz",
4510
- "integrity": "sha1-qrGh+jDUX4jdMhFIh1rALAtV5bQ=",
4511
- "dev": true,
4512
- "requires": {
4513
- "user-home": "^1.1.1"
4514
- }
4515
- },
4516
- "validate-npm-package-license": {
4517
- "version": "3.0.1",
4518
- "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.1.tgz",
4519
- "integrity": "sha1-KAS6vnEq0zeUWaz74kdGqywwP7w=",
4520
- "dev": true,
4521
- "requires": {
4522
- "spdx-correct": "~1.0.0",
4523
- "spdx-expression-parse": "~1.0.0"
4524
- }
4525
- },
4526
- "verror": {
4527
- "version": "1.10.0",
4528
- "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz",
4529
- "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=",
4530
- "dev": true,
4531
- "requires": {
4532
- "assert-plus": "^1.0.0",
4533
- "core-util-is": "1.0.2",
4534
- "extsprintf": "^1.2.0"
4535
- }
4536
- },
4537
- "vinyl": {
4538
- "version": "0.5.3",
4539
- "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-0.5.3.tgz",
4540
- "integrity": "sha1-sEVbOPxeDPMNQyUTLkYZcMIJHN4=",
4541
- "dev": true,
4542
- "requires": {
4543
- "clone": "^1.0.0",
4544
- "clone-stats": "^0.0.1",
4545
- "replace-ext": "0.0.1"
4546
- }
4547
- },
4548
- "vinyl-bufferstream": {
4549
- "version": "1.0.1",
4550
- "resolved": "https://registry.npmjs.org/vinyl-bufferstream/-/vinyl-bufferstream-1.0.1.tgz",
4551
- "integrity": "sha1-BTeGn1gO/6TKRay0dXnkuf5jCBo=",
4552
- "dev": true,
4553
- "requires": {
4554
- "bufferstreams": "1.0.1"
4555
- }
4556
- },
4557
- "vinyl-fs": {
4558
- "version": "0.3.14",
4559
- "resolved": "https://registry.npmjs.org/vinyl-fs/-/vinyl-fs-0.3.14.tgz",
4560
- "integrity": "sha1-mmhRzhysHBzqX+hsCTHWIMLPqeY=",
4561
- "dev": true,
4562
- "requires": {
4563
- "defaults": "^1.0.0",
4564
- "glob-stream": "^3.1.5",
4565
- "glob-watcher": "^0.0.6",
4566
- "graceful-fs": "^3.0.0",
4567
- "mkdirp": "^0.5.0",
4568
- "strip-bom": "^1.0.0",
4569
- "through2": "^0.6.1",
4570
- "vinyl": "^0.4.0"
4571
- },
4572
- "dependencies": {
4573
- "clone": {
4574
- "version": "0.2.0",
4575
- "resolved": "https://registry.npmjs.org/clone/-/clone-0.2.0.tgz",
4576
- "integrity": "sha1-xhJqkK1Pctv1rNskPMN3JP6T/B8=",
4577
- "dev": true
4578
- },
4579
- "readable-stream": {
4580
- "version": "1.0.34",
4581
- "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz",
4582
- "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=",
4583
- "dev": true,
4584
- "requires": {
4585
- "core-util-is": "~1.0.0",
4586
- "inherits": "~2.0.1",
4587
- "isarray": "0.0.1",
4588
- "string_decoder": "~0.10.x"
4589
- }
4590
- },
4591
- "through2": {
4592
- "version": "0.6.5",
4593
- "resolved": "https://registry.npmjs.org/through2/-/through2-0.6.5.tgz",
4594
- "integrity": "sha1-QaucZ7KdVyCQcUEOHXp6lozTrUg=",
4595
- "dev": true,
4596
- "requires": {
4597
- "readable-stream": ">=1.0.33-1 <1.1.0-0",
4598
- "xtend": ">=4.0.0 <4.1.0-0"
4599
- }
4600
- },
4601
- "vinyl": {
4602
- "version": "0.4.6",
4603
- "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-0.4.6.tgz",
4604
- "integrity": "sha1-LzVsh6VQolVGHza76ypbqL94SEc=",
4605
- "dev": true,
4606
- "requires": {
4607
- "clone": "^0.2.0",
4608
- "clone-stats": "^0.0.1"
4609
- }
4610
- }
4611
- }
4612
- },
4613
- "vinyl-sourcemaps-apply": {
4614
- "version": "0.1.4",
4615
- "resolved": "https://registry.npmjs.org/vinyl-sourcemaps-apply/-/vinyl-sourcemaps-apply-0.1.4.tgz",
4616
- "integrity": "sha1-xfy9Q+LyOEI8LcmL3db3m3K8NFs=",
4617
- "dev": true,
4618
- "requires": {
4619
- "source-map": "^0.1.39"
4620
- }
4621
- },
4622
- "vow": {
4623
- "version": "0.4.4",
4624
- "resolved": "https://registry.npmjs.org/vow/-/vow-0.4.4.tgz",
4625
- "integrity": "sha1-yf5GCRKdf1qmIVCOvmS1HJW8e5g=",
4626
- "dev": true
4627
- },
4628
- "vow-fs": {
4629
- "version": "0.3.2",
4630
- "resolved": "https://registry.npmjs.org/vow-fs/-/vow-fs-0.3.2.tgz",
4631
- "integrity": "sha1-6isDTYXh24wnfrLpqG0cFfXTjno=",
4632
- "dev": true,
4633
- "requires": {
4634
- "glob": "3.2.8",
4635
- "node-uuid": "1.4.0",
4636
- "vow": "0.4.4",
4637
- "vow-queue": "0.3.1"
4638
- },
4639
- "dependencies": {
4640
- "glob": {
4641
- "version": "3.2.8",
4642
- "resolved": "https://registry.npmjs.org/glob/-/glob-3.2.8.tgz",
4643
- "integrity": "sha1-VQb0MRchvMYYx9jboUQYh1AwcHM=",
4644
- "dev": true,
4645
- "requires": {
4646
- "inherits": "2",
4647
- "minimatch": "~0.2.11"
4648
- }
4649
- },
4650
- "minimatch": {
4651
- "version": "0.2.14",
4652
- "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-0.2.14.tgz",
4653
- "integrity": "sha1-x054BXT2PG+aCQ6Q775u9TpqdWo=",
4654
- "dev": true,
4655
- "requires": {
4656
- "lru-cache": "2",
4657
- "sigmund": "~1.0.0"
4658
- }
4659
- }
4660
- }
4661
- },
4662
- "vow-queue": {
4663
- "version": "0.3.1",
4664
- "resolved": "https://registry.npmjs.org/vow-queue/-/vow-queue-0.3.1.tgz",
4665
- "integrity": "sha1-WYxRoVsKgabV/AX0dhzrRi3h6Gg=",
4666
- "dev": true,
4667
- "requires": {
4668
- "vow": "~0.4.0"
4669
- }
4670
- },
4671
- "which": {
4672
- "version": "1.3.0",
4673
- "resolved": "https://registry.npmjs.org/which/-/which-1.3.0.tgz",
4674
- "integrity": "sha512-xcJpopdamTuY5duC/KnTTNBraPK54YwpenP4lzxU8H91GudWpFv38u0CKjclE1Wi2EH2EDz5LRcHcKbCIzqGyg==",
4675
- "dev": true,
4676
- "requires": {
4677
- "isexe": "^2.0.0"
4678
- }
4679
- },
4680
- "which-module": {
4681
- "version": "1.0.0",
4682
- "resolved": "https://registry.npmjs.org/which-module/-/which-module-1.0.0.tgz",
4683
- "integrity": "sha1-u6Y8qGGUiZT/MHc2CJ47lgJsKk8=",
4684
- "dev": true
4685
- },
4686
- "wide-align": {
4687
- "version": "1.1.2",
4688
- "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.2.tgz",
4689
- "integrity": "sha512-ijDLlyQ7s6x1JgCLur53osjm/UXUYD9+0PbYKrBsYisYXzCxN+HC3mYDNy/dWdmf3AwqwU3CXwDCvsNgGK1S0w==",
4690
- "dev": true,
4691
- "requires": {
4692
- "string-width": "^1.0.2"
4693
- }
4694
- },
4695
- "wrap-ansi": {
4696
- "version": "2.1.0",
4697
- "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz",
4698
- "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=",
4699
- "dev": true,
4700
- "requires": {
4701
- "string-width": "^1.0.1",
4702
- "strip-ansi": "^3.0.1"
4703
- }
4704
- },
4705
- "wrappy": {
4706
- "version": "1.0.2",
4707
- "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
4708
- "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
4709
- "dev": true
4710
- },
4711
- "xtend": {
4712
- "version": "4.0.1",
4713
- "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz",
4714
- "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=",
4715
- "dev": true
4716
- },
4717
- "y18n": {
4718
- "version": "3.2.1",
4719
- "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz",
4720
- "integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE=",
4721
- "dev": true
4722
- },
4723
- "yallist": {
4724
- "version": "2.1.2",
4725
- "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz",
4726
- "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=",
4727
- "dev": true
4728
- },
4729
- "yargs": {
4730
- "version": "7.1.0",
4731
- "resolved": "https://registry.npmjs.org/yargs/-/yargs-7.1.0.tgz",
4732
- "integrity": "sha1-a6MY6xaWFyf10oT46gA+jWFU0Mg=",
4733
- "dev": true,
4734
- "requires": {
4735
- "camelcase": "^3.0.0",
4736
- "cliui": "^3.2.0",
4737
- "decamelize": "^1.1.1",
4738
- "get-caller-file": "^1.0.1",
4739
- "os-locale": "^1.4.0",
4740
- "read-pkg-up": "^1.0.1",
4741
- "require-directory": "^2.1.1",
4742
- "require-main-filename": "^1.0.1",
4743
- "set-blocking": "^2.0.0",
4744
- "string-width": "^1.0.2",
4745
- "which-module": "^1.0.0",
4746
- "y18n": "^3.2.1",
4747
- "yargs-parser": "^5.0.0"
4748
- },
4749
- "dependencies": {
4750
- "camelcase": {
4751
- "version": "3.0.0",
4752
- "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz",
4753
- "integrity": "sha1-MvxLn82vhF/N9+c7uXysImHwqwo=",
4754
- "dev": true
4755
- }
4756
- }
4757
- },
4758
- "yargs-parser": {
4759
- "version": "5.0.0",
4760
- "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-5.0.0.tgz",
4761
- "integrity": "sha1-J17PDX/+Bcd+ZOfIbkzZS/DhIoo=",
4762
- "dev": true,
4763
- "requires": {
4764
- "camelcase": "^3.0.0"
4765
- },
4766
- "dependencies": {
4767
- "camelcase": {
4768
- "version": "3.0.0",
4769
- "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz",
4770
- "integrity": "sha1-MvxLn82vhF/N9+c7uXysImHwqwo=",
4771
- "dev": true
4772
- }
4773
- }
4774
- }
4775
- }
4776
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
package.json DELETED
@@ -1,22 +0,0 @@
1
- {
2
- "name": "customify",
3
- "devDependencies": {
4
- "gulp": "*",
5
- "gulp-sass": "*",
6
- "gulp-autoprefixer": "~1.0.1",
7
- "gulp-minify-css": "*",
8
- "gulp-ignore": "*",
9
- "gulp-notify": "*",
10
- "gulp-concat": "~2.1.7",
11
- "gulp-exec": "~2.0.1",
12
- "gulp-replace": "~0.4.0",
13
- "gulp-beautify": "*",
14
- "gulp-csscomb": "*",
15
- "gulp-rename": "*",
16
- "gulp-combine-media-queries": "*",
17
- "del": "*",
18
- "gulp-postcss": "*",
19
- "rtlcss": "*",
20
- "es6-promise": "*"
21
- }
22
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
palettes.md ADDED
@@ -0,0 +1,137 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Color Palettes Integration Guide
2
+
3
+ ## 1. Add color controls for all elements on the page
4
+ ```php
5
+ function make_this_function_name_unique( $config ) {
6
+
7
+ // usually the sections key will be here, but a check won't hurt
8
+ if ( ! isset($config['sections']) ) {
9
+ $config['sections'] = array();
10
+ }
11
+
12
+ // this means that we add a new entry named "theme_added_settings" in the sections area
13
+ $config['sections']['theme_added_settings'] = array(
14
+ 'title' => 'Section added dynamically',
15
+ 'settings' => array(
16
+
17
+ // this is the field id and it must be unique
18
+ 'field_example' => array(
19
+ 'type' => 'color', // there is a list of types below
20
+ 'label' => 'Body color', // the label is optional but is nice to have one
21
+ 'css' => array(
22
+
23
+ // the CSS key is the one which controls the output of this field
24
+ array(
25
+ // a CSS selector
26
+ 'selector' => '#logo',
27
+ // the CSS property which should be affected by this field
28
+ 'property' => 'background-color',
29
+ )
30
+
31
+ // repeat this as long as you need
32
+ array(
33
+ 'selector' => 'body',
34
+ 'property' => 'color',
35
+ )
36
+ )
37
+ )
38
+ )
39
+ );
40
+
41
+ // when working with filters always return filtered value
42
+ return $config;
43
+ }
44
+ add_filter('customify_filter_fields', 'make_this_function_name_unique' );
45
+ ```
46
+
47
+ ## 2. Add Style Manager section with master controls
48
+ ### 2.1. Add Style Manager support to the theme
49
+ In your function.php file add the following line of code to add support for the Style Manager section.
50
+ This is usually done
51
+ ```php
52
+ if ( ! function_exists( 'themename_setup' ) ) :
53
+ function listable_setup() {
54
+ ...
55
+ add_theme_support('customizer_style_manager');
56
+ ...
57
+ endif;
58
+
59
+ add_action( 'after_setup_theme', 'themename_setup' );
60
+ ```
61
+
62
+ ### 2.2. Add a function to filter the Style Manager config
63
+ ```php
64
+ /**
65
+ * Add the Style Manager cross-theme Customizer section.
66
+ *
67
+ * @param array $options
68
+ *
69
+ * @return array
70
+ */
71
+ function pixelgrade_add_customify_style_manager_section( $options ) {
72
+ // If the theme hasn't declared support for style manager, bail.
73
+ if ( ! current_theme_supports( 'customizer_style_manager' ) ) {
74
+ return $options;
75
+ }
76
+
77
+ if ( ! isset( $options['sections']['style_manager_section'] ) ) {
78
+ $options['sections']['style_manager_section'] = array();
79
+ }
80
+ }
81
+ ```
82
+ ```php
83
+ add_filter( 'customify_filter_fields', 'pixelgrade_add_customify_style_manager_section', 12, 1 );
84
+ ```
85
+
86
+ ### 2.3. Extend Style Manager fields with proper defaults and connected fields
87
+ ```php
88
+ // The section might be already defined, thus we merge, not replace the entire section config.
89
+ $options['sections']['style_manager_section'] = array_replace_recursive( $options['sections']['style_manager_section'], array(
90
+ 'options' => array(
91
+ 'sm_color_primary' => array(
92
+ 'default' => '#FF0000',
93
+ 'connected_fields' => array(
94
+ 'accent_color',
95
+ ),
96
+ ),
97
+ ...
98
+ ),
99
+ );
100
+
101
+ ```
102
+
103
+ ### 2.4. Create a default Color Palette for the current Theme
104
+ #### 2.4.1 Upload an image to Pixelgrade Cloud in order to use it as a mood background image for this Palette
105
+ #### 2.4.2 Write the proper configuration and use the `customify_get_color_palettes` hook to add it to the main list
106
+ Color values listed in the options attribute should match the ones that we've just set for the options in the Style Manager section (or rather the other way around)
107
+ ```php
108
+ function themename_add_default_color_palette( $color_palettes ) {
109
+
110
+ $color_palettes = array_merge(array(
111
+ 'default' => array(
112
+ 'label' => 'Default',
113
+ 'preview' => array(
114
+ 'background_image_url' => '',
115
+ ),
116
+ 'options' => array(
117
+ 'sm_color_primary' => '#FF4D58',
118
+ 'sm_color_secondary' => '#F53C48',
119
+ 'sm_color_tertiary' => '#FF4D58',
120
+ 'sm_dark_primary' => '#484848',
121
+ 'sm_dark_secondary' => '#2F2929',
122
+ 'sm_dark_tertiary' => '#919191',
123
+ 'sm_light_primary' => '#FFFFFF',
124
+ 'sm_light_secondary' => '#F9F9F9',
125
+ 'sm_light_tertiary' => '#F9F9F9',
126
+ ),
127
+ ),
128
+ ), $color_palettes);
129
+
130
+ return $color_palettes;
131
+ }
132
+ add_filter( 'customify_get_color_palettes', 'themename_add_default_color_palette' );
133
+ ```
134
+ darkest shades should go in dark_primary
135
+ body text color should go in dark_secondary
136
+
137
+ Pairs of options that control the foreground / background for the same element should not stay in the same group (color, dark or light). One should stay in one of the light groups, and the other one can stay either in the color or the dark groups.
readme.txt CHANGED
@@ -2,12 +2,12 @@
2
  Contributors: pixelgrade, euthelup, babbardel, vlad.olaru, cristianfrumusanu, raduconstantin, razvanonofrei
3
  Tags: customizer, css, editor, live, preview, customizer
4
  Requires at least: 4.7.0
5
- Tested up to: 4.9.5
6
- Stable tag: 1.7.3
7
  License: GPLv2 or later
8
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
9
 
10
- Customify is a Theme Customizer Booster that you can easily use to add Fonts, Colors, Live CSS Editor and other options to your theme.
11
 
12
  == Description ==
13
 
@@ -45,6 +45,10 @@ With [Customify](https://github.com/pixelgrade/customify), developers can easily
45
 
46
  == Changelog ==
47
 
 
 
 
 
48
  = 1.7.3 =
49
  * Added HEX field for colors in the current Color Palette
50
  * Updated Google Webfonts list
2
  Contributors: pixelgrade, euthelup, babbardel, vlad.olaru, cristianfrumusanu, raduconstantin, razvanonofrei
3
  Tags: customizer, css, editor, live, preview, customizer
4
  Requires at least: 4.7.0
5
+ Tested up to: 4.9.7
6
+ Stable tag: 1.7.4
7
  License: GPLv2 or later
8
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
9
 
10
+ Customify is a Theme Customizer Booster that you can easily use to customizer Fonts, Colors, Live CSS Editor and other options for your site.
11
 
12
  == Description ==
13
 
45
 
46
  == Changelog ==
47
 
48
+ = 1.7.4 =
49
+ * Reorganized Customizer custom sections and grouped them into Theme Options, thus making the Style Manager panel stand out.
50
+ * Refactored parts for more performance and clarity.
51
+
52
  = 1.7.3 =
53
  * Added HEX field for colors in the current Color Palette
54
  * Updated Google Webfonts list
scss/customizer.scss CHANGED
@@ -97,7 +97,7 @@ $background-hover : #f5fcff;
97
  &:focus, &:hover {
98
  background: $background-hover;
99
  }
100
-
101
  // "X" Icon
102
  &:before {
103
  top: 0px;
@@ -136,7 +136,7 @@ $background-hover : #f5fcff;
136
  margin-right: -$container-spacing;
137
  // margin-left: -$container-spacing;
138
  }
139
-
140
  .control-panel-content {
141
  .control-section:nth-child(2),
142
  .control-section:nth-child(3) {
@@ -146,7 +146,7 @@ $background-hover : #f5fcff;
146
  // Select the Second to Last Element
147
  // https://css-tricks.com/useful-nth-child-recipies/
148
  .control-section:nth-last-child(2) {
149
- border-bottom: 1px solid $borders;
150
  }
151
  }
152
 
@@ -166,7 +166,7 @@ $background-hover : #f5fcff;
166
  }
167
 
168
  #customize-controls .description {
169
- margin-bottom: 9px;
170
 
171
  font-size: 12px;
172
  font-weight: 300;
@@ -220,8 +220,8 @@ $background-hover : #f5fcff;
220
  .wp-core-ui {
221
 
222
  // Primary & Secondary Buttons
223
- .button:not(.theme-details):not(.collapse-sidebar):not(.wp-color-result),
224
- .button-primary,
225
  .button-secondary {
226
  width: auto;
227
  // padding: 6px 20px;
@@ -271,7 +271,7 @@ $background-hover : #f5fcff;
271
  box-shadow: 0px 2px 0px 0px #8db5ca !important;
272
 
273
  &.has-next-sibling {
274
- border-right: none;
275
  }
276
  }
277
  }
@@ -738,7 +738,7 @@ $background-hover : #f5fcff;
738
  &.customize-control-checkbox:not(#customize-control-jetpack_css_mode_control),
739
  &.customize-control-radio {
740
 
741
- // Split into two columns only when
742
  // there is more than one label
743
  label:not(:only-of-type),
744
  // WordPress 4.9 Class
@@ -1524,8 +1524,8 @@ input.customify_font_tooltip {
1524
  display: none;
1525
  }
1526
 
1527
- .font-options__option select,
1528
- .font-options__option input,
1529
  .select2-container {
1530
  // width: 100% !important; // am pus important pentru ca exista un inline de 100px
1531
  }
@@ -1548,8 +1548,8 @@ ul.font-options__options-list {
1548
  }
1549
  }
1550
 
1551
- .select2-container--default
1552
- .select2-selection--single
1553
  .select2-selection__rendered {
1554
  color: inherit;
1555
  line-height: initial;
@@ -1682,7 +1682,7 @@ ul.font-options__options-list {
1682
  color: #39474D;
1683
 
1684
  &:after {
1685
- content: "\f142"; // Change arrow style to be more consistent
1686
  transform: rotate(180deg);
1687
 
1688
  }
@@ -1747,7 +1747,7 @@ ul.font-options__options-list {
1747
  color: #9660c6; // Branding Icons
1748
  }
1749
  }
1750
-
1751
  // Slideshow
1752
  [class*=pixelgrade-featured-posts-slideshow] .widget .widget-title:before {
1753
  content: "\f233"; // images-alt2
@@ -1762,7 +1762,7 @@ ul.font-options__options-list {
1762
  [class*=featured-posts-grid] .widget .widget-title:before {
1763
  content: "\f180";
1764
  }
1765
-
1766
  // List Posts
1767
  [class*=featured-posts-list] .widget .widget-title:before {
1768
  content: "\f164";
@@ -1826,6 +1826,8 @@ ul.font-options__options-list {
1826
  // STYLE MANAGER
1827
  //------------------------------------*/
1828
 
 
 
1829
  $palette_box_shadow: inset 0 0 3px 0 rgba(0,0,0,0.15), inset 0 1px 3px 0 rgba(0,0,0,0.15);
1830
  $palette_box_shadow_stronger: inset 0 2px 3px 0 rgba(0,0,0,0.15), inset 0 0 3px 0 rgba(0,0,0,0.15);
1831
 
@@ -1853,7 +1855,7 @@ $palette_box_shadow_stronger: inset 0 2px 3px 0 rgba(0,0,0,0.15), inset 0 0 3px
1853
 
1854
  box-shadow: $palette_box_shadow;
1855
  }
1856
-
1857
  // Color Palette Hover
1858
  &:hover {
1859
 
@@ -2074,20 +2076,20 @@ $palette_box_shadow_stronger: inset 0 2px 3px 0 rgba(0,0,0,0.15), inset 0 0 3px
2074
  $palette_height: 64px;
2075
  $palette_border-radius: 5px;
2076
 
2077
- .c-palette {
2078
  position: relative;
2079
 
2080
- .c-palette__label {
2081
  flex-grow: 1;
2082
  }
2083
  }
2084
 
2085
- .c-palette:after {
2086
  height: $palette_height;
2087
  border-radius: $palette_border-radius;
2088
  }
2089
 
2090
- .c-palette:after {
2091
  content: "";
2092
  display: block;
2093
  position: absolute;
@@ -2108,7 +2110,7 @@ $palette_border-radius: 5px;
2108
  box-shadow: 0 2px 5px rgba(0, 0, 0, 0.15);
2109
  }
2110
 
2111
- .c-palette__label {
2112
  display: flex;
2113
  align-items: center;
2114
  height: 40px;
@@ -2138,7 +2140,7 @@ $palette_border-radius: 5px;
2138
  height: $palette_height;
2139
  }
2140
 
2141
- .c-palette__overlay {
2142
  position: absolute;
2143
  top: 0;
2144
  left: 0;
@@ -2243,7 +2245,7 @@ $animation-duration: 1s;
2243
  }
2244
  }
2245
 
2246
- .c-palette.animate {
2247
 
2248
  .next {
2249
 
@@ -2354,7 +2356,7 @@ $animation-duration: 1s;
2354
  .colors.next .picker {
2355
  }
2356
 
2357
- .c-palette__blur {
2358
  display: none;
2359
  }
2360
 
@@ -2363,17 +2365,17 @@ $animation-duration: 1s;
2363
  margin: -12px -12px 19px;
2364
  width: auto;
2365
 
2366
- .palette-container {
2367
  padding: 19px;
2368
  background: white;
2369
  }
2370
  }
2371
 
2372
- .c-palette__name {
2373
  margin-right: auto;
2374
  }
2375
 
2376
- .c-palette__control {
2377
  width: 2em;
2378
  height: 2em;
2379
  margin-left: 0.25em;
@@ -2401,7 +2403,7 @@ $animation-duration: 1s;
2401
  }
2402
  }
2403
 
2404
- #sub-accordion-section-style_manager_section {
2405
  display: flex !important;
2406
  flex-direction: column;
2407
  padding: 12px 0 0 !important;
@@ -2414,7 +2416,8 @@ $animation-duration: 1s;
2414
  }
2415
 
2416
  #customize-control-sm_color_palette_control {
2417
- flex-basis: 0;
 
2418
  flex-grow: 1;
2419
  overflow-y: scroll;
2420
  margin-top: -19px;
@@ -2430,7 +2433,7 @@ $animation-duration: 1s;
2430
  display: none !important;
2431
  }
2432
  }
2433
- .c-palette .iris-picker {
2434
  position: absolute;
2435
  top: 100%;
2436
  left: 0;
@@ -2492,7 +2495,7 @@ $animation-duration: 1s;
2492
  }
2493
  }
2494
 
2495
- .c-palette__tooltip {
2496
  position: absolute;
2497
  bottom: 100%;
2498
  left: 50%;
@@ -2524,17 +2527,17 @@ $animation-duration: 1s;
2524
  transform: translateX(-50%);
2525
  }
2526
 
2527
- .c-palette__control:hover & {
2528
  opacity: 1;
2529
  }
2530
  }
2531
 
2532
- .c-palette__control {
2533
  position: relative;
2534
  cursor: pointer;
2535
  }
2536
 
2537
- input.c-palette__input[class] {
2538
  margin-top: 1em;
2539
  }
2540
 
@@ -2550,3 +2553,178 @@ input.c-palette__input[class] {
2550
  //.wp-full-overlay-sidebar {
2551
  // overflow: hidden;
2552
  //}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
97
  &:focus, &:hover {
98
  background: $background-hover;
99
  }
100
+
101
  // "X" Icon
102
  &:before {
103
  top: 0px;
136
  margin-right: -$container-spacing;
137
  // margin-left: -$container-spacing;
138
  }
139
+
140
  .control-panel-content {
141
  .control-section:nth-child(2),
142
  .control-section:nth-child(3) {
146
  // Select the Second to Last Element
147
  // https://css-tricks.com/useful-nth-child-recipies/
148
  .control-section:nth-last-child(2) {
149
+ // border-bottom: 1px solid $borders;
150
  }
151
  }
152
 
166
  }
167
 
168
  #customize-controls .description {
169
+ // margin-bottom: 9px;
170
 
171
  font-size: 12px;
172
  font-weight: 300;
220
  .wp-core-ui {
221
 
222
  // Primary & Secondary Buttons
223
+ .button:not(.theme-details):not(.collapse-sidebar):not(.wp-color-result),
224
+ .button-primary,
225
  .button-secondary {
226
  width: auto;
227
  // padding: 6px 20px;
271
  box-shadow: 0px 2px 0px 0px #8db5ca !important;
272
 
273
  &.has-next-sibling {
274
+ border-right: none;
275
  }
276
  }
277
  }
738
  &.customize-control-checkbox:not(#customize-control-jetpack_css_mode_control),
739
  &.customize-control-radio {
740
 
741
+ // Split into two columns only when
742
  // there is more than one label
743
  label:not(:only-of-type),
744
  // WordPress 4.9 Class
1524
  display: none;
1525
  }
1526
 
1527
+ .font-options__option select,
1528
+ .font-options__option input,
1529
  .select2-container {
1530
  // width: 100% !important; // am pus important pentru ca exista un inline de 100px
1531
  }
1548
  }
1549
  }
1550
 
1551
+ .select2-container--default
1552
+ .select2-selection--single
1553
  .select2-selection__rendered {
1554
  color: inherit;
1555
  line-height: initial;
1682
  color: #39474D;
1683
 
1684
  &:after {
1685
+ content: "\f142"; // Change arrow style to be more consistent
1686
  transform: rotate(180deg);
1687
 
1688
  }
1747
  color: #9660c6; // Branding Icons
1748
  }
1749
  }
1750
+
1751
  // Slideshow
1752
  [class*=pixelgrade-featured-posts-slideshow] .widget .widget-title:before {
1753
  content: "\f233"; // images-alt2
1762
  [class*=featured-posts-grid] .widget .widget-title:before {
1763
  content: "\f180";
1764
  }
1765
+
1766
  // List Posts
1767
  [class*=featured-posts-list] .widget .widget-title:before {
1768
  content: "\f164";
1826
  // STYLE MANAGER
1827
  //------------------------------------*/
1828
 
1829
+ // COLOR PALETTES SECTION //
1830
+
1831
  $palette_box_shadow: inset 0 0 3px 0 rgba(0,0,0,0.15), inset 0 1px 3px 0 rgba(0,0,0,0.15);
1832
  $palette_box_shadow_stronger: inset 0 2px 3px 0 rgba(0,0,0,0.15), inset 0 0 3px 0 rgba(0,0,0,0.15);
1833
 
1855
 
1856
  box-shadow: $palette_box_shadow;
1857
  }
1858
+
1859
  // Color Palette Hover
1860
  &:hover {
1861
 
2076
  $palette_height: 64px;
2077
  $palette_border-radius: 5px;
2078
 
2079
+ .c-color-palette {
2080
  position: relative;
2081
 
2082
+ .c-color-palette__label {
2083
  flex-grow: 1;
2084
  }
2085
  }
2086
 
2087
+ .c-color-palette:after {
2088
  height: $palette_height;
2089
  border-radius: $palette_border-radius;
2090
  }
2091
 
2092
+ .c-color-palette:after {
2093
  content: "";
2094
  display: block;
2095
  position: absolute;
2110
  box-shadow: 0 2px 5px rgba(0, 0, 0, 0.15);
2111
  }
2112
 
2113
+ .c-color-palette__label {
2114
  display: flex;
2115
  align-items: center;
2116
  height: 40px;
2140
  height: $palette_height;
2141
  }
2142
 
2143
+ .c-color-palette__overlay {
2144
  position: absolute;
2145
  top: 0;
2146
  left: 0;
2245
  }
2246
  }
2247
 
2248
+ .c-color-palette.animate {
2249
 
2250
  .next {
2251
 
2356
  .colors.next .picker {
2357
  }
2358
 
2359
+ .c-color-palette__blur {
2360
  display: none;
2361
  }
2362
 
2365
  margin: -12px -12px 19px;
2366
  width: auto;
2367
 
2368
+ .color-palette-container {
2369
  padding: 19px;
2370
  background: white;
2371
  }
2372
  }
2373
 
2374
+ .c-color-palette__name {
2375
  margin-right: auto;
2376
  }
2377
 
2378
+ .c-color-palette__control {
2379
  width: 2em;
2380
  height: 2em;
2381
  margin-left: 0.25em;
2403
  }
2404
  }
2405
 
2406
+ #sub-accordion-section-sm_color_palettes_section {
2407
  display: flex !important;
2408
  flex-direction: column;
2409
  padding: 12px 0 0 !important;
2416
  }
2417
 
2418
  #customize-control-sm_color_palette_control {
2419
+ // flex-basis: 0;
2420
+ flex-shrink: 0;
2421
  flex-grow: 1;
2422
  overflow-y: scroll;
2423
  margin-top: -19px;
2433
  display: none !important;
2434
  }
2435
  }
2436
+ .c-color-palette .iris-picker {
2437
  position: absolute;
2438
  top: 100%;
2439
  left: 0;
2495
  }
2496
  }
2497
 
2498
+ .c-color-palette__tooltip {
2499
  position: absolute;
2500
  bottom: 100%;
2501
  left: 50%;
2527
  transform: translateX(-50%);
2528
  }
2529
 
2530
+ .c-color-palette__control:hover & {
2531
  opacity: 1;
2532
  }
2533
  }
2534
 
2535
+ .c-color-palette__control {
2536
  position: relative;
2537
  cursor: pointer;
2538
  }
2539
 
2540
+ input.c-color-palette__input[class] {
2541
  margin-top: 1em;
2542
  }
2543
 
2553
  //.wp-full-overlay-sidebar {
2554
  // overflow: hidden;
2555
  //}
2556
+
2557
+ .sm_color_matrix {
2558
+ display: flex;
2559
+ flex-wrap: wrap;
2560
+ margin-top: -15px;
2561
+ margin-left: -15px;
2562
+
2563
+ > * {
2564
+ display: flex;
2565
+ flex-wrap: wrap;
2566
+ align-content: flex-start;
2567
+ flex: 0 0 percentage(1/3);
2568
+ padding-top: 15px;
2569
+ padding-left: 15px;
2570
+
2571
+ > * {
2572
+ // width: 15px;
2573
+ // height: 15px;
2574
+ // margin: 2px;
2575
+ background-color: currentColor;
2576
+ border-radius: 50%;
2577
+ border: 1px solid #ccc;
2578
+ animation-duration: 0.75s;
2579
+ animation-name: bounceIn;
2580
+ }
2581
+ }
2582
+ }
2583
+
2584
+ .sm_color_matrix > * {
2585
+ display: grid;
2586
+ grid-auto-rows: 2px;
2587
+ grid-auto-columns: 2px;
2588
+
2589
+
2590
+
2591
+ > :nth-child(1) { grid-area: 16 / 12 / span 12 / span 12; }
2592
+ > :nth-child(2) { grid-area: 26 / 24 / span 4 / span 4; }
2593
+ > :nth-child(3) { grid-area: 13 / 24 / span 4 / span 4; }
2594
+ > :nth-child(4) { grid-area: 8 / 8 / span 8 / span 8; }
2595
+ > :nth-child(5) { grid-area: 32 / 8 / span 4 / span 4; }
2596
+ > :nth-child(6) { grid-area: 30 / 16 / span 8 / span 8; }
2597
+ > :nth-child(7) { grid-area: 4 / 20 / span 8 / span 8; }
2598
+ > :nth-child(8) { grid-area: 17 / 26 / span 8 / span 8; }
2599
+ > :nth-child(9) { grid-area: 22 / 2 / span 8 / span 8; }
2600
+ > :nth-child(10) { grid-area: 28 / 11 / span 2 / span 2; }
2601
+ > :nth-child(11) { grid-area: 9 / 31 / span 6 / span 6; }
2602
+ > :nth-child(11) { grid-area: 26 / 30 / span 9 / span 9; }
2603
+ > :nth-child(12) { grid-area: 17 / 7 / span 4 / span 4; }
2604
+ > :nth-child(13) { grid-area: 19 / 36 / span 6 / span 6; }
2605
+ > :nth-child(14) { grid-area: 12 / 18 / span 2 / span 2; }
2606
+ }
2607
+
2608
+ @keyframes bounceIn {
2609
+ 0%, 20%, 40%, 60%, 80%, 100% {
2610
+ animation-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1);
2611
+ }
2612
+
2613
+ 0% {
2614
+ opacity: 0;
2615
+ transform: scale3d(0.3, 0.3, 0.3);
2616
+ }
2617
+
2618
+ 20% {
2619
+ transform: scale3d(1.1, 1.1, 1.1);
2620
+ }
2621
+
2622
+ 40% {
2623
+ transform: scale3d(0.9, 0.9, 0.9);
2624
+ }
2625
+
2626
+ 60% {
2627
+ opacity: 1;
2628
+ transform: scale3d(1.03, 1.03, 1.03);
2629
+ }
2630
+
2631
+ 80% {
2632
+ transform: scale3d(0.97, 0.97, 0.97);
2633
+ }
2634
+
2635
+ 100% {
2636
+ opacity: 1;
2637
+ transform: scale3d(1, 1, 1);
2638
+ }
2639
+ }
2640
+
2641
+ // SECTIONS AND PANELS WITH ICONS
2642
+ // ========================================
2643
+
2644
+ @mixin section_icon($icon) {
2645
+ h3.accordion-section-title:before {
2646
+ position: relative;
2647
+ float: right;
2648
+ content: $icon;
2649
+ color: #aed2e5;
2650
+ font-family: dashicons;
2651
+ padding: 1px;
2652
+ margin-right: 28px;
2653
+ font-size: 17px;
2654
+ -webkit-font-smoothing: antialiased;
2655
+ }
2656
+ }
2657
+
2658
+ #customize-theme-controls {
2659
+
2660
+ #sub-accordion-panel-style_manager_panel,
2661
+ #sub-accordion-panel-theme_options_panel {
2662
+ .customize-panel-description {
2663
+ display: block;
2664
+ }
2665
+ }
2666
+
2667
+ // Style Manager Section
2668
+ // ----------------------------------------
2669
+ li#accordion-panel-style_manager_panel {
2670
+ @include section_icon("\f155");
2671
+
2672
+ h3.accordion-section-title:before {
2673
+ font-size: 18px;
2674
+ color: #f8bc30; // Yellow color
2675
+ }
2676
+ }
2677
+
2678
+ // Style Manager → Colors / Fonts Panels
2679
+ li#accordion-section-sm_color_palettes_section {
2680
+ @include section_icon("\f100");
2681
+ h3.accordion-section-title {
2682
+ border-top: none;
2683
+ }
2684
+ }
2685
+
2686
+ li#accordion-section-sm_font_palettes_section {
2687
+ @include section_icon("\f122");
2688
+ }
2689
+
2690
+ li#accordion-section-sm_color_palettes_section,
2691
+ li#accordion-section-sm_font_palettes_section {
2692
+ h3.accordion-section-title {
2693
+
2694
+ &:before {
2695
+ padding: 3px;
2696
+ margin-right: 5px;
2697
+ margin-top: -2px;
2698
+ }
2699
+ }
2700
+ }
2701
+
2702
+
2703
+ // Theme Options Section
2704
+ // ----------------------------------------
2705
+ li#accordion-panel-theme_options_panel {
2706
+ @include section_icon("\f538");
2707
+
2708
+ h3.accordion-section-title {
2709
+ border-bottom: 1px solid #ddd;
2710
+ border-left: none;
2711
+ border-right: none;
2712
+ margin: 0 0 15px 0;
2713
+ }
2714
+ }
2715
+
2716
+ // Theme Options Spacing between Sections
2717
+ li[id$="[general]"],
2718
+ li[id$="[footer_section]"] {
2719
+ border-bottom: 1px solid #ddd;
2720
+ border-left: none;
2721
+ border-right: none;
2722
+ margin: 0 0 15px 0;
2723
+ }
2724
+
2725
+ li[id$="[general]"] {
2726
+ h3.accordion-section-title {
2727
+ border-top: none;
2728
+ }
2729
+ }
2730
+ }
settings/general.php CHANGED
@@ -7,6 +7,9 @@ $customify_sections = array();
7
  if ( isset( $config['sections'] ) && ! empty( $config['sections'] ) ) {
8
 
9
  foreach ( $config['sections'] as $id => $section ) {
 
 
 
10
  $customify_sections[$id] = $section['title'];
11
  }
12
 
@@ -18,6 +21,9 @@ if ( isset( $config['panels'] ) && ! empty( $config['panels'] ) ) {
18
 
19
  if ( isset( $panel['sections'] ) && ! empty( $panel['sections'] ) ) {
20
  foreach ( $panel['sections'] as $id => $section ) {
 
 
 
21
  $customify_sections[$id] = $section['title'];
22
  }
23
  }
7
  if ( isset( $config['sections'] ) && ! empty( $config['sections'] ) ) {
8
 
9
  foreach ( $config['sections'] as $id => $section ) {
10
+ if ( empty( $section['title'] ) ) {
11
+ $section['title'] = 'No Title';
12
+ }
13
  $customify_sections[$id] = $section['title'];
14
  }
15
 
21
 
22
  if ( isset( $panel['sections'] ) && ! empty( $panel['sections'] ) ) {
23
  foreach ( $panel['sections'] as $id => $section ) {
24
+ if ( empty( $section['title'] ) ) {
25
+ $section['title'] = 'No Title';
26
+ }
27
  $customify_sections[$id] = $section['title'];
28
  }
29
  }