window.wp = window.wp || {}, function (a, b) {
    var c, d, e = {}, f = Array.prototype.slice;
    c = function () {
    }, d = function (a, d, e) {
        var f;
        return f = d && d.hasOwnProperty("constructor") ? d.constructor : function () {
            var b = a.apply(this, arguments);
            return b
        }, b.extend(f, a), c.prototype = a.prototype, f.prototype = new c, d && b.extend(f.prototype, d), e && b.extend(f, e), f.prototype.constructor = f, f.__super__ = a.prototype, f
    }, e.Class = function (a, c, d) {
        var f, g = arguments;
        return a && c && e.Class.applicator === a && (g = c, b.extend(this, d || {})), f = this, this.instance && (f = function () {
            return f.instance.apply(f, arguments)
        }, b.extend(f, this)), f.initialize.apply(f, g), f
    }, e.Class.extend = function (a, b) {
        var c = d(this, a, b);
        return c.extend = this.extend, c
    }, e.Class.applicator = {}, e.Class.prototype.initialize = function () {
    }, e.Class.prototype.extended = function (a) {
        for (var b = this; "undefined" != typeof b.constructor;) {
            if (b.constructor === a)return !0;
            if ("undefined" == typeof b.constructor.__super__)return !1;
            b = b.constructor.__super__
        }
        return !1
    }, e.Events = {
        trigger: function (a) {
            return this.topics && this.topics[a] && this.topics[a].fireWith(this, f.call(arguments, 1)), this
        }, bind: function (a) {
            return this.topics = this.topics || {}, this.topics[a] = this.topics[a] || b.Callbacks(), this.topics[a].add.apply(this.topics[a], f.call(arguments, 1)), this
        }, unbind: function (a) {
            return this.topics && this.topics[a] && this.topics[a].remove.apply(this.topics[a], f.call(arguments, 1)), this
        }
    }, e.Value = e.Class.extend({
        initialize: function (a, c) {
            this._value = a, this.callbacks = b.Callbacks(), this._dirty = !1, b.extend(this, c || {}), this.set = b.proxy(this.set, this)
        }, instance: function () {
            return arguments.length ? this.set.apply(this, arguments) : this.get()
        }, get: function () {
            return this._value
        }, set: function (a) {
            var b = this._value;
            return a = this._setter.apply(this, arguments), a = this.validate(a), null === a || _.isEqual(b, a) ? this : (this._value = a, this._dirty = !0, this.callbacks.fireWith(this, [a, b]), this)
        }, _setter: function (a) {
            return a
        }, setter: function (a) {
            var b = this.get();
            return this._setter = a, this._value = null, this.set(b), this
        }, resetSetter: function () {
            return this._setter = this.constructor.prototype._setter, this.set(this.get()), this
        }, validate: function (a) {
            return a
        }, bind: function () {
            return this.callbacks.add.apply(this.callbacks, arguments), this
        }, unbind: function () {
            return this.callbacks.remove.apply(this.callbacks, arguments), this
        }, link: function () {
            var a = this.set;
            return b.each(arguments, function () {
                this.bind(a)
            }), this
        }, unlink: function () {
            var a = this.set;
            return b.each(arguments, function () {
                this.unbind(a)
            }), this
        }, sync: function () {
            var a = this;
            return b.each(arguments, function () {
                a.link(this), this.link(a)
            }), this
        }, unsync: function () {
            var a = this;
            return b.each(arguments, function () {
                a.unlink(this), this.unlink(a)
            }), this
        }
    }), e.Values = e.Class.extend({
        defaultConstructor: e.Value, initialize: function (a) {
            b.extend(this, a || {}), this._value = {}, this._deferreds = {}
        }, instance: function (a) {
            return 1 === arguments.length ? this.value(a) : this.when.apply(this, arguments)
        }, value: function (a) {
            return this._value[a]
        }, has: function (a) {
            return "undefined" != typeof this._value[a]
        }, add: function (a, b) {
            return this.has(a) ? this.value(a) : (this._value[a] = b, b.parent = this, b.extended(e.Value) && b.bind(this._change), this.trigger("add", b), this._deferreds[a] && this._deferreds[a].resolve(), this._value[a])
        }, create: function (a) {
            return this.add(a, new this.defaultConstructor(e.Class.applicator, f.call(arguments, 1)))
        }, each: function (a, c) {
            c = "undefined" == typeof c ? this : c, b.each(this._value, function (b, d) {
                a.call(c, d, b)
            })
        }, remove: function (a) {
            var b;
            this.has(a) && (b = this.value(a), this.trigger("remove", b), b.extended(e.Value) && b.unbind(this._change), delete b.parent), delete this._value[a], delete this._deferreds[a]
        }, when: function () {
            var a = this, c = f.call(arguments), d = b.Deferred();
            return b.isFunction(c[c.length - 1]) && d.done(c.pop()), b.when.apply(b, b.map(c, function (c) {
                return a.has(c) ? void 0 : a._deferreds[c] = a._deferreds[c] || b.Deferred()
            })).done(function () {
                var e = b.map(c, function (b) {
                    return a(b)
                });
                return e.length !== c.length ? void a.when.apply(a, c).done(function () {
                    d.resolveWith(a, e)
                }) : void d.resolveWith(a, e)
            }), d.promise()
        }, _change: function () {
            this.parent.trigger("change", this)
        }
    }), b.extend(e.Values.prototype, e.Events), e.ensure = function (a) {
        return "string" == typeof a ? b(a) : a
    }, e.Element = e.Value.extend({
        initialize: function (a, c) {
            var d, f, g, h = this, i = e.Element.synchronizer.html;
            this.element = e.ensure(a), this.events = "", this.element.is("input, select, textarea") && (this.events += "change", i = e.Element.synchronizer.val, this.element.is("input") ? (d = this.element.prop("type"), e.Element.synchronizer[d] && (i = e.Element.synchronizer[d]), "text" === d || "password" === d ? this.events += " keyup" : "range" === d && (this.events += " input propertychange")) : this.element.is("textarea") && (this.events += " keyup")), e.Value.prototype.initialize.call(this, null, b.extend(c || {}, i)), this._value = this.get(), f = this.update, g = this.refresh, this.update = function (a) {
                a !== g.call(h) && f.apply(this, arguments)
            }, this.refresh = function () {
                h.set(g.call(h))
            }, this.bind(this.update), this.element.bind(this.events, this.refresh)
        }, find: function (a) {
            return b(a, this.element)
        }, refresh: function () {
        }, update: function () {
        }
    }), e.Element.synchronizer = {}, b.each(["html", "val"], function (a, b) {
        e.Element.synchronizer[b] = {
            update: function (a) {
                this.element[b](a)
            }, refresh: function () {
                return this.element[b]()
            }
        }
    }), e.Element.synchronizer.checkbox = {
        update: function (a) {
            this.element.prop("checked", a)
        }, refresh: function () {
            return this.element.prop("checked")
        }
    }, e.Element.synchronizer.radio = {
        update: function (a) {
            this.element.filter(function () {
                return this.value === a
            }).prop("checked", !0)
        }, refresh: function () {
            return this.element.filter(":checked").val()
        }
    }, b.support.postMessage = !!window.postMessage, e.Messenger = e.Class.extend({
        add: function (a, b, c) {
            return this[a] = new e.Value(b, c)
        }, initialize: function (a, c) {
            var d = window.parent == window ? null : window.parent;
            b.extend(this, c || {}), this.add("channel", a.channel), this.add("url", a.url || ""), this.add("origin", this.url()).link(this.url).setter(function (a) {
                return a.replace(/([^:]+:\/\/[^\/]+).*/, "$1")
            }), this.add("targetWindow", null), this.targetWindow.set = function (a) {
                var b = this._value;
                return a = this._setter.apply(this, arguments), a = this.validate(a), null === a || b === a ? this : (this._value = a, this._dirty = !0, this.callbacks.fireWith(this, [a, b]), this)
            }, this.targetWindow(a.targetWindow || d), this.receive = b.proxy(this.receive, this), this.receive.guid = b.guid++, b(window).on("message", this.receive)
        }, destroy: function () {
            b(window).off("message", this.receive)
        }, receive: function (a) {
            var b;
            a = a.originalEvent, this.targetWindow() && (this.origin() && a.origin !== this.origin() || "string" == typeof a.data && "{" === a.data[0] && (b = JSON.parse(a.data), b && b.id && "undefined" != typeof b.data && (!b.channel && !this.channel() || this.channel() === b.channel) && this.trigger(b.id, b.data)))
        }, send: function (a, b) {
            var c;
            b = "undefined" == typeof b ? null : b, this.url() && this.targetWindow() && (c = {
                id: a,
                data: b
            }, this.channel() && (c.channel = this.channel()), this.targetWindow().postMessage(JSON.stringify(c), this.origin()))
        }
    }), b.extend(e.Messenger.prototype, e.Events), e = b.extend(new e.Values, e), e.get = function () {
        var a = {};
        return this.each(function (b, c) {
            a[c] = b.get()
        }), a
    }, a.customize = e
}(wp, jQuery);