You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1324 lines
36 KiB
JavaScript

;(function (t) {
var e =
(typeof self == 'object' && self.self === self && self) ||
(typeof global == 'object' && global.global === global && global)
if (typeof define === 'function' && define.amd) {
define(['underscore', 'jquery', 'exports'], function (i, n, r) {
e.Backbone = t(e, r, i, n)
})
} else if (typeof exports !== 'undefined') {
var i = require('underscore'),
n
try {
n = require('jquery')
} catch (r) {}
t(e, exports, i, n)
} else {
e.Backbone = t(e, {}, e._, e.jQuery || e.Zepto || e.ender || e.$)
}
})(function (t, e, i, n) {
var r = t.Backbone
var s = Array.prototype.slice
e.VERSION = '1.4.0'
e.$ = n
e.noConflict = function () {
t.Backbone = r
return this
}
e.emulateHTTP = false
e.emulateJSON = false
var a = (e.Events = {})
var o = /\s+/
var h
var u = function (t, e, n, r, s) {
var a = 0,
h
if (n && typeof n === 'object') {
if (r !== void 0 && 'context' in s && s.context === void 0) s.context = r
for (h = i.keys(n); a < h.length; a++) {
e = u(t, e, h[a], n[h[a]], s)
}
} else if (n && o.test(n)) {
for (h = n.split(o); a < h.length; a++) {
e = t(e, h[a], r, s)
}
} else {
e = t(e, n, r, s)
}
return e
}
a.on = function (t, e, i) {
this._events = u(l, this._events || {}, t, e, { context: i, ctx: this, listening: h })
if (h) {
var n = this._listeners || (this._listeners = {})
n[h.id] = h
h.interop = false
}
return this
}
a.listenTo = function (t, e, n) {
if (!t) return this
var r = t._listenId || (t._listenId = i.uniqueId('l'))
var s = this._listeningTo || (this._listeningTo = {})
var a = (h = s[r])
if (!a) {
this._listenId || (this._listenId = i.uniqueId('l'))
a = h = s[r] = new g(this, t)
}
var o = c(t, e, n, this)
h = void 0
if (o) throw o
if (a.interop) a.on(e, n)
return this
}
var l = function (t, e, i, n) {
if (i) {
var r = t[e] || (t[e] = [])
var s = n.context,
a = n.ctx,
o = n.listening
if (o) o.count++
r.push({ callback: i, context: s, ctx: s || a, listening: o })
}
return t
}
var c = function (t, e, i, n) {
try {
t.on(e, i, n)
} catch (r) {
return r
}
}
a.off = function (t, e, i) {
if (!this._events) return this
this._events = u(f, this._events, t, e, { context: i, listeners: this._listeners })
return this
}
a.stopListening = function (t, e, n) {
var r = this._listeningTo
if (!r) return this
var s = t ? [t._listenId] : i.keys(r)
for (var a = 0; a < s.length; a++) {
var o = r[s[a]]
if (!o) break
o.obj.off(e, n, this)
if (o.interop) o.off(e, n)
}
if (i.isEmpty(r)) this._listeningTo = void 0
return this
}
var f = function (t, e, n, r) {
if (!t) return
var s = r.context,
a = r.listeners
var o = 0,
h
if (!e && !s && !n) {
for (h = i.keys(a); o < h.length; o++) {
a[h[o]].cleanup()
}
return
}
h = e ? [e] : i.keys(t)
for (; o < h.length; o++) {
e = h[o]
var u = t[e]
if (!u) break
var l = []
for (var c = 0; c < u.length; c++) {
var f = u[c]
if ((n && n !== f.callback && n !== f.callback._callback) || (s && s !== f.context)) {
l.push(f)
} else {
var d = f.listening
if (d) d.off(e, n)
}
}
if (l.length) {
t[e] = l
} else {
delete t[e]
}
}
return t
}
a.once = function (t, e, i) {
var n = u(d, {}, t, e, this.off.bind(this))
if (typeof t === 'string' && i == null) e = void 0
return this.on(n, e, i)
}
a.listenToOnce = function (t, e, i) {
var n = u(d, {}, e, i, this.stopListening.bind(this, t))
return this.listenTo(t, n)
}
var d = function (t, e, n, r) {
if (n) {
var s = (t[e] = i.once(function () {
r(e, s)
n.apply(this, arguments)
}))
s._callback = n
}
return t
}
a.trigger = function (t) {
if (!this._events) return this
var e = Math.max(0, arguments.length - 1)
var i = Array(e)
for (var n = 0; n < e; n++) i[n] = arguments[n + 1]
u(v, this._events, t, void 0, i)
return this
}
var v = function (t, e, i, n) {
if (t) {
var r = t[e]
var s = t.all
if (r && s) s = s.slice()
if (r) p(r, n)
if (s) p(s, [e].concat(n))
}
return t
}
var p = function (t, e) {
var i,
n = -1,
r = t.length,
s = e[0],
a = e[1],
o = e[2]
switch (e.length) {
case 0:
while (++n < r) (i = t[n]).callback.call(i.ctx)
return
case 1:
while (++n < r) (i = t[n]).callback.call(i.ctx, s)
return
case 2:
while (++n < r) (i = t[n]).callback.call(i.ctx, s, a)
return
case 3:
while (++n < r) (i = t[n]).callback.call(i.ctx, s, a, o)
return
default:
while (++n < r) (i = t[n]).callback.apply(i.ctx, e)
return
}
}
var g = function (t, e) {
this.id = t._listenId
this.listener = t
this.obj = e
this.interop = true
this.count = 0
this._events = void 0
}
g.prototype.on = a.on
g.prototype.off = function (t, e) {
var i
if (this.interop) {
this._events = u(f, this._events, t, e, { context: void 0, listeners: void 0 })
i = !this._events
} else {
this.count--
i = this.count === 0
}
if (i) this.cleanup()
}
g.prototype.cleanup = function () {
delete this.listener._listeningTo[this.obj._listenId]
if (!this.interop) delete this.obj._listeners[this.id]
}
a.bind = a.on
a.unbind = a.off
i.extend(e, a)
var m = (e.Model = function (t, e) {
var n = t || {}
e || (e = {})
this.preinitialize.apply(this, arguments)
this.cid = i.uniqueId(this.cidPrefix)
this.attributes = {}
if (e.collection) this.collection = e.collection
if (e.parse) n = this.parse(n, e) || {}
var r = i.result(this, 'defaults')
n = i.defaults(i.extend({}, r, n), r)
this.set(n, e)
this.changed = {}
this.initialize.apply(this, arguments)
})
i.extend(m.prototype, a, {
changed: null,
validationError: null,
idAttribute: 'id',
cidPrefix: 'c',
preinitialize: function () {},
initialize: function () {},
toJSON: function (t) {
return i.clone(this.attributes)
},
sync: function () {
return e.sync.apply(this, arguments)
},
get: function (t) {
return this.attributes[t]
},
escape: function (t) {
return i.escape(this.get(t))
},
has: function (t) {
return this.get(t) != null
},
matches: function (t) {
return !!i.iteratee(t, this)(this.attributes)
},
set: function (t, e, n) {
if (t == null) return this
var r
if (typeof t === 'object') {
r = t
n = e
} else {
;(r = {})[t] = e
}
n || (n = {})
if (!this._validate(r, n)) return false
var s = n.unset
var a = n.silent
var o = []
var h = this._changing
this._changing = true
if (!h) {
this._previousAttributes = i.clone(this.attributes)
this.changed = {}
}
var u = this.attributes
var l = this.changed
var c = this._previousAttributes
for (var f in r) {
e = r[f]
if (!i.isEqual(u[f], e)) o.push(f)
if (!i.isEqual(c[f], e)) {
l[f] = e
} else {
delete l[f]
}
s ? delete u[f] : (u[f] = e)
}
if (this.idAttribute in r) this.id = this.get(this.idAttribute)
if (!a) {
if (o.length) this._pending = n
for (var d = 0; d < o.length; d++) {
this.trigger('change:' + o[d], this, u[o[d]], n)
}
}
if (h) return this
if (!a) {
while (this._pending) {
n = this._pending
this._pending = false
this.trigger('change', this, n)
}
}
this._pending = false
this._changing = false
return this
},
unset: function (t, e) {
return this.set(t, void 0, i.extend({}, e, { unset: true }))
},
clear: function (t) {
var e = {}
for (var n in this.attributes) e[n] = void 0
return this.set(e, i.extend({}, t, { unset: true }))
},
hasChanged: function (t) {
if (t == null) return !i.isEmpty(this.changed)
return i.has(this.changed, t)
},
changedAttributes: function (t) {
if (!t) return this.hasChanged() ? i.clone(this.changed) : false
var e = this._changing ? this._previousAttributes : this.attributes
var n = {}
var r
for (var s in t) {
var a = t[s]
if (i.isEqual(e[s], a)) continue
n[s] = a
r = true
}
return r ? n : false
},
previous: function (t) {
if (t == null || !this._previousAttributes) return null
return this._previousAttributes[t]
},
previousAttributes: function () {
return i.clone(this._previousAttributes)
},
fetch: function (t) {
t = i.extend({ parse: true }, t)
var e = this
var n = t.success
t.success = function (i) {
var r = t.parse ? e.parse(i, t) : i
if (!e.set(r, t)) return false
if (n) n.call(t.context, e, i, t)
e.trigger('sync', e, i, t)
}
G(this, t)
return this.sync('read', this, t)
},
save: function (t, e, n) {
var r
if (t == null || typeof t === 'object') {
r = t
n = e
} else {
;(r = {})[t] = e
}
n = i.extend({ validate: true, parse: true }, n)
var s = n.wait
if (r && !s) {
if (!this.set(r, n)) return false
} else if (!this._validate(r, n)) {
return false
}
var a = this
var o = n.success
var h = this.attributes
n.success = function (t) {
a.attributes = h
var e = n.parse ? a.parse(t, n) : t
if (s) e = i.extend({}, r, e)
if (e && !a.set(e, n)) return false
if (o) o.call(n.context, a, t, n)
a.trigger('sync', a, t, n)
}
G(this, n)
if (r && s) this.attributes = i.extend({}, h, r)
var u = this.isNew() ? 'create' : n.patch ? 'patch' : 'update'
if (u === 'patch' && !n.attrs) n.attrs = r
var l = this.sync(u, this, n)
this.attributes = h
return l
},
destroy: function (t) {
t = t ? i.clone(t) : {}
var e = this
var n = t.success
var r = t.wait
var s = function () {
e.stopListening()
e.trigger('destroy', e, e.collection, t)
}
t.success = function (i) {
if (r) s()
if (n) n.call(t.context, e, i, t)
if (!e.isNew()) e.trigger('sync', e, i, t)
}
var a = false
if (this.isNew()) {
i.defer(t.success)
} else {
G(this, t)
a = this.sync('delete', this, t)
}
if (!r) s()
return a
},
url: function () {
var t = i.result(this, 'urlRoot') || i.result(this.collection, 'url') || V()
if (this.isNew()) return t
var e = this.get(this.idAttribute)
return t.replace(/[^\/]$/, '$&/') + encodeURIComponent(e)
},
parse: function (t, e) {
return t
},
clone: function () {
return new this.constructor(this.attributes)
},
isNew: function () {
return !this.has(this.idAttribute)
},
isValid: function (t) {
return this._validate({}, i.extend({}, t, { validate: true }))
},
_validate: function (t, e) {
if (!e.validate || !this.validate) return true
t = i.extend({}, this.attributes, t)
var n = (this.validationError = this.validate(t, e) || null)
if (!n) return true
this.trigger('invalid', this, n, i.extend(e, { validationError: n }))
return false
},
})
var _ = (e.Collection = function (t, e) {
e || (e = {})
this.preinitialize.apply(this, arguments)
if (e.model) this.model = e.model
if (e.comparator !== void 0) this.comparator = e.comparator
this._reset()
this.initialize.apply(this, arguments)
if (t) this.reset(t, i.extend({ silent: true }, e))
})
var y = { add: true, remove: true, merge: true }
var b = { add: true, remove: false }
var x = function (t, e, i) {
i = Math.min(Math.max(i, 0), t.length)
var n = Array(t.length - i)
var r = e.length
var s
for (s = 0; s < n.length; s++) n[s] = t[s + i]
for (s = 0; s < r; s++) t[s + i] = e[s]
for (s = 0; s < n.length; s++) t[s + r + i] = n[s]
}
i.extend(_.prototype, a, {
model: m,
preinitialize: function () {},
initialize: function () {},
toJSON: function (t) {
return this.map(function (e) {
return e.toJSON(t)
})
},
sync: function () {
return e.sync.apply(this, arguments)
},
add: function (t, e) {
return this.set(t, i.extend({ merge: false }, e, b))
},
remove: function (t, e) {
e = i.extend({}, e)
var n = !i.isArray(t)
t = n ? [t] : t.slice()
var r = this._removeModels(t, e)
if (!e.silent && r.length) {
e.changes = { added: [], merged: [], removed: r }
this.trigger('update', this, e)
}
return n ? r[0] : r
},
set: function (t, e) {
if (t == null) return
e = i.extend({}, y, e)
if (e.parse && !this._isModel(t)) {
t = this.parse(t, e) || []
}
var n = !i.isArray(t)
t = n ? [t] : t.slice()
var r = e.at
if (r != null) r = +r
if (r > this.length) r = this.length
if (r < 0) r += this.length + 1
var s = []
var a = []
var o = []
var h = []
var u = {}
var l = e.add
var c = e.merge
var f = e.remove
var d = false
var v = this.comparator && r == null && e.sort !== false
var p = i.isString(this.comparator) ? this.comparator : null
var g, m
for (m = 0; m < t.length; m++) {
g = t[m]
var _ = this.get(g)
if (_) {
if (c && g !== _) {
var b = this._isModel(g) ? g.attributes : g
if (e.parse) b = _.parse(b, e)
_.set(b, e)
o.push(_)
if (v && !d) d = _.hasChanged(p)
}
if (!u[_.cid]) {
u[_.cid] = true
s.push(_)
}
t[m] = _
} else if (l) {
g = t[m] = this._prepareModel(g, e)
if (g) {
a.push(g)
this._addReference(g, e)
u[g.cid] = true
s.push(g)
}
}
}
if (f) {
for (m = 0; m < this.length; m++) {
g = this.models[m]
if (!u[g.cid]) h.push(g)
}
if (h.length) this._removeModels(h, e)
}
var w = false
var E = !v && l && f
if (s.length && E) {
w =
this.length !== s.length ||
i.some(this.models, function (t, e) {
return t !== s[e]
})
this.models.length = 0
x(this.models, s, 0)
this.length = this.models.length
} else if (a.length) {
if (v) d = true
x(this.models, a, r == null ? this.length : r)
this.length = this.models.length
}
if (d) this.sort({ silent: true })
if (!e.silent) {
for (m = 0; m < a.length; m++) {
if (r != null) e.index = r + m
g = a[m]
g.trigger('add', g, this, e)
}
if (d || w) this.trigger('sort', this, e)
if (a.length || h.length || o.length) {
e.changes = { added: a, removed: h, merged: o }
this.trigger('update', this, e)
}
}
return n ? t[0] : t
},
reset: function (t, e) {
e = e ? i.clone(e) : {}
for (var n = 0; n < this.models.length; n++) {
this._removeReference(this.models[n], e)
}
e.previousModels = this.models
this._reset()
t = this.add(t, i.extend({ silent: true }, e))
if (!e.silent) this.trigger('reset', this, e)
return t
},
push: function (t, e) {
return this.add(t, i.extend({ at: this.length }, e))
},
pop: function (t) {
var e = this.at(this.length - 1)
return this.remove(e, t)
},
unshift: function (t, e) {
return this.add(t, i.extend({ at: 0 }, e))
},
shift: function (t) {
var e = this.at(0)
return this.remove(e, t)
},
slice: function () {
return s.apply(this.models, arguments)
},
get: function (t) {
if (t == null) return void 0
return (
this._byId[t] ||
this._byId[this.modelId(this._isModel(t) ? t.attributes : t)] ||
(t.cid && this._byId[t.cid])
)
},
has: function (t) {
return this.get(t) != null
},
at: function (t) {
if (t < 0) t += this.length
return this.models[t]
},
where: function (t, e) {
return this[e ? 'find' : 'filter'](t)
},
findWhere: function (t) {
return this.where(t, true)
},
sort: function (t) {
var e = this.comparator
if (!e) throw new Error('Cannot sort a set without a comparator')
t || (t = {})
var n = e.length
if (i.isFunction(e)) e = e.bind(this)
if (n === 1 || i.isString(e)) {
this.models = this.sortBy(e)
} else {
this.models.sort(e)
}
if (!t.silent) this.trigger('sort', this, t)
return this
},
pluck: function (t) {
return this.map(t + '')
},
fetch: function (t) {
t = i.extend({ parse: true }, t)
var e = t.success
var n = this
t.success = function (i) {
var r = t.reset ? 'reset' : 'set'
n[r](i, t)
if (e) e.call(t.context, n, i, t)
n.trigger('sync', n, i, t)
}
G(this, t)
return this.sync('read', this, t)
},
create: function (t, e) {
e = e ? i.clone(e) : {}
var n = e.wait
t = this._prepareModel(t, e)
if (!t) return false
if (!n) this.add(t, e)
var r = this
var s = e.success
e.success = function (t, e, i) {
if (n) r.add(t, i)
if (s) s.call(i.context, t, e, i)
}
t.save(null, e)
return t
},
parse: function (t, e) {
return t
},
clone: function () {
return new this.constructor(this.models, { model: this.model, comparator: this.comparator })
},
modelId: function (t) {
return t[this.model.prototype.idAttribute || 'id']
},
values: function () {
return new E(this, k)
},
keys: function () {
return new E(this, I)
},
entries: function () {
return new E(this, S)
},
_reset: function () {
this.length = 0
this.models = []
this._byId = {}
},
_prepareModel: function (t, e) {
if (this._isModel(t)) {
if (!t.collection) t.collection = this
return t
}
e = e ? i.clone(e) : {}
e.collection = this
var n = new this.model(t, e)
if (!n.validationError) return n
this.trigger('invalid', this, n.validationError, e)
return false
},
_removeModels: function (t, e) {
var i = []
for (var n = 0; n < t.length; n++) {
var r = this.get(t[n])
if (!r) continue
var s = this.indexOf(r)
this.models.splice(s, 1)
this.length--
delete this._byId[r.cid]
var a = this.modelId(r.attributes)
if (a != null) delete this._byId[a]
if (!e.silent) {
e.index = s
r.trigger('remove', r, this, e)
}
i.push(r)
this._removeReference(r, e)
}
return i
},
_isModel: function (t) {
return t instanceof m
},
_addReference: function (t, e) {
this._byId[t.cid] = t
var i = this.modelId(t.attributes)
if (i != null) this._byId[i] = t
t.on('all', this._onModelEvent, this)
},
_removeReference: function (t, e) {
delete this._byId[t.cid]
var i = this.modelId(t.attributes)
if (i != null) delete this._byId[i]
if (this === t.collection) delete t.collection
t.off('all', this._onModelEvent, this)
},
_onModelEvent: function (t, e, i, n) {
if (e) {
if ((t === 'add' || t === 'remove') && i !== this) return
if (t === 'destroy') this.remove(e, n)
if (t === 'change') {
var r = this.modelId(e.previousAttributes())
var s = this.modelId(e.attributes)
if (r !== s) {
if (r != null) delete this._byId[r]
if (s != null) this._byId[s] = e
}
}
}
this.trigger.apply(this, arguments)
},
})
var w = typeof Symbol === 'function' && Symbol.iterator
if (w) {
_.prototype[w] = _.prototype.values
}
var E = function (t, e) {
this._collection = t
this._kind = e
this._index = 0
}
var k = 1
var I = 2
var S = 3
if (w) {
E.prototype[w] = function () {
return this
}
}
E.prototype.next = function () {
if (this._collection) {
if (this._index < this._collection.length) {
var t = this._collection.at(this._index)
this._index++
var e
if (this._kind === k) {
e = t
} else {
var i = this._collection.modelId(t.attributes)
if (this._kind === I) {
e = i
} else {
e = [i, t]
}
}
return { value: e, done: false }
}
this._collection = void 0
}
return { value: void 0, done: true }
}
var T = (e.View = function (t) {
this.cid = i.uniqueId('view')
this.preinitialize.apply(this, arguments)
i.extend(this, i.pick(t, H))
this._ensureElement()
this.initialize.apply(this, arguments)
})
var P = /^(\S+)\s*(.*)$/
var H = ['model', 'collection', 'el', 'id', 'attributes', 'className', 'tagName', 'events']
i.extend(T.prototype, a, {
tagName: 'div',
$: function (t) {
return this.$el.find(t)
},
preinitialize: function () {},
initialize: function () {},
render: function () {
return this
},
remove: function () {
this._removeElement()
this.stopListening()
return this
},
_removeElement: function () {
this.$el.remove()
},
setElement: function (t) {
this.undelegateEvents()
this._setElement(t)
this.delegateEvents()
return this
},
_setElement: function (t) {
this.$el = t instanceof e.$ ? t : e.$(t)
this.el = this.$el[0]
},
delegateEvents: function (t) {
t || (t = i.result(this, 'events'))
if (!t) return this
this.undelegateEvents()
for (var e in t) {
var n = t[e]
if (!i.isFunction(n)) n = this[n]
if (!n) continue
var r = e.match(P)
this.delegate(r[1], r[2], n.bind(this))
}
return this
},
delegate: function (t, e, i) {
this.$el.on(t + '.delegateEvents' + this.cid, e, i)
return this
},
undelegateEvents: function () {
if (this.$el) this.$el.off('.delegateEvents' + this.cid)
return this
},
undelegate: function (t, e, i) {
this.$el.off(t + '.delegateEvents' + this.cid, e, i)
return this
},
_createElement: function (t) {
return document.createElement(t)
},
_ensureElement: function () {
if (!this.el) {
var t = i.extend({}, i.result(this, 'attributes'))
if (this.id) t.id = i.result(this, 'id')
if (this.className) t['class'] = i.result(this, 'className')
this.setElement(this._createElement(i.result(this, 'tagName')))
this._setAttributes(t)
} else {
this.setElement(i.result(this, 'el'))
}
},
_setAttributes: function (t) {
this.$el.attr(t)
},
})
var $ = function (t, e, i, n) {
switch (e) {
case 1:
return function () {
return t[i](this[n])
}
case 2:
return function (e) {
return t[i](this[n], e)
}
case 3:
return function (e, r) {
return t[i](this[n], C(e, this), r)
}
case 4:
return function (e, r, s) {
return t[i](this[n], C(e, this), r, s)
}
default:
return function () {
var e = s.call(arguments)
e.unshift(this[n])
return t[i].apply(t, e)
}
}
}
var A = function (t, e, n, r) {
i.each(n, function (i, n) {
if (e[n]) t.prototype[n] = $(e, i, n, r)
})
}
var C = function (t, e) {
if (i.isFunction(t)) return t
if (i.isObject(t) && !e._isModel(t)) return R(t)
if (i.isString(t))
return function (e) {
return e.get(t)
}
return t
}
var R = function (t) {
var e = i.matches(t)
return function (t) {
return e(t.attributes)
}
}
var M = {
forEach: 3,
each: 3,
map: 3,
collect: 3,
reduce: 0,
foldl: 0,
inject: 0,
reduceRight: 0,
foldr: 0,
find: 3,
detect: 3,
filter: 3,
select: 3,
reject: 3,
every: 3,
all: 3,
some: 3,
any: 3,
include: 3,
includes: 3,
contains: 3,
invoke: 0,
max: 3,
min: 3,
toArray: 1,
size: 1,
first: 3,
head: 3,
take: 3,
initial: 3,
rest: 3,
tail: 3,
drop: 3,
last: 3,
without: 0,
difference: 0,
indexOf: 3,
shuffle: 1,
lastIndexOf: 3,
isEmpty: 1,
chain: 1,
sample: 3,
partition: 3,
groupBy: 3,
countBy: 3,
sortBy: 3,
indexBy: 3,
findIndex: 3,
findLastIndex: 3,
}
var N = { keys: 1, values: 1, pairs: 1, invert: 1, pick: 0, omit: 0, chain: 1, isEmpty: 1 }
i.each(
[
[_, M, 'models'],
[m, N, 'attributes'],
],
function (t) {
var e = t[0],
n = t[1],
r = t[2]
e.mixin = function (t) {
var n = i.reduce(
i.functions(t),
function (t, e) {
t[e] = 0
return t
},
{},
)
A(e, t, n, r)
}
A(e, i, n, r)
},
)
e.sync = function (t, n, r) {
var s = j[t]
i.defaults(r || (r = {}), { emulateHTTP: e.emulateHTTP, emulateJSON: e.emulateJSON })
var a = { type: s, dataType: 'json' }
if (!r.url) {
a.url = i.result(n, 'url') || V()
}
if (r.data == null && n && (t === 'create' || t === 'update' || t === 'patch')) {
a.contentType = 'application/json'
a.data = JSON.stringify(r.attrs || n.toJSON(r))
}
if (r.emulateJSON) {
a.contentType = 'application/x-www-form-urlencoded'
a.data = a.data ? { model: a.data } : {}
}
if (r.emulateHTTP && (s === 'PUT' || s === 'DELETE' || s === 'PATCH')) {
a.type = 'POST'
if (r.emulateJSON) a.data._method = s
var o = r.beforeSend
r.beforeSend = function (t) {
t.setRequestHeader('X-HTTP-Method-Override', s)
if (o) return o.apply(this, arguments)
}
}
if (a.type !== 'GET' && !r.emulateJSON) {
a.processData = false
}
var h = r.error
r.error = function (t, e, i) {
r.textStatus = e
r.errorThrown = i
if (h) h.call(r.context, t, e, i)
}
var u = (r.xhr = e.ajax(i.extend(a, r)))
n.trigger('request', n, u, r)
return u
}
var j = { create: 'POST', update: 'PUT', patch: 'PATCH', delete: 'DELETE', read: 'GET' }
e.ajax = function () {
return e.$.ajax.apply(e.$, arguments)
}
var O = (e.Router = function (t) {
t || (t = {})
this.preinitialize.apply(this, arguments)
if (t.routes) this.routes = t.routes
this._bindRoutes()
this.initialize.apply(this, arguments)
})
var U = /\((.*?)\)/g
var z = /(\(\?)?:\w+/g
var q = /\*\w+/g
var F = /[\-{}\[\]+?.,\\\^$|#\s]/g
i.extend(O.prototype, a, {
preinitialize: function () {},
initialize: function () {},
route: function (t, n, r) {
if (!i.isRegExp(t)) t = this._routeToRegExp(t)
if (i.isFunction(n)) {
r = n
n = ''
}
if (!r) r = this[n]
var s = this
e.history.route(t, function (i) {
var a = s._extractParameters(t, i)
if (s.execute(r, a, n) !== false) {
s.trigger.apply(s, ['route:' + n].concat(a))
s.trigger('route', n, a)
e.history.trigger('route', s, n, a)
}
})
return this
},
execute: function (t, e, i) {
if (t) t.apply(this, e)
},
navigate: function (t, i) {
e.history.navigate(t, i)
return this
},
_bindRoutes: function () {
if (!this.routes) return
this.routes = i.result(this, 'routes')
var t,
e = i.keys(this.routes)
while ((t = e.pop()) != null) {
this.route(t, this.routes[t])
}
},
_routeToRegExp: function (t) {
t = t
.replace(F, '\\$&')
.replace(U, '(?:$1)?')
.replace(z, function (t, e) {
return e ? t : '([^/?]+)'
})
.replace(q, '([^?]*?)')
return new RegExp('^' + t + '(?:\\?([\\s\\S]*))?$')
},
_extractParameters: function (t, e) {
var n = t.exec(e).slice(1)
return i.map(n, function (t, e) {
if (e === n.length - 1) return t || null
return t ? decodeURIComponent(t) : null
})
},
})
var B = (e.History = function () {
this.handlers = []
this.checkUrl = this.checkUrl.bind(this)
if (typeof window !== 'undefined') {
this.location = window.location
this.history = window.history
}
})
var J = /^[#\/]|\s+$/g
var L = /^\/+|\/+$/g
var W = /#.*$/
B.started = false
i.extend(B.prototype, a, {
interval: 50,
atRoot: function () {
var t = this.location.pathname.replace(/[^\/]$/, '$&/')
return t === this.root && !this.getSearch()
},
matchRoot: function () {
var t = this.decodeFragment(this.location.pathname)
var e = t.slice(0, this.root.length - 1) + '/'
return e === this.root
},
decodeFragment: function (t) {
return decodeURI(t.replace(/%25/g, '%2525'))
},
getSearch: function () {
var t = this.location.href.replace(/#.*/, '').match(/\?.+/)
return t ? t[0] : ''
},
getHash: function (t) {
var e = (t || this).location.href.match(/#(.*)$/)
return e ? e[1] : ''
},
getPath: function () {
var t = this.decodeFragment(this.location.pathname + this.getSearch()).slice(
this.root.length - 1,
)
return t.charAt(0) === '/' ? t.slice(1) : t
},
getFragment: function (t) {
if (t == null) {
if (this._usePushState || !this._wantsHashChange) {
t = this.getPath()
} else {
t = this.getHash()
}
}
return t.replace(J, '')
},
start: function (t) {
if (B.started) throw new Error('Backbone.history has already been started')
B.started = true
this.options = i.extend({ root: '/' }, this.options, t)
this.root = this.options.root
this._wantsHashChange = this.options.hashChange !== false
this._hasHashChange =
'onhashchange' in window && (document.documentMode === void 0 || document.documentMode > 7)
this._useHashChange = this._wantsHashChange && this._hasHashChange
this._wantsPushState = !!this.options.pushState
this._hasPushState = !!(this.history && this.history.pushState)
this._usePushState = this._wantsPushState && this._hasPushState
this.fragment = this.getFragment()
this.root = ('/' + this.root + '/').replace(L, '/')
if (this._wantsHashChange && this._wantsPushState) {
if (!this._hasPushState && !this.atRoot()) {
var e = this.root.slice(0, -1) || '/'
this.location.replace(e + '#' + this.getPath())
return true
} else if (this._hasPushState && this.atRoot()) {
this.navigate(this.getHash(), { replace: true })
}
}
if (!this._hasHashChange && this._wantsHashChange && !this._usePushState) {
this.iframe = document.createElement('iframe')
this.iframe.src = 'javascript:0'
this.iframe.style.display = 'none'
this.iframe.tabIndex = -1
var n = document.body
var r = n.insertBefore(this.iframe, n.firstChild).contentWindow
r.document.open()
r.document.close()
r.location.hash = '#' + this.fragment
}
var s =
window.addEventListener ||
function (t, e) {
return attachEvent('on' + t, e)
}
if (this._usePushState) {
s('popstate', this.checkUrl, false)
} else if (this._useHashChange && !this.iframe) {
s('hashchange', this.checkUrl, false)
} else if (this._wantsHashChange) {
this._checkUrlInterval = setInterval(this.checkUrl, this.interval)
}
if (!this.options.silent) return this.loadUrl()
},
stop: function () {
var t =
window.removeEventListener ||
function (t, e) {
return detachEvent('on' + t, e)
}
if (this._usePushState) {
t('popstate', this.checkUrl, false)
} else if (this._useHashChange && !this.iframe) {
t('hashchange', this.checkUrl, false)
}
if (this.iframe) {
document.body.removeChild(this.iframe)
this.iframe = null
}
if (this._checkUrlInterval) clearInterval(this._checkUrlInterval)
B.started = false
},
route: function (t, e) {
this.handlers.unshift({ route: t, callback: e })
},
checkUrl: function (t) {
var e = this.getFragment()
if (e === this.fragment && this.iframe) {
e = this.getHash(this.iframe.contentWindow)
}
if (e === this.fragment) return false
if (this.iframe) this.navigate(e)
this.loadUrl()
},
loadUrl: function (t) {
if (!this.matchRoot()) return false
t = this.fragment = this.getFragment(t)
return i.some(this.handlers, function (e) {
if (e.route.test(t)) {
e.callback(t)
return true
}
})
},
navigate: function (t, e) {
if (!B.started) return false
if (!e || e === true) e = { trigger: !!e }
t = this.getFragment(t || '')
var i = this.root
if (t === '' || t.charAt(0) === '?') {
i = i.slice(0, -1) || '/'
}
var n = i + t
t = t.replace(W, '')
var r = this.decodeFragment(t)
if (this.fragment === r) return
this.fragment = r
if (this._usePushState) {
this.history[e.replace ? 'replaceState' : 'pushState']({}, document.title, n)
} else if (this._wantsHashChange) {
this._updateHash(this.location, t, e.replace)
if (this.iframe && t !== this.getHash(this.iframe.contentWindow)) {
var s = this.iframe.contentWindow
if (!e.replace) {
s.document.open()
s.document.close()
}
this._updateHash(s.location, t, e.replace)
}
} else {
return this.location.assign(n)
}
if (e.trigger) return this.loadUrl(t)
},
_updateHash: function (t, e, i) {
if (i) {
var n = t.href.replace(/(javascript:|#).*$/, '')
t.replace(n + '#' + e)
} else {
t.hash = '#' + e
}
},
})
e.history = new B()
var D = function (t, e) {
var n = this
var r
if (t && i.has(t, 'constructor')) {
r = t.constructor
} else {
r = function () {
return n.apply(this, arguments)
}
}
i.extend(r, n, e)
r.prototype = i.create(n.prototype, t)
r.prototype.constructor = r
r.__super__ = n.prototype
return r
}
m.extend = _.extend = O.extend = T.extend = B.extend = D
var V = function () {
throw new Error('A "url" property or function must be specified')
}
var G = function (t, e) {
var i = e.error
e.error = function (n) {
if (i) i.call(e.context, t, n, e)
t.trigger('error', t, n, e)
}
}
return e
})