Skip to content

Instantly share code, notes, and snippets.

@erichocean
Created February 16, 2010 22:18
Show Gist options
  • Save erichocean/306005 to your computer and use it in GitHub Desktop.
Save erichocean/306005 to your computer and use it in GitHub Desktop.
/* @license
==========================================================================
SproutCore Costello -- Property Observing Library
Copyright ©2006-2009, Sprout Systems, Inc. and contributors.
Portions copyright ©2008-2009 Apple Inc. All rights reserved.
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.
For more information about SproutCore, visit http://www.sproutcore.com
==========================================================================
@license */
var sys = require("sys");
var exports = exports || {};
var SC = SC || exports;
var SproutCore = SproutCore || SC;
var YES = true, NO = false;
var sc_require = sc_require || function() { };
var sc_resource = sc_resource || function sc_resource() {};
// set up console
SC.console = {
message: function(type, what) {
sys.puts(type + ": " + sys.inspect(what));
},
log: function(what){
this.message("LOG", what);
},
info: function(what){
this.message("INFO", what);
},
error: function(what){
this.message("ERROR", what);
},
warn: function(what){
this.message("WARN", what);
}
};
SC.root = GLOBAL;
SC.mixin = function() {
var e = arguments[0] || {};
var a = 1;
var d = arguments.length;
var b;
if (d === 1) {
e = this || {};
a = 0
}
for (; a < d; a++) {
if (! (b = arguments[a])) {
continue
}
for (var c in b) {
if (!b.hasOwnProperty(c)) {
continue
}
var f = b[c];
if (e === f) {
continue
}
if (f !== undefined) {
e[c] = f
}
}
}
return e
};
SC.supplement = function() {
var e = arguments[0] || {};
var a = 1;
var d = arguments.length;
var b;
if (d === 1) {
e = this || {};
a = 0
}
for (; a < d; a++) {
if (! (b = arguments[a])) {
continue
}
for (var c in b) {
if (!b.hasOwnProperty(c)) {
continue
}
var f = e[c];
var g = b[c];
if (e === g) {
continue
}
if (g !== undefined && f === undefined) {
e[c] = g
}
}
}
return e
};
SC.extend = SC.mixin;
SC.mixin({
T_ERROR: "error",
T_OBJECT: "object",
T_NULL: "null",
T_CLASS: "class",
T_HASH: "hash",
T_FUNCTION: "function",
T_UNDEFINED: "undefined",
T_NUMBER: "number",
T_BOOL: "boolean",
T_ARRAY: "array",
T_STRING: "string",
typeOf: function(b) {
if (b === undefined) {
return SC.T_UNDEFINED
}
if (b === null) {
return SC.T_NULL
}
var a = typeof(b);
if (a == "object") {
if (b instanceof Array) {
a = SC.T_ARRAY
} else {
if (b instanceof Function) {
a = b.isClass ? SC.T_CLASS: SC.T_FUNCTION
} else {
if (SC.Error && (b instanceof SC.Error)) {
a = SC.T_ERROR
} else {
if (b.isObject === true) {
a = SC.T_OBJECT
} else {
a = SC.T_HASH
}
}
}
}
} else {
if (a === SC.T_FUNCTION) {
a = (b.isClass) ? SC.T_CLASS: SC.T_FUNCTION
}
}
return a
},
none: function(a) {
return a === null || a === undefined
},
empty: function(a) {
return a === null || a === undefined || a === ""
},
isArray: function(c) {
if (c && c.objectAt) {
return YES
}
var a = (c ? c.length: null),
b = SC.typeOf(c);
return ! (SC.none(a) || (b === SC.T_FUNCTION) || (b === SC.T_STRING) || c.setInterval)
},
makeArray: function(a) {
return SC.isArray(a) ? a: SC.A(a)
},
A: function(c) {
if (SC.none(c)) {
return []
}
if (c.slice instanceof Function) {
if (typeof(c) === "string") {
return [c]
} else {
return c.slice()
}
}
if (c.toArray) {
return c.toArray()
}
if (!SC.isArray(c)) {
return [c]
}
var b = [],
a = c.length;
while (--a >= 0) {
b[a] = c[a]
}
return b
},
guidKey: "_sc_guid_" + new Date().getTime(),
_nextGUID: 0,
_numberGuids: [],
_stringGuids: {},
_keyCache: {},
guidFor: function(b) {
if (b === undefined) {
return "(undefined)"
}
if (b === null) {
return "(null)"
}
if (b === Object) {
return "(Object)"
}
if (b === Array) {
return "(Array)"
}
var a = this.guidKey;
if (b[a]) {
return b[a]
}
switch (typeof b) {
case SC.T_NUMBER:
return (this._numberGuids[b] = this._numberGuids[b] || ("nu" + b));
case SC.T_STRING:
return (this._stringGuids[b] = this._stringGuids[b] || ("st" + b));
case SC.T_BOOL:
return (b) ? "(true)": "(false)";
default:
return SC.generateGuid(b)
}
},
keyFor: function(d, c) {
var b,
a = this._keyCache[d];
if (!a) {
a = this._keyCache[d] = {}
}
b = a[c];
if (!b) {
b = a[c] = d + "_" + c
}
return b
},
generateGuid: function(b) {
var a = ("sc" + (this._nextGUID++));
if (b) {
b[this.guidKey] = a
}
return a
},
hashFor: function(a) {
return (a && a.hash && (typeof a.hash === SC.T_FUNCTION)) ? a.hash() : this.guidFor(a)
},
isEqual: function(d, c) {
if (d === null) {
return c === null
} else {
if (d === undefined) {
return c === undefined
} else {
return this.hashFor(d) === this.hashFor(c)
}
}
},
compare: function(h, g) {
var f = SC.typeOf(h);
var d = SC.typeOf(g);
var j = SC.ORDER_DEFINITION.indexOf(f);
var b = SC.ORDER_DEFINITION.indexOf(d);
if (j < b) {
return - 1
}
if (j > b) {
return 1
}
switch (f) {
case SC.T_BOOL:
case SC.T_NUMBER:
if (h < g) {
return - 1
}
if (h > g) {
return 1
}
return 0;
case SC.T_STRING:
if (h.localeCompare(g) < 0) {
return - 1
}
if (h.localeCompare(g) > 0) {
return 1
}
return 0;
case SC.T_ARRAY:
var c = Math.min(h.length, g.length);
var a = 0;
var e = 0;
while (a === 0 && e < c) {
a = arguments.callee(h[e], g[e]);
if (a !== 0) {
return a
}
e++
}
if (h.length < g.length) {
return - 1
}
if (h.length > g.length) {
return 1
}
return 0;
case SC.T_OBJECT:
if (h.constructor.isComparable === YES) {
return h.constructor.compare(h, g)
}
return 0;
default:
return 0
}
},
K: function() {
return this
},
EMPTY_ARRAY: [],
EMPTY_HASH: {},
EMPTY_RANGE: {
start: 0,
length: 0
},
beget: function(c) {
if (SC.none(c)) {
return null
}
var a = SC.K;
a.prototype = c;
var b = new a();
a.prototype = null;
if (SC.typeOf(c.didBeget) === SC.T_FUNCTION) {
b = c.didBeget(b)
}
return b
},
copy: function(b) {
var a = b;
if (b && b.isCopyable) {
return b.copy()
}
switch (SC.typeOf(b)) {
case SC.T_ARRAY:
if (b.clone && SC.typeOf(b.clone) === SC.T_FUNCTION) {
a = b.clone()
} else {
a = b.slice()
}
break;
case SC.T_HASH:
case SC.T_OBJECT:
if (b.clone && SC.typeOf(b.clone) === SC.T_FUNCTION) {
a = b.clone()
} else {
a = {};
for (var c in b) {
a[c] = b[c]
}
}
}
return a
},
merge: function() {
var c = {},
b = arguments.length,
a;
for (a = 0; a < b; a++) {
SC.mixin(c, arguments[a])
}
return c
},
keys: function(c) {
var a = [];
for (var b in c) {
a.push(b)
}
return a
},
inspect: function(d) {
var a,
b = [];
for (var c in d) {
a = d[c];
if (a === "toString") {
continue
}
if (SC.typeOf(a) === SC.T_FUNCTION) {
a = "function() { ... }"
}
b.push(c + ": " + a)
}
return "{" + b.join(" , ") + "}"
},
tupleForPropertyPath: function(e, a) {
if (SC.typeOf(e) === SC.T_ARRAY) {
return e
}
var c;
var b = e.indexOf("*");
if (b < 0) {
b = e.lastIndexOf(".")
}
c = (b >= 0) ? e.slice(b + 1) : e;
var d = this.objectForPropertyPath(e, a, b);
return (d && c) ? [d, c] : null
},
objectForPropertyPath: function(f, c, d) {
var g,
b,
e,
a;
if (!c) {
c = SC.root
}
if (SC.typeOf(f) === SC.T_STRING) {
if (d === undefined) {
d = f.length
}
g = 0;
while ((c) && (g < d)) {
b = f.indexOf(".", g);
if ((b < 0) || (b > d)) {
b = d
}
e = f.slice(g, b);
c = c.get ? c.get(e) : c[e];
g = b + 1
}
if (g < d) {
c = undefined
}
} else {
g = 0;
a = f.length;
e = null;
while ((g < a) && c) {
e = f[g++];
if (e) {
c = (c.get) ? c.get(e) : c[e]
}
}
if (g < a) {
c = undefined
}
}
return c
},
STRINGS: {},
stringsFor: function(b, a) {
SC.mixin(SC.STRINGS, a);
return this
}
});
SC.clone = SC.copy;
SC.$A = SC.A;
SC.didLoad = SC.K;
SC.ORDER_DEFINITION = [SC.T_ERROR, SC.T_UNDEFINED, SC.T_NULL, SC.T_BOOL, SC.T_NUMBER, SC.T_STRING, SC.T_ARRAY, SC.T_HASH, SC.T_OBJECT, SC.T_FUNCTION, SC.T_CLASS];
SC.mixin(Function.prototype, {
property: function() {
this.dependentKeys = SC.$A(arguments);
var a = SC.guidFor(this);
this.cacheKey = "__cache__" + a;
this.lastSetValueKey = "__lastValue__" + a;
this.isProperty = YES;
return this
},
cacheable: function(a) {
this.isProperty = YES;
if (!this.dependentKeys) {
this.dependentKeys = []
}
this.isCacheable = (a === undefined) ? YES: a;
return this
},
idempotent: function(a) {
this.isProperty = YES;
if (!this.dependentKeys) {
this.dependentKeys = []
}
this.isVolatile = (a === undefined) ? YES: a;
return this
},
observes: function(a) {
var e = arguments.length,
b = null,
d = null;
while (--e >= 0) {
var c = arguments[e];
if ((c.indexOf(".") < 0) && (c.indexOf("*") < 0)) {
if (!b) {
b = this.localPropertyPaths = []
}
b.push(c)
} else {
if (!d) {
d = this.propertyPaths = []
}
d.push(c)
}
}
return this
}
});
String.prototype.fmt = function() {
var b = arguments;
var a = 0;
return this.replace(/%@([0-9]+)?/g,
function(c, d) {
d = (d) ? parseInt(d, 0) - 1: a++;
c = b[d];
return ((c === null) ? "(null)": (c === undefined) ? "": c).toString()
})
};
String.prototype.loc = function() {
var a = SC.STRINGS[this] || this;
return a.fmt.apply(a, arguments)
};
String.prototype.w = function() {
var c = [],
d = this.split(" "),
b = d.length;
for (var a = 0; a < b; ++a) {
var e = d[a];
if (e.length !== 0) {
c.push(e)
}
}
return c
};
SC.ObserverSet = {
targets: 0,
_membersCacheIsValid: NO,
add: function(d, f, b) {
var c = (d) ? SC.guidFor(d) : "__this__";
var a = this[c];
if (!a) {
a = this[c] = SC.CoreSet.create();
a.target = d;
a.isTargetSet = YES;
this.targets++
}
a.add(f);
if (b !== undefined) {
var e = a.contexts;
if (!b) {
e = {}
}
e[SC.guidFor(f)] = b
}
this._membersCacheIsValid = NO
},
remove: function(c, d) {
var b = (c) ? SC.guidFor(c) : "__this__";
var a = this[b];
if (!a) {
return NO
}
a.remove(d);
if (a.length <= 0) {
a.target = null;
a.isTargetSet = NO;
a.contexts = null;
delete this[b];
this.targets--
} else {
if (a.contexts) {
delete a.contexts[SC.guidFor(d)]
}
}
this._membersCacheIsValid = NO;
return YES
},
invokeMethods: function() {
for (var b in this) {
if (!this.hasOwnProperty(b)) {
continue
}
var c = this[b];
if (c && c.isTargetSet) {
var a = c.length;
var d = c.target;
while (--a >= 0) {
c[a].call(d)
}
}
}
},
getMembers: function() {
if (this._membersCacheIsValid) {
return this._members
}
if (!this._members) {
this._members = []
} else {
this._members.length = 0
}
var b = this._members;
for (var c in this) {
if (!this.hasOwnProperty(c)) {
continue
}
var d = this[c];
if (d && d.isTargetSet) {
var a = d.length;
var e = d.target;
var g = d.contexts;
if (g) {
while (--a >= 0) {
var f = d[a];
b.push([e, f, g[SC.guidFor(f)]])
}
} else {
while (--a >= 0) {
b.push([e, d[a]])
}
}
}
}
this._membersCacheIsValid = YES;
return b
},
clone: function() {
var b,
d,
c,
a = SC.ObserverSet.create();
for (c in this) {
if (!this.hasOwnProperty(c)) {
continue
}
b = this[c];
if (b && b.isTargetSet) {
d = b.clone();
d.target = b.target;
if (b.contexts) {
d.contexts = SC.clone(b.contexts)
}
a[c] = d
}
}
a.targets = this.targets;
a._membersCacheIsValid = NO;
return a
},
create: function() {
return SC.beget(this)
}
};
SC.ObserverSet.slice = SC.ObserverSet.clone;
sc_require("private/observer_set");
SC.LOG_OBSERVERS = NO;
SC.Observable = {
isObservable: YES,
automaticallyNotifiesObserversFor: function(a) {
return YES
},
get: function(c) {
var b = this[c],
a;
if (b === undefined) {
return this.unknownProperty(c)
} else {
if (b && b.isProperty) {
if (b.isCacheable) {
a = this._kvo_cache;
if (!a) {
a = this._kvo_cache = {}
}
return (a[b.cacheKey] !== undefined) ? a[b.cacheKey] : (a[b.cacheKey] = b.call(this, c))
} else {
return b.call(this, c)
}
} else {
return b
}
}
},
set: function(h, f) {
var b = this[h],
i = this.automaticallyNotifiesObserversFor(h),
e = f,
c,
a,
g,
d;
if (this._kvo_cacheable && (a = this._kvo_cache)) {
c = this._kvo_cachedep;
if (!c || (c = c[h]) === undefined) {
c = this._kvo_computeCachedDependentsFor(h)
}
if (c) {
g = c.length;
while (--g >= 0) {
d = c[g];
a[d.cacheKey] = a[d.lastSetValueKey] = undefined
}
}
}
if (b && b.isProperty) {
a = this._kvo_cache;
if (b.isVolatile || !a || (a[b.lastSetValueKey] !== f)) {
if (!a) {
a = this._kvo_cache = {}
}
a[b.lastSetValueKey] = f;
if (i) {
this.propertyWillChange(h)
}
e = b.call(this, h, f);
if (b.isCacheable) {
a[b.cacheKey] = e
}
if (i) {
this.propertyDidChange(h, e, YES)
}
}
} else {
if (b === undefined) {
if (i) {
this.propertyWillChange(h)
}
this.unknownProperty(h, f);
if (i) {
this.propertyDidChange(h, e)
}
} else {
if (this[h] !== f) {
if (i) {
this.propertyWillChange(h)
}
e = this[h] = f;
if (i) {
this.propertyDidChange(h, e)
}
}
}
}
return this
},
unknownProperty: function(a, b) {
if (! (b === undefined)) {
this[a] = b
}
return b
},
beginPropertyChanges: function() {
this._kvo_changeLevel = (this._kvo_changeLevel || 0) + 1;
return this
},
endPropertyChanges: function() {
this._kvo_changeLevel = (this._kvo_changeLevel || 1) - 1;
var b = this._kvo_changeLevel,
a = this._kvo_changes;
if ((b <= 0) && a && (a.length > 0) && !SC.Observers.isObservingSuspended) {
this._notifyPropertyObservers()
}
return this
},
propertyWillChange: function(a) {
return this
},
propertyDidChange: function(l, j, c) {
this._kvo_revision = (this._kvo_revision || 0) + 1;
var b = this._kvo_changeLevel || 0,
g,
k,
h,
a,
d,
f = SC.LOG_OBSERVERS && !(this.LOG_OBSERVING === NO);
if (this._kvo_cacheable && (a = this._kvo_cache)) {
if (!c) {
d = this[l];
if (d && d.isProperty) {
a[d.cacheKey] = a[d.lastSetValueKey] = undefined
}
}
g = this._kvo_cachedep;
if (!g || (g = g[l]) === undefined) {
g = this._kvo_computeCachedDependentsFor(l)
}
if (g) {
k = g.length;
while (--k >= 0) {
h = g[k];
a[h.cacheKey] = a[h.lastSetValueKey] = undefined
}
}
}
var e = SC.Observers.isObservingSuspended;
if ((b > 0) || e) {
var i = this._kvo_changes;
if (!i) {
i = this._kvo_changes = SC.CoreSet.create()
}
i.add(l);
if (e) {
if (f) {
console.log("%@%@: will not notify observers because observing is suspended".fmt(SC.KVO_SPACES, this))
}
SC.Observers.objectHasPendingChanges(this)
}
} else {
this._notifyPropertyObservers(l)
}
return this
},
registerDependentKey: function(h, c) {
var e = this._kvo_dependents,
b = this[h],
i,
g,
a,
f,
d;
if (SC.typeOf(c) === SC.T_ARRAY) {
i = c;
a = 0
} else {
i = arguments;
a = 1
}
g = i.length;
if (!e) {
this._kvo_dependents = e = {}
}
while (--g >= a) {
f = i[g];
d = e[f];
if (!d) {
d = e[f] = []
}
d.push(h)
}
},
_kvo_addCachedDependents: function(b, f, h, c) {
var a = f.length,
e,
d,
g;
while (--a >= 0) {
d = f[a];
c.add(d);
e = this[d];
if (e && (e instanceof Function) && e.isProperty) {
if (e.isCacheable) {
b.push(e)
}
if ((g = h[d]) && g.length > 0) {
this._kvo_addCachedDependents(b, g, h, c)
}
}
}
},
_kvo_computeCachedDependentsFor: function(c) {
var d = this._kvo_cachedep,
f = this._kvo_dependents,
e = f ? f[c] : null,
a,
b;
if (!d) {
d = this._kvo_cachedep = {}
}
if (!e || e.length === 0) {
return d[c] = null
}
a = d[c] = [];
b = SC._TMP_SEEN_SET = (SC._TMP_SEEN_SET || SC.CoreSet.create());
b.add(c);
this._kvo_addCachedDependents(a, e, f, b);
b.clear();
if (a.length === 0) {
a = d[c] = null
}
return a
},
_kvo_for: function(c, b) {
var a = this[c];
if (!this._kvo_cloned) {
this._kvo_cloned = {}
}
if (!a) {
a = this[c] = (b === undefined) ? [] : b.create();
this._kvo_cloned[c] = YES
} else {
if (!this._kvo_cloned[c]) {
a = this[c] = a.copy();
this._kvo_cloned[c] = YES
}
}
return a
},
addObserver: function(c, f, h, b) {
var d,
a,
e,
g;
if (h === undefined) {
h = f;
f = this
}
if (!f) {
f = this
}
if (SC.typeOf(h) === SC.T_STRING) {
h = f[h]
}
if (!h) {
throw "You must pass a method to addObserver()"
}
c = c.toString();
if (c.indexOf(".") >= 0) {
a = SC._ChainObserver.createChain(this, c, f, h, b);
a.masterTarget = f;
a.masterMethod = h;
this._kvo_for(SC.keyFor("_kvo_chains", c)).push(a)
} else {
if ((this[c] === undefined) && (c.indexOf("@") === 0)) {
this.get(c)
}
if (f === this) {
f = null
}
d = SC.keyFor("_kvo_observers", c);
this._kvo_for(d, SC.ObserverSet).add(f, h, b);
this._kvo_for("_kvo_observed_keys", SC.CoreSet).add(c)
}
if (this.didAddObserver) {
this.didAddObserver(c, f, h)
}
return this
},
removeObserver: function(c, f, h) {
var d,
e,
b,
g,
a;
if (h === undefined) {
h = f;
f = this
}
if (!f) {
f = this
}
if (SC.typeOf(h) === SC.T_STRING) {
h = f[h]
}
if (!h) {
throw "You must pass a method to addObserver()"
}
c = c.toString();
if (c.indexOf(".") >= 0) {
d = SC.keyFor("_kvo_chains", c);
if (e = this[d]) {
e = this._kvo_for(d);
a = e.length;
while (--a >= 0) {
b = e[a];
if (b && (b.masterTarget === f) && (b.masterMethod === h)) {
e[a] = b.destroyChain()
}
}
}
} else {
if (f === this) {
f = null
}
d = SC.keyFor("_kvo_observers", c);
if (g = this[d]) {
g = this._kvo_for(d);
g.remove(f, h);
if (g.targets <= 0) {
this._kvo_for("_kvo_observed_keys", SC.CoreSet).remove(c)
}
}
}
if (this.didRemoveObserver) {
this.didRemoveObserver(c, f, h)
}
return this
},
hasObserverFor: function(b) {
SC.Observers.flush(this);
var d = this[SC.keyFor("_kvo_observers", b)],
c = this[SC.keyFor("_kvo_local", b)],
a;
if (c && c.length > 0) {
return YES
}
if (d && d.getMembers().length > 0) {
return YES
}
return NO
},
initObservable: function() {
if (this._observableInited) {
return
}
this._observableInited = YES;
var e,
l,
j,
i,
g,
d,
k;
if (l = this._observers) {
var f = l.length;
for (e = 0; e < f; e++) {
j = l[e];
g = this[j];
d = g.propertyPaths;
k = (d) ? d.length: 0;
for (var b = 0;
b < k; b++) {
var m = d[b];
var a = m.indexOf(".");
if (a < 0) {
this.addObserver(m, this, g)
} else {
if (m.indexOf("*") === 0) {
this.addObserver(m.slice(1), this, g)
} else {
var h = null;
if (a === 0) {
h = this;
m = m.slice(1)
} else {
if (a === 4 && m.slice(0, 5) === "this.") {
h = this;
m = m.slice(5)
} else {
if (a < 0 && m.length === 4 && m === "this") {
h = this;
m = ""
}
}
}
SC.Observers.addObserver(m, this, g, h)
}
}
}
}
}
this.bindings = [];
if (l = this._bindings) {
for (e = 0; e < l.length; e++) {
j = l[e];
i = this[j];
var c = j.slice(0, -7);
this[j] = this.bind(c, i)
}
}
if (l = this._properties) {
for (e = 0; e < l.length;
e++) {
j = l[e];
if (i = this[j]) {
if (i.isCacheable) {
this._kvo_cacheable = YES
}
if (i.dependentKeys && (i.dependentKeys.length > 0)) {
this.registerDependentKey(j, i.dependentKeys)
}
}
}
}
},
observersForKey: function(a) {
var b = this._kvo_for("_kvo_observers", a);
return b.getMembers() || []
},
_notifyPropertyObservers: function(t) {
if (!this._observableInited) {
this.initObservable()
}
SC.Observers.flush(this);
var g = SC.LOG_OBSERVERS && !(this.LOG_OBSERVING === NO);
var o,
r,
m,
d,
n,
l,
q;
var p,
j,
a,
f,
s,
c,
i,
e;
var b,
h,
k;
if (g) {
h = SC.KVO_SPACES = (SC.KVO_SPACES || "") + " ";
console.log('%@%@: notifying observers after change to key "%@"'.fmt(h, this, t))
}
d = this["_kvo_observers_*"];
this._kvo_changeLevel = (this._kvo_changeLevel || 0) + 1;
while (((r = this._kvo_changes) && (r.length > 0)) || t) {
q = ++this.propertyRevision;
if (!r) {
r = SC.CoreSet.create()
}
this._kvo_changes = null;
if (t === "*") {
r.add("*");
r.addEach(this._kvo_for("_kvo_observed_keys", SC.CoreSet))
} else {
if (t) {
r.add(t)
}
}
if (m = this._kvo_dependents) {
for (n = 0; n < r.length; n++) {
t = r[n];
l = m[t];
if (l && (i = l.length)) {
if (g) {
console.log("%@...including dependent keys for %@: %@".fmt(h, t, l))
}
k = this._kvo_cache;
if (!k) {
k = this._kvo_cache = {}
}
while (--i >= 0) {
r.add(t = l[i]);
if (e = this[t]) {
this[e.cacheKey] = undefined;
k[e.cacheKey] = k[e.lastSetValueKey] = undefined
}
}
}
}
}
while (r.length > 0) {
t = r.pop();
o = this[SC.keyFor("_kvo_observers", t)];
if (o) {
p = o.getMembers();
j = p.length;
for (f = 0; f < j; f++) {
a = p[f];
if (a[3] === q) {
continue
}
s = a[0] || this;
c = a[1];
b = a[2];
a[3] = q;
if (g) {
console.log('%@...firing observer on %@ for key "%@"'.fmt(h, s, t))
}
if (b !== undefined) {
c.call(s, this, t, null, b, q)
} else {
c.call(s, this, t, null, q)
}
}
}
p = this[SC.keyFor("_kvo_local", t)];
if (p) {
j = p.length;
for (f = 0; f < j; f++) {
a = p[f];
c = this[a];
if (c) {
if (g) {
console.log('%@...firing local observer %@.%@ for key "%@"'.fmt(h, this, a, t))
}
c.call(this, this, t, null, q)
}
}
}
if (d && t !== "*") {
p = d.getMembers();
j = p.length;
for (f = 0;
f < j; f++) {
a = p[f];
s = a[0] || this;
c = a[1];
b = a[2];
if (g) {
console.log('%@...firing * observer on %@ for key "%@"'.fmt(h, s, t))
}
if (b !== undefined) {
c.call(s, this, t, null, b, q)
} else {
c.call(s, this, t, null, q)
}
}
}
if (this.propertyObserver) {
if (g) {
console.log('%@...firing %@.propertyObserver for key "%@"'.fmt(h, this, t))
}
this.propertyObserver(this, t, null, q)
}
}
if (r) {
r.destroy()
}
t = null
}
this._kvo_changeLevel = (this._kvo_changeLevel || 1) - 1;
if (g) {
SC.KVO_SPACES = h.slice(0, -2)
}
return YES
},
bind: function(a, c, e) {
var d;
if (e !== undefined) {
c = [c, e]
}
var b = SC.typeOf(c);
if (b === SC.T_STRING || b === SC.T_ARRAY) {
d = this[a + "BindingDefault"] || SC.Binding;
d = d.beget().from(c)
} else {
d = c
}
d = d.to(a, this).connect();
this.bindings.push(d);
return d
},
didChangeFor: function(a) {
a = SC.hashFor(a);
var b = this._kvo_didChange_valueCache;
if (!b) {
b = this._kvo_didChange_valueCache = {}
}
var f = this._kvo_didChange_revisionCache;
if (!f) {
f = this._kvo_didChange_revisionCache = {}
}
var e = b[a] || {};
var j = f[a] || {};
var d = false;
var c = this._kvo_revision || 0;
var h = arguments.length;
while (--h >= 1) {
var i = arguments[h];
if (j[i] != c) {
var g = this.get(i);
if (e[i] !== g) {
d = true;
e[i] = g
}
}
j[i] = c
}
b[a] = e;
f[a] = j;
return d
},
setIfChanged: function(a, b) {
return (this.get(a) !== b) ? this.set(a, b) : this
},
getPath: function(b) {
var a = SC.tupleForPropertyPath(b, this);
if (a === null || a[0] === null) {
return undefined
}
return a[0].get(a[1])
},
setPath: function(c, b) {
if (c.indexOf(".") >= 0) {
var a = SC.tupleForPropertyPath(c, this);
if (!a || !a[0]) {
return null
}
a[0].set(a[1], b)
} else {
this.set(c, b)
}
return this
},
setPathIfChanged: function(c, b) {
if (c.indexOf(".") >= 0) {
var a = SC.tupleForPropertyPath(c, this);
if (!a || !a[0]) {
return null
}
if (a[0].get(a[1]) !== b) {
a[0].set(a[1], b)
}
} else {
this.setIfChanged(c, b)
}
return this
},
getEach: function() {
var c = SC.A(arguments);
var b = [];
for (var a = 0; a < c.length;
a++) {
b[b.length] = this.getPath(c[a])
}
return b
},
incrementProperty: function(a) {
this.set(a, (this.get(a) || 0) + 1);
return this.get(a)
},
decrementProperty: function(a) {
this.set(a, (this.get(a) || 0) - 1);
return this.get(a)
},
toggleProperty: function(a, b, c) {
if (b === undefined) {
b = true
}
if (c === undefined) {
c = false
}
b = (this.get(a) == b) ? c: b;
this.set(a, b);
return this.get(a)
},
notifyPropertyChange: function(a, b) {
this.propertyWillChange(a);
this.propertyDidChange(a, b);
return this
},
allPropertiesDidChange: function() {
this._kvo_cache = null;
this._notifyPropertyObservers("*");
return this
},
addProbe: function(a) {
this.addObserver(a, SC.logChange)
},
removeProbe: function(a) {
this.removeObserver(a, SC.logChange)
},
logProperty: function() {
var b = SC.$A(arguments);
for (var a = 0; a < b.length; a++) {
var c = b[a];
console.log("%@:%@: ".fmt(SC.guidFor(this), c), this.get(c))
}
},
propertyRevision: 1
};
SC.logChange = function logChange(c, a, b) {
console.log("CHANGE: %@[%@] => %@".fmt(c, a, c.get(a)))
};
SC.mixin(Array.prototype, SC.Observable);
SC.Enumerator = function(a) {
this.enumerable = a;
this.reset();
return this
};
SC.Enumerator.prototype = {
nextObject: function() {
var c = this._index;
var a = this._length;
if (c >= a) {
return undefined
}
var b = this.enumerable.nextObject(c, this._previousObject, this._context);
this._previousObject = b;
this._index = c + 1;
if (c >= a) {
this._context = SC.Enumerator._pushContext(this._context)
}
return b
},
reset: function() {
var b = this.enumerable;
if (!b) {
throw SC.$error("Enumerator has been destroyed")
}
this._length = b.get ? b.get("length") : b.length;
var a = this._length;
this._index = 0;
this._previousObject = null;
this._context = (a > 0) ? SC.Enumerator._popContext() : null
},
destroy: function() {
this.enumerable = this._length = this._index = this._previousObject = this._context = null
}
};
SC.Enumerator.create = function(a) {
return new SC.Enumerator(a)
};
SC.Enumerator._popContext = function() {
var a = this._contextCache ? this._contextCache.pop() : null;
return a || {}
};
SC.Enumerator._pushContext = function(b) {
this._contextCache = this._contextCache || [];
var a = this._contextCache;
a.push(b);
return null
};
sc_require("core");
sc_require("system/enumerator");
SC.Enumerable = {
isEnumerable: YES,
nextObject: function(a, c, b) {
return this.objectAt ? this.objectAt(a) : this[a]
},
firstObject: function() {
if (this.get("length") === 0) {
return undefined
}
if (this.objectAt) {
return this.objectAt(0)
}
var b = SC.Enumerator._popContext(),
a;
a = this.nextObject(0, null, b);
b = SC.Enumerator._pushContext(b);
return a
}.property(),
enumerator: function() {
return SC.Enumerator.create(this)
},
forEach: function(g, f) {
if (typeof g !== "function") {
throw new TypeError()
}
var b = this.get ? this.get("length") : this.length;
if (f === undefined) {
f = null
}
var e = null;
var c = SC.Enumerator._popContext();
for (var a = 0; a < b; a++) {
var d = this.nextObject(a, e, c);
g.call(f, d, a, this);
e = d
}
e = null;
c = SC.Enumerator._pushContext(c);
return this
},
getEach: function(a) {
return this.map(function(b) {
return b ? (b.get ? b.get(a) : b[a]) : null
},
this)
},
setEach: function(a, b) {
this.forEach(function(c) {
if (c) {
if (c.set) {
c.set(a, b)
} else {
c[a] = b
}
}
},
this);
return this
},
map: function(h, g) {
if (typeof h !== "function") {
throw new TypeError()
}
var b = this.get ? this.get("length") : this.length;
if (g === undefined) {
g = null
}
var c = [];
var f = null;
var d = SC.Enumerator._popContext();
for (var a = 0; a < b; a++) {
var e = this.nextObject(a, f, d);
c[a] = h.call(g, e, a, this);
f = e
}
f = null;
d = SC.Enumerator._pushContext(d);
return c
},
mapProperty: function(a) {
return this.map(function(b) {
return b ? (b.get ? b.get(a) : b[a]) : null
})
},
filter: function(h, g) {
if (typeof h !== "function") {
throw new TypeError()
}
var b = this.get ? this.get("length") : this.length;
if (g === undefined) {
g = null
}
var c = [];
var f = null;
var d = SC.Enumerator._popContext();
for (var a = 0;
a < b; a++) {
var e = this.nextObject(a, f, d);
if (h.call(g, e, a, this)) {
c.push(e)
}
f = e
}
f = null;
d = SC.Enumerator._pushContext(d);
return c
},
sortProperty: function(b) {
var c = (typeof b === SC.T_STRING) ? arguments: b,
a = c.length,
d;
if (this instanceof Array) {
d = this
} else {
d = [];
this.forEach(function(e) {
d.push(e)
})
}
if (!d) {
return []
}
return d.sort(function(g, f) {
var e,
i,
k,
j,
h = 0;
for (e = 0; h === 0 && e < a; e++) {
i = c[e];
k = g ? (g.get ? g.get(i) : g[i]) : null;
j = f ? (f.get ? f.get(i) : f[i]) : null;
h = SC.compare(k, j)
}
return h
})
},
filterProperty: function(j, f) {
var d = this.get ? this.get("length") : this.length;
var e = [];
var i = null;
var b = SC.Enumerator._popContext();
for (var g = 0; g < d; g++) {
var c = this.nextObject(g, i, b);
var h = c ? (c.get ? c.get(j) : c[j]) : null;
var a = (f === undefined) ? !!h: SC.isEqual(h, f);
if (a) {
e.push(c)
}
i = c
}
i = null;
b = SC.Enumerator._pushContext(b);
return e
},
find: function(h, d) {
if (typeof h !== "function") {
throw new TypeError()
}
var c = this.get ? this.get("length") : this.length;
if (d === undefined) {
d = null
}
var g = null,
b,
i = NO,
e = null;
var a = SC.Enumerator._popContext();
for (var f = 0; f < c && !i; f++) {
b = this.nextObject(f, g, a);
if (i = h.call(d, b, f, this)) {
e = b
}
g = b
}
b = g = null;
a = SC.Enumerator._pushContext(a);
return e
},
findProperty: function(i, f) {
var c = this.get ? this.get("length") : this.length;
var j = NO,
d = null,
h = null,
b,
g;
var a = SC.Enumerator._popContext();
for (var e = 0; e < c && !j; e++) {
b = this.nextObject(e, h, a);
g = b ? (b.get ? b.get(i) : b[i]) : null;
j = (f === undefined) ? !!g: SC.isEqual(g, f);
if (j) {
d = b
}
h = b
}
h = b = null;
a = SC.Enumerator._pushContext(a);
return d
},
every: function(h, g) {
if (typeof h !== "function") {
throw new TypeError()
}
var b = this.get ? this.get("length") : this.length;
if (g === undefined) {
g = null
}
var c = YES;
var f = null;
var d = SC.Enumerator._popContext();
for (var a = 0; c && (a < b); a++) {
var e = this.nextObject(a, f, d);
if (!h.call(g, e, a, this)) {
c = NO
}
f = e
}
f = null;
d = SC.Enumerator._pushContext(d);
return c
},
everyProperty: function(i, e) {
var c = this.get ? this.get("length") : this.length;
var d = YES;
var h = null;
var a = SC.Enumerator._popContext();
for (var f = 0; d && (f < c); f++) {
var b = this.nextObject(f, h, a);
var g = b ? (b.get ? b.get(i) : b[i]) : null;
d = (e === undefined) ? !!g: SC.isEqual(g, e);
h = b
}
h = null;
a = SC.Enumerator._pushContext(a);
return d
},
some: function(h, g) {
if (typeof h !== "function") {
throw new TypeError()
}
var b = this.get ? this.get("length") : this.length;
if (g === undefined) {
g = null
}
var c = NO;
var f = null;
var d = SC.Enumerator._popContext();
for (var a = 0; (!c) && (a < b); a++) {
var e = this.nextObject(a, f, d);
if (h.call(g, e, a, this)) {
c = YES
}
f = e
}
f = null;
d = SC.Enumerator._pushContext(d);
return c
},
someProperty: function(i, e) {
var c = this.get ? this.get("length") : this.length;
var d = NO;
var h = null;
var a = SC.Enumerator._popContext();
for (var f = 0; ! d && (f < c); f++) {
var b = this.nextObject(f, h, a);
var g = b ? (b.get ? b.get(i) : b[i]) : null;
d = (e === undefined) ? !!g: SC.isEqual(g, e);
h = b
}
h = null;
a = SC.Enumerator._pushContext(a);
return d
},
reduce: function(g, h, i) {
if (typeof g !== "function") {
throw new TypeError()
}
var c = this.get ? this.get("length") : this.length;
if (c === 0 && h === undefined) {
throw new TypeError()
}
var d = h;
var f = null;
var a = SC.Enumerator._popContext();
for (var e = 0; e < c; e++) {
var b = this.nextObject(e, f, a);
if (b !== null) {
if (d === undefined) {
d = b
} else {
d = g.call(null, d, b, e, this, i)
}
}
f = b
}
f = null;
a = SC.Enumerator._pushContext(a);
if (d === undefined) {
throw new TypeError()
}
return d
},
invoke: function(h) {
var e = this.get ? this.get("length") : this.length;
if (e <= 0) {
return []
}
var i;
var g = [];
var c = arguments.length;
if (c > 1) {
for (i = 1; i < c; i++) {
g.push(arguments[i])
}
}
var f = [];
var j = null;
var b = SC.Enumerator._popContext();
for (i = 0; i < e; i++) {
var d = this.nextObject(i, j, b);
var a = d ? d[h] : null;
if (a) {
f[i] = a.apply(d, g)
}
j = d
}
j = null;
b = SC.Enumerator._pushContext(b);
return f
},
invokeWhile: function(d, i) {
var f = this.get ? this.get("length") : this.length;
if (f <= 0) {
return null
}
var j;
var h = [];
var c = arguments.length;
if (c > 2) {
for (j = 2; j < c; j++) {
h.push(arguments[j])
}
}
var g = d;
var k = null;
var b = SC.Enumerator._popContext();
for (j = 0; (g === d) && (j < f); j++) {
var e = this.nextObject(j, k, b);
var a = e ? e[i] : null;
if (a) {
g = a.apply(e, h)
}
k = e
}
k = null;
b = SC.Enumerator._pushContext(b);
return g
},
toArray: function() {
var a = [];
this.forEach(function(b) {
a.push(b)
},
this);
return a
}
};
SC._buildReducerFor = function(a, b) {
return function(d, e) {
var f = this[a];
if (SC.typeOf(f) !== SC.T_FUNCTION) {
return this.unknownProperty ? this.unknownProperty(d, e) : null
} else {
var c = SC.Enumerable.reduce.call(this, f, null, b);
return c
}
}.property("[]")
};
SC.Reducers = {
"[]": function(a, b) {
return this
}.property(),
enumerableContentDidChange: function(b, a) {
this.notifyPropertyChange("[]");
return this
},
reducedProperty: function(i, g, f) {
if (!i || i.charAt(0) !== "@") {
return undefined
}
var d = i.match(/^@([^(]*)(\(([^)]*)\))?$/);
if (!d || d.length < 2) {
return undefined
}
var h = d[1];
var j = d[3];
h = "reduce" + h.slice(0, 1).toUpperCase() + h.slice(1);
var a = this[h];
if (SC.typeOf(a) !== SC.T_FUNCTION) {
return undefined
}
if (f === NO) {
return SC.Enumerable.reduce.call(this, a, null, j)
}
var c = SC._buildReducerFor(h, j);
var b = this.constructor.prototype;
if (b) {
b[i] = c;
var e = b._properties || [];
e.push(i);
b._properties = e;
this.registerDependentKey(i, "[]")
}
return SC.Enumerable.reduce.call(this, a, null, j)
},
reduceMax: function(a, d, b, f, c) {
if (c && d) {
d = d.get ? d.get(c) : d[c]
}
if (a === null) {
return d
}
return (d > a) ? d: a
},
reduceMaxObject: function(b, f, c, g, d) {
var a = b,
h = f;
if (d) {
if (f) {
h = f.get ? f.get(d) : f[d]
}
if (b) {
a = b.get ? b.get(d) : b[d]
}
}
if (a === null) {
return f
}
return (h > a) ? f: b
},
reduceMin: function(a, d, b, f, c) {
if (c && d) {
d = d.get ? d.get(c) : d[c]
}
if (a === null) {
return d
}
return (d < a) ? d: a
},
reduceMinObject: function(b, f, c, g, d) {
var a = b,
h = f;
if (d) {
if (f) {
h = f.get ? f.get(d) : f[d]
}
if (b) {
a = b.get ? b.get(d) : b[d]
}
}
if (a === null) {
return f
}
return (h < a) ? f: b
},
reduceAverage: function(b, g, d, h, f) {
if (f && g) {
g = g.get ? g.get(f) : g[f]
}
var c = (b || 0) + g;
var a = h.get ? h.get("length") : h.length;
if (d >= a - 1) {
c = c / a
}
return c
},
reduceSum: function(a, d, b, f, c) {
if (c && d) {
d = d.get ? d.get(c) : d[c]
}
return (a === null) ? d: a + d
}
};
SC.mixin(SC.Enumerable, SC.Reducers);
SC.mixin(Array.prototype, SC.Reducers);
Array.prototype.isEnumerable = YES; (function() {
var a = {
nextObject: SC.Enumerable.nextObject,
enumerator: SC.Enumerable.enumerator,
firstObject: SC.Enumerable.firstObject,
sortProperty: SC.Enumerable.sortProperty,
mapProperty: function(g) {
var e = this.length;
var f = [];
for (var d = 0; d < e; d++) {
var h = this[d];
f[d] = h ? (h.get ? h.get(g) : h[g]) : null
}
return f
},
filterProperty: function(h, j) {
var f = this.length;
var g = [];
for (var e = 0; e < f; e++) {
var i = this[e];
var k = i ? (i.get ? i.get(h) : i[h]) : null;
var d = (j === undefined) ? !!k: SC.isEqual(k, j);
if (d) {
g.push(i)
}
}
return g
},
find: function(j, i) {
if (typeof j !== "function") {
throw new TypeError()
}
var e = this.length;
if (i === undefined) {
i = null
}
var g,
f = null,
h = NO;
for (var d = 0; d < e && !h; d++) {
g = this[d];
if (h = j.call(i, g, d, this)) {
f = g
}
}
g = null;
return f
},
findProperty: function(g, j) {
var e = this.length;
var h,
k,
i = NO,
f = null;
for (var d = 0; d < e && !i; d++) {
k = (h = this[d]) ? (h.get ? h.get(g) : h[g]) : null;
i = (j === undefined) ? !!k: SC.isEqual(k, j);
if (i) {
f = h
}
}
h = null;
return f
},
everyProperty: function(g, i) {
var e = this.length;
var f = YES;
for (var d = 0; f && (d < e); d++) {
var h = this[d];
var j = h ? (h.get ? h.get(g) : h[g]) : null;
f = (i === undefined) ? !!j: SC.isEqual(j, i)
}
return f
},
someProperty: function(g, i) {
var e = this.length;
var f = NO;
for (var d = 0; ! f && (d < e);
d++) {
var h = this[d];
var j = h ? (h.get ? h.get(g) : h[g]) : null;
f = (i === undefined) ? !!j: SC.isEqual(j, i)
}
return f
},
invoke: function(f) {
var e = this.length;
if (e <= 0) {
return []
}
var d;
var h = [];
var j = arguments.length;
if (j > 1) {
for (d = 1; d < j; d++) {
h.push(arguments[d])
}
}
var g = [];
for (d = 0;
d < e; d++) {
var i = this[d];
var k = i ? i[f] : null;
if (k) {
g[d] = k.apply(i, h)
}
}
return g
},
invokeWhile: function(f, k) {
var h = this.length;
if (h <= 0) {
return null
}
var l;
var j = [];
var e = arguments.length;
if (e > 2) {
for (l = 2; l < e; l++) {
j.push(arguments[l])
}
}
var i = f;
for (l = 0; (i === f) && (l < h); l++) {
var g = this[l];
var d = g ? g[k] : null;
if (d) {
i = d.apply(g, j)
}
}
return i
},
toArray: function() {
var e = this.length;
if (e <= 0) {
return []
}
var f = [];
for (var d = 0;
d < e; d++) {
var g = this[d];
f.push(g)
}
return f
},
getEach: function(g) {
var f = [];
var e = this.length;
for (var d = 0; d < e; d++) {
var h = this[d];
f[d] = h ? (h.get ? h.get(g) : h[g]) : null
}
return f
},
setEach: function(f, g) {
var e = this.length;
for (var d = 0; d < e; d++) {
var h = this[d];
if (h) {
if (h.set) {
h.set(f, g)
} else {
h[f] = g
}
}
}
return this
}
};
var c = {
forEach: function(h, g) {
if (typeof h !== "function") {
throw new TypeError()
}
var e = this.length;
if (g === undefined) {
g = null
}
for (var d = 0; d < e; d++) {
var f = this[d];
h.call(g, f, d, this)
}
return this
},
map: function(i, h) {
if (typeof i !== "function") {
throw new TypeError()
}
var e = this.length;
if (h === undefined) {
h = null
}
var f = [];
for (var d = 0; d < e; d++) {
var g = this[d];
f[d] = i.call(h, g, d, this)
}
return f
},
filter: function(i, h) {
if (typeof i !== "function") {
throw new TypeError()
}
var e = this.length;
if (h === undefined) {
h = null
}
var f = [];
for (var d = 0; d < e; d++) {
var g = this[d];
if (i.call(h, g, d, this)) {
f.push(g)
}
}
return f
},
every: function(i, h) {
if (typeof i !== "function") {
throw new TypeError()
}
var e = this.length;
if (h === undefined) {
h = null
}
var f = YES;
for (var d = 0; f && (d < e); d++) {
var g = this[d];
if (!i.call(h, g, d, this)) {
f = NO
}
}
return f
},
some: function(i, h) {
if (typeof i !== "function") {
throw new TypeError()
}
var e = this.length;
if (h === undefined) {
h = null
}
var f = NO;
for (var d = 0; (!f) && (d < e); d++) {
var g = this[d];
if (i.call(h, g, d, this)) {
f = YES
}
}
return f
},
reduce: function(j, f, i) {
if (typeof j !== "function") {
throw new TypeError()
}
var e = this.length;
if (e === 0 && f === undefined) {
throw new TypeError()
}
var g = f;
for (var d = 0;
d < e; d++) {
var h = this[d];
if (h !== null) {
if (g === undefined) {
g = h
} else {
g = j.call(null, g, h, d, this, i)
}
}
}
if (g === undefined) {
throw new TypeError()
}
return g
}
};
for (var b in c) {
if (!c.hasOwnProperty(b)) {
continue
}
if (!Array.prototype[b] || ((typeof Prototype === "object") && Prototype.Version.match(/^1\.6/))) {
Array.prototype[b] = c[b]
}
}
SC.mixin(Array.prototype, a)
})();
SC.RangeObserver = {
isRangeObserver: YES,
toString: function() {
var a = this.indexes ? this.indexes.toString() : "SC.IndexSet<..>";
return a.replace("IndexSet", "RangeObserver(%@)".fmt(SC.guidFor(this)))
},
create: function(d, f, e, g, c, a) {
var b = SC.beget(this);
b.source = d;
b.indexes = f ? f.frozenCopy() : null;
b.target = e;
b.method = g;
b.context = c;
b.isDeep = a || NO;
b.beginObserving();
return b
},
extend: function(e) {
var d = SC.beget(this),
c = arguments,
b = c.length,
a;
for (a = 0; a < b; a++) {
SC.mixin(d, c[a])
}
return d
},
destroy: function(a) {
this.endObserving();
return this
},
update: function(a, b) {
if (this.indexes && this.indexes.isEqual(b)) {
return this
}
this.indexes = b ? b.frozenCopy() : null;
this.endObserving().beginObserving();
return this
},
beginObserving: function() {
if (!this.isDeep) {
return this
}
var b = this.observing;
if (!b) {
b = this.observing = SC.CoreSet.create()
}
var a = this._beginObservingForEach;
if (!a) {
a = this._beginObservingForEach = function(c) {
var d = this.source.objectAt(c);
if (d && d.addObserver) {
b.push(d);
d._kvo_needsRangeObserver = YES
}
}
}
this.indexes.forEach(a, this);
this.isObserving = NO;
SC.Observers.addPendingRangeObserver(this);
return this
},
setupPending: function(a) {
var d = this.observing;
if (this.isObserving || !d || (d.get("length") === 0)) {
return YES
}
if (d.contains(a)) {
this.isObserving = YES;
var b = this._setupPendingForEach;
if (!b) {
var c = this.source,
e = this.objectPropertyDidChange;
b = this._setupPendingForEach = function(f) {
var i = this.source.objectAt(f),
g = SC.guidFor(i),
h;
if (i && i.addObserver) {
d.push(i);
i.addObserver("*", this, e);
h = this[g];
if (h === undefined || h === null) {
this[g] = f
} else {
if (h.isIndexSet) {
h.add(f)
} else {
h = this[g] = SC.IndexSet.create(h).add(f)
}
}
}
}
}
this.indexes.forEach(b, this);
return YES
} else {
return NO
}
},
endObserving: function() {
if (!this.isDeep) {
return this
}
var e = this.observing;
if (this.isObserving) {
var b = this.objectPropertyDidChange,
c = this.source,
a,
f,
d;
if (e) {
f = e.length;
for (a = 0; a < f; a++) {
d = e[a];
d.removeObserver("*", this, b);
this[SC.guidFor(d)] = null
}
e.length = 0
}
this.isObserving = NO
}
if (e) {
e.clear()
}
return this
},
rangeDidChange: function(b) {
var a = this.indexes;
if (!b || !a || a.intersects(b)) {
this.endObserving();
this.method.call(this.target, this.source, null, "[]", b, this.context);
this.beginObserving()
}
return this
},
objectPropertyDidChange: function(d, f, g, a) {
var e = this.context,
h = this.method,
c = SC.guidFor(d),
b = this[c];
if (b && !b.isIndexSet) {
b = this[c] = SC.IndexSet.create(b).freeze()
}
if (e) {
h.call(this.target, this.source, d, f, b, e, a)
} else {
h.call(this.target, this.source, d, f, b, a)
}
}
};
sc_require("mixins/observable");
sc_require("mixins/enumerable");
sc_require("system/range_observer");
SC.OUT_OF_RANGE_EXCEPTION = "Index out of range";
SC.Array = {
isSCArray: YES,
replace: function(a, c, b) {
throw "replace() must be implemented to support SC.Array"
},
objectAt: function(a) {
if (a < 0) {
return undefined
}
if (a >= this.get("length")) {
return undefined
}
return this.get(a)
},
"[]": function(a, b) {
if (b !== undefined) {
this.replace(0, this.get("length"), b)
}
return this
}.property(),
insertAt: function(a, b) {
if (a > this.get("length")) {
throw SC.OUT_OF_RANGE_EXCEPTION
}
this.replace(a, 0, [b]);
return this
},
removeAt: function(d, a) {
var c = 0,
b = [];
if (typeof d === SC.T_NUMBER) {
if ((d < 0) || (d >= this.get("length"))) {
throw SC.OUT_OF_RANGE_EXCEPTION
}
if (a === undefined) {
this.replace(d, 1, b);
return this
} else {
d = SC.IndexSet.create(d, a)
}
}
this.beginPropertyChanges();
d.forEachRange(function(f, e) {
f -= c;
c += e;
this.replace(f, e, b)
},
this);
this.endPropertyChanges();
return this
},
removeObject: function(b) {
var c = this.get("length") || 0;
while (--c >= 0) {
var a = this.objectAt(c);
if (a == b) {
this.removeAt(c)
}
}
return this
},
removeObjects: function(a) {
this.beginPropertyChanges();
a.forEach(function(b) {
this.removeObject(b)
},
this);
this.endPropertyChanges();
return this
},
pushObject: function(a) {
this.insertAt(this.get("length"), a);
return a
},
pushObjects: function(a) {
this.beginPropertyChanges();
a.forEach(function(b) {
this.pushObject(b)
},
this);
this.endPropertyChanges();
return this
},
popObject: function() {
var a = this.get("length");
if (a === 0) {
return null
}
var b = this.objectAt(a - 1);
this.removeAt(a - 1);
return b
},
shiftObject: function() {
if (this.get("length") === 0) {
return null
}
var a = this.objectAt(0);
this.removeAt(0);
return a
},
unshiftObject: function(a) {
this.insertAt(0, a);
return a
},
unshiftObjects: function(a) {
this.beginPropertyChanges();
a.forEach(function(b) {
this.unshiftObject(b)
},
this);
this.endPropertyChanges();
return this
},
isEqual: function(a) {
if (!a) {
return false
}
if (a == this) {
return true
}
var b = a.get("length");
if (b != this.get("length")) {
return false
}
while (--b >= 0) {
if (!SC.isEqual(a.objectAt(b), this.objectAt(b))) {
return false
}
}
return true
},
compact: function() {
return this.without(null)
},
without: function(b) {
if (this.indexOf(b) < 0) {
return this
}
var a = [];
this.forEach(function(c) {
if (c !== b) {
a[a.length] = c
}
});
return a
},
uniq: function() {
var a = [];
this.forEach(function(b) {
if (a.indexOf(b) < 0) {
a[a.length] = b
}
});
return a
},
rangeObserverClass: SC.RangeObserver,
addRangeObserver: function(d, f, h, e) {
var a = this._array_rangeObservers;
if (!a) {
a = this._array_rangeObservers = SC.CoreSet.create()
}
if (this._array_oldLength === undefined) {
this._array_oldLength = this.get("length")
}
var g = this.rangeObserverClass;
var b = NO;
var c = g.create(this, d, f, h, e, b);
a.add(c);
if (!this._array_isNotifyingRangeObservers) {
this._array_isNotifyingRangeObservers = YES;
this.addObserver("[]", this, this._array_notifyRangeObservers)
}
return c
},
updateRangeObserver: function(b, a) {
return b.update(this, a)
},
removeRangeObserver: function(c) {
var b = c.destroy(this);
var a = this._array_rangeObservers;
if (a) {
a.remove(c)
}
return b
},
enumerableContentDidChange: function(h, g, f) {
var a = this._array_rangeObservers,
d = this._array_oldLength,
e,
c,
b;
this.beginPropertyChanges();
this.notifyPropertyChange("length");
if (a && a.length > 0) {
if (d === undefined) {
d = 0
}
this._array_oldLength = e = this.get("length");
if (h === undefined) {
h = 0
}
if (f === undefined) {
f = e - d
}
if (f !== 0 || g === undefined) {
c = e - h;
if (f < 0) {
c -= f
}
} else {
c = g
}
b = this._array_rangeChanges;
if (!b) {
b = this._array_rangeChanges = SC.IndexSet.create()
}
b.add(h, c)
}
this.notifyPropertyChange("[]");
this.endPropertyChanges();
return this
},
_array_notifyRangeObservers: function() {
var c = this._array_rangeObservers,
d = this._array_rangeChanges,
b = c ? c.length: 0,
a,
e;
if (b > 0 && d && d.length > 0) {
for (a = 0; a < b; a++) {
c[a].rangeDidChange(d)
}
d.clear()
}
}
};
SC.mixin(Array.prototype, SC.Array);
SC.Array = SC.mixin({},
SC.Enumerable, SC.Array);
SC.Array.slice = function(b, d) {
var a = [];
var c = this.get("length");
if (SC.none(b)) {
b = 0
}
if (SC.none(d) || (d > c)) {
d = c
}
while (b < d) {
a[a.length] = this.objectAt(b++)
}
return a
};
SC.Array.indexOf = function(d, c) {
var b,
a = this.get("length");
if (c === undefined) {
c = 0
} else {
c = (c < 0) ? Math.ceil(c) : Math.floor(c)
}
if (c < 0) {
c += a
}
for (b = c; b < a; b++) {
if (this.objectAt(b) === d) {
return b
}
}
return - 1
};
if (!Array.prototype.indexOf) {
Array.prototype.indexOf = SC.Array.indexOf
}
SC.Array.lastIndexOf = function(d, c) {
var b,
a = this.get("length");
if (c === undefined) {
c = a - 1
} else {
c = (c < 0) ? Math.ceil(c) : Math.floor(c)
}
if (c < 0) {
c += a
}
for (b = c; b >= 0; b--) {
if (this.objectAt(b) === d) {
return b
}
}
return - 1
};
if (!Array.prototype.lastIndexOf) {
Array.prototype.lastIndexOf = SC.Array.lastIndexOf
} (function() {
SC.mixin(Array.prototype, {
replace: function(d, g, f) {
if (this.isFrozen) {
throw SC.FROZEN_ERROR
}
if (!f || f.length === 0) {
this.splice(d, g)
} else {
var e = [d, g].concat(f);
this.splice.apply(this, e)
}
var c = f ? (f.get ? f.get("length") : f.length) : 0;
this.enumerableContentDidChange(d, g, c - g);
return this
},
unknownProperty: function(d, e) {
var c = this.reducedProperty(d, e);
if ((e !== undefined) && c === undefined) {
c = this[d] = e
}
return c
}
});
var b = Array.prototype.indexOf;
if (!b || (b === SC.Array.indexOf)) {
Array.prototype.indexOf = function(f, e) {
var d,
c = this.length;
if (e === undefined) {
e = 0
} else {
e = (e < 0) ? Math.ceil(e) : Math.floor(e)
}
if (e < 0) {
e += c
}
for (d = e;
d < c; d++) {
if (this[d] === f) {
return d
}
}
return - 1
}
}
var a = Array.prototype.lastIndexOf;
if (!a || (a === SC.Array.lastIndexOf)) {
Array.prototype.lastIndexOf = function(f, e) {
var d,
c = this.length;
if (e === undefined) {
e = c - 1
} else {
e = (e < 0) ? Math.ceil(e) : Math.floor(e)
}
if (e < 0) {
e += c
}
for (d = e;
d >= 0; d--) {
if (this[d] === f) {
return d
}
}
return - 1
}
}
})();
SC.Comparable = {
isComparable: YES,
compare: function(d, c) {
throw "%@.compare() is not implemented".fmt(this.toString())
}
};
SC.Copyable = {
isCopyable: YES,
copy: function() {
throw "%@.copy() is not implemented"
},
frozenCopy: function() {
var a = this.get ? this.get("isFrozen") : this.isFrozen;
if (a === YES) {
return this
} else {
if (a === undefined) {
throw "%@ does not support freezing".fmt(this)
} else {
return this.copy().freeze()
}
}
}
};
SC.mixin(Array.prototype, SC.Copyable);
Array.prototype.copy = Array.prototype.slice;
SC.DelegateSupport = {
delegateFor: function(c) {
var b = 1,
a = arguments.length,
d;
while (b < a) {
d = arguments[b];
if (d && d[c] !== undefined) {
return d
}
b++
}
return (this[c] !== undefined) ? this: null
},
invokeDelegateMethod: function(c, a, b) {
b = SC.A(arguments);
b = b.slice(2, b.length);
if (!c || !c[a]) {
c = this
}
var d = c[a];
return d ? d.apply(c, b) : null
},
getDelegateProperty: function(d, e) {
var b = 1,
a = arguments.length,
c;
while (b < a) {
c = arguments[b++];
if (c && c[d] !== undefined) {
return c.get ? c.get(d) : c[d]
}
}
return (this[d] !== undefined) ? this.get(d) : undefined
}
};
SC.FROZEN_ERROR = new Error("Cannot modify a frozen object");
SC.Freezable = {
isFreezable: YES,
isFrozen: NO,
freeze: function() {
if (this.set) {
this.set("isFrozen", YES)
} else {
this.isFrozen = YES
}
return this
}
};
SC.mixin(Array.prototype, SC.Freezable);
sc_require("mixins/enumerable");
sc_require("mixins/observable");
sc_require("mixins/freezable");
sc_require("mixins/copyable");
SC.Set = SC.mixin({},
SC.Enumerable, SC.Observable, SC.Freezable, {
create: function(b) {
var c,
a,
d = SC.Set._pool,
e = this.isObservable;
if (!e && b === undefined && d.length > 0) {
c = d.pop()
} else {
c = SC.beget(this);
if (e) {
c.initObservable()
}
if (b && b.isEnumerable && b.get("length") > 0) {
c.isObservable = NO;
if (b.isSCArray) {
a = b.get ? b.get("length") : b.length;
while (--a >= 0) {
c.add(b.objectAt(a))
}
} else {
if (b.isSet) {
a = b.length;
while (--a >= 0) {
c.add(b[a])
}
} else {
b.forEach(function(f) {
c.add(f)
},
this)
}
}
c.isObservable = e
}
}
return c
},
isSet: YES,
length: 0,
firstObject: function() {
return (this.length > 0) ? this[0] : undefined
}.property(),
clear: function() {
if (this.isFrozen) {
throw SC.FROZEN_ERROR
}
this.length = 0;
return this
},
contains: function(b) {
if (b === null) {
return NO
}
var a = this[SC.hashFor(b)];
return (!SC.none(a) && (a < this.length) && (this[a] === b))
},
isEqual: function(a) {
if (!a || !a.isSet || (a.get("length") !== this.get("length"))) {
return NO
}
var b = this.get("length");
while (--b >= 0) {
if (!a.contains(this[b])) {
return NO
}
}
return YES
},
add: function(d) {
if (this.isFrozen) {
throw SC.FROZEN_ERROR
}
if (d === null || d === undefined) {
return this
}
var c = SC.hashFor(d);
var b = this[c];
var a = this.length;
if ((b === null || b === undefined) || (b >= a) || (this[b] !== d)) {
this[a] = d;
this[c] = a;
this.length = a + 1
}
if (this.isObservable) {
this.enumerableContentDidChange()
}
return this
},
addEach: function(c) {
if (this.isFrozen) {
throw SC.FROZEN_ERROR
}
if (!c || !c.isEnumerable) {
throw "%@.addEach must pass enumerable".fmt(this)
}
var a,
b = this.isObservable;
if (b) {
this.beginPropertyChanges()
}
if (c.isSCArray) {
a = c.get("length");
while (--a >= 0) {
this.add(c.objectAt(a))
}
} else {
if (c.isSet) {
a = c.length;
while (--a >= 0) {
this.add(c[a])
}
} else {
c.forEach(function(d) {
this.add(d)
},
this)
}
}
if (b) {
this.endPropertyChanges()
}
return this
},
remove: function(d) {
if (this.isFrozen) {
throw SC.FROZEN_ERROR
}
if (SC.none(d)) {
return this
}
var c = SC.hashFor(d);
var b = this[c];
var a = this.length;
if (SC.none(b) || (b >= a) || (this[b] !== d)) {
return this
}
delete this[c];
if (b < (a - 1)) {
d = this[b] = this[a - 1];
this[SC.hashFor(d)] = b
}
this.length = a - 1;
if (this.isObservable) {
this.enumerableContentDidChange()
}
return this
},
pop: function() {
if (this.isFrozen) {
throw SC.FROZEN_ERROR
}
var a = (this.length > 0) ? this[this.length - 1] : null;
if (a) {
this.remove(a)
}
return a
},
removeEach: function(c) {
if (this.isFrozen) {
throw SC.FROZEN_ERROR
}
if (!c || !c.isEnumerable) {
throw "%@.addEach must pass enumerable".fmt(this)
}
var a,
b = this.isObservable;
if (b) {
this.beginPropertyChanges()
}
if (c.isSCArray) {
a = c.get("length");
while (--a >= 0) {
this.remove(c.objectAt(a))
}
} else {
if (c.isSet) {
a = c.length;
while (--a >= 0) {
this.remove(c[a])
}
} else {
c.forEach(function(d) {
this.remove(d)
},
this)
}
}
if (b) {
this.endPropertyChanges()
}
return this
},
copy: function() {
return this.constructor.create(this)
},
destroy: function() {
this.isFrozen = NO;
if (!this.isObservable) {
SC.Set._pool.push(this.clear())
}
return this
},
forEach: function(c, d) {
var b = this.length;
if (!d) {
d = this
}
for (var a = 0; a < b;
a++) {
c.call(d, this[a], a, this)
}
return this
},
toString: function() {
var b = this.length,
a,
c = [];
for (a = 0; a < b; a++) {
c[a] = this[a]
}
return "SC.Set<%@>".fmt(c.join(","))
},
_pool: [],
isObservable: YES
});
SC.Set.constructor = SC.Set;
SC.Set.clone = SC.Set.copy;
SC.Set.push = SC.Set.unshift = SC.Set.add;
SC.Set.shift = SC.Set.pop;
SC.Set.addObject = SC.Set.add;
SC.Set.removeObject = SC.Set.remove;
SC.Set._pool = [];
SC.CoreSet = SC.beget(SC.Set);
SC.CoreSet.isObservable = NO;
SC.CoreSet.constructor = SC.CoreSet;
sc_require("core");
sc_require("mixins/observable");
sc_require("mixins/array");
sc_require("system/set");
SC.BENCHMARK_OBJECTS = NO;
SC._object_extend = function _object_extend(g, f) {
if (!f) {
throw "SC.Object.extend expects a non-null value. Did you forget to 'sc_require' something? Or were you passing a Protocol to extend() as if it were a mixin?"
}
g._kvo_cloned = null;
var w,
m,
s,
e,
h = g.concatenatedProperties,
k = SC.K;
var c,
b;
m = (h) ? h.length: 0;
var a = (m > 0) ? {}: null;
while (--m >= 0) {
w = h[m];
c = g[w];
b = f[w];
if (c) {
if (! (c instanceof Array)) {
c = SC.$A(c)
}
a[w] = (b) ? c.concat(b) : b
} else {
if (! (b instanceof Array)) {
b = SC.$A(b)
}
a[w] = b
}
}
var v = g._bindings,
l = NO;
var t = g._observers,
u = NO;
var i = g._properties,
d = NO;
var p,
j,
n;
var r = g.outlets,
q = NO;
if (f.outlets) {
r = (r || SC.EMPTY_ARRAY).concat(f.outlets);
q = YES
}
for (w in f) {
if (w === "_kvo_cloned") {
continue
}
if (!f.hasOwnProperty(w)) {
continue
}
var o = (a.hasOwnProperty(w) ? a[w] : null) || f[w];
if (w.slice( - 7) === "Binding") {
if (!l) {
v = (v || SC.EMPTY_ARRAY).slice();
l = YES
}
if (v === null) {
v = (g._bindings || SC.EMPTY_ARRAY).slice()
}
v[v.length] = w
} else {
if (o && (o instanceof Function)) {
if (!o.superclass && (o !== (e = g[w]))) {
o.superclass = o.base = e || k
}
if (o.propertyPaths) {
if (!u) {
t = (t || SC.EMPTY_ARRAY).slice();
u = YES
}
t[t.length] = w
} else {
if (p = o.localPropertyPaths) {
j = p.length;
while (--j >= 0) {
n = g._kvo_for(SC.keyFor("_kvo_local", p[j]), SC.Set);
n.add(w);
g._kvo_for("_kvo_observed_keys", SC.CoreSet).add(p[j])
}
} else {
if (o.dependentKeys) {
if (!d) {
i = (i || SC.EMPTY_ARRAY).slice();
d = YES
}
i[i.length] = w
} else {
if (o.autoconfiguredOutlet) {
if (!q) {
r = (r || SC.EMPTY_ARRAY).slice();
q = YES
}
r[r.length] = w
}
}
}
}
}
}
g[w] = o
}
if (f.hasOwnProperty("toString")) {
w = "toString";
o = (a.hasOwnProperty(w) ? a[w] : null) || f[w];
if (!o.superclass && (o !== (e = g[w]))) {
o.superclass = o.base = e || k
}
g[w] = o
}
g._bindings = v || [];
g._observers = t || [];
g._properties = i || [];
g.outlets = r || [];
return g
};
SC.Object = function(a) {
return this._object_init(a)
};
SC.mixin(SC.Object, {
mixin: function(b) {
var a = arguments.length,
c;
for (c = 0; c < a; c++) {
SC.mixin(this, arguments[c])
}
return this
},
superclass: null,
extend: function(e) {
var d = SC.BENCHMARK_OBJECTS;
if (d) {
SC.Benchmark.start("SC.Object.extend")
}
var g,
c = function(h) {
return this._object_init(h)
};
for (g in this) {
if (!this.hasOwnProperty(g)) {
continue
}
c[g] = this[g]
}
if (this.hasOwnProperty("toString")) {
c.toString = this.toString
}
c.superclass = this;
SC.generateGuid(c);
c.subclasses = SC.Set.create();
this.subclasses.add(c);
var f = (c.prototype = SC.beget(this.prototype));
var b,
a = arguments.length;
for (b = 0; b < a; b++) {
SC._object_extend(f, arguments[b])
}
f.constructor = c;
if (d) {
SC.Benchmark.end("SC.Object.extend")
}
return c
},
create: function(a) {
var b = this;
return new b(arguments)
},
isClass: YES,
subclasses: SC.Set.create(),
toString: function() {
return SC._object_className(this)
},
subclassOf: function(b) {
if (this === b) {
return NO
}
var a = this;
while (a = a.superclass) {
if (a === b) {
return YES
}
}
return NO
},
hasSubclass: function(a) {
return (a && a.subclassOf) ? a.subclassOf(this) : NO
},
kindOf: function(a) {
return (this === a) || this.subclassOf(a)
}
});
SC.Object.prototype = {
_kvo_enabled: YES,
_object_init: function(c) {
var b,
a = (c) ? c.length: 0;
for (b = 0; b < a; b++) {
SC._object_extend(this, c[b])
}
SC.generateGuid(this);
this.init();
var d = this.initMixin;
a = (d) ? d.length: 0;
for (b = 0; b < a; b++) {
d[b].call(this)
}
return this
},
mixin: function() {
var b,
a = arguments.length;
for (b = 0; b < a; b++) {
SC.mixin(this, arguments[b])
}
for (b = 0; b < a; b++) {
var c = arguments[b].initMixin;
if (c) {
c.call(this)
}
}
return this
},
init: function() {
this.initObservable();
return this
},
isDestroyed: NO,
destroy: function() {
if (this.get("isDestroyed")) {
return this
}
this.set("isDestroyed", YES);
var b,
c = this.destroyMixin,
a = (c) ? c.length: 0;
for (b = 0; b < a; b++) {
c[b].call(this)
}
return this
},
isObject: true,
respondsTo: function(a) {
return !! (SC.typeOf(this[a]) === SC.T_FUNCTION)
},
tryToPerform: function(b, c, a) {
return this.respondsTo(b) && (this[b](c, a) !== NO)
},
superclass: function(b) {
var a = arguments.callee.caller;
if (!a) {
throw "superclass cannot determine the caller method"
}
return a.superclass ? a.superclass.apply(this, arguments) : null
},
instanceOf: function(a) {
return this.constructor === a
},
kindOf: function(a) {
return this.constructor.kindOf(a)
},
toString: function() {
if (!this._object_toString) {
var a = SC._object_className(this.constructor);
var b = "%@:%@".fmt(a, SC.guidFor(this));
if (a) {
this._object_toString = b
} else {
return b
}
}
return this._object_toString
},
awake: function(a) {
this.outlets.forEach(function(b) {
this.get(b)
},
this);
this.bindings.invoke("sync")
},
invokeOnce: function(a) {
SC.RunLoop.currentRunLoop.invokeOnce(this, a);
return this
},
invokeLast: function(a) {
SC.RunLoop.currentRunLoop.invokeLast(this, a);
return this
},
concatenatedProperties: ["concatenatedProperties", "initMixin", "destroyMixin"]
};
SC.Object.prototype.constructor = SC.Object;
SC.mixin(SC.Object.prototype, SC.Observable);
function findClassNames() {
if (SC._object_foundObjectClassNames) {
return
}
SC._object_foundObjectClassNames = true;
var b = [];
var a = function(c, d, g) {
g--;
if (b.indexOf(d) >= 0) {
return
}
b.push(d);
for (var e in d) {
if (e == "__scope__") {
continue
}
if (e == "superclass") {
continue
}
if (!e.match(/^[A-Z0-9]/)) {
continue
}
var h = (c) ? [c, e].join(".") : e;
var f = d[e];
switch (SC.typeOf(f)) {
case SC.T_CLASS:
if (!f._object_className) {
f._object_className = h
}
if (g >= 0) {
a(h, f, g)
}
break;
case SC.T_OBJECT:
if (g >= 0) {
a(h, f, g)
}
break;
case SC.T_HASH:
if (((c) || (h === "SC")) && (g >= 0)) {
a(h, f, g)
}
break;
default:
break
}
}
};
a(null, SC.root, 2) //eh...
}
SC.instanceOf = function(a, b) {
return !! (a && a.constructor === b)
};
SC.kindOf = function(a, b) {
if (a && !a.isClass) {
a = a.constructor
}
return !! (a && a.kindOf && a.kindOf(b))
};
SC._object_className = function(b) {
if (!SC.isReady) {
return ""
}
if (!b._object_className) {
findClassNames()
}
if (b._object_className) {
return b._object_className
}
var a = b;
while (a && !a._object_className) {
a = a.superclass
}
return (a && a._object_className) ? a._object_className: "Anonymous"
};
sc_require("system/object");
SC._ChainObserver = function(a) {
this.property = a
};
SC._ChainObserver.createChain = function(d, j, f, a, b) {
var c = j.split("."),
h = new SC._ChainObserver(c[0]),
g = h,
e = c.length;
for (var i = 1; i < e; i++) {
g = g.next = new SC._ChainObserver(c[i])
}
h.objectDidChange(d);
g.target = f;
g.method = a;
g.context = b;
return h
};
SC._ChainObserver.prototype = {
isChainObserver: true,
object: null,
property: null,
next: null,
target: null,
method: null,
objectDidChange: function(a) {
if (a === this.object) {
return
}
if (this.object && this.object.removeObserver) {
this.object.removeObserver(this.property, this, this.propertyDidChange)
}
this.object = a;
if (this.object && this.object.addObserver) {
this.object.addObserver(this.property, this, this.propertyDidChange)
}
this.propertyDidChange()
},
propertyDidChange: function() {
var b = this.object;
var e = this.property;
var d = (b && b.get) ? b.get(e) : null;
if (this.next) {
this.next.objectDidChange(d)
}
var f = this.target,
g = this.method,
c = this.context;
if (f && g) {
var a = b ? b.propertyRevision: null;
if (c) {
g.call(f, b, e, d, c, a)
} else {
g.call(f, b, e, d, a)
}
}
},
destroyChain: function() {
var a = this.object;
if (a && a.removeObserver) {
a.removeObserver(this.property, this, this.propertyDidChange)
}
if (this.next) {
this.next.destroyChain()
}
this.next = this.target = this.method = this.object = this.context = null;
return null
}
};
sc_require("mixins/observable");
sc_require("system/set");
SC.Observers = {
queue: [],
addObserver: function(c, d, e, b) {
var a;
if (SC.typeOf(c) === SC.T_STRING) {
a = SC.tupleForPropertyPath(c, b)
} else {
a = c
}
if (a) {
a[0].addObserver(a[1], d, e)
} else {
this.queue.push([c, d, e, b])
}
},
removeObserver: function(f, g, h, d) {
var c,
b,
a,
e;
a = SC.tupleForPropertyPath(f, d);
if (a) {
a[0].removeObserver(a[1], g, h)
}
c = this.queue.length;
b = this.queue;
while (--c >= 0) {
e = b[c];
if ((e[0] === f) && (e[1] === g) && (e[2] == h) && (e[3] === d)) {
b[c] = null
}
}
},
addPendingRangeObserver: function(a) {
var b = this.rangeObservers;
if (!b) {
b = this.rangeObservers = SC.CoreSet.create()
}
b.add(a);
return this
},
_TMP_OUT: [],
flush: function(a) {
var e = this.queue;
if (e && e.length > 0) {
var h = (this.queue = []);
var i = e.length;
while (--i >= 0) {
var j = e[i];
if (!j) {
continue
}
var f = SC.tupleForPropertyPath(j[0], j[3]);
if (f) {
f[0].addObserver(f[1], j[1], j[2])
} else {
h.push(j)
}
}
}
if (a._kvo_needsRangeObserver) {
var g = this.rangeObservers,
d = g ? g.get("length") : 0,
b = this._TMP_OUT,
c;
for (i = 0; i < d; i++) {
c = g[i];
if (c.setupPending(a)) {
b.push(c)
}
}
if (b.length > 0) {
g.removeEach(b)
}
b.length = 0;
a._kvo_needsRangeObserver = NO
}
},
isObservingSuspended: 0,
_pending: SC.CoreSet.create(),
objectHasPendingChanges: function(a) {
this._pending.add(a)
},
suspendPropertyObserving: function() {
this.isObservingSuspended++
},
resumePropertyObserving: function() {
var c;
if (--this.isObservingSuspended <= 0) {
c = this._pending;
this._pending = SC.CoreSet.create();
var b,
a = c.length;
for (b = 0; b < a; b++) {
c[b]._notifyPropertyObservers()
}
c.clear();
c = null
}
}
};
sc_require("system/object");
SC.LOG_BINDINGS = NO;
SC.BENCHMARK_BINDING_NOTIFICATIONS = NO;
SC.BENCHMARK_BINDING_SETUP = NO;
SC.MULTIPLE_PLACEHOLDER = "@@MULT@@";
SC.NULL_PLACEHOLDER = "@@NULL@@";
SC.EMPTY_PLACEHOLDER = "@@EMPTY@@";
SC.Binding = {
beget: function(b) {
var a = SC.beget(this);
a.parentBinding = this;
if (b !== undefined) {
a = a.from(b)
}
return a
},
builder: function() {
var b = this;
var a = function(c) {
return b.beget().from(c)
};
a.beget = function() {
return b.beget()
};
return a
},
from: function(b, a) {
if (!b) {
return this
}
var c = (this === SC.Binding) ? this.beget() : this;
c._fromPropertyPath = b;
c._fromRoot = a;
c._fromTuple = null;
return c
},
to: function(b, a) {
var c = (this === SC.Binding) ? this.beget() : this;
c._toPropertyPath = b;
c._toRoot = a;
c._toTuple = null;
return c
},
connect: function() {
if (this.isConnected) {
return this
}
this.isConnected = YES;
this._connectionPending = YES;
this._syncOnConnect = YES;
SC.Binding._connectQueue.add(this);
return this
},
_connect: function() {
if (!this._connectionPending) {
return
}
this._connectionPending = NO;
var c,
a;
var b = SC.BENCHMARK_BINDING_SETUP;
if (b) {
SC.Benchmark.start("SC.Binding.connect()")
}
c = this._fromPropertyPath;
a = this._fromRoot;
if (SC.typeOf(c) === SC.T_STRING) {
if (c.indexOf(".") === 0) {
c = c.slice(1);
if (!a) {
a = this._toRoot
}
} else {
if (c.indexOf("*") === 0) {
c = [this._fromRoot || this._toRoot, c.slice(1)];
a = null
}
}
}
SC.Observers.addObserver(c, this, this.fromPropertyDidChange, a);
if (!this._oneWay) {
c = this._toPropertyPath;
a = this._toRoot;
SC.Observers.addObserver(c, this, this.toPropertyDidChange, a)
}
if (b) {
SC.Benchmark.end("SC.Binding.connect()")
}
if (this._syncOnConnect) {
this._syncOnConnect = NO;
if (b) {
SC.Benchmark.start("SC.Binding.connect().sync")
}
this.sync();
if (b) {
SC.Benchmark.end("SC.Binding.connect().sync")
}
}
},
disconnect: function() {
if (!this.isConnected) {
return this
}
if (this._connectionPending) {
this._connectionPending = NO
} else {
SC.Observers.removeObserver(this._fromPropertyPath, this, this.fromPropertyDidChange, this._fromRoot);
if (!this._oneWay) {
SC.Observers.removeObserver(this._toPropertyPath, this, this.toPropertyDidChange, this._toRoot)
}
}
this.isConnected = NO;
return this
},
fromPropertyDidChange: function(c, b) {
var a = c ? c.get(b) : null;
if (a !== this._bindingValue) {
this._setBindingValue(c, b);
this._changePending = YES;
SC.Binding._changeQueue.add(this)
}
},
toPropertyDidChange: function(c, b) {
if (this._oneWay) {
return
}
var a = c.get(b);
if (a !== this._transformedBindingValue) {
this._setBindingValue(c, b);
this._changePending = YES;
SC.Binding._changeQueue.add(this)
}
},
_setBindingValue: function(b, a) {
this._bindingSource = b;
this._bindingKey = a
},
_computeBindingValue: function() {
var g = this._bindingSource,
e = this._bindingKey,
c;
if (!g) {
return
}
this._bindingValue = c = g.getPath(e);
var f = this._transforms;
if (f) {
var b = f.length;
for (var a = 0; a < b; a++) {
var d = f[a];
c = d(c, this)
}
}
if (this._noError && SC.typeOf(c) === SC.T_ERROR) {
c = null
}
this._transformedBindingValue = c
},
_connectQueue: SC.CoreSet.create(),
_alternateConnectQueue: SC.CoreSet.create(),
_changeQueue: SC.CoreSet.create(),
_alternateChangeQueue: SC.CoreSet.create(),
_changePending: NO,
flushPendingChanges: function() {
if (this._isFlushing) {
return NO
}
this._isFlushing = YES;
SC.Observers.suspendPropertyObserving();
var b = NO;
var c = SC.LOG_BINDINGS;
var a,
d;
while ((a = this._connectQueue).length > 0) {
this._connectQueue = this._alternateConnectQueue;
this._alternateConnectQueue = a;
while (d = a.pop()) {
d._connect()
}
}
while ((a = this._changeQueue).length > 0) {
if (c) {
console.log("Begin: Trigger changed bindings")
}
b = YES;
this._changeQueue = this._alternateChangeQueue;
this._alternateChangeQueue = a;
while (d = a.pop()) {
d.applyBindingValue()
}
if (c) {
console.log("End: Trigger changed bindings")
}
}
this._isFlushing = NO;
SC.Observers.resumePropertyObserving();
return b
},
applyBindingValue: function() {
this._changePending = NO;
this._computeBindingTargets();
this._computeBindingValue();
var a = this._bindingValue;
var b = this._transformedBindingValue;
var c = SC.BENCHMARK_BINDING_NOTIFICATIONS;
var d = SC.LOG_BINDINGS;
if (!this._oneWay && this._fromTarget) {
if (d) {
console.log("%@: %@ -> %@".fmt(this, a, b))
}
if (c) {
SC.Benchmark.start(this.toString() + "->")
}
this._fromTarget.setPathIfChanged(this._fromPropertyKey, a);
if (c) {
SC.Benchmark.end(this.toString() + "->")
}
}
if (this._toTarget) {
if (d) {
console.log("%@: %@ <- %@".fmt(this, a, b))
}
if (c) {
SC.Benchmark.start(this.toString() + "<-")
}
this._toTarget.setPathIfChanged(this._toPropertyKey, b);
if (c) {
SC.Benchmark.start(this.toString() + "<-")
}
}
},
sync: function() {
if (!this.isConnected) {
return this
}
if (this._connectionPending) {
this._syncOnConnect = YES
} else {
this._computeBindingTargets();
var c = this._fromTarget;
var b = this._fromPropertyKey;
if (!c || !b) {
return this
}
var a = c.getPath(b);
if (a !== this._bindingValue) {
this._setBindingValue(c, b);
this._changePending = YES;
SC.Binding._changeQueue.add(this)
}
}
return this
},
_syncOnConnect: NO,
_computeBindingTargets: function() {
if (!this._fromTarget) {
var c,
b,
a;
c = this._fromPropertyPath;
b = this._fromRoot;
if (SC.typeOf(c) === SC.T_STRING) {
if (c.indexOf(".") === 0) {
c = c.slice(1);
if (!b) {
b = this._toRoot
}
} else {
if (c.indexOf("*") === 0) {
c = [b || this._toRoot, c.slice(1)];
b = null
}
}
}
a = SC.tupleForPropertyPath(c, b);
if (a) {
this._fromTarget = a[0];
this._fromPropertyKey = a[1]
}
}
if (!this._toTarget) {
c = this._toPropertyPath;
b = this._toRoot;
a = SC.tupleForPropertyPath(c, b);
if (a) {
this._toTarget = a[0];
this._toPropertyKey = a[1]
}
}
},
oneWay: function(c, a) {
if ((a === undefined) && (SC.typeOf(c) === SC.T_BOOL)) {
a = c;
c = null
}
var b = this.from(c);
if (b === SC.Binding) {
b = b.beget()
}
b._oneWay = (a === undefined) ? YES: a;
return b
},
transform: function(b) {
var c = (this === SC.Binding) ? this.beget() : this;
var a = c._transforms;
if (a && (a === c.parentBinding._transform)) {
a = c._transforms = a.slice()
}
if (!a) {
a = c._transforms = []
}
a.push(b);
return c
},
resetTransforms: function() {
var a = (this === SC.Binding) ? this.beget() : this;
a._transforms = null;
return a
},
noError: function(c, a) {
if ((a === undefined) && (SC.typeOf(c) === SC.T_BOOL)) {
a = c;
c = null
}
var b = this.from(c);
if (b === SC.Binding) {
b = b.beget()
}
b._noError = (a === undefined) ? YES: a;
return b
},
single: function(b, a) {
if (a === undefined) {
a = SC.MULTIPLE_PLACEHOLDER
}
return this.from(b).transform(function(e, d) {
if (e && e.isEnumerable) {
var c = e.get("length");
e = (c > 1) ? a: (c <= 0) ? null: e.firstObject()
}
return e
})
},
notEmpty: function(b, a) {
if (a === undefined) {
a = SC.EMPTY_PLACEHOLDER
}
return this.from(b).transform(function(d, c) {
if (SC.none(d) || (d === "") || (SC.isArray(d) && d.length === 0)) {
d = a
}
return d
})
},
notNull: function(b, a) {
if (a === undefined) {
a = SC.EMPTY_PLACEHOLDER
}
return this.from(b).transform(function(d, c) {
if (SC.none(d)) {
d = a
}
return d
})
},
multiple: function(a) {
return this.from(a).transform(function(b) {
if (!SC.isArray(b)) {
b = (b == null) ? [] : [b]
}
return b
})
},
bool: function(a) {
return this.from(a).transform(function(b) {
var c = SC.typeOf(b);
if (c === SC.T_ERROR) {
return b
}
return (c == SC.T_ARRAY) ? (b.length > 0) : (b === "") ? NO: !!b
})
},
not: function(a) {
return this.from(a).transform(function(b) {
var c = SC.typeOf(b);
if (c === SC.T_ERROR) {
return b
}
return ! ((c == SC.T_ARRAY) ? (b.length > 0) : (b === "") ? NO: !!b)
})
},
isNull: function(a) {
return this.from(a).transform(function(b) {
var c = SC.typeOf(b);
return (c === SC.T_ERROR) ? b: SC.none(b)
})
},
toString: function() {
var c = this._fromRoot ? "<%@>:%@".fmt(this._fromRoot, this._fromPropertyPath) : this._fromPropertyPath;
var b = this._toRoot ? "<%@>:%@".fmt(this._toRoot, this._toPropertyPath) : this._toPropertyPath;
var a = this._oneWay ? "[oneWay]": "";
return "SC.Binding%@(%@ -> %@)%@".fmt(SC.guidFor(this), c, b, a)
}
};
SC.binding = function(b, a) {
return SC.Binding.from(b, a)
};
SC.Cookie = SC.Object.extend({
name: null,
value: "",
expires: null,
path: null,
domain: null,
secure: NO,
isCookie: YES,
destroy: function() {
this.set("expires", -1);
this.write();
arguments.callee.base.apply(this, arguments)
},
write: function() {
var b = this.get("name"),
i = this.get("value"),
c = this.get("expires"),
k = this.get("path"),
e = this.get("domain"),
a = this.get("secure");
var h = "";
if (c && (SC.typeOf(c) === SC.T_NUMBER || (SC.DateTime && c.get && c.get("milliseconds")) || SC.typeOf(c.toUTCString) === SC.T_FUNCTION)) {
var d;
if (SC.typeOf(c) === SC.T_NUMBER) {
d = new Date();
d.setTime(d.getTime() + (c * 24 * 60 * 60 * 1000))
} else {
if (SC.DateTime && c.get && c.get("milliseconds")) {
d = new Date(c.get("milliseconds"))
} else {
if (SC.typeOf(c.toUTCString) === SC.T_FUNCTION) {
d = c
}
}
}
if (d) {
h = "; expires=" + d.toUTCString()
}
}
var j = k ? "; path=" + k: "";
var g = e ? "; domain=" + e: "";
var f = a ? "; secure": "";
document.cookie = [b, "=", encodeURIComponent(i), h, j, g, f].join("");
return this
}
});
SC.Cookie.mixin({
find: function(a) {
if (document.cookie && document.cookie != "") {
var d = document.cookie.split(";");
for (var c = 0; c < d.length; c++) {
var b = String(d[c]).trim();
if (b.substring(0, a.length + 1) === (a + "=")) {
return SC.Cookie.create({
name: a,
value: decodeURIComponent(b.substring(a.length + 1))
})
}
}
}
return null
}
});
SC.Error = SC.Object.extend({
code: -1,
message: "",
errorValue: null,
errorObject: function() {
return this
}.property().cacheable(),
label: null,
toString: function() {
return "SC.Error:%@:%@ (%@)".fmt(SC.guidFor(this), this.get("message"), this.get("code"))
},
isError: YES
});
SC.Error.desc = function(d, a, e, c) {
var b = {
message: d
};
if (a !== undefined) {
b.label = a
}
if (c !== undefined) {
b.code = c
}
if (e !== undefined) {
b.errorValue = e
}
return this.create(b)
};
SC.$error = function(b, a, d, e) {
return SC.Error.desc(b, a, d, e)
};
SC.ok = function(a) {
return (a !== false) && !(a && a.isError)
};
SC.$ok = SC.ok;
SC.val = function(a) {
if (a && a.isError) {
return a.get ? a.get("errorValue") : null
} else {
return a
}
};
SC.$val = SC.val;
SC.Error.HAS_MULTIPLE_VALUES = -100;
sc_require("mixins/enumerable");
sc_require("mixins/observable");
sc_require("mixins/freezable");
sc_require("mixins/copyable");
SC.IndexSet = SC.mixin({},
SC.Enumerable, SC.Observable, SC.Freezable, SC.Copyable, {
_sc_sliceContent: function(e) {
if (e.length < 1000) {
return e.slice()
}
var d = 0,
a = [],
b = e[0];
while (b !== 0) {
a[d] = b;
d = (b < 0) ? (0 - b) : b;
b = e[d]
}
a[d] = 0;
this._hint(0, d, a);
return a
},
create: function(c, b) {
var a = SC.beget(this);
a.initObservable();
if (c && c.isIndexSet) {
a._content = this._sc_sliceContent(c._content);
a.max = c.max;
a.length = c.length;
a.source = c.source
} else {
a._content = [0];
if (c !== undefined) {
a.add(c, b)
}
}
return a
},
isIndexSet: YES,
HINT_SIZE: 256,
length: 0,
max: 0,
min: function() {
var a = this._content,
b = a[0];
return (b === 0) ? -1: (b > 0) ? 0: Math.abs(b)
}.property("[]").cacheable(),
firstObject: function() {
return (this.get("length") > 0) ? this.get("min") : undefined
}.property(),
rangeStartForIndex: function(c) {
var f = this._content,
a = this.get("max"),
b,
e,
d;
if (c >= a) {
return a
}
if (Math.abs(f[c]) > c) {
return c
}
d = c - (c % SC.IndexSet.HINT_SIZE);
b = f[d];
if (b < 0 || b > c) {
b = d
}
e = Math.abs(f[b]);
while (e < c) {
b = e;
e = Math.abs(f[b])
}
return b
},
isEqual: function(c) {
if (c === this) {
return YES
}
if (!c || !c.isIndexSet || (c.max !== this.max) || (c.length !== this.length)) {
return NO
}
var e = this._content,
b = c._content,
d = 0,
a = e[d];
do {
if (b[d] !== a) {
return NO
}
d = Math.abs(a);
a = e[d]
}
while (d !== 0);
return YES
},
indexBefore: function(b) {
if (b === 0) {
return - 1
}
b--;
var c = this._content,
a = this.get("max"),
d = this.rangeStartForIndex(b);
if (!c) {
return null
}
while ((d === a) || (c[d] < 0)) {
if (d === 0) {
return - 1
}
b = d - 1;
d = this.rangeStartForIndex(b)
}
return b
},
indexAfter: function(b) {
var d = this._content,
a = this.get("max"),
e,
c;
if (!d || (b >= a)) {
return - 1
}
b++;
e = this.rangeStartForIndex(b);
c = d[e];
while (c < 0) {
if (c === 0) {
return - 1
}
b = e = Math.abs(c);
c = d[e]
}
return b
},
contains: function(g, c) {
var b,
f,
a,
e,
d;
if (c === undefined) {
if (g === null || g === undefined) {
return NO
}
if (typeof g === SC.T_NUMBER) {
c = 1
} else {
if (g && g.isIndexSet) {
if (g === this) {
return YES
}
b = g._content;
f = 0;
a = b[f];
while (a !== 0) {
if ((a > 0) && !this.contains(f, a - f)) {
return NO
}
f = Math.abs(a);
a = b[f]
}
return YES
} else {
c = g.length;
g = g.start
}
}
}
e = this.rangeStartForIndex(g);
d = this._content[e];
return (d > 0) && (e <= g) && (d >= (g + c))
},
intersects: function(f, c) {
var b,
e,
a,
d;
if (c === undefined) {
if (typeof f === SC.T_NUMBER) {
c = 1
} else {
if (f && f.isIndexSet) {
if (f === this) {
return YES
}
b = f._content;
e = 0;
a = b[e];
while (a !== 0) {
if ((a > 0) && this.intersects(e, a - e)) {
return YES
}
e = Math.abs(a);
a = b[e]
}
return NO
} else {
c = f.length;
f = f.start
}
}
}
e = this.rangeStartForIndex(f);
b = this._content;
a = b[e];
d = f + c;
while (e < d) {
if (a === 0) {
return NO
}
if ((a > 0) && (a > f)) {
return YES
}
e = Math.abs(a);
a = b[e]
}
return NO
},
without: function(b, a) {
if (b === this) {
return SC.IndexSet.create()
}
return this.clone().remove(b, a)
},
replace: function(c, a) {
if (a === undefined) {
if (typeof c === SC.T_NUMBER) {
a = 1
} else {
if (c && c.isIndexSet) {
this._content = this._sc_sliceContent(c._content);
this.beginPropertyChanges().set("max", c.max).set("length", c.length).set("source", c.source).enumerableContentDidChange().endPropertyChanges();
return this
} else {
a = c.length;
c = c.start
}
}
}
var b = this.length;
this._content.length = 1;
this._content[0] = 0;
this.length = this.max = 0;
return this.add(c, a)
},
add: function(a, b) {
if (this.isFrozen) {
throw SC.FROZEN_ERROR
}
var e,
i,
d;
if (a && a.isIndexSet) {
e = a._content;
if (!e) {
return this
}
i = 0;
d = e[0];
while (d !== 0) {
if (d > 0) {
this.add(i, d - i)
}
i = d < 0 ? 0 - d: d;
d = e[i]
}
return this
} else {
if (b === undefined) {
if (a === null || a === undefined) {
return this
} else {
if (typeof a === SC.T_NUMBER) {
b = 1
} else {
b = a.length;
a = a.start
}
}
} else {
if (b === null) {
b = 1
}
}
}
if (b <= 0) {
return this
}
var f = this.get("max"),
c = f,
h,
g;
e = this._content;
if (a === f) {
if (a > 0) {
i = this.rangeStartForIndex(a - 1);
d = e[i];
if (d > 0) {
delete e[f];
e[i] = f = a + b;
a = i
} else {
e[f] = f = a + b
}
} else {
e[a] = f = b
}
e[f] = 0;
this.set("max", f);
this.set("length", this.length + b);
b = f - a
} else {
if (a > f) {
e[f] = 0 - a;
e[a] = a + b;
e[a + b] = 0;
this.set("max", a + b);
this.set("length", this.length + b);
b = a + b - f;
a = f
} else {
i = this.rangeStartForIndex(a);
d = e[i];
f = a + b;
h = 0;
if ((a > 0) && (i === a) && (d <= 0)) {
i = this.rangeStartForIndex(a - 1);
d = e[i]
}
if (d < 0) {
e[i] = 0 - a;
if (Math.abs(d) > f) {
e[a] = 0 - f;
e[f] = d
} else {
e[a] = d
}
} else {
a = i;
if (d > f) {
f = d
}
}
i = a;
while (i < f) {
g = e[i];
if (g === 0) {
e[f] = 0;
d = f;
h += f - i
} else {
d = Math.abs(g);
if (d > f) {
e[f] = g;
d = f
}
if (g < 0) {
h += d - i
}
}
delete e[i];
i = d
}
if ((i = e[f]) > 0) {
delete e[f];
f = i
}
e[a] = f;
if (f > c) {
this.set("max", f)
}
this.set("length", this.get("length") + h);
b = f - a
}
}
this._hint(a, b);
if (h !== 0) {
this.enumerableContentDidChange()
}
return this
},
remove: function(a, b) {
if (this.isFrozen) {
throw SC.FROZEN_ERROR
}
if (b === undefined) {
if (a === null || a === undefined) {
return this
} else {
if (typeof a === SC.T_NUMBER) {
b = 1
} else {
if (a.isIndexSet) {
a.forEachRange(this.remove, this);
return this
} else {
b = a.length;
a = a.start
}
}
}
}
if (b <= 0) {
return this
}
var f = this.get("max"),
c = f,
e = this._content,
j,
d,
i,
g,
h;
if (a >= f) {
return this
}
j = this.rangeStartForIndex(a);
d = e[j];
h = a + b;
i = 0;
if ((a > 0) && (j === a) && (d > 0)) {
j = this.rangeStartForIndex(a - 1);
d = e[j]
}
if (d > 0) {
e[j] = a;
if (d > h) {
e[a] = h;
e[h] = d
} else {
e[a] = d
}
} else {
a = j;
d = Math.abs(d);
if (d > h) {
h = d
}
}
j = a;
while (j < h) {
g = e[j];
if (g === 0) {
e[h] = 0;
d = h
} else {
d = Math.abs(g);
if (d > h) {
e[h] = g;
d = h
}
if (g > 0) {
i += d - j
}
}
delete e[j];
j = d
}
if ((j = e[h]) < 0) {
delete e[h];
h = Math.abs(j)
}
if (e[h] === 0) {
delete e[h];
e[a] = 0;
this.set("max", a)
} else {
e[a] = 0 - h
}
this.set("length", this.get("length") - i);
b = h - a;
this._hint(a, b);
if (i !== 0) {
this.enumerableContentDidChange()
}
return this
},
_hint: function(g, d, c) {
if (c === undefined) {
c = this._content
}
var b = SC.IndexSet.HINT_SIZE,
a = Math.abs(c[g]),
f = g - (g % b) + b,
e = g + d;
while (f < e) {
while ((a !== 0) && (a <= f)) {
g = a;
a = Math.abs(c[g])
}
if (a === 0) {
delete c[f]
} else {
if (f !== g) {
c[f] = g
}
}
f += b
}
},
clear: function() {
if (this.isFrozen) {
throw SC.FROZEN_ERROR
}
var a = this.length;
this._content.length = 1;
this._content[0] = 0;
this.set("length", 0).set("max", 0);
if (a > 0) {
this.enumerableContentDidChange()
}
},
addEach: function(b) {
if (this.isFrozen) {
throw SC.FROZEN_ERROR
}
this.beginPropertyChanges();
var a = b.get("length");
if (b.isSCArray) {
while (--a >= 0) {
this.add(b.objectAt(a))
}
} else {
if (b.isEnumerable) {
b.forEach(function(c) {
this.add(c)
},
this)
}
}
this.endPropertyChanges();
return this
},
removeEach: function(b) {
if (this.isFrozen) {
throw SC.FROZEN_ERROR
}
this.beginPropertyChanges();
var a = b.get("length");
if (b.isSCArray) {
while (--a >= 0) {
this.remove(b.objectAt(a))
}
} else {
if (b.isEnumerable) {
b.forEach(function(c) {
this.remove(c)
},
this)
}
}
this.endPropertyChanges();
return this
},
clone: function() {
return SC.IndexSet.create(this)
},
inspect: function() {
var e = this._content,
b = e.length,
a = 0,
c = [],
d;
for (a = 0; a < b; a++) {
d = e[a];
if (d !== undefined) {
c.push("%@:%@".fmt(a, d))
}
}
return "SC.IndexSet<%@>".fmt(c.join(" , "))
},
forEachRange: function(f, d) {
var b = this._content,
e = 0,
a = b[e],
c = this.source;
if (d === undefined) {
d = null
}
while (a !== 0) {
if (a > 0) {
f.call(d, e, a - e, this, c)
}
e = Math.abs(a);
a = b[e]
}
return this
},
forEachIn: function(b, c, j, f) {
var g = this._content,
i = 0,
h = 0,
d = b + c,
a = this.source,
e = g[i];
if (f === undefined) {
f = null
}
while (e !== 0) {
if (i < b) {
i = b
}
while ((i < e) && (i < d)) {
j.call(f, i++, h++, this, a)
}
if (i >= d) {
i = e = 0
} else {
i = Math.abs(e);
e = g[i]
}
}
return this
},
lengthIn: function(g, d) {
var a = 0;
if (d === undefined) {
if (g === null || g === undefined) {
return 0
} else {
if (typeof g === SC.T_NUMBER) {
d = 1
} else {
if (g.isIndexSet) {
g.forEachRange(function(i, h) {
a += this.lengthIn(i, h)
},
this);
return a
} else {
d = g.length;
g = g.start
}
}
}
}
if (this.get("length") === 0) {
return 0
}
var c = this._content,
f = 0,
b = c[f],
e = g + d;
while (f < e && b !== 0) {
if (b > 0) {
a += (b > e) ? e - f: b - f
}
f = Math.abs(b);
b = c[f]
}
return a
},
source: null,
indexOf: function(d, c) {
var f = this.source;
if (!f) {
throw "%@.indexOf() requires source".fmt(this)
}
var b = f.get("length"),
e = this._content,
g = e[0] < 0 ? Math.abs(e[0]) : 0,
a;
while (g >= 0 && g < b) {
a = f.indexOf(d, g);
if (a < 0) {
return - 1
}
if (this.contains(a)) {
return a
}
g = a + 1
}
return - 1
},
lastIndexOf: function(d, c) {
var e = this.source;
if (!e) {
throw "%@.lastIndexOf() requires source".fmt(this)
}
var b = e.get("length"),
f = this.max - 1,
a;
if (f >= b) {
f = b - 1
}
while (f >= 0) {
a = e.lastIndexOf(d, f);
if (a < 0) {
return - 1
}
if (this.contains(a)) {
return a
}
f = a + 1
}
return - 1
},
forEachObject: function(g, e) {
var d = this.source;
if (!d) {
throw "%@.forEachObject() requires source".fmt(this)
}
var c = this._content,
f = 0,
a = 0,
b = c[f];
if (e === undefined) {
e = null
}
while (b !== 0) {
while (f < b) {
g.call(e, d.objectAt(f), f, d, this);
f++
}
f = Math.abs(b);
b = c[f]
}
return this
},
addObject: function(c, d) {
var e = this.source;
if (!e) {
throw "%@.addObject() requires source".fmt(this)
}
var b = e.get("length"),
f = 0,
a;
while (f >= 0 && f < b) {
a = e.indexOf(c, f);
if (a >= 0) {
this.add(a);
if (d) {
return this
}
f = a++
} else {
return this
}
}
return this
},
addObjects: function(b, a) {
b.forEach(function(c) {
this.addObject(c, a)
},
this);
return this
},
removeObject: function(c, d) {
var e = this.source;
if (!e) {
throw "%@.removeObject() requires source".fmt(this)
}
var b = e.get("length"),
f = 0,
a;
while (f >= 0 && f < b) {
a = e.indexOf(c, f);
if (a >= 0) {
this.remove(a);
if (d) {
return this
}
f = a + 1
} else {
return this
}
}
return this
},
removeObjects: function(b, a) {
b.forEach(function(c) {
this.removeObject(c, a)
},
this);
return this
},
LOG_OBSERVING: NO,
forEach: function(g, e) {
var c = this._content,
f = 0,
a = 0,
d = this.source,
b = c[f];
if (e === undefined) {
e = null
}
while (b !== 0) {
while (f < b) {
g.call(e, f++, a++, this, d)
}
f = Math.abs(b);
b = c[f]
}
return this
},
nextObject: function(f, b, c) {
var e = this._content,
d = c.next,
a = this.get("max");
if (b === null) {
b = d = 0
} else {
if (b >= a) {
delete c.next;
return null
} else {
b++
}
}
if (b === d) {
do {
b = Math.abs(d);
d = e[b]
}
while (d < 0);
c.next = d
}
return b
},
toString: function() {
var a = [];
this.forEachRange(function(c, b) {
a.push(b === 1 ? c: "%@..%@".fmt(c, c + b - 1))
},
this);
return "SC.IndexSet<%@>".fmt(a.join(","))
},
max: 0
});
SC.IndexSet.slice = SC.IndexSet.copy = SC.IndexSet.clone;
SC.IndexSet.EMPTY = SC.IndexSet.create().freeze();
SC.LOGGER_LOG_DELIMITER = ", ";
SC.LOGGER_LOG_ERROR = "ERROR: ";
SC.LOGGER_LOG_INFO = "INFO: ";
SC.LOGGER_LOG_WARN = "WARNING: ";
SC.Logger = SC.Object.create({
exists: function() {
return typeof(this.get("reporter")) !== "undefined" && this.get("reporter") != null
}.property("reporter").cacheable(),
fallBackOnAlert: NO,
fallBackOnLog: YES,
format: YES,
reporter: SC.console,
log: function() {
var a = this.get("reporter");
if (this.get("exists") && typeof(a.log) === "function") {
if (this.get("format")) {
a.log(this._argumentsToString.apply(this, arguments))
} else {
a.log.apply(a, arguments)
}
return true
} else {
if (this.fallBackOnAlert) {
var b = this.get("format") ? this._argumentsToString.apply(this, arguments) : arguments;
if (this.get("exists") && typeof(a.alert) === "function") {
a.alert(b)
} else {
alert(b)
}
return true
}
}
return false
},
dir: function() {
var a = this.get("reporter");
if (this.get("exists") && typeof(a.dir) === "function") {
a.dir.apply(a, arguments);
return true
}
return (this.fallBackOnLog) ? this.log.apply(this, arguments) : false
},
dirxml: function() {
var a = this.get("reporter");
if (this.get("exists") && typeof(a.dirxml) === "function") {
a.dirxml.apply(a, arguments);
return true
}
return (this.fallBackOnLog) ? this.log.apply(this, arguments) : false
},
error: function() {
var c = this.get("reporter");
if (this.get("exists") && typeof(c.error) === "function") {
c.error.apply(c, arguments);
return true
} else {
if (this.fallBackOnLog) {
var b = this._argumentsToArray(arguments);
if (typeof(b.unshift) === "function") {
b.unshift(SC.LOGGER_LOG_ERROR)
}
return this.log.apply(this, b)
}
}
return false
},
group: function(b) {
var a = this.get("reporter");
if (this.get("exists") && typeof(a.group) === "function") {
a.group(b);
return true
}
return false
},
groupEnd: function() {
var a = this.get("reporter");
if (this.get("exists") && typeof(a.groupEnd) === "function") {
a.groupEnd();
return true
}
return false
},
info: function() {
var c = this.get("reporter");
if (this.get("exists") && typeof(c.info) === "function") {
c.info.apply(c, arguments);
return true
} else {
if (this.fallBackOnLog) {
var b = this._argumentsToArray(arguments);
if (typeof(b.unshift) === "function") {
b.unshift(SC.LOGGER_LOG_INFO)
}
return this.log.apply(this, b)
}
}
return false
},
profile: function() {
var a = this.get("reporter");
if (this.get("exists") && typeof(a.profile) === "function") {
a.profile();
return true
}
return false
},
profileEnd: function() {
var a = this.get("reporter");
if (this.get("exists") && typeof(a.profileEnd) === "function") {
a.profileEnd();
return true
}
return false
},
time: function(b) {
var a = this.get("reporter");
if (this.get("exists") && typeof(a.time) === "function") {
a.time(b);
return true
}
return false
},
timeEnd: function(b) {
var a = this.get("reporter");
if (this.get("exists") && typeof(a.timeEnd) === "function") {
a.timeEnd(b);
return true
}
return false
},
trace: function() {
var a = this.get("reporter");
if (this.get("exists") && typeof(a.trace) === "function") {
a.trace();
return true
}
return false
},
warn: function() {
var c = this.get("reporter");
if (this.get("exists") && typeof(c.warn) === "function") {
c.warn.apply(c, arguments);
return true
} else {
if (this.fallBackOnLog) {
var b = this._argumentsToArray(arguments);
if (typeof(b.unshift) === "function") {
b.unshift(SC.LOGGER_LOG_WARN)
}
return this.log.apply(this, b)
}
}
return false
},
_argumentsToArray: function(d) {
if (!d) {
return []
}
var b = [];
for (var c = 0; c < d.length; c++) {
b[c] = d[c]
}
return b
},
_argumentsToString: function() {
var b = "";
for (var a = 0; a < arguments.length - 1; a++) {
b += arguments[a] + SC.LOGGER_LOG_DELIMITER
}
b += arguments[arguments.length - 1];
return b
}
});
sc_require("private/observer_set");
SC.RunLoop = SC.Object.extend({
beginRunLoop: function() {
this._start = new Date().getTime();
if (SC.LOG_BINDINGS || SC.LOG_OBSERVERS) {
console.log("-- SC.RunLoop.beginRunLoop at %@".fmt(this._start))
}
return this
},
endRunLoop: function() {
var a;
if (SC.LOG_BINDINGS || SC.LOG_OBSERVERS) {
console.log("-- SC.RunLoop.endRunLoop ~ flushing application queues")
}
do {
a = this.flushApplicationQueues();
if (!a) {
a = this._flushinvokeLastQueue()
}
}
while (a);
this._start = null;
if (SC.LOG_BINDINGS || SC.LOG_OBSERVERS) {
console.log("-- SC.RunLoop.endRunLoop ~ End")
}
return this
},
invokeOnce: function(a, b) {
if (b === undefined) {
b = a;
a = this
}
if (SC.typeOf(b) === SC.T_STRING) {
b = a[b]
}
if (!this._invokeQueue) {
this._invokeQueue = SC.ObserverSet.create()
}
this._invokeQueue.add(a, b);
return this
},
invokeLast: function(a, b) {
if (b === undefined) {
b = a;
a = this
}
if (SC.typeOf(b) === SC.T_STRING) {
b = a[b]
}
if (!this._invokeLastQueue) {
this._invokeLastQueue = SC.ObserverSet.create()
}
this._invokeLastQueue.add(a, b);
return this
},
flushApplicationQueues: function() {
var b = NO;
var a = this._invokeQueue;
if (a && a.targets > 0) {
this._invokeQueue = null;
b = YES;
a.invokeMethods()
}
return SC.Binding.flushPendingChanges() || b
},
_flushinvokeLastQueue: function() {
var a = this._invokeLastQueue,
b = NO;
if (a && a.targets > 0) {
this._invokeLastQueue = null;
b = YES;
if (b) {
a.invokeMethods()
}
}
return b
}
});
SC.RunLoop.currentRunLoop = null;
SC.RunLoop.runLoopClass = SC.RunLoop;
SC.RunLoop.begin = function() {
var a = this.currentRunLoop;
if (!a) {
a = this.currentRunLoop = this.runLoopClass.create()
}
a.beginRunLoop();
return this
};
SC.RunLoop.end = function() {
var a = this.currentRunLoop;
if (!a) {
throw "SC.RunLoop.end() called outside of a runloop!"
}
a.endRunLoop();
return this
};
SC.run = function(b, a) {
SC.RunLoop.begin();
b.call(a);
SC.RunLoop.end()
};
sc_require("system/object");
sc_require("mixins/enumerable");
sc_require("mixins/copyable");
sc_require("mixins/freezable");
SC.SelectionSet = SC.Object.extend(SC.Enumerable, SC.Freezable, SC.Copyable, {
isSelectionSet: YES,
length: function() {
var a = 0,
b = this._sets,
c = this._objects;
if (c) {
a += c.get("length")
}
if (b) {
b.forEach(function(d) {
a += d.get("length")
})
}
return a
}.property().cacheable(),
sources: function() {
var c = [],
d = this._sets,
b = d ? d.length: 0,
a,
f,
e;
for (a = 0; a < b; a++) {
f = d[a];
if (f && f.get("length") > 0 && f.source) {
c.push(f.source)
}
}
return c
}.property().cacheable(),
indexSetForSource: function(e) {
if (!e || !e.isSCArray) {
return null
}
var b = this._indexSetCache,
d = this._objects,
c,
a;
if (!b) {
b = this._indexSetCache = {}
}
c = b[SC.guidFor(e)];
if (c && c._sourceRevision && (c._sourceRevision !== e.propertyRevision)) {
c = null
}
if (!c) {
c = this._indexSetForSource(e, NO);
if (c && c.get("length") === 0) {
c = null
}
if (d) {
if (c) {
c = c.copy()
}
d.forEach(function(f) {
if ((a = e.indexOf(f)) >= 0) {
if (!c) {
c = SC.IndexSet.create()
}
c.add(a)
}
},
this)
}
if (c) {
c = b[SC.guidFor(e)] = c.frozenCopy();
c._sourceRevision = e.propertyRevision
}
}
return c
},
_indexSetForSource: function(f, g) {
if (g === undefined) {
g = YES
}
var d = SC.guidFor(f),
c = this[d],
e = this._sets,
a = e ? e.length: 0,
b = null;
if (c >= a) {
c = null
}
if (SC.none(c)) {
if (g && !this.isFrozen) {
this.propertyWillChange("sources");
if (!e) {
e = this._sets = []
}
b = e[a] = SC.IndexSet.create();
b.source = f;
this[d] = a;
this.propertyDidChange("sources")
}
} else {
b = e ? e[c] : null
}
return b
},
add: function(a, b, d) {
if (this.isFrozen) {
throw SC.FROZEN_ERROR
}
var g,
f,
j,
i,
c,
e,
h,
k;
if (b === undefined && d === undefined) {
if (!a) {
throw "Must pass params to SC.SelectionSet.add()"
}
if (a.isIndexSet) {
return this.add(a.source, a)
}
if (a.isSelectionSet) {
g = a._sets;
k = a._objects;
f = g ? g.length: 0;
this.beginPropertyChanges();
for (j = 0; j < f; j++) {
i = g[j];
if (i && i.get("length") > 0) {
this.add(i.source, i)
}
}
if (k) {
this.addObjects(k)
}
this.endPropertyChanges();
return this
}
}
i = this._indexSetForSource(a, YES);
c = this.get("length");
h = i.get("length");
e = c - h;
i.add(b, d);
this._indexSetCache = null;
e += i.get("length");
if (e !== c) {
this.propertyDidChange("length");
this.enumerableContentDidChange();
if (h === 0) {
this.notifyPropertyChange("sources")
}
}
return this
},
remove: function(a, b, d) {
if (this.isFrozen) {
throw SC.FROZEN_ERROR
}
var g,
f,
j,
i,
c,
e,
h,
k;
if (b === undefined && d === undefined) {
if (!a) {
throw "Must pass params to SC.SelectionSet.remove()"
}
if (a.isIndexSet) {
return this.remove(a.source, a)
}
if (a.isSelectionSet) {
g = a._sets;
k = a._objects;
f = g ? g.length: 0;
this.beginPropertyChanges();
for (j = 0; j < f; j++) {
i = g[j];
if (i && i.get("length") > 0) {
this.remove(i.source, i)
}
}
if (k) {
this.removeObjects(k)
}
this.endPropertyChanges();
return this
}
}
i = this._indexSetForSource(a, YES);
c = this.get("length");
e = c - i.get("length");
if (i && (k = this._objects)) {
if (d !== undefined) {
b = SC.IndexSet.create(b, d);
d = undefined
}
k.forEach(function(l) {
j = a.indexOf(l);
if (b.contains(j)) {
k.remove(l);
e--
}
},
this)
}
i.remove(b, d);
h = i.get("length");
e += h;
this._indexSetCache = null;
if (e !== c) {
this.propertyDidChange("length");
this.enumerableContentDidChange();
if (h === 0) {
this.notifyPropertyChange("sources")
}
}
return this
},
contains: function(b, d, a) {
if (d === undefined && a === undefined) {
return this.containsObject(b)
}
var c = this.indexSetForSource(b);
if (!c) {
return NO
}
return c.contains(d, a)
},
intersects: function(b, d, a) {
var c = this.indexSetForSource(b, NO);
if (!c) {
return NO
}
return c.intersects(d, a)
},
_TMP_ARY: [],
addObject: function(b) {
var c = this._TMP_ARY,
a;
c[0] = b;
a = this.addObjects(c);
c.length = 0;
return a
},
addObjects: function(a) {
var d = this._objects,
b,
c;
if (!d) {
d = this._objects = SC.CoreSet.create()
}
b = d.get("length");
d.addEach(a);
c = d.get("length");
this._indexSetCache = null;
if (c !== b) {
this.propertyDidChange("length");
this.enumerableContentDidChange()
}
return this
},
removeObject: function(b) {
var c = this._TMP_ARY,
a;
c[0] = b;
a = this.removeObjects(c);
c.length = 0;
return a
},
removeObjects: function(b) {
var e = this._objects,
c,
d,
a;
if (!e) {
return this
}
c = e.get("length");
e.removeEach(b);
d = e.get("length");
if (a = this._sets) {
a.forEach(function(f) {
c += f.get("length");
f.removeObjects(b);
d += f.get("length")
},
this)
}
this._indexSetCache = null;
if (d !== c) {
this.propertyDidChange("length");
this.enumerableContentDidChange()
}
return this
},
containsObject: function(c) {
var e = this._objects;
if (e && e.contains(c)) {
return YES
}
var d = this._sets,
b = d ? d.length: 0,
a,
f;
for (a = 0; a < b; a++) {
f = d[a];
if (f && f.indexOf(c) >= 0) {
return YES
}
}
return NO
},
constrain: function(d) {
var e,
b,
a,
c;
this.beginPropertyChanges();
this.get("sources").forEach(function(f) {
if (f === d) {
return
}
var g = this._indexSetForSource(d, NO);
if (g) {
this.remove(d, g)
}
},
this);
e = this._indexSetForSource(d, NO);
if (e && ((a = e.get("max")) > (b = d.get("length")))) {
this.remove(d, b, a - b)
}
if (c = this._objects) {
c.forEach(function(f) {
if (d.indexOf(f) < 0) {
this.removeObject(f)
}
},
this)
}
this.endPropertyChanges();
return this
},
isEqual: function(g) {
var f,
d,
b,
a,
c,
e;
if (!g || !g.isSelectionSet) {
return NO
}
if (g === this) {
return YES
}
if ((this._sets === g._sets) && (this._objects === g._objects)) {
return YES
}
if (this.get("length") !== g.get("length")) {
return NO
}
f = this._objects;
d = g._objects;
if (f || d) {
if ((f ? f.get("length") : 0) !== (d ? d.get("length") : 0)) {
return NO
}
if (f && !f.isEqual(d)) {
return NO
}
}
c = this.get("sources");
a = c.get("length");
for (b = 0; b < a; b++) {
e = c.objectAt(b);
f = this._indexSetForSource(e, NO);
d = this._indexSetForSource(e, NO);
if ( !! d !== !!f) {
return NO
}
if (f && !f.isEqual(d)) {
return NO
}
}
return YES
},
clear: function() {
if (this.isFrozen) {
throw SC.FROZEN_ERROR
}
if (this._sets) {
this._sets.length = 0
}
if (this._objects) {
this._objects = null
}
this._indexSetCache = null;
this.propertyDidChange("length");
this.enumerableContentDidChange();
this.notifyPropertyChange("sources");
return this
},
copy: function() {
var c = this.constructor.create(),
d = this._sets,
b = d ? d.length: 0,
a,
e;
if (d && b > 0) {
d = c._sets = d.slice();
for (a = 0; a < b; a++) {
if (! (e = d[a])) {
continue
}
e = d[a] = e.copy();
c[SC.guidFor(e.source)] = a
}
}
if (this._objects) {
c._objects = this._objects.copy()
}
return c
},
freeze: function() {
if (this.isFrozen) {
return this
}
var a = this._sets,
b = a ? a.length: 0,
c;
while (--b >= 0) {
if (c = a[b]) {
c.freeze()
}
}
if (this._objects) {
this._objects.freeze()
}
return arguments.callee.base.apply(this, arguments)
},
toString: function() {
var a = this._sets || [];
a = a.map(function(b) {
return b.toString().replace("SC.IndexSet", SC.guidFor(b.source))
},
this);
if (this._objects) {
a.push(this._objects.toString())
}
return "SC.SelectionSet:%@<%@>".fmt(SC.guidFor(this), a.join(","))
},
firstObject: function() {
var b = this._sets,
c = this._objects;
if (b && b.get("length") > 0) {
var e = b ? b[0] : null,
d = e ? e.source: null,
a = e ? e.firstObject() : -1;
if (d && a >= 0) {
return d.objectAt(a)
}
}
return c ? c.firstObject() : undefined
}.property(),
nextObject: function(c, e, b) {
var d,
a;
if (c === 0) {
d = b.objects = [];
this.forEach(function(f) {
d.push(f)
},
this);
b.max = d.length
}
d = b.objects;
a = d[c];
if (c + 1 >= b.max) {
b.objects = b.max = null
}
return a
},
forEach: function(g, e) {
var c = this._sets,
d = this._objects,
b = c ? c.length: 0,
f,
a;
for (a = 0; a < b; a++) {
f = c[a];
if (f) {
f.forEachObject(g, e)
}
}
if (d) {
d.forEach(g, e)
}
return this
}
});
SC.SelectionSet.prototype.clone = SC.SelectionSet.prototype.copy;
SC.SelectionSet.EMPTY = SC.SelectionSet.create().freeze();
sc_require("mixins/enumerable");
sc_require("mixins/array");
sc_require("mixins/observable");
sc_require("mixins/delegate_support");
SC.SparseArray = SC.Object.extend(SC.Observable, SC.Enumerable, SC.Array, SC.DelegateSupport, {
_requestingLength: 0,
_requestingIndex: 0,
length: function() {
var a = this.delegate;
if (a && SC.none(this._length) && a.sparseArrayDidRequestLength) {
this._requestingLength++;
a.sparseArrayDidRequestLength(this);
this._requestingLength--
}
return this._length || 0
}.property().cacheable(),
provideLength: function(a) {
if (SC.none(a)) {
this._sa_content = null
}
if (a !== this._length) {
this._length = a;
if (this._requestingLength <= 0) {
this.enumerableContentDidChange()
}
}
return this
},
rangeWindowSize: 1,
requestedRangeIndex: [],
objectAt: function(a) {
var c = this._sa_content,
b;
if (!c) {
c = this._sa_content = []
}
if ((b = c[a]) === undefined) {
this.requestIndex(a);
b = c[a]
}
return b
},
definedIndexes: function(d) {
var c = SC.IndexSet.create(),
e = this._sa_content,
b,
a;
if (!e) {
return c.freeze()
}
if (d) {
d.forEach(function(f) {
if (e[f] !== undefined) {
c.add(f)
}
})
} else {
a = e.length;
for (b = 0; b < a; b++) {
if (e[b] !== undefined) {
c.add(b)
}
}
}
return c.freeze()
},
_TMP_RANGE: {},
requestIndex: function(b) {
var c = this.delegate;
if (!c) {
return this
}
var a = this.get("rangeWindowSize"),
e = b;
if (a > 1) {
e = e - Math.floor(e % a)
}
if (a < 1) {
a = 1
}
this._requestingIndex++;
if (c.sparseArrayDidRequestRange) {
var d = this._TMP_RANGE;
if (this.wasRangeRequested(e) === -1) {
d.start = e;
d.length = a;
c.sparseArrayDidRequestRange(this, d);
this.requestedRangeIndex.push(e)
}
} else {
if (c.sparseArrayDidRequestIndex) {
while (--a >= 0) {
c.sparseArrayDidRequestIndex(this, e + a)
}
}
}
this._requestingIndex--;
return this
},
wasRangeRequested: function(c) {
var b,
a;
for (b = 0, a = this.requestedRangeIndex.length;
b < a; b++) {
if (this.requestedRangeIndex[b] === c) {
return b
}
}
return - 1
},
rangeRequestCompleted: function(b) {
var a = this.wasRangeRequested(b);
if (a >= 0) {
this.requestedRangeIndex.removeAt(a, 1);
return YES
}
return NO
},
provideObjectsInRange: function(b, e) {
var c = this._sa_content;
if (!c) {
c = this._sa_content = []
}
var d = b.start,
a = b.length;
while (--a >= 0) {
c[d + a] = e[a]
}
if (this._requestingIndex <= 0) {
this.enumerableContentDidChange()
}
return this
},
_TMP_PROVIDE_ARRAY: [],
_TMP_PROVIDE_RANGE: {
length: 1
},
provideObjectAtIndex: function(c, b) {
var d = this._TMP_PROVIDE_ARRAY,
a = this._TMP_PROVIDE_RANGE;
d[0] = b;
a.start = c;
return this.provideObjectsInRange(a, d)
},
objectsDidChangeInRange: function(a) {
var b = this._sa_content;
if (b) {
if (a.start === 0 && SC.maxRange(a) >= b.length) {
this._sa_content = null
} else {
var d = a.start,
c = Math.min(d + a.length, b.length);
while (--c >= d) {
b[c] = undefined
}
}
}
this.enumerableContentDidChange(a);
return this
},
indexOf: function(c) {
var a = this.delegate;
if (a && a.sparseArrayDidRequestIndexOf) {
return a.sparseArrayDidRequestIndexOf(this, c)
} else {
var b = this._sa_content;
if (!b) {
b = this._sa_content = []
}
return b.indexOf(c)
}
},
replace: function(b, g, e) {
e = e || [];
var c = this.delegate;
if (c) {
if (!c.sparseArrayShouldReplace || !c.sparseArrayShouldReplace(this, b, g, e)) {
return this
}
}
var d = this._sa_content;
if (!d) {
d = this._sa_content = []
}
d.replace(b, g, e);
var a = e ? (e.get ? e.get("length") : e.length) : 0;
var f = a - g;
if (!SC.none(this._length)) {
this.propertyWillChange("length");
this._length += f;
this.propertyDidChange("length")
}
this.enumerableContentDidChange(b, g, f);
return this
},
reset: function() {
this._sa_content = null;
this._length = null;
this.enumerableContentDidChange();
this.invokeDelegateMethod(this.delegate, "sparseArrayDidReset", this);
return this
}
});
SC.SparseArray.array = function(a) {
return this.create({
_length: a || 0
})
};
if ((typeof SC !== "undefined") && SC && SC.bundleDidLoad) {
SC.bundleDidLoad("sproutcore/runtime")
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment