/******/ (function() { // webpackBootstrap
var CustomifyAutoCSS = window.CustomifyAutoCSS || null;
(function ($, api) {
  CustomifyAutoCSS = function () {
    this.values = {};
    this.lastValues = {};
    this.devices = ['desktop', 'tablet', 'mobile'];
  };
  CustomifyAutoCSS._change = false;
  CustomifyAutoCSS.prototype.fonts = {};
  CustomifyAutoCSS.prototype.styling_fields = {
    color: null,
    image: null,
    position: null,
    cover: null,
    repeat: null,
    attachment: null,
    border_width: null,
    border_color: null,
    border_style: null
  };
  CustomifyAutoCSS.prototype.subsets = {};
  CustomifyAutoCSS.prototype.variants = {};
  CustomifyAutoCSS.prototype.media_queries = {
    all: '%s',
    desktop: '%s',
    tablet: '@media screen and (max-width: 1024px) { %s }',
    mobile: '@media screen and (max-width: 568px) { %s }'
  };
  CustomifyAutoCSS.prototype.css = {
    all: '',
    desktop: '',
    tablet: '',
    mobile: ''
  };
  CustomifyAutoCSS.prototype.css_root = {
    all: '',
    desktop: '',
    tablet: '',
    mobile: ''
  };
  CustomifyAutoCSS.prototype.box_shadow_fields = {
    color: null,
    x: 0,
    y: 0,
    blur: 0,
    spread: 0,
    inset: null
  };
  CustomifyAutoCSS.prototype.reset = function () {
    this.fonts = {};
    this.subsets = {};
    this.variants = {};
    this.css = {
      all: '',
      desktop: '',
      tablet: '',
      mobile: ''
    };
    this.css_root = {
      all: '',
      desktop: '',
      tablet: '',
      mobile: ''
    };
  };

  // Foundational typography settings that emit :root tokens — single
  // source of truth for typography_field_uses_vars() (route gate) and
  // typography_var_name() (token name). Keep in lockstep with PHP
  // Customify_Customizer_Auto_CSS::TYPO_VAR_MAP.
  var TYPO_VAR_MAP = {
    'global_typography_base_p': 'body',
    'global_typography_base_heading': 'heading',
    'global_typography_heading_h1': 'h1',
    'global_typography_heading_h2': 'h2',
    'global_typography_heading_h3': 'h3',
    'global_typography_heading_h4': 'h4',
    'global_typography_heading_h5': 'h5',
    'global_typography_heading_h6': 'h6'
  };

  /**
   * Mirror of PHP typography_field_uses_vars(). Tokens are restricted
   * to the foundational typography (TYPO_VAR_MAP) — Base body, shared
   * Heading family/weight, h1–h6 type scale. Component-leaf roles
   * (site title, tagline, widget title) and per-component typography
   * stay in legacy selector-scoped (literal) mode.
   */
  CustomifyAutoCSS.prototype.typography_field_uses_vars = function (field) {
    var name = field && field.name ? String(field.name) : '';
    return !!TYPO_VAR_MAP[name];
  };

  /**
   * Mirror of PHP typography_var_name(). Keep the strip rule in
   * lockstep with class-customizer-auto-css.php typography_var_name().
   */
  CustomifyAutoCSS.prototype.typography_var_name = function (setting_name, property) {
    var name = String(setting_name || '');
    // Foundational settings map to explicit semantic names via the
    // shared TYPO_VAR_MAP (lockstep with PHP).
    if (TYPO_VAR_MAP[name]) {
      return '--customify-typo-' + TYPO_VAR_MAP[name] + '-' + property;
    }
    // Fallback for opted-in non-foundational fields.
    var gp = 'global_typography_';
    if (name.length > gp.length && name.indexOf(gp) === 0) {
      name = name.substr(gp.length);
    }
    var suffixes = ['_modal_font_size', '_typography', '_font_size', '_typo'];
    for (var i = 0; i < suffixes.length; i++) {
      var s = suffixes[i];
      if (name.length > s.length && name.substr(-s.length) === s) {
        name = name.substr(0, name.length - s.length);
        break;
      }
    }
    name = name.replace(/_/g, '-');
    return '--customify-typo-' + name + '-' + property;
  };

  /**
   * Convert a map of "property: value;" CSS lines into custom-property
   * lines scoped to the given typography setting. Mirrors the PHP
   * code_to_root_vars() helper.
   */
  CustomifyAutoCSS.prototype.code_to_root_vars = function (setting_name, code_map) {
    var vars = [];
    var that = this;
    _.each(code_map, function (css_line) {
      if (!_.isString(css_line)) {
        return;
      }
      var line = css_line.replace(/^\s+|\s+$/g, '');
      if (line === '') {
        return;
      }
      var m = line.match(/^([a-z-]+)\s*:\s*(.+?);?\s*$/i);
      if (!m) {
        return;
      }
      var property = m[1].toLowerCase();
      var value = m[2].replace(/^\s+|\s+$/g, '');
      vars.push(that.typography_var_name(setting_name, property) + ': ' + value + ';');
    });
    return vars;
  };
  CustomifyAutoCSS.prototype.encodeValue = function (value) {
    return encodeURI(JSON.stringify(value));
  };
  CustomifyAutoCSS.prototype.decodeValue = function (value) {
    return JSON.parse(decodeURI(value));
  };
  CustomifyAutoCSS.prototype.loop_fields = function (fields, values, skip_if_val_null, no_selector) {
    if (_.isUndefined(skip_if_val_null)) {
      skip_if_val_null = false;
    }
    if (!_.isObject(values)) {
      values = {};
    }
    var that = this;
    var fields_code = {};
    _.each(fields, function (field) {
      var v = !_.isUndefined(values[field.name]) ? values[field.name] : null;
      if (!(_.isNull(v) && skip_if_val_null)) {
        if (field.selector && field.css_format) {
          switch (field.type) {
            case 'css_ruler':
              fields_code[field.name] = that.css_ruler(field, v, no_selector);
              break;
            case 'slider':
              fields_code[field.name] = that.slider(field, v, no_selector);
              break;
            case 'color':
              fields_code[field.name] = that.color(field, v, no_selector);
              break;
            case 'shadow':
              fields_code[field.name] = that.shadow(field, v, no_selector);
              break;
            case 'checkbox':
              if (field.css_format == 'html_class') {
                that.html_class(field, v);
              } else {
                fields_code[field.name] = that.checkbox(field, v, no_selector);
              }
              break;
            case 'image':
              fields_code[field.name] = that.image(field, v, no_selector);
              break;
            case 'text_align':
            case 'text_align_no_justify':
              fields_code[field.name] = that.text_align(field, v, no_selector);
              break;
            case 'font':
              fields_code[field.name] = that.font(field, v, no_selector);
              break;
            case 'styling':
              fields_code[field.name] = that.styling(field, v, no_selector);
              break;
            case 'typography':
              fields_code[field.name] = that.typography(field, v, no_selector);
              break;
            case 'modal':
              that.modal(field, v);
              break;
            case 'columns_settings':
              that.columns_settings(field);
              break;
            default:
              switch (field.css_format) {
                case 'background':
                case 'styling':
                  fields_code[field.name] = that.styling(field, v, no_selector);
                  break;
                case 'typography':
                  fields_code[field.name] = that.typography(field, v, no_selector);
                  break;
                case 'html_class':
                  that.html_class(field, v);
                  break;
                case 'html_replace':
                  that.html_replace(field, v);
                  break;
                default:
                  fields_code[field.name] = that.maybe_devices_setup(field, 'setup_default', v, no_selector);
              }
          }
        } // end if selector and css format
      }
    }); // end _.each

    return fields_code;
  };
  CustomifyAutoCSS.prototype.run = function (setting_name) {
    if (_.isUndefined(setting_name)) {
      setting_name = false;
    }
    this.lastValues = this.values;
    this.values = api.get();
    if (window.Customify_JS) {
      if (window.Customify_JS.css_media_queries) {
        this.media_queries = window.Customify_JS.css_media_queries;
      }
    }
    this.reset();
    var that = this;
    that.loop_fields(Customify_Preview_Config.fields);
    var css_code = '';

    // Flush :root typography variable buckets first. Each device's
    // accumulated `--var: value;` lines get wrapped in a single
    // :root { ... } block, then wrapped in the matching media
    // query template — multiple typography fields collapse into
    // one rule per device.
    var ri = 0;
    _.each(that.css_root, function (vars_chunk, device) {
      if (vars_chunk === '') {
        ri++;
        return;
      }
      var new_line = '';
      if (ri > 0) {
        new_line = "\r\n\r\n";
      }
      var root_block = ":root {\r\n\t" + vars_chunk + "\r\n}";
      css_code += new_line + that.media_queries[device].replace(/%s/g, root_block) + "\r\n";
      ri++;
    });
    var i = 0;
    _.each(that.css, function (code, device) {
      var new_line = '';
      if (i > 0) {
        new_line = "\r\n\r\n\r\n\r\n\r";
      }
      css_code += new_line + that.media_queries[device].replace(/%s/g, code) + "\r\n";
      i++;
    });
    var url = that.get_google_fonts_url();
    if ($('#customify-google-font-css').length <= 0) {
      $('head').prepend("<link rel='stylesheet' id='customify-google-font-css'  href='' type='text/css' media='all' />");
    }
    if (url) {
      //css_code = "\r\n@import url('"+url+"');\r\n\r\n"+css_code;
      $('#customify-google-font-css').attr('href', url);
    } else {
      $('#customify-google-font-css').remove();
    }
    css_code = css_code.trim();
    if ($('#customify-style-inline-css').length <= 0) {
      $('head').append("<style id='customify-style-inline-css' type='text/css'></style>");
    }
    $('#customify-style-inline-css').html(css_code);
    $(document).trigger('header_builder_panel_changed', ['auto_render_css', setting_name]);
    $(document).trigger('after_auto_render_css', ['after_auto_render_css', setting_name]);
  };
  CustomifyAutoCSS.prototype.get_setting = function (name, device, key) {
    if (_.isUndefined(device)) {
      device = 'desktop';
    }
    if (_.isUndefined(key)) {
      key = false;
    }
    var get_value = null;
    var value;
    var df = false;
    if (!_.isUndefined(Customify_Preview_Config.fields['setting|' + name])) {
      var field = Customify_Preview_Config.fields['setting|' + name];
      df = !_.isUndefined(field.default) ? field.default : false;
    }
    value = !_.isUndefined(this.values[name]) ? this.values[name] : df;
    if (_.isString(value)) {
      try {
        var decodeValue = this.decodeValue(value);
        if (!_.isNull(decodeValue)) {
          value = decodeValue;
        }
      } catch (e) {}
    }
    if (!key) {
      if (device !== 'all') {
        if (_.isObject(value) && !_.isUndefined(value[device])) {
          get_value = value[device];
        }
      } else {
        get_value = value;
      }
    } else {
      var value_by_key = _.isUndefined(value[key]) ? value[key] : false;
      if (device !== 'all' && _.isObject(value_by_key)) {
        if (_.isObject(value_by_key) && !_.isUndefined(value_by_key[device])) {
          get_value = value_by_key[device];
        } else {
          get_value = value_by_key;
        }
      } else {
        get_value = value_by_key;
      }
    }
    return get_value;
  };
  CustomifyAutoCSS.prototype.get_google_fonts_url = function () {
    var url = '//fonts.googleapis.com/css?family=';
    var s = '';
    var that = this;
    if (_.isEmpty(that.fonts)) {
      return false;
    }
    _.each(that.fonts, function (font_name) {
      if (s) {
        s += '|';
      }
      s += font_name.replace(/\s/g, '+');
      var v = {};
      if (!_.isUndefined(that.variants[font_name])) {
        _.each(that.variants[font_name], function (_v) {
          if (_v !== 'regular') {
            switch (_v) {
              case 'italic':
                v[_v] = '400i';
                break;
              default:
                if (_.isString(_v)) {
                  v[_v] = _v.replace('italic', 'i');
                } else {
                  v[_v] = _v;
                }
            }
          } else {
            v[_v] = '400';
          }
        });
      }
      if (!_.isEmpty(v)) {
        s += ':' + that.join(v, ',');
      }
    });
    url += s;
    if (!_.isEmpty(that.subsets)) {
      url += '&subset=' + that.join(that.subsets, ',');
    }
    return url;
  };
  CustomifyAutoCSS.prototype.join = function (object, glue) {
    if (_.isUndefined(glue)) {
      glue = '';
    }
    if (_.isArray(object)) {
      return object.join(glue);
    }
    if (!_.isObject(object) || _.isEmpty(object)) {
      return '';
    }
    var array = _.values(object);
    return array.join(glue);
  };
  CustomifyAutoCSS.prototype.str_value = function (value, format, value_no_unit) {
    if (_.isEmpty(value)) {
      return '';
    }
    if (!_.isString(format)) {
      return '';
    }
    if (_.isUndefined(value_no_unit)) {
      value_no_unit = '';
    }
    var find = '{{value}}';
    var reg = new RegExp(find, 'g');
    var s = format.replace(reg, value);
    var find_2 = '{{value_no_unit}}';
    var reg2 = new RegExp(find_2, 'g');
    s = s.replace(reg2, value_no_unit);
    return s;
  };
  CustomifyAutoCSS.prototype.setup_color = function (value, format) {
    if (format) {
      if (value) {
        return this.str_value(value, format);
      }
    }
    return false;
  };
  CustomifyAutoCSS.prototype.setup_checkbox = function (value, format) {
    if (format) {
      if (value) {
        return format;
      }
    }
    return false;
  };
  CustomifyAutoCSS.prototype.setup_image = function (value, format) {
    var image = this.sanitize_media(value);
    if (image.url) {
      if (format) {
        return this.str_value(image.url, format);
      }
    }
    return false;
  };
  CustomifyAutoCSS.prototype.setup_slider = function (value, format) {
    // Mirror PHP setup_slider(): slider fields declare their `default`
    // as a bare scalar (e.g. narrow_width => 800) which is what the
    // live-preview reads via `api.get()` until the user actually drags
    // the slider. Without this cast, `_.isObject( 800 )` is false →
    // `value = {}` → `value.value` is null → empty string returned →
    // the `css_format` rule never renders. Visible symptom on
    // narrow_width: dragging the slider does nothing on a fresh page
    // because the rule was missing in the first place; the per-field
    // baseline gets restored only after the first save flips the
    // option to `{value, unit}` shape. Cast the scalar here so first-
    // paint preview matches a saved-state preview.
    if ((typeof value === 'number' || typeof value === 'string') && value !== '') {
      value = {
        value: value,
        unit: 'px'
      };
    }
    if (!_.isObject(value)) {
      value = {};
    }
    value = _.defaults(value, {
      unit: 'px',
      value: null
    });
    if (!value.unit) {
      value.unit = 'px';
    }

    // Unitless sentinel: multi-unit sliders store '-' when the user
    // picks the unitless option (line-height multiplier). Emit the
    // bare number. Keep the empty-unit→px coercion above first so
    // legacy values keep resolving to px. Mirrors PHP setup_slider().
    if (value.unit === '-') {
      value.unit = '';
    }
    var c = '';
    var v = '';
    if (format) {
      if (value.value) {
        v = value.value + value.unit;
        c = this.str_value(v, format, value.value);
      }
    }
    return c;
  };
  CustomifyAutoCSS.prototype.setup_shadow = function (value, format) {
    var that = this;
    if (!_.isObject(value)) {
      return '';
    }
    var p = _.defaults(value, that.box_shadow_fields);
    var color = that.sanitize_color(p.color);
    var position = p.inset ? 'inset' : '';
    if (!color) {
      return '';
    }
    if (!p.blur) {
      p.blur = 0;
    }
    if (!p.spread) {
      p.spread = 0;
    }
    if (!p.x) {
      p.x = 0;
    }
    if (!p.y) {
      p.y = 0;
    }
    var style = p.x + 'px' + ' ' + p.y + 'px' + ' ' + p.blur + 'px' + ' ' + p.spread + 'px' + ' ' + color + ' ' + position;

    /* offset-x | offset-y | blur-radius | spread-radius | color */
    //box-shadow: 2px 2px 2px 1px rgba(0, 0, 0, 0.2);
    return this.str_value(style, format);
  };
  CustomifyAutoCSS.prototype.setup_default = function (value, format) {
    if (format) {
      if (value) {
        return this.str_value(value, format);
      }
    }
    return false;
  };
  CustomifyAutoCSS.prototype.setup_css_ruler = function (value, format) {
    if (!_.isObject(value)) {
      value = {};
    }
    value = _.defaults(value, {
      unit: '',
      top: '',
      right: '',
      bottom: '',
      left: ''
    });
    if (!_.isUndefined(value.unit)) {
      value.unit = 'px';
    }
    format = _.defaults(format, {
      top: '',
      right: '',
      bottom: '',
      left: ''
    });
    var that = this;
    var code = {};
    _.each(format, function (string, pos) {
      var v = value[pos];
      if (v && string) {
        if (string) {
          v = v + value['unit'];
          code[pos] = that.str_value(v, string);
        }
      }
    });
    return that.join(code, "\n\t");
  };
  CustomifyAutoCSS.prototype.setup_text_align = function (value, format) {
    if (format) {
      if (value) {
        return this.str_value(value, format);
      }
    }
    return false;
  };
  CustomifyAutoCSS.prototype.sanitize_color = function (color) {
    return color;
  };
  CustomifyAutoCSS.prototype.sanitize_slider = function (value) {
    value = _.defaults(value, {
      unit: 'px',
      value: null
    });
    return value;
  };
  CustomifyAutoCSS.prototype.sanitize_media = function (value) {
    if (!_.isObject(value)) {
      value = {};
    }
    return _.defaults(value, {
      id: null,
      url: null,
      mime: null
    });
  };
  CustomifyAutoCSS.prototype.maybe_devices_setup = function (field, call_back, values, no_selector) {
    var code = '';
    var code_array = {};
    var has_device = false;
    var format = !_.isEmpty(field.css_format) ? field.css_format : false;
    var that = this;
    if (_.isUndefined(no_selector)) {
      no_selector = false;
    }
    var no_value = false;
    if (_.isUndefined(values) || _.isNull(values)) {
      values = {};
      no_value = true;
    }
    if (!_.isUndefined(field.device_settings) && field.device_settings) {
      has_device = true;
      _.each(that.devices, function (device) {
        var value = null;
        if (no_value) {
          value = that.get_setting(field.name, device);
        } else {
          if (!_.isUndefined(values[device])) {
            value = values[device];
          }
        }
        var _c = false;
        if (that[call_back]) {
          _c = that[call_back](value, format);
        }
        if (_c) {
          code_array[device] = _c;
        }
      });
    } else {
      if (no_value) {
        values = that.get_setting(field.name, 'all');
      }
      if (that[call_back]) {
        code = that[call_back](values, format);
      }
      code_array.no_devices = code;
    }
    if (_.isEmpty(code_array)) {
      // return false;
    }
    code = '';
    if (no_selector) {
      return code_array;
    } else {
      if (has_device) {
        _.each(that.devices, function (device) {
          if (!_.isUndefined(code_array[device])) {
            var _c = code_array[device];
            if (_c) {
              if (field.selector === 'format') {
                that.css[device] += "\r\n" + _c + "\r\n";
              } else {
                that.css[device] += "\r\n" + field.selector + " {\r\n\t" + _c + "\r\n}\r\n";
              }
            }
          }
        });
      } else {
        if (code_array.no_devices) {
          if (field.selector === 'format') {
            that.css.all += "\r\n" + code_array.no_devices + "\r\n";
          } else {
            that.css.all += "\r\n" + field.selector + "  {\r\n\t" + code_array.no_devices + "\r\n}\r\n";
          }
        }
      }
    }
    return code;
  };
  CustomifyAutoCSS.prototype.setup_font = function (value) {
    if (!_.isObject(value)) {
      value = {};
    }
    value = _.defaults(value, {
      font: null,
      type: null,
      variant: null,
      // font variant user selected
      subsets: null,
      // font variant user selected
      font_data: null // Original data
    });
    if (!value.font) {
      return '';
    }
    if (value.type == 'google') {
      this.fonts[value.font] = value.font;
      if (value.variant) {
        if (_.isUndefined(this.variants[value.font])) {
          this.variants[value.font] = {};
          if (_.isString(value.variant)) {
            var vr;
            vr = {};
            vr[value.variant] = value.variant;
            this.variants[value.font] = _.extend(this.variants[value.font], vr);
          } else {
            this.variants[value.font] = _.extend(this.variants[value.font], value.variant);
          }
        }
      }
      if (value.subsets) {
        this.subsets = _.extend(this.subsets, value.subsets);
      }
    }
    return "font-family: \"" + value.font + "\";";
  };
  CustomifyAutoCSS.prototype.font = function (field, values) {
    var code = '';
    var that = this;
    if (field.device_settings) {
      _.each(this.devices, function (device) {
        var value = null;
        if (_.isEmpty(values)) {
          value = that.get_setting(field.name, device);
        } else {
          if (!_.isUndefined(values[device])) {
            device = values[device];
          }
        }
        var _c = that.setup_font(value);
        if (_c) {
          that.css[device] = "\r\n" + field.selector + " {\r\n\t" + _c + "\r\n}\r\n";
          if ('desktop' === device) {
            code += "\r\n" + field.selector + " {\r\n\t" + _c + "\r\n}";
          } else {
            code += "\r\n." + device + " " + field.selector + " {\r\n\t" + _c + "\r\n}\r\n";
          }
        }
      });
    } else {
      if (_.isEmpty(values)) {
        values = that.get_setting(field.name);
      }
      code = that.setup_font(values);
      that.css['all'] += " " + field.selector + "  {\r\n\t" + code + "\r\n}\r\n";
      code += " " + field.selector + "  {\r\n\t" + code + "\r\n}\r\n";
    }
    return code;
  };
  CustomifyAutoCSS.prototype.css_ruler = function (field, value, no_selector) {
    return this.maybe_devices_setup(field, 'setup_css_ruler', value, no_selector);
  };
  CustomifyAutoCSS.prototype.shadow = function (field, value, no_selector) {
    return this.maybe_devices_setup(field, 'setup_shadow', value, no_selector);
  };
  CustomifyAutoCSS.prototype.slider = function (field, value, no_selector) {
    return this.maybe_devices_setup(field, 'setup_slider', value, no_selector);
  };
  CustomifyAutoCSS.prototype.color = function (field, value, no_selector) {
    return this.maybe_devices_setup(field, 'setup_color', value, no_selector);
  };
  CustomifyAutoCSS.prototype.checkbox = function (field, value, no_selector) {
    return this.maybe_devices_setup(field, 'setup_checkbox', value, no_selector);
  };
  CustomifyAutoCSS.prototype.image = function (field, value, no_selector) {
    return this.maybe_devices_setup(field, 'setup_image', value, no_selector);
  };
  CustomifyAutoCSS.prototype.text_align = function (field, value, no_selector) {
    return this.maybe_devices_setup(field, 'setup_text_align', value, no_selector);
  };
  CustomifyAutoCSS.prototype.setup_styling_fields = function (fields, list, selectors, type) {
    var that = this;
    var newfs;
    var i;
    var newList = [];
    if (!_.isObject(selectors)) {
      selectors = {};
    }
    if (_.isUndefined(type)) {
      type = 'normal';
    }
    if (fields === false) {
      newList = null;
    } else {
      if (!_.isObject(fields)) {
        fields = {};
      }
      newfs = {};
      i = 0;
      _.each(list, function (f) {
        if (!_.isUndefined(that.box_shadow_fields[f.name])) {
          if (_.isUndefined(fields[f.name]) || fields[f.name]) {
            newfs[f.name] = f;
            newfs[f.name]['selector'] = null;
          }
        } else {
          if (_.isUndefined(fields[f.name]) || fields[f.name]) {
            newfs[f.name] = f;
            if (!_.isUndefined(selectors[type + '_' + f.name])) {
              newfs[f.name]['selector'] = selectors[type + '_' + f.name];
            } else {
              newfs[f.name]['selector'] = selectors[type];
            }
            i++;
          }
        }
      });
      newList = newfs;
    }
    return newList;
  };
  CustomifyAutoCSS.prototype.styling = function (field) {
    var that = this;
    // Setup file by default no need `css_format` key if filed have name in the list above
    var values = this.get_setting(field.name, 'all');
    if (!_.isObject(values) && !_.isArray(values)) {
      values = {};
    }
    values = _.defaults(values, {
      'normal': {},
      'hover': {}
    });
    var selectors = {};
    if (_.isString(field.selector)) {
      selectors['normal'] = field.selector;
      selectors['hover'] = field.selector;
    } else {
      selectors = _.defaults(field.selector, {
        normal: null,
        hover: null
      });
    }
    var tabs = null,
      normal_fields = -1,
      hover_fields = -1;
    if (!_.isUndefined(field.fields) && _.isObject(field.fields)) {
      if (!_.isUndefined(field.fields.tabs)) {
        tabs = field.tabs;
      }
      if (!_.isUndefined(field.fields.normal_fields)) {
        normal_fields = field.normal_fields;
      }
      if (!_.isUndefined(field.fields.hover_fields)) {
        hover_fields = field.hover_fields;
      }
    }
    var listNormalFields = that.setup_styling_fields(normal_fields, Customify_Preview_Config.styling_config.normal_fields, selectors, 'normal');
    var listHoverFields = that.setup_styling_fields(hover_fields, Customify_Preview_Config.styling_config.hover_fields, selectors, 'hover');
    var listTabs = _.clone(Customify_Preview_Config.styling_config.tabs);
    if (tabs === false) {
      listTabs['hover'] = false;
    } else if (_.isObject(tabs)) {
      listTabs = tabs;
    }
    var _join = function (lists, codeList) {
      _.each(lists, function (f, name) {
        if (_.isUndefined(selectorCSSAll[f.selector])) {
          selectorCSSAll[f.selector] = '';
        }
        if (!_.isUndefined(codeList[name])) {
          if (!_.isUndefined(codeList[name].no_devices)) {
            if (codeList[name].no_devices) {
              selectorCSSAll[f.selector] += codeList[name].no_devices;
            }
          } else {
            _.each(codeList[name], function (code, device) {
              if (_.isUndefined(selectorCSSDevices[device])) {
                selectorCSSDevices[device] = {};
              }
              if (_.isUndefined(selectorCSSDevices[device][f.selector])) {
                selectorCSSDevices[device][f.selector] = '';
              }
              if (code) {
                selectorCSSDevices[device][f.selector] += code;
              }
            });
          }
        }
      });
    };
    var selectorCSSAll = {};
    var selectorCSSDevices = {};

    // Do no use bg settings if no bg
    if (!_.isEmpty(values)) {
      if (!_.isUndefined(values['normal']['bg_image'])) {
        var _img = that.sanitize_media(values['normal']['bg_image']);
        if (!_img.url) {
          delete values['normal']['bg_repeat'];
          delete values['normal']['bg_cover'];
          delete values['normal']['bg_position'];
          delete values['normal']['bg_attachment'];
        }
      }
    }
    var normal_style = that.loop_fields(listNormalFields, values['normal'], true, true);
    var hover_style = that.loop_fields(listHoverFields, values['hover'], true, true);
    _join(listNormalFields, normal_style);
    _join(listHoverFields, hover_style);
    _.each(selectorCSSAll, function (code, s) {
      that.css.all += "\r\n" + s + "  {\r\n\t" + code + "\r\n}\r\n";
    });
    _.each(that.devices, function (device) {
      var css = '';
      if (!_.isUndefined(selectorCSSDevices[device])) {
        var deviceCode = selectorCSSDevices[device];
        _.each(deviceCode, function (c, s) {
          if (_.isString(c)) {
            css += "\r\n" + s + "  {\r\n\t" + c + "\r\n}\r\n";
          } else {
            css += "\r\n" + s + "  {\r\n\t" + that.join(c, "\n") + "\r\n}\r\n";
          }
        });
      }
      that.css[device] += css;
    });
  };
  CustomifyAutoCSS.prototype.modal = function (field) {
    var that = this;
    var values = this.get_setting(field.name, 'all');
    if (!_.isObject(values)) {
      values = {};
    }
    if (_.isObject(field.fields.tabs)) {
      _.each(field.fields.tabs, function (title, key) {
        if (_.isObject(field.fields[key + '_fields'])) {
          that.loop_fields(field.fields[key + '_fields'], values[key]);
        }
      });
    }
  };

  /**
   * Emit per-column CSS for a `columns_settings` field. Mirror of
   * Customify_Customizer_Auto_CSS::columns_settings() in
   * inc/customizer/class-customizer-auto-css.php so the preview can
   * update live (postMessage) without the full refresh.
   *
   * Resolves per column:
   *   direction = forced_direction > saved.direction > default_direction > 'row'
   *   align     = forced_align > saved.align > default_align > position default
   * Position default for align: first → flex-start, last → flex-end,
   * single column → flex-start, otherwise → flex-center.
   */
  CustomifyAutoCSS.prototype.columns_settings = function (field) {
    var that = this;
    var values = this.get_setting(field.name, 'all');
    // Robust decode — framework's get_setting uses `decodeURI` which leaves
    // reserved chars (`:`, `,`, etc.) escaped, so JSON.parse fails when the
    // value was URI-component-encoded by our React control. Fall back to
    // decodeURIComponent so we always end up with a parsed object.
    if (typeof values === 'string' && values.length) {
      try {
        values = JSON.parse(decodeURIComponent(values));
      } catch (_) {
        try {
          values = JSON.parse(values);
        } catch (__) {}
      }
    }
    if (!_.isObject(values) || _.isArray(values)) {
      values = {};
    }
    var rowSelector = field.selector || '';
    if (!rowSelector) return;
    var colSelectors = _.isObject(field.col_selectors) && !_.isArray(field.col_selectors) ? field.col_selectors : {};
    var forcedDirection = _.isString(field.forced_direction) ? field.forced_direction : '';
    var forcedAlign = _.isString(field.forced_align) ? field.forced_align : '';
    var defaultDirection = _.isString(field.default_direction) ? field.default_direction : '';
    var defaultAlign = _.isString(field.default_align) ? field.default_align : '';
    var columnKeys = _.isArray(field.column_keys) ? field.column_keys : [];
    var devicesList = _.isArray(field.devices) && field.devices.length ? field.devices : ['desktop', 'mobile'];
    var deviceScope = _.isObject(field.device_scope) && !_.isArray(field.device_scope) ? field.device_scope : {};

    // Legacy fallback — see matching PHP comment in
    // Customify_Customizer_Auto_CSS::columns_settings().
    if (!_.isEmpty(values) && _.isUndefined(values.desktop) && _.isUndefined(values.mobile)) {
      var hasColKey = _.some(columnKeys, function (ck) {
        return !_.isUndefined(values[ck]);
      });
      if (hasColKey) {
        values = {
          desktop: values
        };
      }
    }
    var activeCount = columnKeys.length;
    if (field.col_layout_setting) {
      var clRaw = this.get_setting(field.col_layout_setting, 'all');
      var clData = null;
      if (_.isObject(clRaw) && !_.isArray(clRaw)) {
        clData = clRaw;
      } else if (_.isString(clRaw)) {
        try {
          clData = JSON.parse(decodeURIComponent(clRaw));
        } catch (e) {
          try {
            clData = JSON.parse(clRaw);
          } catch (e2) {}
        }
      }
      if (clData && clData.count) {
        var cnt = parseInt(clData.count, 10);
        if (!isNaN(cnt) && cnt >= 1) {
          activeCount = Math.min(columnKeys.length, cnt);
        }
      }
    }
    var activeColumns = columnKeys.slice(0, activeCount);

    // Build deviceMap from field's `devices` config. Devices with a
    // `device_scope` entry land in the unwrapped `all` bucket and
    // inject the scope class into the selector below — see matching
    // PHP comment.
    var deviceMap = {};
    _.each(devicesList, function (d) {
      deviceMap[d] = deviceScope[d] ? 'all' : d;
    });
    _.each(deviceMap, function (cssBucket, deviceKey) {
      var src = _.isObject(values) && _.isObject(values[deviceKey]) && !_.isArray(values[deviceKey]) ? values[deviceKey] : {};
      var deviceValues = _.clone(src);
      _.each(activeColumns, function (ck) {
        if (_.isUndefined(deviceValues[ck])) {
          deviceValues[ck] = {};
        }
      });
      if (_.isEmpty(deviceValues)) return;
      _.each(deviceValues, function (colValue, colKey) {
        if (!_.isObject(colValue) || _.isArray(colValue)) {
          colValue = {};
        }
        var selector;
        if (colSelectors[colKey]) {
          selector = colSelectors[colKey];
        } else {
          var scope = deviceScope[deviceKey] ? ' ' + String(deviceScope[deviceKey]).replace(/^\s+|\s+$/g, '') : '';
          selector = rowSelector.replace(/\s+$/, '') + scope + ' .col-v2-' + colKey;
        }
        var rules = [];

        // Resolve direction: forced > saved > field default > 'row'.
        var savedDirection = _.isString(colValue.direction) ? colValue.direction : '';
        var direction;
        if (forcedDirection !== '') {
          direction = forcedDirection;
        } else if (savedDirection !== '') {
          direction = savedDirection;
        } else if (defaultDirection !== '') {
          direction = defaultDirection;
        } else {
          direction = 'row';
        }
        if (direction !== 'row' && direction !== 'column') {
          direction = 'row';
        }

        // Position-based default align: first → flex-start, last → flex-end,
        // single column → flex-start, otherwise → flex-center.
        var colIndex = _.indexOf(activeColumns, colKey);
        var positionAlign = 'flex-center';
        if (colIndex < 0) {
          positionAlign = '';
        } else if (activeColumns.length === 1 || colIndex === 0) {
          positionAlign = 'flex-start';
        } else if (colIndex === activeColumns.length - 1) {
          positionAlign = 'flex-end';
        }

        // Resolve align: forced > saved > field default > position-based.
        var savedAlign = _.isString(colValue.align) ? colValue.align : '';
        var align;
        if (forcedAlign !== '') {
          align = forcedAlign;
        } else if (savedAlign !== '') {
          align = savedAlign;
        } else if (defaultAlign !== '') {
          align = defaultAlign;
        } else {
          align = positionAlign;
        }

        // Map align → justify-content keyword (shared between the
        // column-slot rule and the per-item rule emitted below).
        var justifyValue = '';
        switch (align) {
          case 'flex-start':
            justifyValue = 'flex-start';
            break;
          case 'flex-center':
            justifyValue = 'center';
            break;
          case 'flex-end':
            justifyValue = 'flex-end';
            break;
          case 'space-between':
            justifyValue = 'space-between';
            break;
        }

        // Emit flexbox rules on the column slot.
        //
        // Row direction: align → justify-content on the column so
        // items distribute horizontally inside the slot.
        //
        // Column direction: align does NOT go on the column. It's
        // applied below to each `.item--inner` so the chosen value
        // aligns the item's own internal content horizontally.
        rules.push('display: flex;');
        rules.push('flex-direction: ' + direction + ';');
        if (direction === 'row') {
          if (justifyValue !== '') {
            rules.push('justify-content: ' + justifyValue + ';');
          }
          rules.push('align-items: center;');
        }

        // Gap — { unit, value } or scalar.
        if (!_.isUndefined(colValue.gap)) {
          var gapVal = colValue.gap;
          var gapNum = null;
          var gapUnit = 'em';
          if (_.isObject(gapVal) && !_.isArray(gapVal)) {
            if (!_.isUndefined(gapVal.value) && gapVal.value !== '' && gapVal.value !== null) {
              gapNum = gapVal.value;
              gapUnit = gapVal.unit ? gapVal.unit : 'em';
            }
          } else if (gapVal !== '' && gapVal !== null) {
            gapNum = gapVal;
          }
          if (gapNum !== null) {
            rules.push('gap: ' + parseFloat(gapNum) + gapUnit + ';');
          }
        }

        // Padding — 4-side object with unit/link.
        if (_.isObject(colValue.padding) && !_.isArray(colValue.padding)) {
          var padding = colValue.padding;
          var pUnit = padding.unit ? padding.unit : 'px';
          _.each(['top', 'right', 'bottom', 'left'], function (side) {
            var v = padding[side];
            if (v === null || _.isUndefined(v) || v === '') return;
            rules.push('padding-' + side + ': ' + parseFloat(v) + pUnit + ';');
          });
        }
        if (!rules.length) return;
        that.css[cssBucket] += selector + " {\r\n\t" + rules.join("\r\n\t") + "\r\n}\r\n";

        // Column direction: each `.item--inner` becomes its own
        // flex container with the resolved `justify-content` so the
        // user's align choice controls horizontal placement of the
        // item's internal content.
        if (direction === 'column' && justifyValue !== '') {
          that.css[cssBucket] += selector + " .item--inner {\r\n\tdisplay: flex;\r\n\tjustify-content: " + justifyValue + ";\r\n}\r\n";
        }
      });
    });
  };
  CustomifyAutoCSS.prototype.setup_font_style = function (value) {
    if (!_.isObject(value)) {
      value = {};
    }
    value = _.defaults(value, {
      b: null,
      i: null,
      u: null,
      s: null,
      t: null
    });
    var css = {};
    if (value['b']) {
      css['b'] = 'font-weight: bold;';
    }
    if (value['i']) {
      css['i'] = 'font-style: italic;';
    }
    var decoration = {};
    if (value['u']) {
      decoration['underline'] = 'underline';
    }
    if (value['s']) {
      decoration['line-through'] = 'line-through';
    }
    if (!_.isEmpty(decoration)) {
      css['d'] = 'text-decoration: ' + this.join(decoration, ' ') + ';';
    }
    if (value['t']) {
      css['t'] = 'text-transform: uppercase;';
    }
    return this.join(css, "\r\n\t");
  };
  CustomifyAutoCSS.prototype.html_replace = function (field, value) {
    var selector = field.selector;
    var v = _.clone(value);
    if (_.isUndefined(v) || _.isEmpty(v)) {
      v = field.default;
    }
    $(selector).html(v);
  };
  CustomifyAutoCSS.prototype.html_class = function (field, v) {
    var value;
    if (_.isUndefined(v)) {
      value = _.clone(v);
    } else {
      value = this.get_setting(field.name, 'all');
    }
    var that = this;
    var selector = field.selector;
    var last_value = null;
    var is_checkbox = field.type === 'checkbox';
    if (!_.isUndefined(that.lastValues[field.name])) {
      last_value = that.lastValues[field.name];
    }
    if (_.isString(last_value)) {
      try {
        var decodeValue = that.decodeValue(last_value);
        if (!_.isNull(decodeValue)) {
          last_value = decodeValue;
        }
      } catch (e) {}
    }
    if (is_checkbox && (_.isUndefined(field.device_settings) || !field.device_settings)) {
      var _n = field.name.split('__');
      var cl;
      if (_n.length > 1) {
        cl = _n[1] + '-active';
      } else {
        cl = field.name + '-active';
      }
      if (value) {
        $(selector).addClass(cl);
      } else {
        $(selector).removeClass(cl);
      }
      return;
    }
    if (_.isString(last_value) && !_.isEmpty(last_value)) {
      $(selector).removeClass(last_value);
    } else {
      if (_.isObject(last_value)) {
        _.each(last_value, function (n, d) {
          if (n) {
            var cl = d + '--' + n;
            if (is_checkbox) {
              cl = field.name + '-' + cl;
            }
            $(selector).removeClass(cl);
          }
        });
      }
    }
    if (_.isString(value)) {
      $(selector).addClass(value);
    } else {
      if (_.isObject(value)) {
        _.each(value, function (n, d) {
          if (n) {
            var cl = d + '--' + n;
            if (is_checkbox) {
              cl = field.name + '-' + cl;
            }
            $(selector).addClass(cl);
          }
        });
      }
    }
  };
  CustomifyAutoCSS.prototype.typography = function (field, values) {
    if (_.isUndefined(values) || !_.isObject(values)) {
      values = this.get_setting(field.name, 'all');
    }
    var that = this;
    if (!_.isObject(values)) {
      values = {};
    }
    values = _.defaults(values, {
      font: null,
      font_type: null,
      languages: null,
      font_size: null,
      font_weight: null,
      line_height: null,
      letter_spacing: null,
      style: null,
      text_decoration: null,
      text_transform: null
    });
    var code = {};
    var fields = {};
    var devices_css = {};
    _.each(Customify_Preview_Config.typo_fields, function (f) {
      fields[f.name] = f;
    });

    // Honor per-field `fields` overrides — keep in lockstep with
    // PHP typography() so vars/legacy emit match.
    if (field && _.isObject(field.fields)) {
      _.each(field.fields, function (enabled, key) {
        if (enabled === false) {
          delete fields[key];
        }
      });
    }
    if (!_.isUndefined(fields.font)) {
      code.font = this.setup_font({
        font: values.font,
        type: values.font_type,
        subsets: values.languages,
        variant: values.variant
      });
    }

    // Font Style
    if (!_.isUndefined(fields.style)) {
      //code.font_style = this.setup_font_style( values.font_style );
      if (values.style && values.style !== 'default') {
        code.style = 'font-style: ' + values.style + ';';
      }
    }

    // Font Weight
    if (!_.isUndefined(fields.font_weight)) {
      if (values.font_weight && values.font_weight !== 'default' && values.font_weight !== 'default') {
        if (values.font_weight === 'regular') {
          values.font_weight = 'normal';
        }
        code.font_weight = 'font-weight: ' + values.font_weight + ';';
      }
    }

    // Text Decoration
    if (!_.isUndefined(fields.text_decoration)) {
      if (values.text_decoration && values.text_decoration !== 'default') {
        code.text_decoration = 'text-decoration: ' + values.text_decoration + ';';
      }
    }

    // Text Transform
    if (!_.isUndefined(fields.text_transform)) {
      if (values.text_transform && values.text_transform !== 'default') {
        code.text_transform = 'text-transform: ' + values.text_transform + ';';
      }
    }
    if (!_.isUndefined(fields.font_size)) {
      fields.font_size.css_format = 'font-size: {{value}};';
      var font_size_css = this.maybe_devices_setup(fields.font_size, 'setup_slider', values.font_size, true);
      if (!_.isEmpty(font_size_css)) {
        if (!_.isUndefined(font_size_css.no_devices)) {
          code.font_size = font_size_css.no_devices;
        } else {
          _.each(font_size_css, function (_c, device) {
            if (device == 'desktop') {
              code.font_size = _c;
            } else {
              if (_.isUndefined(devices_css[device])) {
                devices_css[device] = {};
              }
              devices_css[device]['font_size'] = _c;
            }
          });
        }
      }
    }
    if (!_.isUndefined(fields.line_height)) {
      fields.line_height['css_format'] = 'line-height: {{value}};';
      var line_height_css = this.maybe_devices_setup(fields.line_height, 'setup_slider', values['line_height'], true);
      if (!_.isEmpty(line_height_css)) {
        if (!_.isUndefined(line_height_css['no_devices'])) {
          code['line_height'] = line_height_css['no_devices'];
        } else {
          _.each(line_height_css, function (_c, device) {
            if (device == 'desktop') {
              code['line_height'] = _c;
            } else {
              if (_.isUndefined(devices_css[device])) {
                devices_css[device] = {};
              }
              devices_css[device]['line_height'] = _c;
            }
          });
        }
      }
    }
    if (!_.isUndefined(fields.letter_spacing)) {
      fields['letter_spacing']['css_format'] = 'letter-spacing: {{value}};';
      var letter_spacing_cs = this.maybe_devices_setup(fields['letter_spacing'], 'setup_slider', values['letter_spacing'], true);
      if (letter_spacing_cs) {
        if (!_.isUndefined(letter_spacing_cs['no_devices'])) {
          code['letter_spacing'] = letter_spacing_cs['no_devices'];
        } else {
          _.each(letter_spacing_cs, function (_c, device) {
            if (device == 'desktop') {
              code['letter_spacing'] = _c;
            } else {
              if (_.isUndefined(devices_css[device])) {
                devices_css[device] = {};
              }
              devices_css[device]['letter_spacing'] = _c;
            }
          });
        }
      }
    }

    // Only foundational typography (Base body, shared Heading,
    // h1–h6 scale) emits :root tokens. Component-leaf global
    // typography (site title, tagline, widget title) and
    // per-component typography fall through to selector-scoped
    // literal output here.
    if (!that.typography_field_uses_vars(field)) {
      _.each(devices_css, function (els, device) {
        that.css[device] += " " + field['selector'] + " {\r\n\t" + that.join(els, "\r\n\t") + "\r\n}";
      });
      that.css['all'] += " " + field['selector'] + " {\r\n\t" + that.join(code, "\r\n\t") + "\r\n}";
      return;
    }

    // Vars mode: split per-property. Core props (family/weight/
    // size/line-height) → :root vars. Cosmetic props (letter-spacing,
    // text-decoration, text-transform, font-style) → selector-scoped
    // literal CSS (no token). Keep in lockstep with PHP typography().
    // Only font_size / line_height are device-scoped (both core), so
    // every devices_css entry goes straight to :root vars.
    _.each(devices_css, function (els, device) {
      var vars = that.code_to_root_vars(field.name, els);
      if (vars.length) {
        if (that.css_root[device] !== '') {
          that.css_root[device] += "\r\n\t";
        }
        that.css_root[device] += vars.join("\r\n\t");
      }
    });
    var cosmeticKeys = ['style', 'text_decoration', 'text_transform', 'letter_spacing'];
    var cosmetic = {};
    var core = {};
    _.each(code, function (line, key) {
      if (!line) {
        return;
      } // mirror PHP array_filter($code) — drop empty lines
      if (_.contains(cosmeticKeys, key)) {
        cosmetic[key] = line;
      } else {
        core[key] = line;
      }
    });
    if (!_.isEmpty(cosmetic)) {
      that.css['all'] += " " + field['selector'] + " {\r\n\t" + that.join(cosmetic, "\r\n\t") + "\r\n}";
    }
    var allVars = that.code_to_root_vars(field.name, core);
    if (allVars.length) {
      if (that.css_root['all'] !== '') {
        that.css_root['all'] += "\r\n\t";
      }
      that.css_root['all'] += allVars.join("\r\n\t");
    }
  };
  var CustomifyAutoCSSInit = new CustomifyAutoCSS();
  api.bind('preview-ready', function () {
    //CustomifyAutoCSSInit.run();
    CustomifyAutoCSSInit.lastValues = api.get();
    CustomifyAutoCSSInit.values = api.get();
  });
  api.bind('change', function () {
    // CustomifyAutoCSSInit.run();
  });
  _.each(Customify_Preview_Config.fields, function (field) {
    if (field.selector && field.css_format || field.type === 'modal') {
      wp.customize(field.name, function (setting) {
        setting.bind(function (to) {
          CustomifyAutoCSSInit.run(field.name);
        });
      });
    }

    // row_layout settings (e.g. footer_main_col_layout) carry no
    // selector/css_format themselves, but the linked columns_settings
    // field reads `count` from them to decide how many columns to emit
    // CSS for. Without this bind, adding a column live in the preview
    // shows no rule for the new col-v2-{key} until the user saves +
    // reloads (PHP regen on page load).
    if (field.type === 'row_layout') {
      wp.customize(field.name, function (setting) {
        setting.bind(function () {
          CustomifyAutoCSSInit.run(field.name);
        });
      });
    }
  });
})(jQuery, wp.customize);
/******/ })()
;