8889841cPK,[I!dist/wp-color-picker-alpha.min.jsnu[/**! * wp-color-picker-alpha * * Overwrite Automattic Iris for enabled Alpha Channel in wpColorPicker * Only run in input and is defined data alpha in true * * Version: 3.0.0 * https://github.com/kallookoo/wp-color-picker-alpha * Licensed under the GPLv2 license or later. */ !function(e,a){var l,o={version:300};if("wpColorPickerAlpha"in window&&"version"in window.wpColorPickerAlpha){var t=parseInt(window.wpColorPickerAlpha.version,10);if(!isNaN(t)&&o.version<=t)return}Color.fn.hasOwnProperty("to_s")||(Color.fn.to_s=function(o){"hex"===(o=o||"hex")&&this._alpha<1&&(o="rgba");var a="";return"hex"===o?a=this.toString():this.error||(a=this.toCSS(o).replace(/\(\s+/,"(").replace(/\s+\)/,")")),a},window.wpColorPickerAlpha=o,l="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAIAAAHnlligAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAHJJREFUeNpi+P///4EDBxiAGMgCCCAGFB5AADGCRBgYDh48CCRZIJS9vT2QBAggFBkmBiSAogxFBiCAoHogAKIKAlBUYTELAiAmEtABEECk20G6BOmuIl0CIMBQ/IEMkO0myiSSraaaBhZcbkUOs0HuBwDplz5uFJ3Z4gAAAABJRU5ErkJggg==",e.widget("a8c.iris",e.a8c.iris,{alphaOptions:{alphaEnabled:!1},_getColor:function(o){return o===a&&(o=this._color),this.alphaOptions.alphaEnabled?(o=o.to_s(this.alphaOptions.alphaColorType),this.alphaOptions.alphaColorWithSpace||(o=o.replace(/\s+/g,"")),o):o.toString()},_create:function(){try{this.alphaOptions=this.element.wpColorPicker("instance").alphaOptions}catch(o){}e.extend({},this.alphaOptions,{alphaEnabled:!1,alphaCustomWidth:130,alphaReset:!1,alphaColorType:"hex",alphaColorWithSpace:!1}),this._super()},_addInputListeners:function(i){function o(o){var a=i.val(),t=new Color(a),a=a.replace(/^(#|(rgb|hsl)a?)/,""),r=l.alphaOptions.alphaColorType;i.removeClass("iris-error"),t.error?""!==a&&i.addClass("iris-error"):"hex"===r&&"keyup"===o.type&&a.match(/^[0-9a-fA-F]{3}$/)||t.toIEOctoHex()!==l._color.toIEOctoHex()&&l._setOption("color",l._getColor(t))}var l=this;i.on("change",o).on("keyup",l._debounce(o,100)),l.options.hide&&i.one("focus",function(){l.show()})},_initControls:function(){var t,o,a,r;this._super(),this.alphaOptions.alphaEnabled&&(a=(o=(t=this).controls.strip.clone(!1,!1)).find(".iris-slider-offset"),r={stripAlpha:o,stripAlphaSlider:a},o.addClass("iris-strip-alpha"),a.addClass("iris-slider-offset-alpha"),o.appendTo(t.picker.find(".iris-picker-inner")),e.each(r,function(o,a){t.controls[o]=a}),t.controls.stripAlphaSlider.slider({orientation:"vertical",min:0,max:100,step:1,value:parseInt(100*t._color._alpha),slide:function(o,a){t.active="strip",t._color._alpha=parseFloat(a.value/100),t._change.apply(t,arguments)}}))},_dimensions:function(o){if(this._super(o),this.alphaOptions.alphaEnabled){for(var a=this,t=a.options,r=a.controls.square,o=a.picker.find(".iris-strip"),i=Math.round(a.picker.outerWidth(!0)-(t.border?22:0)),l=Math.round(r.outerWidth()),e=Math.round((i-l)/2),s=Math.round(e/2),n=Math.round(l+2*e+2*s);i'):t.toggler.append(''),t.colorAlpha=t.toggler.find("span.color-alpha").css({width:"30px",height:"100%",position:"absolute",top:0,"background-color":r.val()}),"ltr"===t.colorAlpha.css("direction")?t.colorAlpha.css({"border-bottom-left-radius":"2px","border-top-left-radius":"2px",left:0}):t.colorAlpha.css({"border-bottom-right-radius":"2px","border-top-right-radius":"2px",right:0}),r.iris({change:function(o,a){t.colorAlpha.css({"background-color":a.color.to_s(t.alphaOptions.alphaColorType)}),e.isFunction(t.options.change)&&t.options.change.call(this,o,a)}}),t.wrap.on("click.wpcolorpicker",function(o){o.stopPropagation()}),t.toggler.click(function(){t.toggler.hasClass("wp-picker-open")?t.close():t.open()}),r.change(function(o){var a=e(this).val();(r.hasClass("iris-error")||""===a||a.match(/^(#|(rgb|hsl)a?)$/))&&(i&&t.toggler.removeAttr("style"),t.colorAlpha.css("background-color",""),e.isFunction(t.options.clear)&&t.options.clear.call(this,o))}),t.button.click(function(o){e(this).hasClass("wp-picker-default")?r.val(t.options.defaultColor).change():e(this).hasClass("wp-picker-clear")&&(r.val(""),i&&t.toggler.removeAttr("style"),t.colorAlpha.css("background-color",""),e.isFunction(t.options.clear)&&t.options.clear.call(this,o),r.trigger("change"))})}}))}(jQuery);PK,[ҷ,,dist/control.jsnu[!function(){var e=function(e,t,i,a){var r=this;this.rowIndex=e,this.container=t,this.label=i,this.header=this.container.find(".repeater-row-header"),this.header.on("click",(function(){r.toggleMinimize()})),this.container.on("click",".repeater-row-remove",(function(){r.remove()})),this.header.on("mousedown",(function(){r.container.trigger("row:start-dragging")})),this.container.on("keyup change","input, select, textarea",(function(e){r.container.trigger("row:update",[r.rowIndex,jQuery(e.target).data("field"),e.target])})),this.setRowIndex=function(e){this.rowIndex=e,this.container.attr("data-row",e),this.container.data("row",e),this.updateLabel()},this.toggleMinimize=function(){this.container.toggleClass("minimized"),this.header.find(".dashicons").toggleClass("dashicons-arrow-up").toggleClass("dashicons-arrow-down")},this.remove=function(){this.container.slideUp(300,(function(){jQuery(this).detach()})),this.container.trigger("row:remove",[this.rowIndex])},this.updateLabel=function(){var e,t,i;if("field"===this.label.type&&(e=this.container.find('.repeater-field [data-field="'+this.label.field+'"]'),_.isFunction(e.val)&&""!==(t=e.val())))return _.isUndefined(a.params.fields[this.label.field])||_.isUndefined(a.params.fields[this.label.field].type)||("select"===a.params.fields[this.label.field].type?_.isUndefined(a.params.fields[this.label.field].choices)||_.isUndefined(a.params.fields[this.label.field].choices[e.val()])||(t=a.params.fields[this.label.field].choices[e.val()]):"radio"!==a.params.fields[this.label.field].type&&"radio-image"!==a.params.fields[this.label.field].type||(i=a.selector+' [data-row="'+this.rowIndex+'"] .repeater-field [data-field="'+this.label.field+'"]:checked',t=jQuery(i).val())),void this.header.find(".repeater-row-label").text(t);this.header.find(".repeater-row-label").text(this.label.value+" "+(this.rowIndex+1))},this.updateLabel()};wp.customize.controlConstructor.repeater=wp.customize.Control.extend({ready:function(){!_.isUndefined(window.kirkiControlLoader)&&_.isFunction(kirkiControlLoader)?kirkiControlLoader(this):this.initKirkiControl()},initKirkiControl:function(e){var t,i,a;a=(e=e||this).params.value,e.settingField=e.container.find("[data-customize-setting-link]").first(),e.setValue([],!1),e.repeaterFieldsContainer=e.container.find(".repeater-fields").first(),e.currentIndex=0,e.rows=[],t=!1,_.isUndefined(e.params.choices.limit)||(t=!(0>=e.params.choices.limit)&&parseInt(e.params.choices.limit,10)),e.container.on("click","button.repeater-add",(function(a){a.preventDefault(),!t||e.currentIndex/g,interpolate:/\{\{\{([\s\S]+?)\}\}\}/g,escape:/\{\{([^\}]+?)\}\}(?!\})/g,variable:"data"};return function(i){return _.template(e.container.find(".customize-control-repeater-content").first().html(),null,t)(i)}})),a.length&&_.each(a,(function(t){i=e.addRow(t),e.initColorPicker(),e.initSelect(i,t)})),e.repeaterFieldsContainer.sortable({handle:".repeater-row-header",update:function(){e.sort()}})},openFrame:function(e){wp.customize.utils.isKeydownButNotEnterEvent(e)||(this.$thisButton.closest(".repeater-field").hasClass("repeater-field-cropped_image")?this.initCropperFrame():this.initFrame(),this.frame.open())},initFrame:function(){var e=this.getMimeType();this.frame=wp.media({states:[new wp.media.controller.Library({library:wp.media.query({type:e}),multiple:!1,date:!1})]}),this.frame.on("select",this.onSelect,this)},initCropperFrame:function(){var e=this.$thisButton.siblings("input.hidden-field").attr("data-field"),t=this.getMimeType();_.isString(e)&&""!==e&&_.isObject(this.params.fields[e])&&"cropped_image"===this.params.fields[e].type&&["width","height","flex_width","flex_height"].forEach(function(t){_.isUndefined(this.params.fields[e][t])||(this.params[t]=this.params.fields[e][t])}.bind(this)),this.frame=wp.media({button:{text:"Select and Crop",close:!1},states:[new wp.media.controller.Library({library:wp.media.query({type:t}),multiple:!1,date:!1,suggestedWidth:this.params.width,suggestedHeight:this.params.height}),new wp.media.controller.CustomizeImageCropper({imgSelectOptions:this.calculateImageSelectOptions,control:this})]}),this.frame.on("select",this.onSelectForCrop,this),this.frame.on("cropped",this.onCropped,this),this.frame.on("skippedcrop",this.onSkippedCrop,this)},onSelect:function(){var e=this.frame.state().get("selection").first().toJSON();this.$thisButton.closest(".repeater-field").hasClass("repeater-field-upload")?this.setFileInRepeaterField(e):this.setImageInRepeaterField(e)},onSelectForCrop:function(){var e=this.frame.state().get("selection").first().toJSON();this.params.width!==e.width||this.params.height!==e.height||this.params.flex_width||this.params.flex_height?this.frame.setState("cropper"):this.setImageInRepeaterField(e)},onCropped:function(e){this.setImageInRepeaterField(e)},calculateImageSelectOptions:function(e,t){var i,a,r,n=t.get("control"),s=!!parseInt(n.params.flex_width,10),o=!!parseInt(n.params.flex_height,10),l=e.get("width"),d=e.get("height"),h=parseInt(n.params.width,10),p=parseInt(n.params.height,10),c=h/p,u=l,f=d;return t.set("canSkipCrop",!n.mustBeCropped(s,o,h,p,l,d)),u/f>c?h=(p=f)*c:p=(h=u)/c,r={handles:!0,keys:!0,instance:!0,persistent:!0,imageWidth:l,imageHeight:d,x1:i=(u-h)/2,y1:a=(f-p)/2,x2:h+i,y2:p+a},!1===o&&!1===s&&(r.aspectRatio=h+":"+p),!1===o&&(r.maxHeight=p),!1===s&&(r.maxWidth=h),r},mustBeCropped:function(e,t,i,a,r,n){return!(!0===e&&!0===t||!0===e&&a===n||!0===t&&i===r||i===r&&a===n||r<=i)},onSkippedCrop:function(){var e=this.frame.state().get("selection").first().toJSON();this.setImageInRepeaterField(e)},setImageInRepeaterField:function(e){var t=this.$thisButton.closest(".repeater-field-image,.repeater-field-cropped_image");t.find(".kirki-image-attachment").html('').hide().slideDown("slow"),t.find(".hidden-field").val(e.id),this.$thisButton.text(this.$thisButton.data("alt-label")),t.find(".remove-button").show(),t.find("input, textarea, select").trigger("change"),this.frame.close()},setFileInRepeaterField:function(e){var t=this.$thisButton.closest(".repeater-field-upload");t.find(".kirki-file-attachment").html(' '+e.filename+"").hide().slideDown("slow"),t.find(".hidden-field").val(e.id),this.$thisButton.text(this.$thisButton.data("alt-label")),t.find(".upload-button").show(),t.find(".remove-button").show(),t.find("input, textarea, select").trigger("change"),this.frame.close()},getMimeType:function(){var e=this.$thisButton.siblings("input.hidden-field").attr("data-field");return _.isString(e)&&""!==e&&_.isObject(this.params.fields[e])&&"upload"===this.params.fields[e].type&&!_.isUndefined(this.params.fields[e].mime_type)?this.params.fields[e].mime_type:"image"},removeImage:function(e){var t,i;wp.customize.utils.isKeydownButNotEnterEvent(e)||(i=(t=this.$thisButton.closest(".repeater-field-image,.repeater-field-cropped_image,.repeater-field-upload")).find(".upload-button"),t.find(".kirki-image-attachment").slideUp("fast",(function(){jQuery(this).show().html(jQuery(this).data("placeholder"))})),t.find(".hidden-field").val(""),i.text(i.data("label")),this.$thisButton.hide(),t.find("input, textarea, select").trigger("change"))},removeFile:function(e){var t,i;wp.customize.utils.isKeydownButNotEnterEvent(e)||(i=(t=this.$thisButton.closest(".repeater-field-upload")).find(".upload-button"),t.find(".kirki-file-attachment").slideUp("fast",(function(){jQuery(this).show().html(jQuery(this).data("placeholder"))})),t.find(".hidden-field").val(""),i.text(i.data("label")),this.$thisButton.hide(),t.find("input, textarea, select").trigger("change"))},getValue:function(){return JSON.parse(decodeURI(this.setting.get()))},setValue:function(e,t,i){var a=e,r=[];i&&(jQuery.each(this.params.fields,(function(e,t){"image"!==t.type&&"cropped_image"!==t.type&&"upload"!==t.type||r.push(e)})),jQuery.each(e,(function(e,t){jQuery.each(r,(function(i,r){_.isUndefined(t[r])||_.isUndefined(t[r].id)||(a[e][r]=t[r].id)}))}))),this.setting.set(encodeURI(JSON.stringify(a))),t&&this.settingField.trigger("change")},addRow:function(t){var i,a,r,n=this,s=n.repeaterTemplate(),o=this.getValue(),l={};if(s){if(i=jQuery.extend(!0,{},n.params.fields),t)for(r in t)t.hasOwnProperty(r)&&i.hasOwnProperty(r)&&(i[r].default=t[r]);for(r in i.index=this.currentIndex,s=s(i),(a=new e(n.currentIndex,jQuery(s).appendTo(n.repeaterFieldsContainer),n.params.row_label,n)).container.on("row:remove",(function(e,t){n.deleteRow(t)})),a.container.on("row:update",(function(e,t,i,r){n.updateField.call(n,e,t,i,r),a.updateLabel()})),this.rows[this.currentIndex]=a,i)i.hasOwnProperty(r)&&(l[r]=i[r].default);return o[this.currentIndex]=l,this.setValue(o,!0),this.currentIndex++,a}},sort:function(){var e=this,t=this.repeaterFieldsContainer.find(".repeater-row"),i=[],a=e.getValue(),r=[],n=[];t.each((function(e,t){i.push(jQuery(t).data("row"))})),jQuery.each(i,(function(t,i){r[t]=e.rows[i],r[t].setRowIndex(t),n[t]=a[i]})),e.rows=r,e.setValue(n)},deleteRow:function(e){var t,i=this.getValue();for(t in i[e]&&this.rows[e]&&(delete i[e],delete this.rows[e],this.setValue(i,!0)),this.rows)this.rows.hasOwnProperty(t)&&this.rows[t]&&this.rows[t].updateLabel()},updateField:function(e,t,i,a){var r,n,s;this.rows[t]&&this.params.fields[i]&&(r=this.params.fields[i].type,n=this.rows[t],s=this.getValue(),a=jQuery(a),_.isUndefined(s[n.rowIndex][i])||(s[n.rowIndex][i]="checkbox"===r?a.is(":checked"):a.val(),this.setValue(s,!0)))},initColorPicker:function(){var e=this,t=e.container.find(".kirki-classic-color-picker"),i=t.data("field"),a={};_.isUndefined(i)||_.isUndefined(e.params.fields[i])||_.isUndefined(e.params.fields[i].palettes)||!_.isObject(e.params.fields[i].palettes)||(a.palettes=e.params.fields[i].palettes),a.change=function(t,i){var a=jQuery(t.target),r=a.closest(".repeater-row").data("row"),n=e.getValue(),s=i.color._alpha<1?i.color.to_s():i.color.toString();n[r][a.data("field")]=s,e.setValue(n,!0),setTimeout((function(){t.target.value=s}),50)},t.length&&0!==t.length&&t.wpColorPicker(a)},initSelect:function(e,t){var i,a=this,r=e.container.find(".repeater-field select");0!==r.length&&(i=r.data("field"),multiple=jQuery(r).data("multiple"),(t=t||{})[i]=t[i]||"",jQuery(r).val(t[i]||jQuery(r).val()),this.container.on("change",".repeater-field select",(function(e){var t=jQuery(e.target),i=t.closest(".repeater-row").data("row"),r=a.getValue();r[i][t.data("field")]=jQuery(this).val(),a.setValue(r)})))}})}(); //# sourceMappingURL=control.js.map PK,[!jIX X dist/control.cssnu[.customize-control-repeater{position:relative}.customize-control-repeater .repeater-fields .repeater-row{background:#eee;border:1px solid #e5e5e5;margin-top:.5rem;position:relative}.customize-control-repeater .repeater-fields .repeater-row.minimized{border:1px solid #dfdfdf;padding:0}.customize-control-repeater .repeater-fields .repeater-row.minimized:hover{border:1px solid #e5e5e5}.customize-control-repeater .repeater-fields .repeater-row.minimized .repeater-row-content{display:none}.customize-control-repeater .repeater-fields .repeater-row label{clear:both;margin-bottom:12px}.customize-control-repeater .repeater-fields .repeater-row .repeater-field.repeater-field-,.customize-control-repeater .repeater-fields .repeater-row .repeater-field.repeater-field-radio-image input{display:none}.customize-control-repeater .repeater-fields .repeater-row .repeater-field.repeater-field-radio-image input img{border:1px solid transparent}.customize-control-repeater .repeater-fields .repeater-row .repeater-field.repeater-field-radio-image input:checked+label img{border:1px solid #3498db;-webkit-box-shadow:0 0 5px 2px rgba(0,0,0,.25);box-shadow:0 0 5px 2px rgba(0,0,0,.25)}.customize-control-repeater .repeater-fields .repeater-row .repeater-field:last-child{border-bottom:none;padding-bottom:0}.customize-control-repeater button.repeater-add{margin-top:1rem}.customize-control-repeater .repeater-row-content{background:#fff;padding:10px 15px}.customize-control-repeater .repeater-field{border-bottom:1px dotted #ccc;clear:both;margin-bottom:12px;padding-bottom:12px;width:100%}.customize-control-repeater .repeater-field .customize-control-description,.customize-control-repeater .repeater-field .customize-control-title{font-size:13px;line-height:normal}.customize-control-repeater .repeater-field.repeater-field-hidden{border:0;margin:0;padding:0}.customize-control-repeater .repeater-field-select select{margin-left:0}.customize-control-repeater .repeater-field-checkbox label{line-height:28px}.customize-control-repeater .repeater-field-checkbox input{line-height:28px;margin-right:5px}.customize-control-repeater .repeater-field-textarea textarea{resize:vertical;width:100%}.customize-control-repeater .repeater-row-header{word-wrap:break-word;background:#fff;border-bottom:1px solid #dfdfdf;height:auto;line-height:30px;min-height:20px;overflow:hidden;padding:10px 15px;position:relative}.customize-control-repeater .repeater-row-header:hover{cursor:move}.customize-control-repeater .repeater-row-header .dashicons{color:#a0a5aa;font-size:18px;position:absolute;right:12px;top:2px}.customize-control-repeater .repeater-row-label{display:block;font-size:13px;font-weight:600;height:18px;line-height:20px;overflow:hidden;width:90%}.customize-control-repeater .repeater-row-remove{color:#a00}.customize-control-repeater .repeater-row-remove:hover{color:red}.customize-control-repeater .repeater-minimize{line-height:36px}.customize-control-repeater .remove-button,.customize-control-repeater .upload-button{width:48%}.kirki-image-attachment{margin:0 0 10px;text-align:center}.kirki-image-attachment img{display:inline-block}.kirki-file-attachment{margin:0 0 10px;text-align:center}.kirki-file-attachment .file{background:#f9f9f9;border:1px dotted #c3c3c3;display:block;padding:10px 5px}.limit{border-radius:3px;padding:3px}.limit.highlight{background:#d32f2f;color:#fff} /*# sourceMappingURL=control.css.map */ PK,[pDdist/control.js.mapnu[{"mappings":"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","sources":["packages/kirki-framework/control-repeater/src/control.js"],"sourcesContent":["import \"./control.scss\";\n\n/* global kirkiControlLoader */\n/* eslint max-depth: 0 */\n/* eslint no-useless-escape: 0 */\nvar RepeaterRow = function (rowIndex, container, label, control) {\n var self = this;\n this.rowIndex = rowIndex;\n this.container = container;\n this.label = label;\n this.header = this.container.find(\".repeater-row-header\");\n\n this.header.on(\"click\", function () {\n self.toggleMinimize();\n });\n\n this.container.on(\"click\", \".repeater-row-remove\", function () {\n self.remove();\n });\n\n this.header.on(\"mousedown\", function () {\n self.container.trigger(\"row:start-dragging\");\n });\n\n this.container.on(\"keyup change\", \"input, select, textarea\", function (e) {\n self.container.trigger(\"row:update\", [\n self.rowIndex,\n jQuery(e.target).data(\"field\"),\n e.target,\n ]);\n });\n\n this.setRowIndex = function (rowNum) {\n this.rowIndex = rowNum;\n this.container.attr(\"data-row\", rowNum);\n this.container.data(\"row\", rowNum);\n this.updateLabel();\n };\n\n this.toggleMinimize = function () {\n // Store the previous state.\n this.container.toggleClass(\"minimized\");\n this.header\n .find(\".dashicons\")\n .toggleClass(\"dashicons-arrow-up\")\n .toggleClass(\"dashicons-arrow-down\");\n };\n\n this.remove = function () {\n this.container.slideUp(300, function () {\n jQuery(this).detach();\n });\n this.container.trigger(\"row:remove\", [this.rowIndex]);\n };\n\n this.updateLabel = function () {\n var rowLabelField, rowLabel, rowLabelSelector;\n\n if (\"field\" === this.label.type) {\n rowLabelField = this.container.find(\n '.repeater-field [data-field=\"' + this.label.field + '\"]'\n );\n if (_.isFunction(rowLabelField.val)) {\n rowLabel = rowLabelField.val();\n if (\"\" !== rowLabel) {\n if (!_.isUndefined(control.params.fields[this.label.field])) {\n if (!_.isUndefined(control.params.fields[this.label.field].type)) {\n if (\"select\" === control.params.fields[this.label.field].type) {\n if (\n !_.isUndefined(\n control.params.fields[this.label.field].choices\n ) &&\n !_.isUndefined(\n control.params.fields[this.label.field].choices[\n rowLabelField.val()\n ]\n )\n ) {\n rowLabel =\n control.params.fields[this.label.field].choices[\n rowLabelField.val()\n ];\n }\n } else if (\n \"radio\" === control.params.fields[this.label.field].type ||\n \"radio-image\" === control.params.fields[this.label.field].type\n ) {\n rowLabelSelector =\n control.selector +\n ' [data-row=\"' +\n this.rowIndex +\n '\"] .repeater-field [data-field=\"' +\n this.label.field +\n '\"]:checked';\n rowLabel = jQuery(rowLabelSelector).val();\n }\n }\n }\n this.header.find(\".repeater-row-label\").text(rowLabel);\n return;\n }\n }\n }\n this.header\n .find(\".repeater-row-label\")\n .text(this.label.value + \" \" + (this.rowIndex + 1));\n };\n this.updateLabel();\n};\n\nwp.customize.controlConstructor.repeater = wp.customize.Control.extend({\n // When we're finished loading continue processing\n ready: function () {\n var control = this;\n\n // Init the control.\n if (\n !_.isUndefined(window.kirkiControlLoader) &&\n _.isFunction(kirkiControlLoader)\n ) {\n kirkiControlLoader(control);\n } else {\n control.initKirkiControl();\n }\n },\n\n initKirkiControl: function (control) {\n var limit, theNewRow, settingValue;\n control = control || this;\n\n // The current value set in Control Class (set in Kirki_Customize_Repeater_Control::to_json() function)\n settingValue = control.params.value;\n\n // The hidden field that keeps the data saved (though we never update it)\n control.settingField = control.container\n .find(\"[data-customize-setting-link]\")\n .first();\n\n // Set the field value for the first time, we'll fill it up later\n control.setValue([], false);\n\n // The DIV that holds all the rows\n control.repeaterFieldsContainer = control.container\n .find(\".repeater-fields\")\n .first();\n\n // Set number of rows to 0\n control.currentIndex = 0;\n\n // Save the rows objects\n control.rows = [];\n\n // Default limit choice\n limit = false;\n if (!_.isUndefined(control.params.choices.limit)) {\n limit =\n 0 >= control.params.choices.limit\n ? false\n : parseInt(control.params.choices.limit, 10);\n }\n\n control.container.on(\"click\", \"button.repeater-add\", function (e) {\n e.preventDefault();\n if (!limit || control.currentIndex < limit) {\n theNewRow = control.addRow();\n theNewRow.toggleMinimize();\n control.initColorPicker();\n control.initSelect(theNewRow);\n } else {\n jQuery(control.selector + \" .limit\").addClass(\"highlight\");\n }\n });\n\n control.container.on(\"click\", \".repeater-row-remove\", function () {\n control.currentIndex--;\n if (!limit || control.currentIndex < limit) {\n jQuery(control.selector + \" .limit\").removeClass(\"highlight\");\n }\n });\n\n control.container.on(\n \"click keypress\",\n \".repeater-field-image .upload-button,.repeater-field-cropped_image .upload-button,.repeater-field-upload .upload-button\",\n function (e) {\n e.preventDefault();\n control.$thisButton = jQuery(this);\n control.openFrame(e);\n }\n );\n\n control.container.on(\n \"click keypress\",\n \".repeater-field-image .remove-button,.repeater-field-cropped_image .remove-button\",\n function (e) {\n e.preventDefault();\n control.$thisButton = jQuery(this);\n control.removeImage(e);\n }\n );\n\n control.container.on(\n \"click keypress\",\n \".repeater-field-upload .remove-button\",\n function (e) {\n e.preventDefault();\n control.$thisButton = jQuery(this);\n control.removeFile(e);\n }\n );\n\n /**\n * Function that loads the Mustache template\n */\n control.repeaterTemplate = _.memoize(function () {\n var compiled,\n /*\n * Underscore's default ERB-style templates are incompatible with PHP\n * when asp_tags is enabled, so WordPress uses Mustache-inspired templating syntax.\n *\n * @see trac ticket #22344.\n */\n options = {\n evaluate: /<#([\\s\\S]+?)#>/g,\n interpolate: /\\{\\{\\{([\\s\\S]+?)\\}\\}\\}/g,\n escape: /\\{\\{([^\\}]+?)\\}\\}(?!\\})/g,\n variable: \"data\",\n };\n\n return function (data) {\n compiled = _.template(\n control.container\n .find(\".customize-control-repeater-content\")\n .first()\n .html(),\n null,\n options\n );\n return compiled(data);\n };\n });\n\n // When we load the control, the fields have not been filled up\n // This is the first time that we create all the rows\n if (settingValue.length) {\n _.each(settingValue, function (subValue) {\n theNewRow = control.addRow(subValue);\n control.initColorPicker();\n control.initSelect(theNewRow, subValue);\n });\n }\n\n control.repeaterFieldsContainer.sortable({\n handle: \".repeater-row-header\",\n update: function () {\n control.sort();\n },\n });\n },\n\n /**\n * Open the media modal.\n *\n * @param {Object} event - The JS event.\n * @returns {void}\n */\n openFrame: function (event) {\n if (wp.customize.utils.isKeydownButNotEnterEvent(event)) {\n return;\n }\n\n if (\n this.$thisButton\n .closest(\".repeater-field\")\n .hasClass(\"repeater-field-cropped_image\")\n ) {\n this.initCropperFrame();\n } else {\n this.initFrame();\n }\n\n this.frame.open();\n },\n\n initFrame: function () {\n var libMediaType = this.getMimeType();\n\n this.frame = wp.media({\n states: [\n new wp.media.controller.Library({\n library: wp.media.query({ type: libMediaType }),\n multiple: false,\n date: false,\n }),\n ],\n });\n\n // When a file is selected, run a callback.\n this.frame.on(\"select\", this.onSelect, this);\n },\n\n /**\n * Create a media modal select frame, and store it so the instance can be reused when needed.\n * This is mostly a copy/paste of Core api.CroppedImageControl in /wp-admin/js/customize-control.js\n *\n * @returns {void}\n */\n initCropperFrame: function () {\n // We get the field id from which this was called\n var currentFieldId = this.$thisButton\n .siblings(\"input.hidden-field\")\n .attr(\"data-field\"),\n attrs = [\"width\", \"height\", \"flex_width\", \"flex_height\"], // A list of attributes to look for\n libMediaType = this.getMimeType();\n\n // Make sure we got it\n if (_.isString(currentFieldId) && \"\" !== currentFieldId) {\n // Make fields is defined and only do the hack for cropped_image\n if (\n _.isObject(this.params.fields[currentFieldId]) &&\n \"cropped_image\" === this.params.fields[currentFieldId].type\n ) {\n //Iterate over the list of attributes\n attrs.forEach(\n function (el) {\n // If the attribute exists in the field\n if (!_.isUndefined(this.params.fields[currentFieldId][el])) {\n // Set the attribute in the main object\n this.params[el] = this.params.fields[currentFieldId][el];\n }\n }.bind(this)\n );\n }\n }\n\n this.frame = wp.media({\n button: {\n text: \"Select and Crop\",\n close: false,\n },\n states: [\n new wp.media.controller.Library({\n library: wp.media.query({ type: libMediaType }),\n multiple: false,\n date: false,\n suggestedWidth: this.params.width,\n suggestedHeight: this.params.height,\n }),\n new wp.media.controller.CustomizeImageCropper({\n imgSelectOptions: this.calculateImageSelectOptions,\n control: this,\n }),\n ],\n });\n\n this.frame.on(\"select\", this.onSelectForCrop, this);\n this.frame.on(\"cropped\", this.onCropped, this);\n this.frame.on(\"skippedcrop\", this.onSkippedCrop, this);\n },\n\n onSelect: function () {\n var attachment = this.frame.state().get(\"selection\").first().toJSON();\n\n if (\n this.$thisButton\n .closest(\".repeater-field\")\n .hasClass(\"repeater-field-upload\")\n ) {\n this.setFileInRepeaterField(attachment);\n } else {\n this.setImageInRepeaterField(attachment);\n }\n },\n\n /**\n * After an image is selected in the media modal, switch to the cropper\n * state if the image isn't the right size.\n */\n\n onSelectForCrop: function () {\n var attachment = this.frame.state().get(\"selection\").first().toJSON();\n\n if (\n this.params.width === attachment.width &&\n this.params.height === attachment.height &&\n !this.params.flex_width &&\n !this.params.flex_height\n ) {\n this.setImageInRepeaterField(attachment);\n } else {\n this.frame.setState(\"cropper\");\n }\n },\n\n /**\n * After the image has been cropped, apply the cropped image data to the setting.\n *\n * @param {object} croppedImage Cropped attachment data.\n * @returns {void}\n */\n onCropped: function (croppedImage) {\n this.setImageInRepeaterField(croppedImage);\n },\n\n /**\n * Returns a set of options, computed from the attached image data and\n * control-specific data, to be fed to the imgAreaSelect plugin in\n * wp.media.view.Cropper.\n *\n * @param {wp.media.model.Attachment} attachment - The attachment from the WP API.\n * @param {wp.media.controller.Cropper} controller - Media controller.\n * @returns {Object} - Options.\n */\n calculateImageSelectOptions: function (attachment, controller) {\n var control = controller.get(\"control\"),\n flexWidth = !!parseInt(control.params.flex_width, 10),\n flexHeight = !!parseInt(control.params.flex_height, 10),\n realWidth = attachment.get(\"width\"),\n realHeight = attachment.get(\"height\"),\n xInit = parseInt(control.params.width, 10),\n yInit = parseInt(control.params.height, 10),\n ratio = xInit / yInit,\n xImg = realWidth,\n yImg = realHeight,\n x1,\n y1,\n imgSelectOptions;\n\n controller.set(\n \"canSkipCrop\",\n !control.mustBeCropped(\n flexWidth,\n flexHeight,\n xInit,\n yInit,\n realWidth,\n realHeight\n )\n );\n\n if (xImg / yImg > ratio) {\n yInit = yImg;\n xInit = yInit * ratio;\n } else {\n xInit = xImg;\n yInit = xInit / ratio;\n }\n\n x1 = (xImg - xInit) / 2;\n y1 = (yImg - yInit) / 2;\n\n imgSelectOptions = {\n handles: true,\n keys: true,\n instance: true,\n persistent: true,\n imageWidth: realWidth,\n imageHeight: realHeight,\n x1: x1,\n y1: y1,\n x2: xInit + x1,\n y2: yInit + y1,\n };\n\n if (false === flexHeight && false === flexWidth) {\n imgSelectOptions.aspectRatio = xInit + \":\" + yInit;\n }\n if (false === flexHeight) {\n imgSelectOptions.maxHeight = yInit;\n }\n if (false === flexWidth) {\n imgSelectOptions.maxWidth = xInit;\n }\n\n return imgSelectOptions;\n },\n\n /**\n * Return whether the image must be cropped, based on required dimensions.\n *\n * @param {bool} flexW - The flex-width.\n * @param {bool} flexH - The flex-height.\n * @param {int} dstW - Initial point distance in the X axis.\n * @param {int} dstH - Initial point distance in the Y axis.\n * @param {int} imgW - Width.\n * @param {int} imgH - Height.\n * @returns {bool} - Whether the image must be cropped or not based on required dimensions.\n */\n mustBeCropped: function (flexW, flexH, dstW, dstH, imgW, imgH) {\n return !(\n (true === flexW && true === flexH) ||\n (true === flexW && dstH === imgH) ||\n (true === flexH && dstW === imgW) ||\n (dstW === imgW && dstH === imgH) ||\n imgW <= dstW\n );\n },\n\n /**\n * If cropping was skipped, apply the image data directly to the setting.\n *\n * @returns {void}\n */\n onSkippedCrop: function () {\n var attachment = this.frame.state().get(\"selection\").first().toJSON();\n this.setImageInRepeaterField(attachment);\n },\n\n /**\n * Updates the setting and re-renders the control UI.\n *\n * @param {object} attachment - The attachment object.\n * @returns {void}\n */\n setImageInRepeaterField: function (attachment) {\n var $targetDiv = this.$thisButton.closest(\n \".repeater-field-image,.repeater-field-cropped_image\"\n );\n\n $targetDiv\n .find(\".kirki-image-attachment\")\n .html('')\n .hide()\n .slideDown(\"slow\");\n\n $targetDiv.find(\".hidden-field\").val(attachment.id);\n this.$thisButton.text(this.$thisButton.data(\"alt-label\"));\n $targetDiv.find(\".remove-button\").show();\n\n //This will activate the save button\n $targetDiv.find(\"input, textarea, select\").trigger(\"change\");\n this.frame.close();\n },\n\n /**\n * Updates the setting and re-renders the control UI.\n *\n * @param {object} attachment - The attachment object.\n * @returns {void}\n */\n setFileInRepeaterField: function (attachment) {\n var $targetDiv = this.$thisButton.closest(\".repeater-field-upload\");\n\n $targetDiv\n .find(\".kirki-file-attachment\")\n .html(\n ' ' +\n attachment.filename +\n \"\"\n )\n .hide()\n .slideDown(\"slow\");\n\n $targetDiv.find(\".hidden-field\").val(attachment.id);\n this.$thisButton.text(this.$thisButton.data(\"alt-label\"));\n $targetDiv.find(\".upload-button\").show();\n $targetDiv.find(\".remove-button\").show();\n\n //This will activate the save button\n $targetDiv.find(\"input, textarea, select\").trigger(\"change\");\n this.frame.close();\n },\n\n getMimeType: function () {\n // We get the field id from which this was called\n var currentFieldId = this.$thisButton\n .siblings(\"input.hidden-field\")\n .attr(\"data-field\");\n\n // Make sure we got it\n if (_.isString(currentFieldId) && \"\" !== currentFieldId) {\n // Make fields is defined and only do the hack for cropped_image\n if (\n _.isObject(this.params.fields[currentFieldId]) &&\n \"upload\" === this.params.fields[currentFieldId].type\n ) {\n // If the attribute exists in the field\n if (!_.isUndefined(this.params.fields[currentFieldId].mime_type)) {\n // Set the attribute in the main object\n return this.params.fields[currentFieldId].mime_type;\n }\n }\n }\n return \"image\";\n },\n\n removeImage: function (event) {\n var $targetDiv, $uploadButton;\n\n if (wp.customize.utils.isKeydownButNotEnterEvent(event)) {\n return;\n }\n\n $targetDiv = this.$thisButton.closest(\n \".repeater-field-image,.repeater-field-cropped_image,.repeater-field-upload\"\n );\n $uploadButton = $targetDiv.find(\".upload-button\");\n\n $targetDiv.find(\".kirki-image-attachment\").slideUp(\"fast\", function () {\n jQuery(this).show().html(jQuery(this).data(\"placeholder\"));\n });\n $targetDiv.find(\".hidden-field\").val(\"\");\n $uploadButton.text($uploadButton.data(\"label\"));\n this.$thisButton.hide();\n\n $targetDiv.find(\"input, textarea, select\").trigger(\"change\");\n },\n\n removeFile: function (event) {\n var $targetDiv, $uploadButton;\n\n if (wp.customize.utils.isKeydownButNotEnterEvent(event)) {\n return;\n }\n\n $targetDiv = this.$thisButton.closest(\".repeater-field-upload\");\n $uploadButton = $targetDiv.find(\".upload-button\");\n\n $targetDiv.find(\".kirki-file-attachment\").slideUp(\"fast\", function () {\n jQuery(this).show().html(jQuery(this).data(\"placeholder\"));\n });\n $targetDiv.find(\".hidden-field\").val(\"\");\n $uploadButton.text($uploadButton.data(\"label\"));\n this.$thisButton.hide();\n\n $targetDiv.find(\"input, textarea, select\").trigger(\"change\");\n },\n\n /**\n * Get the current value of the setting\n *\n * @returns {Object} - Returns the value.\n */\n getValue: function () {\n // The setting is saved in JSON\n return JSON.parse(decodeURI(this.setting.get()));\n },\n\n /**\n * Set a new value for the setting\n *\n * @param {Object} newValue - The new value.\n * @param {bool} refresh - If we want to refresh the previewer or not\n * @param {bool} filtering - If we want to filter or not.\n * @returns {void}\n */\n setValue: function (newValue, refresh, filtering) {\n // We need to filter the values after the first load to remove data requrired for diplay but that we don't want to save in DB\n var filteredValue = newValue,\n filter = [];\n\n if (filtering) {\n jQuery.each(this.params.fields, function (index, value) {\n if (\n \"image\" === value.type ||\n \"cropped_image\" === value.type ||\n \"upload\" === value.type\n ) {\n filter.push(index);\n }\n });\n jQuery.each(newValue, function (index, value) {\n jQuery.each(filter, function (ind, field) {\n if (!_.isUndefined(value[field]) && !_.isUndefined(value[field].id)) {\n filteredValue[index][field] = value[field].id;\n }\n });\n });\n }\n\n this.setting.set(encodeURI(JSON.stringify(filteredValue)));\n\n if (refresh) {\n // Trigger the change event on the hidden field so\n // previewer refresh the website on Customizer\n this.settingField.trigger(\"change\");\n }\n },\n\n /**\n * Add a new row to repeater settings based on the structure.\n *\n * @param {Object} data - (Optional) Object of field => value pairs (undefined if you want to get the default values)\n * @returns {Object} - Returns the new row.\n */\n addRow: function (data) {\n var control = this,\n template = control.repeaterTemplate(), // The template for the new row (defined on Kirki_Customize_Repeater_Control::render_content() ).\n settingValue = this.getValue(), // Get the current setting value.\n newRowSetting = {}, // Saves the new setting data.\n templateData, // Data to pass to the template\n newRow,\n i;\n\n if (template) {\n // The control structure is going to define the new fields\n // We need to clone control.params.fields. Assigning it\n // ould result in a reference assignment.\n templateData = jQuery.extend(true, {}, control.params.fields);\n\n // But if we have passed data, we'll use the data values instead\n if (data) {\n for (i in data) {\n if (data.hasOwnProperty(i) && templateData.hasOwnProperty(i)) {\n templateData[i].default = data[i];\n }\n }\n }\n\n templateData.index = this.currentIndex;\n\n // Append the template content\n template = template(templateData);\n\n // Create a new row object and append the element\n newRow = new RepeaterRow(\n control.currentIndex,\n jQuery(template).appendTo(control.repeaterFieldsContainer),\n control.params.row_label,\n control\n );\n\n newRow.container.on(\"row:remove\", function (e, rowIndex) {\n control.deleteRow(rowIndex);\n });\n\n newRow.container.on(\n \"row:update\",\n function (e, rowIndex, fieldName, element) {\n control.updateField.call(control, e, rowIndex, fieldName, element); // eslint-disable-line no-useless-call\n newRow.updateLabel();\n }\n );\n\n // Add the row to rows collection\n this.rows[this.currentIndex] = newRow;\n\n for (i in templateData) {\n if (templateData.hasOwnProperty(i)) {\n newRowSetting[i] = templateData[i].default;\n }\n }\n\n settingValue[this.currentIndex] = newRowSetting;\n this.setValue(settingValue, true);\n\n this.currentIndex++;\n\n return newRow;\n }\n },\n\n sort: function () {\n var control = this,\n $rows = this.repeaterFieldsContainer.find(\".repeater-row\"),\n newOrder = [],\n settings = control.getValue(),\n newRows = [],\n newSettings = [];\n\n $rows.each(function (i, element) {\n newOrder.push(jQuery(element).data(\"row\"));\n });\n\n jQuery.each(newOrder, function (newPosition, oldPosition) {\n newRows[newPosition] = control.rows[oldPosition];\n newRows[newPosition].setRowIndex(newPosition);\n\n newSettings[newPosition] = settings[oldPosition];\n });\n\n control.rows = newRows;\n control.setValue(newSettings);\n },\n\n /**\n * Delete a row in the repeater setting\n *\n * @param {int} index - Position of the row in the complete Setting Array\n * @returns {void}\n */\n deleteRow: function (index) {\n var currentSettings = this.getValue(),\n row,\n prop;\n\n if (currentSettings[index]) {\n // Find the row\n row = this.rows[index];\n if (row) {\n // Remove the row settings\n delete currentSettings[index];\n\n // Remove the row from the rows collection\n delete this.rows[index];\n\n // Update the new setting values\n this.setValue(currentSettings, true);\n }\n }\n\n // Remap the row numbers\n for (prop in this.rows) {\n if (this.rows.hasOwnProperty(prop) && this.rows[prop]) {\n this.rows[prop].updateLabel();\n }\n }\n },\n\n /**\n * Update a single field inside a row.\n * Triggered when a field has changed\n *\n * @param {Object} e - Event Object\n * @param {int} rowIndex - The row's index as an integer.\n * @param {string} fieldId - The field ID.\n * @param {string|Object} element - The element's identifier, or jQuery Object of the element.\n * @returns {void}\n */\n updateField: function (e, rowIndex, fieldId, element) {\n var type, row, currentSettings;\n\n if (!this.rows[rowIndex]) {\n return;\n }\n\n if (!this.params.fields[fieldId]) {\n return;\n }\n\n type = this.params.fields[fieldId].type;\n row = this.rows[rowIndex];\n currentSettings = this.getValue();\n\n element = jQuery(element);\n\n if (_.isUndefined(currentSettings[row.rowIndex][fieldId])) {\n return;\n }\n\n if (\"checkbox\" === type) {\n currentSettings[row.rowIndex][fieldId] = element.is(\":checked\");\n } else {\n // Update the settings\n currentSettings[row.rowIndex][fieldId] = element.val();\n }\n this.setValue(currentSettings, true);\n },\n\n /**\n * Init the color picker on color fields\n * Called after AddRow\n *\n * @returns {void}\n */\n initColorPicker: function () {\n var control = this;\n var colorPicker = control.container.find(\".kirki-classic-color-picker\");\n var fieldId = colorPicker.data(\"field\");\n var options = {};\n\n // We check if the color palette parameter is defined.\n if (\n !_.isUndefined(fieldId) &&\n !_.isUndefined(control.params.fields[fieldId]) &&\n !_.isUndefined(control.params.fields[fieldId].palettes) &&\n _.isObject(control.params.fields[fieldId].palettes)\n ) {\n options.palettes = control.params.fields[fieldId].palettes;\n }\n\n // When the color picker value is changed we update the value of the field\n options.change = function (event, ui) {\n var currentPicker = jQuery(event.target);\n var row = currentPicker.closest(\".repeater-row\");\n var rowIndex = row.data(\"row\");\n var currentSettings = control.getValue();\n var value = ui.color._alpha < 1 ? ui.color.to_s() : ui.color.toString();\n\n currentSettings[rowIndex][currentPicker.data(\"field\")] = value;\n control.setValue(currentSettings, true);\n\n\t\t\t// By default if the alpha is 1, the input will be rgb.\n\t\t\t// We setTimeout to 50ms to prevent race value set.\n\t\t\tsetTimeout(function() {\n\t\t\t\tevent.target.value = value;\n\t\t\t}, 50);\n };\n\n // Init the color picker\n if (colorPicker.length && 0 !== colorPicker.length) {\n colorPicker.wpColorPicker(options);\n }\n },\n\n /**\n * Init the dropdown-pages field.\n * Called after AddRow\n *\n * @param {object} theNewRow the row that was added to the repeater\n * @param {object} data the data for the row if we're initializing a pre-existing row\n * @returns {void}\n */\n initSelect: function (theNewRow, data) {\n var control = this,\n dropdown = theNewRow.container.find(\".repeater-field select\"),\n dataField;\n\n if (0 === dropdown.length) {\n return;\n }\n\n dataField = dropdown.data(\"field\");\n multiple = jQuery(dropdown).data(\"multiple\");\n\n data = data || {};\n data[dataField] = data[dataField] || \"\";\n\n jQuery(dropdown).val(data[dataField] || jQuery(dropdown).val());\n\n this.container.on(\"change\", \".repeater-field select\", function (event) {\n var currentDropdown = jQuery(event.target),\n row = currentDropdown.closest(\".repeater-row\"),\n rowIndex = row.data(\"row\"),\n currentSettings = control.getValue();\n\n currentSettings[rowIndex][currentDropdown.data(\"field\")] =\n jQuery(this).val();\n control.setValue(currentSettings);\n });\n },\n});\n"],"names":["$c32ddecb66401709$var$RepeaterRow","rowIndex","container","label","control","self","this","header","find","on","toggleMinimize","remove","trigger","e","jQuery","target","data","setRowIndex","rowNum","attr","updateLabel","toggleClass","slideUp","detach","rowLabelField","rowLabel","rowLabelSelector","type","field","_","isFunction","val","isUndefined","params","fields","choices","selector","text","value","wp","customize","controlConstructor","repeater","Control","extend","ready","window","kirkiControlLoader","initKirkiControl","limit","theNewRow","settingValue","settingField","first","setValue","repeaterFieldsContainer","currentIndex","rows","parseInt","preventDefault","addRow","initColorPicker","initSelect","addClass","removeClass","$thisButton","openFrame","removeImage","removeFile","repeaterTemplate","memoize","options","evaluate","interpolate","escape","variable","template","html","compiled","length","each","subValue","sortable","handle","update","sort","event","utils","isKeydownButNotEnterEvent","closest","hasClass","initCropperFrame","initFrame","frame","open","libMediaType","getMimeType","media","states","controller","Library","library","query","multiple","date","onSelect","currentFieldId","siblings","isString","isObject","forEach","el","bind","button","close","suggestedWidth","width","suggestedHeight","height","CustomizeImageCropper","imgSelectOptions","calculateImageSelectOptions","onSelectForCrop","onCropped","onSkippedCrop","attachment","state","get","toJSON","setFileInRepeaterField","setImageInRepeaterField","flex_width","flex_height","setState","croppedImage","x1","y1","flexWidth","flexHeight","realWidth","realHeight","xInit","yInit","ratio","xImg","yImg","set","mustBeCropped","handles","keys","instance","persistent","imageWidth","imageHeight","x2","y2","aspectRatio","maxHeight","maxWidth","flexW","flexH","dstW","dstH","imgW","imgH","$targetDiv","url","hide","slideDown","id","show","filename","mime_type","$uploadButton","getValue","JSON","parse","decodeURI","setting","newValue","refresh","filtering","filteredValue","filter","index","push","ind","encodeURI","stringify","templateData","newRow","i","newRowSetting","hasOwnProperty","default","appendTo","row_label","deleteRow","fieldName","element","updateField","call","$rows","newOrder","settings","newRows","newSettings","newPosition","oldPosition","prop","currentSettings","fieldId","row","is","colorPicker","palettes","change","ui","currentPicker","color","_alpha","to_s","toString","setTimeout","wpColorPicker","dataField","dropdown","currentDropdown"],"version":3,"file":"control.js.map"}PK,[5ӡ%%dist/control.css.mapnu[{"mappings":"AAAA,4BACE,iBCCF,CDEA,2DAGE,eAAA,CAFA,wBAAA,CACA,gBAAA,CAEA,iBCCF,CDEA,qEACE,wBAAA,CACA,SCCF,CDEA,2EACE,wBCCF,CDEA,2FAIE,YCFF,CDKA,iEAEE,UAAA,CADA,kBCDF,CDYA,uMAKE,YCTF,CDYA,gHAME,4BCdF,CDiBA,8HASE,wBAAA,CAFA,8CAAA,CACA,sCCnBF,CDuBA,sFAIE,kBAAA,CACA,gBCvBF,CD0BA,gDACE,eCvBF,CD0BA,kDAEE,eAAA,CADA,iBCtBF,CD0BA,4CAKE,6BAAA,CAFA,UAAA,CAFA,kBAAA,CAGA,mBAAA,CAFA,UCpBF,CD+BA,gJACE,cAAA,CACA,kBCvBF,CD0BA,kEAGE,QAAA,CAFA,QAAA,CACA,SCtBF,CD0BA,0DACE,aCvBF,CD0BA,2DACE,gBCvBF,CD0BA,2DACE,gBAAA,CACA,gBCvBF,CD0BA,8DAEE,eAAA,CADA,UCtBF,CD0BA,iDASE,oBAAA,CARA,eAAA,CACA,+BAAA,CAGA,WAAA,CAEA,gBAAA,CADA,eAAA,CAEA,eAAA,CAJA,iBAAA,CADA,iBCjBF,CD0BA,uDACE,WCvBF,CD0BA,4DAKE,aAAA,CAJA,cAAA,CACA,iBAAA,CACA,UAAA,CACA,OCtBF,CD0BA,gDAIE,aAAA,CAHA,cAAA,CACA,eAAA,CAKA,WAAA,CAJA,gBAAA,CAGA,eAAA,CADA,SCrBF,CD0BA,iDACE,UCvBF,CD0BA,uDACE,SCvBF,CD0BA,+CACE,gBCvBF,CD0BA,sFAEE,SCvBF,CD0BA,wBAGE,eAAA,CADA,iBCtBF,CD0BA,4BACE,oBCvBF,CD0BA,uBAGE,eAAA,CADA,iBCtBF,CD0BA,6BAIE,kBAAA,CADA,yBAAA,CAFA,aAAA,CACA,gBCrBF,CD0BA,OAEE,iBAAA,CADA,WCtBF,CD0BA,iBACE,kBAAA,CACA,UCvBF","sources":["packages/kirki-framework/control-repeater/src/control.scss","%3Cinput%20css%209hCl6T%3E"],"sourcesContent":[".customize-control-repeater {\n position: relative;\n}\n\n.customize-control-repeater .repeater-fields .repeater-row {\n border: 1px solid #e5e5e5;\n margin-top: 0.5rem;\n background: #eee;\n position: relative;\n}\n\n.customize-control-repeater .repeater-fields .repeater-row.minimized {\n border: 1px solid #dfdfdf;\n padding: 0;\n}\n\n.customize-control-repeater .repeater-fields .repeater-row.minimized:hover {\n border: 1px solid #e5e5e5;\n}\n\n.customize-control-repeater\n .repeater-fields\n .repeater-row.minimized\n .repeater-row-content {\n display: none;\n}\n\n.customize-control-repeater .repeater-fields .repeater-row label {\n margin-bottom: 12px;\n clear: both;\n}\n\n.customize-control-repeater\n .repeater-fields\n .repeater-row\n .repeater-field.repeater-field- {\n display: none;\n}\n\n.customize-control-repeater\n .repeater-fields\n .repeater-row\n .repeater-field.repeater-field-radio-image\n input {\n display: none;\n}\n\n.customize-control-repeater\n .repeater-fields\n .repeater-row\n .repeater-field.repeater-field-radio-image\n input\n img {\n border: 1px solid transparent;\n}\n\n.customize-control-repeater\n .repeater-fields\n .repeater-row\n .repeater-field.repeater-field-radio-image\n input:checked\n + label\n img {\n -webkit-box-shadow: 0 0 5px 2px rgba(0, 0, 0, 0.25);\n box-shadow: 0 0 5px 2px rgba(0, 0, 0, 0.25);\n border: 1px solid #3498db;\n}\n\n.customize-control-repeater\n .repeater-fields\n .repeater-row\n .repeater-field:last-child {\n border-bottom: none;\n padding-bottom: 0;\n}\n\n.customize-control-repeater button.repeater-add {\n margin-top: 1rem;\n}\n\n.customize-control-repeater .repeater-row-content {\n padding: 10px 15px;\n background: #fff;\n}\n\n.customize-control-repeater .repeater-field {\n margin-bottom: 12px;\n width: 100%;\n clear: both;\n padding-bottom: 12px;\n border-bottom: 1px dotted #ccc;\n}\n\n.customize-control-repeater .repeater-field .customize-control-title {\n font-size: 13px;\n line-height: initial;\n}\n\n.customize-control-repeater .repeater-field .customize-control-description {\n font-size: 13px;\n line-height: initial;\n}\n\n.customize-control-repeater .repeater-field.repeater-field-hidden {\n margin: 0;\n padding: 0;\n border: 0;\n}\n\n.customize-control-repeater .repeater-field-select select {\n margin-left: 0;\n}\n\n.customize-control-repeater .repeater-field-checkbox label {\n line-height: 28px;\n}\n\n.customize-control-repeater .repeater-field-checkbox input {\n line-height: 28px;\n margin-right: 5px;\n}\n\n.customize-control-repeater .repeater-field-textarea textarea {\n width: 100%;\n resize: vertical;\n}\n\n.customize-control-repeater .repeater-row-header {\n background: white;\n border-bottom: 1px solid #dfdfdf;\n position: relative;\n padding: 10px 15px;\n height: auto;\n min-height: 20px;\n line-height: 30px;\n overflow: hidden;\n word-wrap: break-word;\n}\n\n.customize-control-repeater .repeater-row-header:hover {\n cursor: move;\n}\n\n.customize-control-repeater .repeater-row-header .dashicons {\n font-size: 18px;\n position: absolute;\n right: 12px;\n top: 2px;\n color: #a0a5aa;\n}\n\n.customize-control-repeater .repeater-row-label {\n font-size: 13px;\n font-weight: 600;\n line-height: 20px;\n display: block;\n width: 90%;\n overflow: hidden;\n height: 18px;\n}\n\n.customize-control-repeater .repeater-row-remove {\n color: #a00;\n}\n\n.customize-control-repeater .repeater-row-remove:hover {\n color: #f00;\n}\n\n.customize-control-repeater .repeater-minimize {\n line-height: 36px;\n}\n\n.customize-control-repeater .remove-button,\n.customize-control-repeater .upload-button {\n width: 48%;\n}\n\n.kirki-image-attachment {\n margin: 0;\n text-align: center;\n margin-bottom: 10px;\n}\n\n.kirki-image-attachment img {\n display: inline-block;\n}\n\n.kirki-file-attachment {\n margin: 0;\n text-align: center;\n margin-bottom: 10px;\n}\n\n.kirki-file-attachment .file {\n display: block;\n padding: 10px 5px;\n border: 1px dotted #c3c3c3;\n background: #f9f9f9;\n}\n\n.limit {\n padding: 3px;\n border-radius: 3px;\n}\n\n.limit.highlight {\n background: #d32f2f;\n color: #fff;\n}\n",".customize-control-repeater {\n position: relative;\n}\n\n.customize-control-repeater .repeater-fields .repeater-row {\n border: 1px solid #e5e5e5;\n margin-top: 0.5rem;\n background: #eee;\n position: relative;\n}\n\n.customize-control-repeater .repeater-fields .repeater-row.minimized {\n border: 1px solid #dfdfdf;\n padding: 0;\n}\n\n.customize-control-repeater .repeater-fields .repeater-row.minimized:hover {\n border: 1px solid #e5e5e5;\n}\n\n.customize-control-repeater .repeater-fields .repeater-row.minimized .repeater-row-content {\n display: none;\n}\n\n.customize-control-repeater .repeater-fields .repeater-row label {\n margin-bottom: 12px;\n clear: both;\n}\n\n.customize-control-repeater .repeater-fields .repeater-row .repeater-field.repeater-field- {\n display: none;\n}\n\n.customize-control-repeater .repeater-fields .repeater-row .repeater-field.repeater-field-radio-image input {\n display: none;\n}\n\n.customize-control-repeater .repeater-fields .repeater-row .repeater-field.repeater-field-radio-image input img {\n border: 1px solid transparent;\n}\n\n.customize-control-repeater .repeater-fields .repeater-row .repeater-field.repeater-field-radio-image input:checked + label img {\n -webkit-box-shadow: 0 0 5px 2px rgba(0, 0, 0, 0.25);\n box-shadow: 0 0 5px 2px rgba(0, 0, 0, 0.25);\n border: 1px solid #3498db;\n}\n\n.customize-control-repeater .repeater-fields .repeater-row .repeater-field:last-child {\n border-bottom: none;\n padding-bottom: 0;\n}\n\n.customize-control-repeater button.repeater-add {\n margin-top: 1rem;\n}\n\n.customize-control-repeater .repeater-row-content {\n padding: 10px 15px;\n background: #fff;\n}\n\n.customize-control-repeater .repeater-field {\n margin-bottom: 12px;\n width: 100%;\n clear: both;\n padding-bottom: 12px;\n border-bottom: 1px dotted #ccc;\n}\n\n.customize-control-repeater .repeater-field .customize-control-title {\n font-size: 13px;\n line-height: initial;\n}\n\n.customize-control-repeater .repeater-field .customize-control-description {\n font-size: 13px;\n line-height: initial;\n}\n\n.customize-control-repeater .repeater-field.repeater-field-hidden {\n margin: 0;\n padding: 0;\n border: 0;\n}\n\n.customize-control-repeater .repeater-field-select select {\n margin-left: 0;\n}\n\n.customize-control-repeater .repeater-field-checkbox label {\n line-height: 28px;\n}\n\n.customize-control-repeater .repeater-field-checkbox input {\n line-height: 28px;\n margin-right: 5px;\n}\n\n.customize-control-repeater .repeater-field-textarea textarea {\n width: 100%;\n resize: vertical;\n}\n\n.customize-control-repeater .repeater-row-header {\n background: white;\n border-bottom: 1px solid #dfdfdf;\n position: relative;\n padding: 10px 15px;\n height: auto;\n min-height: 20px;\n line-height: 30px;\n overflow: hidden;\n word-wrap: break-word;\n}\n\n.customize-control-repeater .repeater-row-header:hover {\n cursor: move;\n}\n\n.customize-control-repeater .repeater-row-header .dashicons {\n font-size: 18px;\n position: absolute;\n right: 12px;\n top: 2px;\n color: #a0a5aa;\n}\n\n.customize-control-repeater .repeater-row-label {\n font-size: 13px;\n font-weight: 600;\n line-height: 20px;\n display: block;\n width: 90%;\n overflow: hidden;\n height: 18px;\n}\n\n.customize-control-repeater .repeater-row-remove {\n color: #a00;\n}\n\n.customize-control-repeater .repeater-row-remove:hover {\n color: #f00;\n}\n\n.customize-control-repeater .repeater-minimize {\n line-height: 36px;\n}\n\n.customize-control-repeater .remove-button,\n.customize-control-repeater .upload-button {\n width: 48%;\n}\n\n.kirki-image-attachment {\n margin: 0;\n text-align: center;\n margin-bottom: 10px;\n}\n\n.kirki-image-attachment img {\n display: inline-block;\n}\n\n.kirki-file-attachment {\n margin: 0;\n text-align: center;\n margin-bottom: 10px;\n}\n\n.kirki-file-attachment .file {\n display: block;\n padding: 10px 5px;\n border: 1px dotted #c3c3c3;\n background: #f9f9f9;\n}\n\n.limit {\n padding: 3px;\n border-radius: 3px;\n}\n\n.limit.highlight {\n background: #d32f2f;\n color: #fff;\n}\n/*# sourceMappingURL=control.css.map */\n"],"names":[],"version":3,"file":"control.css.map"}PK,[ʻsrc/Field/Repeater.phpnu[type = 'repeater'; } /** * Sets the $transport * * @access protected * @since 1.0 * @return void */ protected function set_transport() { // Force using refresh mode. // Currently the repeater control does not support postMessage. $this->transport = 'refresh'; } /** * Sets the $sanitize_callback * * @access protected * @since 1.0 * @return void */ protected function set_sanitize_callback() { if ( empty( $this->sanitize_callback ) ) { $this->sanitize_callback = [ $this, 'sanitize' ]; } } /** * The sanitize method that will be used as a falback * * @access public * @since 1.0 * @param string|array $value The control's value. */ public function sanitize( $value ) { // is the value formatted as a string? if ( is_string( $value ) ) { $value = rawurldecode( $value ); $value = json_decode( $value, true ); } // Nothing to sanitize if we don't have fields. if ( empty( $this->fields ) ) { return $value; } foreach ( $value as $row_id => $row_value ) { // Make sure the row is formatted as an array. if ( ! is_array( $row_value ) ) { $value[ $row_id ] = []; continue; } // Start parsing sub-fields in rows. foreach ( $row_value as $subfield_id => $subfield_value ) { // Make sure this is a valid subfield. // If it's not, then unset it. if ( ! isset( $this->fields[ $subfield_id ] ) ) { unset( $value[ $row_id ][ $subfield_id ] ); } // Get the subfield-type. if ( ! isset( $this->fields[ $subfield_id ]['type'] ) ) { continue; } $subfield = $this->fields[ $subfield_id ]; $subfield_type = $subfield['type']; // Allow using a sanitize-callback on a per-field basis. if ( isset( $this->fields[ $subfield_id ]['sanitize_callback'] ) ) { $subfield_value = call_user_func( $this->fields[ $subfield_id ]['sanitize_callback'], $subfield_value ); } else { switch ( $subfield_type ) { case 'image': case 'cropped_image': case 'upload': $save_as = isset( $subfield['choices'] ) && isset( $subfield['choices']['save_as'] ) ? $subfield['choices']['save_as'] : 'url'; $subfield_value = Upload::sanitize( $subfield_value, $save_as ); break; case 'dropdown-pages': $subfield_value = (int) $subfield_value; break; case 'color': if ( $subfield_value ) { $subfield_value = \Kirki\Field\ReactColorful::sanitize( $subfield_value ); } break; case 'text': $subfield_value = sanitize_text_field( $subfield_value ); break; case 'url': case 'link': $subfield_value = esc_url_raw( $subfield_value ); break; case 'email': $subfield_value = filter_var( $subfield_value, FILTER_SANITIZE_EMAIL ); break; case 'tel': $subfield_value = sanitize_text_field( $subfield_value ); break; case 'checkbox': $subfield_value = (bool) $subfield_value; break; case 'select': if ( isset( $this->fields[ $subfield_id ]['multiple'] ) ) { if ( true === $this->fields[ $subfield_id ]['multiple'] ) { $multiple = 2; } $multiple = (int) $this->fields[ $subfield_id ]['multiple']; if ( 1 < $multiple ) { $subfield_value = (array) $subfield_value; foreach ( $subfield_value as $sub_subfield_key => $sub_subfield_value ) { $subfield_value[ $sub_subfield_key ] = sanitize_text_field( $sub_subfield_value ); } } else { $subfield_value = sanitize_text_field( $subfield_value ); } } break; case 'radio': case 'radio-image': $subfield_value = sanitize_text_field( $subfield_value ); break; case 'textarea': $subfield_value = html_entity_decode( wp_kses_post( $subfield_value ) ); } } $value[ $row_id ][ $subfield_id ] = $subfield_value; } } return $value; } } PK,[i~eBPBPsrc/Control/Repeater.phpnu[row_label = [ 'type' => 'text', 'value' => esc_attr__( 'row', 'kirki' ), 'field' => false, ]; // Validate row-labels. $this->row_label( $args ); if ( empty( $this->button_label ) ) { /* translators: %s represents the label of the row. */ $this->button_label = sprintf( esc_html__( 'Add new %s', 'kirki' ), $this->row_label['value'] ); } if ( empty( $args['fields'] ) || ! is_array( $args['fields'] ) ) { $args['fields'] = []; } // An array to store keys of fields that need to be filtered. $media_fields_to_filter = []; foreach ( $args['fields'] as $key => $value ) { if ( ! isset( $value['default'] ) ) { $args['fields'][ $key ]['default'] = ''; } if ( ! isset( $value['label'] ) ) { $args['fields'][ $key ]['label'] = ''; } $args['fields'][ $key ]['id'] = $key; // We check if the filed is an uploaded media ( image , file, video, etc.. ). if ( isset( $value['type'] ) ) { switch ( $value['type'] ) { case 'image': case 'cropped_image': case 'upload': // We add it to the list of fields that need some extra filtering/processing. $media_fields_to_filter[ $key ] = true; break; case 'dropdown-pages': // If the field is a dropdown-pages field then add it to args. $dropdown = wp_dropdown_pages( [ 'name' => '', 'echo' => 0, 'show_option_none' => esc_html__( 'Select a Page', 'kirki' ), 'option_none_value' => '0', 'selected' => '', ] ); // Hackily add in the data link parameter. $dropdown = str_replace( 'get_link(), $dropdown ); // phpcs:ignore Generic.Formatting.MultipleStatementAlignment $args['fields'][ $key ]['dropdown'] = $dropdown; break; } } } $this->fields = $args['fields']; // Now we are going to filter the fields. // First we create a copy of the value that would be used otherwise. $this->filtered_value = $this->value(); if ( is_array( $this->filtered_value ) && ! empty( $this->filtered_value ) ) { // We iterate over the list of fields. foreach ( $this->filtered_value as &$filtered_value_field ) { if ( is_array( $filtered_value_field ) && ! empty( $filtered_value_field ) ) { // We iterate over the list of properties for this field. foreach ( $filtered_value_field as $key => &$value ) { // We check if this field was marked as requiring extra filtering (in this case image, cropped_images, upload). if ( array_key_exists( $key, $media_fields_to_filter ) ) { // What follows was made this way to preserve backward compatibility. // The repeater control use to store the URL for images instead of the attachment ID. // We check if the value look like an ID (otherwise it's probably a URL so don't filter it). if ( is_numeric( $value ) ) { // "sanitize" the value. $attachment_id = (int) $value; // Try to get the attachment_url. $url = wp_get_attachment_url( $attachment_id ); $filename = basename( get_attached_file( $attachment_id ) ); // If we got a URL. if ( $url ) { // 'id' is needed for form hidden value, URL is needed to display the image. $value = [ 'id' => $attachment_id, 'url' => $url, 'filename' => $filename, ]; } } } } } } } } /** * Enqueue control related scripts/styles. * * @access public * @since 1.0 * @return void */ public function enqueue() { parent::enqueue(); // Enqueue the style. wp_enqueue_style( 'wp-color-picker' ); wp_enqueue_style( 'kirki-control-repeater-style', URL::get_from_path( dirname( dirname( __DIR__ ) ) . '/dist/control.css' ), [], self::$control_ver ); // Enqueue the script. wp_enqueue_script( 'wp-color-picker-alpha', URL::get_from_path( dirname( dirname( __DIR__ ) ) . '/dist/wp-color-picker-alpha.min.js' ), array( 'jquery', 'customize-base', 'wp-color-picker' ), self::$control_ver, false ); wp_enqueue_script( 'kirki-control-repeater', URL::get_from_path( dirname( dirname( __DIR__ ) ) . '/dist/control.js' ), [ 'wp-color-picker-alpha' ], self::$control_ver, false ); } /** * Refresh the parameters passed to the JavaScript via JSON. * * @access public * @since 1.0 * @return void */ public function to_json() { parent::to_json(); $fields = $this->fields; $this->json['fields'] = $fields; $this->json['row_label'] = $this->row_label; // If filtered_value has been set and is not empty we use it instead of the actual value. if ( is_array( $this->filtered_value ) && ! empty( $this->filtered_value ) ) { $this->json['value'] = $this->filtered_value; } $this->json['value'] = apply_filters( "kirki_controls_repeater_value_{$this->id}", $this->json['value'] ); } /** * Render the control's content. * Allows the content to be overriden without having to rewrite the wrapper in $this->render(). * * @access protected * @since 1.0 * @return void */ protected function render_content() { ?>
    choices['limit'] ) ) : ?>

    choices['limit'] ) ); ?>

    repeater_js_template(); } /** * An Underscore (JS) template for this control's content (but not its container). * Class variables for this control class are available in the `data` JS object. * * @access public * @since 1.0 * @return void */ public function repeater_js_template() { ?> row_label['type'] = $args['row_label']['type']; } // Validating row label type. if ( isset( $args['row_label']['value'] ) && ! empty( $args['row_label']['value'] ) ) { $this->row_label['value'] = esc_html( $args['row_label']['value'] ); } // Validating row label field. if ( isset( $args['row_label']['field'] ) && ! empty( $args['row_label']['field'] ) && isset( $args['fields'][ sanitize_key( $args['row_label']['field'] ) ] ) ) { $this->row_label['field'] = esc_html( $args['row_label']['field'] ); } else { // If from field is not set correctly, making sure standard is set as the type. $this->row_label['type'] = 'text'; } } } } PK,[/jjsrc/control.jsnu[import "./control.scss"; /* global kirkiControlLoader */ /* eslint max-depth: 0 */ /* eslint no-useless-escape: 0 */ var RepeaterRow = function (rowIndex, container, label, control) { var self = this; this.rowIndex = rowIndex; this.container = container; this.label = label; this.header = this.container.find(".repeater-row-header"); this.header.on("click", function () { self.toggleMinimize(); }); this.container.on("click", ".repeater-row-remove", function () { self.remove(); }); this.header.on("mousedown", function () { self.container.trigger("row:start-dragging"); }); this.container.on("keyup change", "input, select, textarea", function (e) { self.container.trigger("row:update", [ self.rowIndex, jQuery(e.target).data("field"), e.target, ]); }); this.setRowIndex = function (rowNum) { this.rowIndex = rowNum; this.container.attr("data-row", rowNum); this.container.data("row", rowNum); this.updateLabel(); }; this.toggleMinimize = function () { // Store the previous state. this.container.toggleClass("minimized"); this.header .find(".dashicons") .toggleClass("dashicons-arrow-up") .toggleClass("dashicons-arrow-down"); }; this.remove = function () { this.container.slideUp(300, function () { jQuery(this).detach(); }); this.container.trigger("row:remove", [this.rowIndex]); }; this.updateLabel = function () { var rowLabelField, rowLabel, rowLabelSelector; if ("field" === this.label.type) { rowLabelField = this.container.find( '.repeater-field [data-field="' + this.label.field + '"]' ); if (_.isFunction(rowLabelField.val)) { rowLabel = rowLabelField.val(); if ("" !== rowLabel) { if (!_.isUndefined(control.params.fields[this.label.field])) { if (!_.isUndefined(control.params.fields[this.label.field].type)) { if ("select" === control.params.fields[this.label.field].type) { if ( !_.isUndefined( control.params.fields[this.label.field].choices ) && !_.isUndefined( control.params.fields[this.label.field].choices[ rowLabelField.val() ] ) ) { rowLabel = control.params.fields[this.label.field].choices[ rowLabelField.val() ]; } } else if ( "radio" === control.params.fields[this.label.field].type || "radio-image" === control.params.fields[this.label.field].type ) { rowLabelSelector = control.selector + ' [data-row="' + this.rowIndex + '"] .repeater-field [data-field="' + this.label.field + '"]:checked'; rowLabel = jQuery(rowLabelSelector).val(); } } } this.header.find(".repeater-row-label").text(rowLabel); return; } } } this.header .find(".repeater-row-label") .text(this.label.value + " " + (this.rowIndex + 1)); }; this.updateLabel(); }; wp.customize.controlConstructor.repeater = wp.customize.Control.extend({ // When we're finished loading continue processing ready: function () { var control = this; // Init the control. if ( !_.isUndefined(window.kirkiControlLoader) && _.isFunction(kirkiControlLoader) ) { kirkiControlLoader(control); } else { control.initKirkiControl(); } }, initKirkiControl: function (control) { var limit, theNewRow, settingValue; control = control || this; // The current value set in Control Class (set in Kirki_Customize_Repeater_Control::to_json() function) settingValue = control.params.value; // The hidden field that keeps the data saved (though we never update it) control.settingField = control.container .find("[data-customize-setting-link]") .first(); // Set the field value for the first time, we'll fill it up later control.setValue([], false); // The DIV that holds all the rows control.repeaterFieldsContainer = control.container .find(".repeater-fields") .first(); // Set number of rows to 0 control.currentIndex = 0; // Save the rows objects control.rows = []; // Default limit choice limit = false; if (!_.isUndefined(control.params.choices.limit)) { limit = 0 >= control.params.choices.limit ? false : parseInt(control.params.choices.limit, 10); } control.container.on("click", "button.repeater-add", function (e) { e.preventDefault(); if (!limit || control.currentIndex < limit) { theNewRow = control.addRow(); theNewRow.toggleMinimize(); control.initColorPicker(); control.initSelect(theNewRow); } else { jQuery(control.selector + " .limit").addClass("highlight"); } }); control.container.on("click", ".repeater-row-remove", function () { control.currentIndex--; if (!limit || control.currentIndex < limit) { jQuery(control.selector + " .limit").removeClass("highlight"); } }); control.container.on( "click keypress", ".repeater-field-image .upload-button,.repeater-field-cropped_image .upload-button,.repeater-field-upload .upload-button", function (e) { e.preventDefault(); control.$thisButton = jQuery(this); control.openFrame(e); } ); control.container.on( "click keypress", ".repeater-field-image .remove-button,.repeater-field-cropped_image .remove-button", function (e) { e.preventDefault(); control.$thisButton = jQuery(this); control.removeImage(e); } ); control.container.on( "click keypress", ".repeater-field-upload .remove-button", function (e) { e.preventDefault(); control.$thisButton = jQuery(this); control.removeFile(e); } ); /** * Function that loads the Mustache template */ control.repeaterTemplate = _.memoize(function () { var compiled, /* * Underscore's default ERB-style templates are incompatible with PHP * when asp_tags is enabled, so WordPress uses Mustache-inspired templating syntax. * * @see trac ticket #22344. */ options = { evaluate: /<#([\s\S]+?)#>/g, interpolate: /\{\{\{([\s\S]+?)\}\}\}/g, escape: /\{\{([^\}]+?)\}\}(?!\})/g, variable: "data", }; return function (data) { compiled = _.template( control.container .find(".customize-control-repeater-content") .first() .html(), null, options ); return compiled(data); }; }); // When we load the control, the fields have not been filled up // This is the first time that we create all the rows if (settingValue.length) { _.each(settingValue, function (subValue) { theNewRow = control.addRow(subValue); control.initColorPicker(); control.initSelect(theNewRow, subValue); }); } control.repeaterFieldsContainer.sortable({ handle: ".repeater-row-header", update: function () { control.sort(); }, }); }, /** * Open the media modal. * * @param {Object} event - The JS event. * @returns {void} */ openFrame: function (event) { if (wp.customize.utils.isKeydownButNotEnterEvent(event)) { return; } if ( this.$thisButton .closest(".repeater-field") .hasClass("repeater-field-cropped_image") ) { this.initCropperFrame(); } else { this.initFrame(); } this.frame.open(); }, initFrame: function () { var libMediaType = this.getMimeType(); this.frame = wp.media({ states: [ new wp.media.controller.Library({ library: wp.media.query({ type: libMediaType }), multiple: false, date: false, }), ], }); // When a file is selected, run a callback. this.frame.on("select", this.onSelect, this); }, /** * Create a media modal select frame, and store it so the instance can be reused when needed. * This is mostly a copy/paste of Core api.CroppedImageControl in /wp-admin/js/customize-control.js * * @returns {void} */ initCropperFrame: function () { // We get the field id from which this was called var currentFieldId = this.$thisButton .siblings("input.hidden-field") .attr("data-field"), attrs = ["width", "height", "flex_width", "flex_height"], // A list of attributes to look for libMediaType = this.getMimeType(); // Make sure we got it if (_.isString(currentFieldId) && "" !== currentFieldId) { // Make fields is defined and only do the hack for cropped_image if ( _.isObject(this.params.fields[currentFieldId]) && "cropped_image" === this.params.fields[currentFieldId].type ) { //Iterate over the list of attributes attrs.forEach( function (el) { // If the attribute exists in the field if (!_.isUndefined(this.params.fields[currentFieldId][el])) { // Set the attribute in the main object this.params[el] = this.params.fields[currentFieldId][el]; } }.bind(this) ); } } this.frame = wp.media({ button: { text: "Select and Crop", close: false, }, states: [ new wp.media.controller.Library({ library: wp.media.query({ type: libMediaType }), multiple: false, date: false, suggestedWidth: this.params.width, suggestedHeight: this.params.height, }), new wp.media.controller.CustomizeImageCropper({ imgSelectOptions: this.calculateImageSelectOptions, control: this, }), ], }); this.frame.on("select", this.onSelectForCrop, this); this.frame.on("cropped", this.onCropped, this); this.frame.on("skippedcrop", this.onSkippedCrop, this); }, onSelect: function () { var attachment = this.frame.state().get("selection").first().toJSON(); if ( this.$thisButton .closest(".repeater-field") .hasClass("repeater-field-upload") ) { this.setFileInRepeaterField(attachment); } else { this.setImageInRepeaterField(attachment); } }, /** * After an image is selected in the media modal, switch to the cropper * state if the image isn't the right size. */ onSelectForCrop: function () { var attachment = this.frame.state().get("selection").first().toJSON(); if ( this.params.width === attachment.width && this.params.height === attachment.height && !this.params.flex_width && !this.params.flex_height ) { this.setImageInRepeaterField(attachment); } else { this.frame.setState("cropper"); } }, /** * After the image has been cropped, apply the cropped image data to the setting. * * @param {object} croppedImage Cropped attachment data. * @returns {void} */ onCropped: function (croppedImage) { this.setImageInRepeaterField(croppedImage); }, /** * Returns a set of options, computed from the attached image data and * control-specific data, to be fed to the imgAreaSelect plugin in * wp.media.view.Cropper. * * @param {wp.media.model.Attachment} attachment - The attachment from the WP API. * @param {wp.media.controller.Cropper} controller - Media controller. * @returns {Object} - Options. */ calculateImageSelectOptions: function (attachment, controller) { var control = controller.get("control"), flexWidth = !!parseInt(control.params.flex_width, 10), flexHeight = !!parseInt(control.params.flex_height, 10), realWidth = attachment.get("width"), realHeight = attachment.get("height"), xInit = parseInt(control.params.width, 10), yInit = parseInt(control.params.height, 10), ratio = xInit / yInit, xImg = realWidth, yImg = realHeight, x1, y1, imgSelectOptions; controller.set( "canSkipCrop", !control.mustBeCropped( flexWidth, flexHeight, xInit, yInit, realWidth, realHeight ) ); if (xImg / yImg > ratio) { yInit = yImg; xInit = yInit * ratio; } else { xInit = xImg; yInit = xInit / ratio; } x1 = (xImg - xInit) / 2; y1 = (yImg - yInit) / 2; imgSelectOptions = { handles: true, keys: true, instance: true, persistent: true, imageWidth: realWidth, imageHeight: realHeight, x1: x1, y1: y1, x2: xInit + x1, y2: yInit + y1, }; if (false === flexHeight && false === flexWidth) { imgSelectOptions.aspectRatio = xInit + ":" + yInit; } if (false === flexHeight) { imgSelectOptions.maxHeight = yInit; } if (false === flexWidth) { imgSelectOptions.maxWidth = xInit; } return imgSelectOptions; }, /** * Return whether the image must be cropped, based on required dimensions. * * @param {bool} flexW - The flex-width. * @param {bool} flexH - The flex-height. * @param {int} dstW - Initial point distance in the X axis. * @param {int} dstH - Initial point distance in the Y axis. * @param {int} imgW - Width. * @param {int} imgH - Height. * @returns {bool} - Whether the image must be cropped or not based on required dimensions. */ mustBeCropped: function (flexW, flexH, dstW, dstH, imgW, imgH) { return !( (true === flexW && true === flexH) || (true === flexW && dstH === imgH) || (true === flexH && dstW === imgW) || (dstW === imgW && dstH === imgH) || imgW <= dstW ); }, /** * If cropping was skipped, apply the image data directly to the setting. * * @returns {void} */ onSkippedCrop: function () { var attachment = this.frame.state().get("selection").first().toJSON(); this.setImageInRepeaterField(attachment); }, /** * Updates the setting and re-renders the control UI. * * @param {object} attachment - The attachment object. * @returns {void} */ setImageInRepeaterField: function (attachment) { var $targetDiv = this.$thisButton.closest( ".repeater-field-image,.repeater-field-cropped_image" ); $targetDiv .find(".kirki-image-attachment") .html('') .hide() .slideDown("slow"); $targetDiv.find(".hidden-field").val(attachment.id); this.$thisButton.text(this.$thisButton.data("alt-label")); $targetDiv.find(".remove-button").show(); //This will activate the save button $targetDiv.find("input, textarea, select").trigger("change"); this.frame.close(); }, /** * Updates the setting and re-renders the control UI. * * @param {object} attachment - The attachment object. * @returns {void} */ setFileInRepeaterField: function (attachment) { var $targetDiv = this.$thisButton.closest(".repeater-field-upload"); $targetDiv .find(".kirki-file-attachment") .html( ' ' + attachment.filename + "" ) .hide() .slideDown("slow"); $targetDiv.find(".hidden-field").val(attachment.id); this.$thisButton.text(this.$thisButton.data("alt-label")); $targetDiv.find(".upload-button").show(); $targetDiv.find(".remove-button").show(); //This will activate the save button $targetDiv.find("input, textarea, select").trigger("change"); this.frame.close(); }, getMimeType: function () { // We get the field id from which this was called var currentFieldId = this.$thisButton .siblings("input.hidden-field") .attr("data-field"); // Make sure we got it if (_.isString(currentFieldId) && "" !== currentFieldId) { // Make fields is defined and only do the hack for cropped_image if ( _.isObject(this.params.fields[currentFieldId]) && "upload" === this.params.fields[currentFieldId].type ) { // If the attribute exists in the field if (!_.isUndefined(this.params.fields[currentFieldId].mime_type)) { // Set the attribute in the main object return this.params.fields[currentFieldId].mime_type; } } } return "image"; }, removeImage: function (event) { var $targetDiv, $uploadButton; if (wp.customize.utils.isKeydownButNotEnterEvent(event)) { return; } $targetDiv = this.$thisButton.closest( ".repeater-field-image,.repeater-field-cropped_image,.repeater-field-upload" ); $uploadButton = $targetDiv.find(".upload-button"); $targetDiv.find(".kirki-image-attachment").slideUp("fast", function () { jQuery(this).show().html(jQuery(this).data("placeholder")); }); $targetDiv.find(".hidden-field").val(""); $uploadButton.text($uploadButton.data("label")); this.$thisButton.hide(); $targetDiv.find("input, textarea, select").trigger("change"); }, removeFile: function (event) { var $targetDiv, $uploadButton; if (wp.customize.utils.isKeydownButNotEnterEvent(event)) { return; } $targetDiv = this.$thisButton.closest(".repeater-field-upload"); $uploadButton = $targetDiv.find(".upload-button"); $targetDiv.find(".kirki-file-attachment").slideUp("fast", function () { jQuery(this).show().html(jQuery(this).data("placeholder")); }); $targetDiv.find(".hidden-field").val(""); $uploadButton.text($uploadButton.data("label")); this.$thisButton.hide(); $targetDiv.find("input, textarea, select").trigger("change"); }, /** * Get the current value of the setting * * @returns {Object} - Returns the value. */ getValue: function () { // The setting is saved in JSON return JSON.parse(decodeURI(this.setting.get())); }, /** * Set a new value for the setting * * @param {Object} newValue - The new value. * @param {bool} refresh - If we want to refresh the previewer or not * @param {bool} filtering - If we want to filter or not. * @returns {void} */ setValue: function (newValue, refresh, filtering) { // We need to filter the values after the first load to remove data requrired for diplay but that we don't want to save in DB var filteredValue = newValue, filter = []; if (filtering) { jQuery.each(this.params.fields, function (index, value) { if ( "image" === value.type || "cropped_image" === value.type || "upload" === value.type ) { filter.push(index); } }); jQuery.each(newValue, function (index, value) { jQuery.each(filter, function (ind, field) { if (!_.isUndefined(value[field]) && !_.isUndefined(value[field].id)) { filteredValue[index][field] = value[field].id; } }); }); } this.setting.set(encodeURI(JSON.stringify(filteredValue))); if (refresh) { // Trigger the change event on the hidden field so // previewer refresh the website on Customizer this.settingField.trigger("change"); } }, /** * Add a new row to repeater settings based on the structure. * * @param {Object} data - (Optional) Object of field => value pairs (undefined if you want to get the default values) * @returns {Object} - Returns the new row. */ addRow: function (data) { var control = this, template = control.repeaterTemplate(), // The template for the new row (defined on Kirki_Customize_Repeater_Control::render_content() ). settingValue = this.getValue(), // Get the current setting value. newRowSetting = {}, // Saves the new setting data. templateData, // Data to pass to the template newRow, i; if (template) { // The control structure is going to define the new fields // We need to clone control.params.fields. Assigning it // ould result in a reference assignment. templateData = jQuery.extend(true, {}, control.params.fields); // But if we have passed data, we'll use the data values instead if (data) { for (i in data) { if (data.hasOwnProperty(i) && templateData.hasOwnProperty(i)) { templateData[i].default = data[i]; } } } templateData.index = this.currentIndex; // Append the template content template = template(templateData); // Create a new row object and append the element newRow = new RepeaterRow( control.currentIndex, jQuery(template).appendTo(control.repeaterFieldsContainer), control.params.row_label, control ); newRow.container.on("row:remove", function (e, rowIndex) { control.deleteRow(rowIndex); }); newRow.container.on( "row:update", function (e, rowIndex, fieldName, element) { control.updateField.call(control, e, rowIndex, fieldName, element); // eslint-disable-line no-useless-call newRow.updateLabel(); } ); // Add the row to rows collection this.rows[this.currentIndex] = newRow; for (i in templateData) { if (templateData.hasOwnProperty(i)) { newRowSetting[i] = templateData[i].default; } } settingValue[this.currentIndex] = newRowSetting; this.setValue(settingValue, true); this.currentIndex++; return newRow; } }, sort: function () { var control = this, $rows = this.repeaterFieldsContainer.find(".repeater-row"), newOrder = [], settings = control.getValue(), newRows = [], newSettings = []; $rows.each(function (i, element) { newOrder.push(jQuery(element).data("row")); }); jQuery.each(newOrder, function (newPosition, oldPosition) { newRows[newPosition] = control.rows[oldPosition]; newRows[newPosition].setRowIndex(newPosition); newSettings[newPosition] = settings[oldPosition]; }); control.rows = newRows; control.setValue(newSettings); }, /** * Delete a row in the repeater setting * * @param {int} index - Position of the row in the complete Setting Array * @returns {void} */ deleteRow: function (index) { var currentSettings = this.getValue(), row, prop; if (currentSettings[index]) { // Find the row row = this.rows[index]; if (row) { // Remove the row settings delete currentSettings[index]; // Remove the row from the rows collection delete this.rows[index]; // Update the new setting values this.setValue(currentSettings, true); } } // Remap the row numbers for (prop in this.rows) { if (this.rows.hasOwnProperty(prop) && this.rows[prop]) { this.rows[prop].updateLabel(); } } }, /** * Update a single field inside a row. * Triggered when a field has changed * * @param {Object} e - Event Object * @param {int} rowIndex - The row's index as an integer. * @param {string} fieldId - The field ID. * @param {string|Object} element - The element's identifier, or jQuery Object of the element. * @returns {void} */ updateField: function (e, rowIndex, fieldId, element) { var type, row, currentSettings; if (!this.rows[rowIndex]) { return; } if (!this.params.fields[fieldId]) { return; } type = this.params.fields[fieldId].type; row = this.rows[rowIndex]; currentSettings = this.getValue(); element = jQuery(element); if (_.isUndefined(currentSettings[row.rowIndex][fieldId])) { return; } if ("checkbox" === type) { currentSettings[row.rowIndex][fieldId] = element.is(":checked"); } else { // Update the settings currentSettings[row.rowIndex][fieldId] = element.val(); } this.setValue(currentSettings, true); }, /** * Init the color picker on color fields * Called after AddRow * * @returns {void} */ initColorPicker: function () { var control = this; var colorPicker = control.container.find(".kirki-classic-color-picker"); var fieldId = colorPicker.data("field"); var options = {}; // We check if the color palette parameter is defined. if ( !_.isUndefined(fieldId) && !_.isUndefined(control.params.fields[fieldId]) && !_.isUndefined(control.params.fields[fieldId].palettes) && _.isObject(control.params.fields[fieldId].palettes) ) { options.palettes = control.params.fields[fieldId].palettes; } // When the color picker value is changed we update the value of the field options.change = function (event, ui) { var currentPicker = jQuery(event.target); var row = currentPicker.closest(".repeater-row"); var rowIndex = row.data("row"); var currentSettings = control.getValue(); var value = ui.color._alpha < 1 ? ui.color.to_s() : ui.color.toString(); currentSettings[rowIndex][currentPicker.data("field")] = value; control.setValue(currentSettings, true); // By default if the alpha is 1, the input will be rgb. // We setTimeout to 50ms to prevent race value set. setTimeout(function() { event.target.value = value; }, 50); }; // Init the color picker if (colorPicker.length && 0 !== colorPicker.length) { colorPicker.wpColorPicker(options); } }, /** * Init the dropdown-pages field. * Called after AddRow * * @param {object} theNewRow the row that was added to the repeater * @param {object} data the data for the row if we're initializing a pre-existing row * @returns {void} */ initSelect: function (theNewRow, data) { var control = this, dropdown = theNewRow.container.find(".repeater-field select"), dataField; if (0 === dropdown.length) { return; } dataField = dropdown.data("field"); multiple = jQuery(dropdown).data("multiple"); data = data || {}; data[dataField] = data[dataField] || ""; jQuery(dropdown).val(data[dataField] || jQuery(dropdown).val()); this.container.on("change", ".repeater-field select", function (event) { var currentDropdown = jQuery(event.target), row = currentDropdown.closest(".repeater-row"), rowIndex = row.data("row"), currentSettings = control.getValue(); currentSettings[rowIndex][currentDropdown.data("field")] = jQuery(this).val(); control.setValue(currentSettings); }); }, }); PK,[pY^^src/Settings/Repeater.phpnu[id}", [ $this, 'sanitize_repeater_setting' ], 10, 1 ); } /** * Fetch the value of the setting. * * @access public * @since 1.0 * @return mixed The value. */ public function value() { return (array) parent::value(); } /** * Convert the JSON encoded setting coming from Customizer to an Array. * * @access public * @since 1.0 * @param string $value URL Encoded JSON Value. * @return array */ public function sanitize_repeater_setting( $value ) { if ( ! is_array( $value ) ) { $value = json_decode( urldecode( $value ) ); } if ( empty( $value ) || ! is_array( $value ) ) { $value = []; } // Make sure that every row is an array, not an object. foreach ( $value as $key => $val ) { $value[ $key ] = (array) $val; if ( empty( $val ) ) { unset( $value[ $key ] ); } } // Reindex array. if ( is_array( $value ) ) { $value = array_values( $value ); } return $value; } } PK,[C## composer.jsonnu[{ "name": "kirki-framework/control-repeater", "type": "library", "version": "1.0.5", "description": "Repeater control for the Kirki Customizer framework.", "keywords": [ "wordpress", "customizer", "framework" ], "homepage": "https://kirki.org/", "license": "MIT", "authors": [ { "name": "Kirki Framework", "email": "connect@mapsteps.com" } ], "require": { "php": ">=7.0", "kirki-framework/url-getter": "*", "kirki-framework/control-generic": "*", "kirki-framework/control-select": "*", "kirki-framework/control-checkbox": "*", "kirki-framework/control-radio": "*", "kirki-framework/control-color": "*", "kirki-framework/control-image": "*", "kirki-framework/control-upload": "*" }, "autoload": { "psr-4": { "Kirki\\Control\\": "src/Control", "Kirki\\Field\\": "src/Field", "Kirki\\Settings\\": "src/Settings" } } } PK,[ln00LICENSEnu[MIT License Copyright (c) 2019 kirki-framework Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. PK,[I!dist/wp-color-picker-alpha.min.jsnu[PK,[ҷ,, dist/control.jsnu[PK,[!jIX X Hdist/control.cssnu[PK,[pDUdist/control.js.mapnu[PK,[5ӡ%%rdist/control.css.mapnu[PK,[ʻ\ src/Field/Repeater.phpnu[PK,[i~eBPBP]3src/Control/Repeater.phpnu[PK,[/jjsrc/control.jsnu[PK,[pY^^src/Settings/Repeater.phpnu[PK,[C## composer.jsonnu[PK,[ln00LICENSEnu[PK W