Resources/js/can.jquery-1.1.6.js
changeset 0 80c32ef237c6
equal deleted inserted replaced
-1:000000000000 0:80c32ef237c6
       
     1 /*!
       
     2  * CanJS - 1.1.6
       
     3  * http://canjs.us/
       
     4  * Copyright (c) 2013 Bitovi
       
     5  * Mon, 15 Jul 2013 04:14:43 GMT
       
     6  * Licensed MIT
       
     7  * Includes: can/construct/construct.js,can/observe/observe.js,can/observe/compute/compute.js,can/model/model.js,can/view/view.js,can/view/ejs/ejs.js,can/control/control.js,can/route/route.js,can/control/route/route.js,can/observe/backup/backup.js,can/util/object/object.js,can/util/string/string.js
       
     8  * Download from: http://bitbuilder.herokuapp.com/can.custom.js?configuration=jquery&plugins=can%2Fconstruct%2Fconstruct.js&plugins=can%2Fobserve%2Fobserve.js&plugins=can%2Fobserve%2Fcompute%2Fcompute.js&plugins=can%2Fmodel%2Fmodel.js&plugins=can%2Fview%2Fview.js&plugins=can%2Fview%2Fejs%2Fejs.js&plugins=can%2Fcontrol%2Fcontrol.js&plugins=can%2Froute%2Froute.js&plugins=can%2Fcontrol%2Froute%2Froute.js&plugins=can%2Fobserve%2Fbackup%2Fbackup.js&plugins=can%2Futil%2Fobject%2Fobject.js&plugins=can%2Futil%2Fstring%2Fstring.js
       
     9  */
       
    10 (function(undefined) {
       
    11 
       
    12     // ## can/util/can.js
       
    13     var __m5 = (function() {
       
    14         var can = window.can || {};
       
    15         if (typeof GLOBALCAN === 'undefined' || GLOBALCAN !== false) {
       
    16             window.can = can;
       
    17         }
       
    18 
       
    19         can.isDeferred = function(obj) {
       
    20             var isFunction = this.isFunction;
       
    21             // Returns `true` if something looks like a deferred.
       
    22             return obj && isFunction(obj.then) && isFunction(obj.pipe);
       
    23         };
       
    24 
       
    25         var cid = 0;
       
    26         can.cid = function(object, name) {
       
    27             if (object._cid) {
       
    28                 return object._cid
       
    29             } else {
       
    30                 return object._cid = (name || "") + (++cid)
       
    31             }
       
    32         }
       
    33         can.VERSION = '@EDGE';
       
    34         return can;
       
    35     })();
       
    36 
       
    37     // ## can/util/array/each.js
       
    38     var __m6 = (function(can) {
       
    39         can.each = function(elements, callback, context) {
       
    40             var i = 0,
       
    41                 key;
       
    42             if (elements) {
       
    43                 if (typeof elements.length === 'number' && elements.pop) {
       
    44                     if (elements.attr) {
       
    45                         elements.attr('length');
       
    46                     }
       
    47                     for (key = elements.length; i < key; i++) {
       
    48                         if (callback.call(context || elements[i], elements[i], i, elements) === false) {
       
    49                             break;
       
    50                         }
       
    51                     }
       
    52                 } else if (elements.hasOwnProperty) {
       
    53                     for (key in elements) {
       
    54                         if (elements.hasOwnProperty(key)) {
       
    55                             if (callback.call(context || elements[key], elements[key], key, elements) === false) {
       
    56                                 break;
       
    57                             }
       
    58                         }
       
    59                     }
       
    60                 }
       
    61             }
       
    62             return elements;
       
    63         };
       
    64 
       
    65         return can;
       
    66     })(__m5);
       
    67 
       
    68     // ## can/util/jquery/jquery.js
       
    69     var __m3 = (function($, can) {
       
    70         // _jQuery node list._
       
    71         $.extend(can, $, {
       
    72                 trigger: function(obj, event, args) {
       
    73                     if (obj.trigger) {
       
    74                         obj.trigger(event, args);
       
    75                     } else {
       
    76                         $.event.trigger(event, args, obj, true);
       
    77                     }
       
    78                 },
       
    79                 addEvent: function(ev, cb) {
       
    80                     $([this]).bind(ev, cb);
       
    81                     return this;
       
    82                 },
       
    83                 removeEvent: function(ev, cb) {
       
    84                     $([this]).unbind(ev, cb);
       
    85                     return this;
       
    86                 },
       
    87                 // jquery caches fragments, we always needs a new one
       
    88                 buildFragment: function(elems, context) {
       
    89                     var oldFragment = $.buildFragment,
       
    90                         ret;
       
    91 
       
    92                     elems = [elems];
       
    93                     // Set context per 1.8 logic
       
    94                     context = context || document;
       
    95                     context = !context.nodeType && context[0] || context;
       
    96                     context = context.ownerDocument || context;
       
    97 
       
    98                     ret = oldFragment.call(jQuery, elems, context);
       
    99 
       
   100                     return ret.cacheable ? $.clone(ret.fragment) : ret.fragment || ret;
       
   101                 },
       
   102                 $: $,
       
   103                 each: can.each
       
   104             });
       
   105 
       
   106         // Wrap binding functions.
       
   107         $.each(['bind', 'unbind', 'undelegate', 'delegate'], function(i, func) {
       
   108             can[func] = function() {
       
   109                 var t = this[func] ? this : $([this]);
       
   110                 t[func].apply(t, arguments);
       
   111                 return this;
       
   112             };
       
   113         });
       
   114 
       
   115         // Wrap modifier functions.
       
   116         $.each(["append", "filter", "addClass", "remove", "data", "get"], function(i, name) {
       
   117             can[name] = function(wrapped) {
       
   118                 return wrapped[name].apply(wrapped, can.makeArray(arguments).slice(1));
       
   119             };
       
   120         });
       
   121 
       
   122         // Memory safe destruction.
       
   123         var oldClean = $.cleanData;
       
   124 
       
   125         $.cleanData = function(elems) {
       
   126             $.each(elems, function(i, elem) {
       
   127                 if (elem) {
       
   128                     can.trigger(elem, "destroyed", [], false);
       
   129                 }
       
   130             });
       
   131             oldClean(elems);
       
   132         };
       
   133 
       
   134         return can;
       
   135     })(jQuery, __m5, __m6);
       
   136 
       
   137     // ## can/util/string/string.js
       
   138     var __m2 = (function(can) {
       
   139         // ##string.js
       
   140         // _Miscellaneous string utility functions._  
       
   141 
       
   142         // Several of the methods in this plugin use code adapated from Prototype
       
   143         // Prototype JavaScript framework, version 1.6.0.1.
       
   144         // © 2005-2007 Sam Stephenson
       
   145         var strUndHash = /_|-/,
       
   146             strColons = /\=\=/,
       
   147             strWords = /([A-Z]+)([A-Z][a-z])/g,
       
   148             strLowUp = /([a-z\d])([A-Z])/g,
       
   149             strDash = /([a-z\d])([A-Z])/g,
       
   150             strReplacer = /\{([^\}]+)\}/g,
       
   151             strQuote = /"/g,
       
   152             strSingleQuote = /'/g,
       
   153 
       
   154             // Returns the `prop` property from `obj`.
       
   155             // If `add` is true and `prop` doesn't exist in `obj`, create it as an
       
   156             // empty object.
       
   157             getNext = function(obj, prop, add) {
       
   158                 var result = obj[prop];
       
   159 
       
   160                 if (result === undefined && add === true) {
       
   161                     result = obj[prop] = {}
       
   162                 }
       
   163                 return result
       
   164             },
       
   165 
       
   166             // Returns `true` if the object can have properties (no `null`s).
       
   167             isContainer = function(current) {
       
   168                 return (/^f|^o/).test(typeof current);
       
   169             };
       
   170 
       
   171         can.extend(can, {
       
   172                 // Escapes strings for HTML.
       
   173 
       
   174                 esc: function(content) {
       
   175                     // Convert bad values into empty strings
       
   176                     var isInvalid = content === null || content === undefined || (isNaN(content) && ("" + content === 'NaN'));
       
   177                     return ("" + (isInvalid ? '' : content))
       
   178                         .replace(/&/g, '&amp;')
       
   179                         .replace(/</g, '&lt;')
       
   180                         .replace(/>/g, '&gt;')
       
   181                         .replace(strQuote, '&#34;')
       
   182                         .replace(strSingleQuote, "&#39;");
       
   183                 },
       
   184 
       
   185 
       
   186                 getObject: function(name, roots, add) {
       
   187 
       
   188                     // The parts of the name we are looking up
       
   189                     // `['App','Models','Recipe']`
       
   190                     var parts = name ? name.split('.') : [],
       
   191                         length = parts.length,
       
   192                         current,
       
   193                         r = 0,
       
   194                         i, container, rootsLength;
       
   195 
       
   196                     // Make sure roots is an `array`.
       
   197                     roots = can.isArray(roots) ? roots : [roots || window];
       
   198 
       
   199                     rootsLength = roots.length
       
   200 
       
   201                     if (!length) {
       
   202                         return roots[0];
       
   203                     }
       
   204 
       
   205                     // For each root, mark it as current.
       
   206                     for (r; r < rootsLength; r++) {
       
   207                         current = roots[r];
       
   208                         container = undefined;
       
   209 
       
   210                         // Walk current to the 2nd to last object or until there
       
   211                         // is not a container.
       
   212                         for (i = 0; i < length && isContainer(current); i++) {
       
   213                             container = current;
       
   214                             current = getNext(container, parts[i]);
       
   215                         }
       
   216 
       
   217                         // If we found property break cycle
       
   218                         if (container !== undefined && current !== undefined) {
       
   219                             break
       
   220                         }
       
   221                     }
       
   222 
       
   223                     // Remove property from found container
       
   224                     if (add === false && current !== undefined) {
       
   225                         delete container[parts[i - 1]]
       
   226                     }
       
   227 
       
   228                     // When adding property add it to the first root
       
   229                     if (add === true && current === undefined) {
       
   230                         current = roots[0]
       
   231 
       
   232                         for (i = 0; i < length && isContainer(current); i++) {
       
   233                             current = getNext(current, parts[i], true);
       
   234                         }
       
   235                     }
       
   236 
       
   237                     return current;
       
   238                 },
       
   239                 // Capitalizes a string.
       
   240 
       
   241                 capitalize: function(s, cache) {
       
   242                     // Used to make newId.
       
   243                     return s.charAt(0).toUpperCase() + s.slice(1);
       
   244                 },
       
   245 
       
   246                 // Underscores a string.
       
   247 
       
   248                 underscore: function(s) {
       
   249                     return s
       
   250                         .replace(strColons, '/')
       
   251                         .replace(strWords, '$1_$2')
       
   252                         .replace(strLowUp, '$1_$2')
       
   253                         .replace(strDash, '_')
       
   254                         .toLowerCase();
       
   255                 },
       
   256                 // Micro-templating.
       
   257 
       
   258                 sub: function(str, data, remove) {
       
   259                     var obs = [];
       
   260 
       
   261                     str = str || '';
       
   262 
       
   263                     obs.push(str.replace(strReplacer, function(whole, inside) {
       
   264 
       
   265                                 // Convert inside to type.
       
   266                                 var ob = can.getObject(inside, data, remove === true ? false : undefined);
       
   267 
       
   268                                 if (ob === undefined) {
       
   269                                     obs = null;
       
   270                                     return "";
       
   271                                 }
       
   272 
       
   273                                 // If a container, push into objs (which will return objects found).
       
   274                                 if (isContainer(ob) && obs) {
       
   275                                     obs.push(ob);
       
   276                                     return "";
       
   277                                 }
       
   278 
       
   279                                 return "" + ob;
       
   280                             }));
       
   281 
       
   282                     return obs === null ? obs : (obs.length <= 1 ? obs[0] : obs);
       
   283                 },
       
   284 
       
   285                 // These regex's are used throughout the rest of can, so let's make
       
   286                 // them available.
       
   287                 replacer: strReplacer,
       
   288                 undHash: strUndHash
       
   289             });
       
   290         return can;
       
   291     })(__m3);
       
   292 
       
   293     // ## can/construct/construct.js
       
   294     var __m1 = (function(can) {
       
   295 
       
   296         // ## construct.js
       
   297         // `can.Construct`  
       
   298         // _This is a modified version of
       
   299         // [John Resig's class](http://ejohn.org/blog/simple-javascript-inheritance/).  
       
   300         // It provides class level inheritance and callbacks._
       
   301 
       
   302         // A private flag used to initialize a new class instance without
       
   303         // initializing it's bindings.
       
   304         var initializing = 0;
       
   305 
       
   306 
       
   307         can.Construct = function() {
       
   308             if (arguments.length) {
       
   309                 return can.Construct.extend.apply(can.Construct, arguments);
       
   310             }
       
   311         };
       
   312 
       
   313 
       
   314         can.extend(can.Construct, {
       
   315 
       
   316                 newInstance: function() {
       
   317                     // Get a raw instance object (`init` is not called).
       
   318                     var inst = this.instance(),
       
   319                         arg = arguments,
       
   320                         args;
       
   321 
       
   322                     // Call `setup` if there is a `setup`
       
   323                     if (inst.setup) {
       
   324                         args = inst.setup.apply(inst, arguments);
       
   325                     }
       
   326 
       
   327                     // Call `init` if there is an `init`  
       
   328                     // If `setup` returned `args`, use those as the arguments
       
   329                     if (inst.init) {
       
   330                         inst.init.apply(inst, args || arguments);
       
   331                     }
       
   332 
       
   333                     return inst;
       
   334                 },
       
   335                 // Overwrites an object with methods. Used in the `super` plugin.
       
   336                 // `newProps` - New properties to add.  
       
   337                 // `oldProps` - Where the old properties might be (used with `super`).  
       
   338                 // `addTo` - What we are adding to.
       
   339                 _inherit: function(newProps, oldProps, addTo) {
       
   340                     can.extend(addTo || newProps, newProps || {})
       
   341                 },
       
   342                 // used for overwriting a single property.
       
   343                 // this should be used for patching other objects
       
   344                 // the super plugin overwrites this
       
   345                 _overwrite: function(what, oldProps, propName, val) {
       
   346                     what[propName] = val;
       
   347                 },
       
   348                 // Set `defaults` as the merger of the parent `defaults` and this 
       
   349                 // object's `defaults`. If you overwrite this method, make sure to
       
   350                 // include option merging logic.
       
   351 
       
   352                 setup: function(base, fullName) {
       
   353                     this.defaults = can.extend(true, {}, base.defaults, this.defaults);
       
   354                 },
       
   355                 // Create's a new `class` instance without initializing by setting the
       
   356                 // `initializing` flag.
       
   357                 instance: function() {
       
   358 
       
   359                     // Prevents running `init`.
       
   360                     initializing = 1;
       
   361 
       
   362                     var inst = new this();
       
   363 
       
   364                     // Allow running `init`.
       
   365                     initializing = 0;
       
   366 
       
   367                     return inst;
       
   368                 },
       
   369                 // Extends classes.
       
   370 
       
   371                 extend: function(fullName, klass, proto) {
       
   372                     // Figure out what was passed and normalize it.
       
   373                     if (typeof fullName != 'string') {
       
   374                         proto = klass;
       
   375                         klass = fullName;
       
   376                         fullName = null;
       
   377                     }
       
   378 
       
   379                     if (!proto) {
       
   380                         proto = klass;
       
   381                         klass = null;
       
   382                     }
       
   383                     proto = proto || {};
       
   384 
       
   385                     var _super_class = this,
       
   386                         _super = this.prototype,
       
   387                         name, shortName, namespace, prototype;
       
   388 
       
   389                     // Instantiate a base class (but only create the instance,
       
   390                     // don't run the init constructor).
       
   391                     prototype = this.instance();
       
   392 
       
   393                     // Copy the properties over onto the new prototype.
       
   394                     can.Construct._inherit(proto, _super, prototype);
       
   395 
       
   396                     // The dummy class constructor.
       
   397 
       
   398                     function Constructor() {
       
   399                         // All construction is actually done in the init method.
       
   400                         if (!initializing) {
       
   401                             return this.constructor !== Constructor && arguments.length ?
       
   402                             // We are being called without `new` or we are extending.
       
   403                             arguments.callee.extend.apply(arguments.callee, arguments) :
       
   404                             // We are being called with `new`.
       
   405                             this.constructor.newInstance.apply(this.constructor, arguments);
       
   406                         }
       
   407                     }
       
   408 
       
   409                     // Copy old stuff onto class (can probably be merged w/ inherit)
       
   410                     for (name in _super_class) {
       
   411                         if (_super_class.hasOwnProperty(name)) {
       
   412                             Constructor[name] = _super_class[name];
       
   413                         }
       
   414                     }
       
   415 
       
   416                     // Copy new static properties on class.
       
   417                     can.Construct._inherit(klass, _super_class, Constructor);
       
   418 
       
   419                     // Setup namespaces.
       
   420                     if (fullName) {
       
   421 
       
   422                         var parts = fullName.split('.'),
       
   423                             shortName = parts.pop(),
       
   424                             current = can.getObject(parts.join('.'), window, true),
       
   425                             namespace = current,
       
   426                             _fullName = can.underscore(fullName.replace(/\./g, "_")),
       
   427                             _shortName = can.underscore(shortName);
       
   428 
       
   429 
       
   430 
       
   431                         current[shortName] = Constructor;
       
   432                     }
       
   433 
       
   434                     // Set things that shouldn't be overwritten.
       
   435                     can.extend(Constructor, {
       
   436                             constructor: Constructor,
       
   437                             prototype: prototype,
       
   438 
       
   439                             namespace: namespace,
       
   440 
       
   441                             _shortName: _shortName,
       
   442 
       
   443                             fullName: fullName,
       
   444                             _fullName: _fullName
       
   445                         });
       
   446 
       
   447                     // Dojo and YUI extend undefined
       
   448                     if (shortName !== undefined) {
       
   449                         Constructor.shortName = shortName;
       
   450                     }
       
   451 
       
   452                     // Make sure our prototype looks nice.
       
   453                     Constructor.prototype.constructor = Constructor;
       
   454 
       
   455 
       
   456                     // Call the class `setup` and `init`
       
   457                     var t = [_super_class].concat(can.makeArray(arguments)),
       
   458                         args = Constructor.setup.apply(Constructor, t);
       
   459 
       
   460                     if (Constructor.init) {
       
   461                         Constructor.init.apply(Constructor, args || t);
       
   462                     }
       
   463 
       
   464 
       
   465                     return Constructor;
       
   466 
       
   467                 }
       
   468 
       
   469             });
       
   470         return can.Construct;
       
   471     })(__m2);
       
   472 
       
   473     // ## can/util/bind/bind.js
       
   474     var __m8 = (function(can) {
       
   475 
       
   476 
       
   477         // ## Bind helpers
       
   478         can.bindAndSetup = function() {
       
   479             // Add the event to this object
       
   480             can.addEvent.apply(this, arguments);
       
   481             // If not initializing, and the first binding
       
   482             // call bindsetup if the function exists.
       
   483             if (!this._init) {
       
   484                 if (!this._bindings) {
       
   485                     this._bindings = 1;
       
   486                     // setup live-binding
       
   487                     this._bindsetup && this._bindsetup();
       
   488 
       
   489                 } else {
       
   490                     this._bindings++;
       
   491                 }
       
   492 
       
   493             }
       
   494 
       
   495             return this;
       
   496         };
       
   497 
       
   498         can.unbindAndTeardown = function(ev, handler) {
       
   499             // Remove the event handler
       
   500             can.removeEvent.apply(this, arguments);
       
   501 
       
   502             this._bindings--;
       
   503             // If there are no longer any bindings and
       
   504             // there is a bindteardown method, call it.
       
   505             if (!this._bindings) {
       
   506                 this._bindteardown && this._bindteardown();
       
   507             }
       
   508             return this;
       
   509         }
       
   510 
       
   511         return can;
       
   512 
       
   513     })(__m3);
       
   514 
       
   515     // ## can/observe/observe.js
       
   516     var __m7 = (function(can, bind) {
       
   517         // ## observe.js  
       
   518         // `can.Observe`  
       
   519         // _Provides the observable pattern for JavaScript Objects._  
       
   520         // Returns `true` if something is an object with properties of its own.
       
   521         var canMakeObserve = function(obj) {
       
   522             return obj && !can.isDeferred(obj) && (can.isArray(obj) || can.isPlainObject(obj) || (obj instanceof can.Observe));
       
   523         },
       
   524 
       
   525             // Removes all listeners.
       
   526             unhookup = function(items, namespace) {
       
   527                 return can.each(items, function(item) {
       
   528                     if (item && item.unbind) {
       
   529                         item.unbind("change" + namespace);
       
   530                     }
       
   531                 });
       
   532             },
       
   533             // Listens to changes on `child` and "bubbles" the event up.  
       
   534             // `child` - The object to listen for changes on.  
       
   535             // `prop` - The property name is at on.  
       
   536             // `parent` - The parent object of prop.
       
   537             // `ob` - (optional) The Observe object constructor
       
   538             // `list` - (optional) The observable list constructor
       
   539             hookupBubble = function(child, prop, parent, Ob, List) {
       
   540                 Ob = Ob || Observe;
       
   541                 List = List || Observe.List;
       
   542 
       
   543                 // If it's an `array` make a list, otherwise a child.
       
   544                 if (child instanceof Observe) {
       
   545                     // We have an `observe` already...
       
   546                     // Make sure it is not listening to this already
       
   547                     // It's only listening if it has bindings already.
       
   548                     parent._bindings && unhookup([child], parent._cid);
       
   549                 } else if (can.isArray(child)) {
       
   550                     child = new List(child);
       
   551                 } else {
       
   552                     child = new Ob(child);
       
   553                 }
       
   554                 // only listen if something is listening to you
       
   555                 if (parent._bindings) {
       
   556                     // Listen to all changes and `batchTrigger` upwards.
       
   557                     bindToChildAndBubbleToParent(child, prop, parent)
       
   558                 }
       
   559 
       
   560 
       
   561                 return child;
       
   562             },
       
   563             bindToChildAndBubbleToParent = function(child, prop, parent) {
       
   564                 child.bind("change" + parent._cid, function() {
       
   565                     // `batchTrigger` the type on this...
       
   566                     var args = can.makeArray(arguments),
       
   567                         ev = args.shift();
       
   568                     args[0] = (prop === "*" ? [parent.indexOf(child), args[0]] : [prop, args[0]]).join(".");
       
   569 
       
   570                     // track objects dispatched on this observe		
       
   571                     ev.triggeredNS = ev.triggeredNS || {};
       
   572 
       
   573                     // if it has already been dispatched exit
       
   574                     if (ev.triggeredNS[parent._cid]) {
       
   575                         return;
       
   576                     }
       
   577 
       
   578                     ev.triggeredNS[parent._cid] = true;
       
   579                     // send change event with modified attr to parent	
       
   580                     can.trigger(parent, ev, args);
       
   581                     // send modified attr event to parent
       
   582                     //can.trigger(parent, args[0], args);
       
   583                 });
       
   584             }
       
   585             // An `id` to track events for a given observe.
       
   586         observeId = 0,
       
   587         // A helper used to serialize an `Observe` or `Observe.List`.  
       
   588         // `observe` - The observable.  
       
   589         // `how` - To serialize with `attr` or `serialize`.  
       
   590         // `where` - To put properties, in an `{}` or `[]`.
       
   591         serialize = function(observe, how, where) {
       
   592             // Go through each property.
       
   593             observe.each(function(val, name) {
       
   594                 // If the value is an `object`, and has an `attrs` or `serialize` function.
       
   595                 where[name] = canMakeObserve(val) && can.isFunction(val[how]) ?
       
   596                 // Call `attrs` or `serialize` to get the original data back.
       
   597                 val[how]() :
       
   598                 // Otherwise return the value.
       
   599                 val;
       
   600             });
       
   601             return where;
       
   602         },
       
   603         attrParts = function(attr, keepKey) {
       
   604             if (keepKey) {
       
   605                 return [attr];
       
   606             }
       
   607             return can.isArray(attr) ? attr : ("" + attr).split(".");
       
   608         },
       
   609         // Which batch of events this is for -- might not want to send multiple
       
   610         // messages on the same batch.  This is mostly for event delegation.
       
   611         batchNum = 1,
       
   612         // how many times has start been called without a stop
       
   613         transactions = 0,
       
   614         // an array of events within a transaction
       
   615         batchEvents = [],
       
   616         stopCallbacks = [],
       
   617         makeBindSetup = function(wildcard) {
       
   618             return function() {
       
   619                 var parent = this;
       
   620                 this._each(function(child, prop) {
       
   621                     if (child && child.bind) {
       
   622                         bindToChildAndBubbleToParent(child, wildcard || prop, parent)
       
   623                     }
       
   624                 })
       
   625             };
       
   626         };
       
   627 
       
   628 
       
   629         var Observe = can.Map = can.Observe = can.Construct({
       
   630 
       
   631                 // keep so it can be overwritten
       
   632                 bind: can.bindAndSetup,
       
   633                 unbind: can.unbindAndTeardown,
       
   634                 id: "id",
       
   635                 canMakeObserve: canMakeObserve,
       
   636                 // starts collecting events
       
   637                 // takes a callback for after they are updated
       
   638                 // how could you hook into after ejs
       
   639 
       
   640                 startBatch: function(batchStopHandler) {
       
   641                     transactions++;
       
   642                     batchStopHandler && stopCallbacks.push(batchStopHandler);
       
   643                 },
       
   644 
       
   645                 stopBatch: function(force, callStart) {
       
   646                     if (force) {
       
   647                         transactions = 0;
       
   648                     } else {
       
   649                         transactions--;
       
   650                     }
       
   651 
       
   652                     if (transactions == 0) {
       
   653                         var items = batchEvents.slice(0),
       
   654                             callbacks = stopCallbacks.slice(0);
       
   655                         batchEvents = [];
       
   656                         stopCallbacks = [];
       
   657                         batchNum++;
       
   658                         callStart && this.startBatch();
       
   659                         can.each(items, function(args) {
       
   660                             can.trigger.apply(can, args);
       
   661                         });
       
   662                         can.each(callbacks, function(cb) {
       
   663                             cb();
       
   664                         });
       
   665                     }
       
   666                 },
       
   667 
       
   668                 triggerBatch: function(item, event, args) {
       
   669                     // Don't send events if initalizing.
       
   670                     if (!item._init) {
       
   671                         if (transactions == 0) {
       
   672                             return can.trigger(item, event, args);
       
   673                         } else {
       
   674                             event = typeof event === "string" ? {
       
   675                                 type: event
       
   676                             } :
       
   677                                 event;
       
   678                             event.batchNum = batchNum;
       
   679                             batchEvents.push([
       
   680                                     item,
       
   681                                     event,
       
   682                                     args
       
   683                                 ]);
       
   684                         }
       
   685                     }
       
   686                 },
       
   687 
       
   688                 keys: function(observe) {
       
   689                     var keys = [];
       
   690                     Observe.__reading && Observe.__reading(observe, '__keys');
       
   691                     for (var keyName in observe._data) {
       
   692                         keys.push(keyName);
       
   693                     }
       
   694                     return keys;
       
   695                 }
       
   696             },
       
   697 
       
   698             {
       
   699                 setup: function(obj) {
       
   700                     // `_data` is where we keep the properties.
       
   701                     this._data = {};
       
   702 
       
   703                     // The namespace this `object` uses to listen to events.
       
   704                     can.cid(this, ".observe");
       
   705                     // Sets all `attrs`.
       
   706                     this._init = 1;
       
   707                     this.attr(obj);
       
   708                     this.bind('change' + this._cid, can.proxy(this._changes, this));
       
   709                     delete this._init;
       
   710                 },
       
   711                 _bindsetup: makeBindSetup(),
       
   712                 _bindteardown: function() {
       
   713                     var cid = this._cid;
       
   714                     this._each(function(child) {
       
   715                         unhookup([child], cid)
       
   716                     })
       
   717                 },
       
   718                 _changes: function(ev, attr, how, newVal, oldVal) {
       
   719                     Observe.triggerBatch(this, {
       
   720                             type: attr,
       
   721                             batchNum: ev.batchNum
       
   722                         }, [newVal, oldVal]);
       
   723                 },
       
   724                 _triggerChange: function(attr, how, newVal, oldVal) {
       
   725                     Observe.triggerBatch(this, "change", can.makeArray(arguments))
       
   726                 },
       
   727                 // no live binding iterator
       
   728                 _each: function(callback) {
       
   729                     var data = this.__get();
       
   730                     for (var prop in data) {
       
   731                         if (data.hasOwnProperty(prop)) {
       
   732                             callback(data[prop], prop)
       
   733                         }
       
   734                     }
       
   735                 },
       
   736 
       
   737                 attr: function(attr, val) {
       
   738                     // This is super obfuscated for space -- basically, we're checking
       
   739                     // if the type of the attribute is not a `number` or a `string`.
       
   740                     var type = typeof attr;
       
   741                     if (type !== "string" && type !== "number") {
       
   742                         return this._attrs(attr, val)
       
   743                     } else if (arguments.length === 1) { // If we are getting a value.
       
   744                         // Let people know we are reading.
       
   745                         Observe.__reading && Observe.__reading(this, attr)
       
   746                         return this._get(attr)
       
   747                     } else {
       
   748                         // Otherwise we are setting.
       
   749                         this._set(attr, val);
       
   750                         return this;
       
   751                     }
       
   752                 },
       
   753 
       
   754                 each: function() {
       
   755                     Observe.__reading && Observe.__reading(this, '__keys');
       
   756                     return can.each.apply(undefined, [this.__get()].concat(can.makeArray(arguments)))
       
   757                 },
       
   758 
       
   759                 removeAttr: function(attr) {
       
   760                     // Info if this is List or not
       
   761                     var isList = this instanceof can.Observe.List,
       
   762                         // Convert the `attr` into parts (if nested).
       
   763                         parts = attrParts(attr),
       
   764                         // The actual property to remove.
       
   765                         prop = parts.shift(),
       
   766                         // The current value.
       
   767                         current = isList ? this[prop] : this._data[prop];
       
   768 
       
   769                     // If we have more parts, call `removeAttr` on that part.
       
   770                     if (parts.length) {
       
   771                         return current.removeAttr(parts)
       
   772                     } else {
       
   773                         if (isList) {
       
   774                             this.splice(prop, 1)
       
   775                         } else if (prop in this._data) {
       
   776                             // Otherwise, `delete`.
       
   777                             delete this._data[prop];
       
   778                             // Create the event.
       
   779                             if (!(prop in this.constructor.prototype)) {
       
   780                                 delete this[prop]
       
   781                             }
       
   782                             // Let others know the number of keys have changed
       
   783                             Observe.triggerBatch(this, "__keys");
       
   784                             this._triggerChange(prop, "remove", undefined, current);
       
   785 
       
   786                         }
       
   787                         return current;
       
   788                     }
       
   789                 },
       
   790                 // Reads a property from the `object`.
       
   791                 _get: function(attr) {
       
   792                     var value = typeof attr === 'string' && !! ~attr.indexOf('.') && this.__get(attr);
       
   793                     if (value) {
       
   794                         return value;
       
   795                     }
       
   796 
       
   797                     // break up the attr (`"foo.bar"`) into `["foo","bar"]`
       
   798                     var parts = attrParts(attr),
       
   799                         // get the value of the first attr name (`"foo"`)
       
   800                         current = this.__get(parts.shift());
       
   801                     // if there are other attributes to read
       
   802                     return parts.length ?
       
   803                     // and current has a value
       
   804                     current ?
       
   805                     // lookup the remaining attrs on current
       
   806                     current._get(parts) :
       
   807                     // or if there's no current, return undefined
       
   808                     undefined :
       
   809                     // if there are no more parts, return current
       
   810                     current;
       
   811                 },
       
   812                 // Reads a property directly if an `attr` is provided, otherwise
       
   813                 // returns the "real" data object itself.
       
   814                 __get: function(attr) {
       
   815                     return attr ? this._data[attr] : this._data;
       
   816                 },
       
   817                 // Sets `attr` prop as value on this object where.
       
   818                 // `attr` - Is a string of properties or an array  of property values.
       
   819                 // `value` - The raw value to set.
       
   820                 _set: function(attr, value, keepKey) {
       
   821                     // Convert `attr` to attr parts (if it isn't already).
       
   822                     var parts = attrParts(attr, keepKey),
       
   823                         // The immediate prop we are setting.
       
   824                         prop = parts.shift(),
       
   825                         // The current value.
       
   826                         current = this.__get(prop);
       
   827 
       
   828                     // If we have an `object` and remaining parts.
       
   829                     if (canMakeObserve(current) && parts.length) {
       
   830                         // That `object` should set it (this might need to call attr).
       
   831                         current._set(parts, value)
       
   832                     } else if (!parts.length) {
       
   833                         // We're in "real" set territory.
       
   834                         if (this.__convert) {
       
   835                             value = this.__convert(prop, value)
       
   836                         }
       
   837                         this.__set(prop, value, current)
       
   838                     } else {
       
   839                         throw "can.Observe: Object does not exist"
       
   840                     }
       
   841                 },
       
   842                 __set: function(prop, value, current) {
       
   843 
       
   844                     // Otherwise, we are setting it on this `object`.
       
   845                     // TODO: Check if value is object and transform
       
   846                     // are we changing the value.
       
   847                     if (value !== current) {
       
   848                         // Check if we are adding this for the first time --
       
   849                         // if we are, we need to create an `add` event.
       
   850                         var changeType = this.__get().hasOwnProperty(prop) ? "set" : "add";
       
   851 
       
   852                         // Set the value on data.
       
   853                         this.___set(prop,
       
   854 
       
   855                             // If we are getting an object.
       
   856                             canMakeObserve(value) ?
       
   857 
       
   858                             // Hook it up to send event.
       
   859                             hookupBubble(value, prop, this) :
       
   860                             // Value is normal.
       
   861                             value);
       
   862 
       
   863                         if (changeType == "add") {
       
   864                             // If there is no current value, let others know that
       
   865                             // the the number of keys have changed
       
   866 
       
   867                             Observe.triggerBatch(this, "__keys", undefined);
       
   868 
       
   869                         }
       
   870                         // `batchTrigger` the change event.
       
   871                         this._triggerChange(prop, changeType, value, current);
       
   872 
       
   873                         //Observe.triggerBatch(this, prop, [value, current]);
       
   874                         // If we can stop listening to our old value, do it.
       
   875                         current && unhookup([current], this._cid);
       
   876                     }
       
   877 
       
   878                 },
       
   879                 // Directly sets a property on this `object`.
       
   880                 ___set: function(prop, val) {
       
   881                     this._data[prop] = val;
       
   882                     // Add property directly for easy writing.
       
   883                     // Check if its on the `prototype` so we don't overwrite methods like `attrs`.
       
   884                     if (!(prop in this.constructor.prototype)) {
       
   885                         this[prop] = val
       
   886                     }
       
   887                 },
       
   888 
       
   889 
       
   890                 bind: can.bindAndSetup,
       
   891 
       
   892                 unbind: can.unbindAndTeardown,
       
   893 
       
   894                 serialize: function() {
       
   895                     return serialize(this, 'serialize', {});
       
   896                 },
       
   897 
       
   898                 _attrs: function(props, remove) {
       
   899 
       
   900                     if (props === undefined) {
       
   901                         return serialize(this, 'attr', {})
       
   902                     }
       
   903 
       
   904                     props = can.extend({}, props);
       
   905                     var prop,
       
   906                         self = this,
       
   907                         newVal;
       
   908                     Observe.startBatch();
       
   909                     this.each(function(curVal, prop) {
       
   910                         newVal = props[prop];
       
   911 
       
   912                         // If we are merging...
       
   913                         if (newVal === undefined) {
       
   914                             remove && self.removeAttr(prop);
       
   915                             return;
       
   916                         }
       
   917 
       
   918                         if (self.__convert) {
       
   919                             newVal = self.__convert(prop, newVal)
       
   920                         }
       
   921 
       
   922                         // if we're dealing with models, want to call _set to let converter run
       
   923                         if (newVal instanceof can.Observe) {
       
   924                             self.__set(prop, newVal, curVal)
       
   925                             // if its an object, let attr merge
       
   926                         } else if (canMakeObserve(curVal) && canMakeObserve(newVal) && curVal.attr) {
       
   927                             curVal.attr(newVal, remove)
       
   928                             // otherwise just set
       
   929                         } else if (curVal != newVal) {
       
   930                             self.__set(prop, newVal, curVal)
       
   931                         }
       
   932 
       
   933                         delete props[prop];
       
   934                     })
       
   935                     // Add remaining props.
       
   936                     for (var prop in props) {
       
   937                         newVal = props[prop];
       
   938                         this._set(prop, newVal, true)
       
   939                     }
       
   940                     Observe.stopBatch()
       
   941                     return this;
       
   942                 },
       
   943 
       
   944 
       
   945                 compute: function(prop) {
       
   946                     return can.compute(this, prop);
       
   947                 }
       
   948             });
       
   949         // Helpers for `observable` lists.
       
   950         var splice = [].splice,
       
   951 
       
   952             list = Observe(
       
   953 
       
   954                 {
       
   955                     setup: function(instances, options) {
       
   956                         this.length = 0;
       
   957                         can.cid(this, ".observe")
       
   958                         this._init = 1;
       
   959                         if (can.isDeferred(instances)) {
       
   960                             this.replace(instances)
       
   961                         } else {
       
   962                             this.push.apply(this, can.makeArray(instances || []));
       
   963                         }
       
   964                         // this change needs to be ignored
       
   965                         this.bind('change' + this._cid, can.proxy(this._changes, this));
       
   966                         can.extend(this, options);
       
   967                         delete this._init;
       
   968                     },
       
   969                     _triggerChange: function(attr, how, newVal, oldVal) {
       
   970 
       
   971                         Observe.prototype._triggerChange.apply(this, arguments)
       
   972                         // `batchTrigger` direct add and remove events...
       
   973                         if (!~attr.indexOf('.')) {
       
   974 
       
   975                             if (how === 'add') {
       
   976                                 Observe.triggerBatch(this, how, [newVal, +attr]);
       
   977                                 Observe.triggerBatch(this, 'length', [this.length]);
       
   978                             } else if (how === 'remove') {
       
   979                                 Observe.triggerBatch(this, how, [oldVal, +attr]);
       
   980                                 Observe.triggerBatch(this, 'length', [this.length]);
       
   981                             } else {
       
   982                                 Observe.triggerBatch(this, how, [newVal, +attr])
       
   983                             }
       
   984 
       
   985                         }
       
   986 
       
   987                     },
       
   988                     __get: function(attr) {
       
   989                         return attr ? this[attr] : this;
       
   990                     },
       
   991                     ___set: function(attr, val) {
       
   992                         this[attr] = val;
       
   993                         if (+attr >= this.length) {
       
   994                             this.length = (+attr + 1)
       
   995                         }
       
   996                     },
       
   997                     _each: function(callback) {
       
   998                         var data = this.__get();
       
   999                         for (var i = 0; i < data.length; i++) {
       
  1000                             callback(data[i], i)
       
  1001                         }
       
  1002                     },
       
  1003                     _bindsetup: makeBindSetup("*"),
       
  1004                     // Returns the serialized form of this list.
       
  1005 
       
  1006                     serialize: function() {
       
  1007                         return serialize(this, 'serialize', []);
       
  1008                     },
       
  1009 
       
  1010                     splice: function(index, howMany) {
       
  1011                         var args = can.makeArray(arguments),
       
  1012                             i;
       
  1013 
       
  1014                         for (i = 2; i < args.length; i++) {
       
  1015                             var val = args[i];
       
  1016                             if (canMakeObserve(val)) {
       
  1017                                 args[i] = hookupBubble(val, "*", this, this.constructor.Observe, this.constructor)
       
  1018                             }
       
  1019                         }
       
  1020                         if (howMany === undefined) {
       
  1021                             howMany = args[1] = this.length - index;
       
  1022                         }
       
  1023                         var removed = splice.apply(this, args);
       
  1024                         can.Observe.startBatch();
       
  1025                         if (howMany > 0) {
       
  1026                             this._triggerChange("" + index, "remove", undefined, removed);
       
  1027                             unhookup(removed, this._cid);
       
  1028                         }
       
  1029                         if (args.length > 2) {
       
  1030                             this._triggerChange("" + index, "add", args.slice(2), removed);
       
  1031                         }
       
  1032                         can.Observe.stopBatch();
       
  1033                         return removed;
       
  1034                     },
       
  1035 
       
  1036                     _attrs: function(items, remove) {
       
  1037                         if (items === undefined) {
       
  1038                             return serialize(this, 'attr', []);
       
  1039                         }
       
  1040 
       
  1041                         // Create a copy.
       
  1042                         items = can.makeArray(items);
       
  1043 
       
  1044                         Observe.startBatch();
       
  1045                         this._updateAttrs(items, remove);
       
  1046                         Observe.stopBatch()
       
  1047                     },
       
  1048 
       
  1049                     _updateAttrs: function(items, remove) {
       
  1050                         var len = Math.min(items.length, this.length);
       
  1051 
       
  1052                         for (var prop = 0; prop < len; prop++) {
       
  1053                             var curVal = this[prop],
       
  1054                                 newVal = items[prop];
       
  1055 
       
  1056                             if (canMakeObserve(curVal) && canMakeObserve(newVal)) {
       
  1057                                 curVal.attr(newVal, remove)
       
  1058                             } else if (curVal != newVal) {
       
  1059                                 this._set(prop, newVal)
       
  1060                             } else {
       
  1061 
       
  1062                             }
       
  1063                         }
       
  1064                         if (items.length > this.length) {
       
  1065                             // Add in the remaining props.
       
  1066                             this.push.apply(this, items.slice(this.length));
       
  1067                         } else if (items.length < this.length && remove) {
       
  1068                             this.splice(items.length)
       
  1069                         }
       
  1070                     }
       
  1071                 }),
       
  1072 
       
  1073             // Converts to an `array` of arguments.
       
  1074             getArgs = function(args) {
       
  1075                 return args[0] && can.isArray(args[0]) ?
       
  1076                     args[0] :
       
  1077                     can.makeArray(args);
       
  1078             };
       
  1079         // Create `push`, `pop`, `shift`, and `unshift`
       
  1080         can.each({
       
  1081 
       
  1082                 push: "length",
       
  1083 
       
  1084                 unshift: 0
       
  1085             },
       
  1086             // Adds a method
       
  1087             // `name` - The method name.
       
  1088             // `where` - Where items in the `array` should be added.
       
  1089 
       
  1090             function(where, name) {
       
  1091                 var orig = [][name]
       
  1092                 list.prototype[name] = function() {
       
  1093                     // Get the items being added.
       
  1094                     var args = [],
       
  1095                         // Where we are going to add items.
       
  1096                         len = where ? this.length : 0,
       
  1097                         i = arguments.length,
       
  1098                         res,
       
  1099                         val,
       
  1100                         constructor = this.constructor;
       
  1101 
       
  1102                     // Go through and convert anything to an `observe` that needs to be converted.
       
  1103                     while (i--) {
       
  1104                         val = arguments[i];
       
  1105                         args[i] = canMakeObserve(val) ?
       
  1106                             hookupBubble(val, "*", this, this.constructor.Observe, this.constructor) :
       
  1107                             val;
       
  1108                     }
       
  1109 
       
  1110                     // Call the original method.
       
  1111                     res = orig.apply(this, args);
       
  1112 
       
  1113                     if (!this.comparator || args.length) {
       
  1114 
       
  1115                         this._triggerChange("" + len, "add", args, undefined);
       
  1116                     }
       
  1117 
       
  1118                     return res;
       
  1119                 }
       
  1120             });
       
  1121 
       
  1122         can.each({
       
  1123 
       
  1124                 pop: "length",
       
  1125 
       
  1126                 shift: 0
       
  1127             },
       
  1128             // Creates a `remove` type method
       
  1129 
       
  1130             function(where, name) {
       
  1131                 list.prototype[name] = function() {
       
  1132 
       
  1133                     var args = getArgs(arguments),
       
  1134                         len = where && this.length ? this.length - 1 : 0;
       
  1135 
       
  1136                     var res = [][name].apply(this, args)
       
  1137 
       
  1138                     // Create a change where the args are
       
  1139                     // `len` - Where these items were removed.
       
  1140                     // `remove` - Items removed.
       
  1141                     // `undefined` - The new values (there are none).
       
  1142                     // `res` - The old, removed values (should these be unbound).
       
  1143                     this._triggerChange("" + len, "remove", undefined, [res])
       
  1144 
       
  1145                     if (res && res.unbind) {
       
  1146                         res.unbind("change" + this._cid)
       
  1147                     }
       
  1148                     return res;
       
  1149                 }
       
  1150             });
       
  1151 
       
  1152         can.extend(list.prototype, {
       
  1153 
       
  1154                 indexOf: function(item) {
       
  1155                     this.attr('length')
       
  1156                     return can.inArray(item, this)
       
  1157                 },
       
  1158 
       
  1159 
       
  1160                 join: [].join,
       
  1161 
       
  1162 
       
  1163                 reverse: [].reverse,
       
  1164 
       
  1165 
       
  1166                 slice: function() {
       
  1167                     var temp = Array.prototype.slice.apply(this, arguments);
       
  1168                     return new this.constructor(temp);
       
  1169                 },
       
  1170 
       
  1171 
       
  1172                 concat: function() {
       
  1173                     var args = [];
       
  1174                     can.each(can.makeArray(arguments), function(arg, i) {
       
  1175                         args[i] = arg instanceof can.Observe.List ? arg.serialize() : arg;
       
  1176                     });
       
  1177                     return new this.constructor(Array.prototype.concat.apply(this.serialize(), args));
       
  1178                 },
       
  1179 
       
  1180 
       
  1181                 forEach: function(cb, thisarg) {
       
  1182                     can.each(this, cb, thisarg || this);
       
  1183                 },
       
  1184 
       
  1185 
       
  1186                 replace: function(newList) {
       
  1187                     if (can.isDeferred(newList)) {
       
  1188                         newList.then(can.proxy(this.replace, this));
       
  1189                     } else {
       
  1190                         this.splice.apply(this, [0, this.length].concat(can.makeArray(newList || [])));
       
  1191                     }
       
  1192 
       
  1193                     return this;
       
  1194                 }
       
  1195             });
       
  1196 
       
  1197         can.List = Observe.List = list;
       
  1198         Observe.setup = function() {
       
  1199             can.Construct.setup.apply(this, arguments);
       
  1200             // I would prefer not to do it this way. It should
       
  1201             // be using the attributes plugin to do this type of conversion.
       
  1202             this.List = Observe.List({
       
  1203                     Observe: this
       
  1204                 }, {});
       
  1205         }
       
  1206         return Observe;
       
  1207     })(__m3, __m8, __m1);
       
  1208 
       
  1209     // ## can/observe/compute/compute.js
       
  1210     var __m9 = (function(can, bind) {
       
  1211 
       
  1212         // returns the
       
  1213         // - observes and attr methods are called by func
       
  1214         // - the value returned by func
       
  1215         // ex: `{value: 100, observed: [{obs: o, attr: "completed"}]}`
       
  1216         var getValueAndObserved = function(func, self) {
       
  1217 
       
  1218             var oldReading;
       
  1219             if (can.Observe) {
       
  1220                 // Set a callback on can.Observe to know
       
  1221                 // when an attr is read.
       
  1222                 // Keep a reference to the old reader
       
  1223                 // if there is one.  This is used
       
  1224                 // for nested live binding.
       
  1225                 oldReading = can.Observe.__reading;
       
  1226                 can.Observe.__reading = function(obj, attr) {
       
  1227                     // Add the observe and attr that was read
       
  1228                     // to `observed`
       
  1229                     observed.push({
       
  1230                             obj: obj,
       
  1231                             attr: attr + ""
       
  1232                         });
       
  1233                 };
       
  1234             }
       
  1235 
       
  1236             var observed = [],
       
  1237                 // Call the "wrapping" function to get the value. `observed`
       
  1238                 // will have the observe/attribute pairs that were read.
       
  1239                 value = func.call(self);
       
  1240 
       
  1241             // Set back so we are no longer reading.
       
  1242             if (can.Observe) {
       
  1243                 can.Observe.__reading = oldReading;
       
  1244             }
       
  1245             return {
       
  1246                 value: value,
       
  1247                 observed: observed
       
  1248             };
       
  1249         },
       
  1250             // Calls `callback(newVal, oldVal)` everytime an observed property
       
  1251             // called within `getterSetter` is changed and creates a new result of `getterSetter`.
       
  1252             // Also returns an object that can teardown all event handlers.
       
  1253             computeBinder = function(getterSetter, context, callback, computeState) {
       
  1254                 // track what we are observing
       
  1255                 var observing = {},
       
  1256                     // a flag indicating if this observe/attr pair is already bound
       
  1257                     matched = true,
       
  1258                     // the data to return 
       
  1259                     data = {
       
  1260                         // we will maintain the value while live-binding is taking place
       
  1261                         value: undefined,
       
  1262                         // a teardown method that stops listening
       
  1263                         teardown: function() {
       
  1264                             for (var name in observing) {
       
  1265                                 var ob = observing[name];
       
  1266                                 ob.observe.obj.unbind(ob.observe.attr, onchanged);
       
  1267                                 delete observing[name];
       
  1268                             }
       
  1269                         }
       
  1270                     },
       
  1271                     batchNum;
       
  1272 
       
  1273                 // when a property value is changed
       
  1274                 var onchanged = function(ev) {
       
  1275                     // If the compute is no longer bound (because the same change event led to an unbind)
       
  1276                     // then do not call getValueAndBind, or we will leak bindings.
       
  1277                     if (computeState && !computeState.bound) {
       
  1278                         return;
       
  1279                     }
       
  1280                     if (ev.batchNum === undefined || ev.batchNum !== batchNum) {
       
  1281                         // store the old value
       
  1282                         var oldValue = data.value,
       
  1283                             // get the new value
       
  1284                             newvalue = getValueAndBind();
       
  1285 
       
  1286                         // update the value reference (in case someone reads)
       
  1287                         data.value = newvalue;
       
  1288                         // if a change happened
       
  1289                         if (newvalue !== oldValue) {
       
  1290                             callback(newvalue, oldValue);
       
  1291                         }
       
  1292                         batchNum = batchNum = ev.batchNum;
       
  1293                     }
       
  1294 
       
  1295 
       
  1296                 };
       
  1297 
       
  1298                 // gets the value returned by `getterSetter` and also binds to any attributes
       
  1299                 // read by the call
       
  1300                 var getValueAndBind = function() {
       
  1301                     var info = getValueAndObserved(getterSetter, context),
       
  1302                         newObserveSet = info.observed;
       
  1303 
       
  1304                     var value = info.value;
       
  1305                     matched = !matched;
       
  1306 
       
  1307                     // go through every attribute read by this observe
       
  1308                     can.each(newObserveSet, function(ob) {
       
  1309                         // if the observe/attribute pair is being observed
       
  1310                         if (observing[ob.obj._cid + "|" + ob.attr]) {
       
  1311                             // mark at as observed
       
  1312                             observing[ob.obj._cid + "|" + ob.attr].matched = matched;
       
  1313                         } else {
       
  1314                             // otherwise, set the observe/attribute on oldObserved, marking it as being observed
       
  1315                             observing[ob.obj._cid + "|" + ob.attr] = {
       
  1316                                 matched: matched,
       
  1317                                 observe: ob
       
  1318                             };
       
  1319                             ob.obj.bind(ob.attr, onchanged);
       
  1320                         }
       
  1321                     });
       
  1322 
       
  1323                     // Iterate through oldObserved, looking for observe/attributes
       
  1324                     // that are no longer being bound and unbind them
       
  1325                     for (var name in observing) {
       
  1326                         var ob = observing[name];
       
  1327                         if (ob.matched !== matched) {
       
  1328                             ob.observe.obj.unbind(ob.observe.attr, onchanged);
       
  1329                             delete observing[name];
       
  1330                         }
       
  1331                     }
       
  1332                     return value;
       
  1333                 };
       
  1334                 // set the initial value
       
  1335                 data.value = getValueAndBind();
       
  1336 
       
  1337                 data.isListening = !can.isEmptyObject(observing);
       
  1338                 return data;
       
  1339             }
       
  1340 
       
  1341             // if no one is listening ... we can not calculate every time
       
  1342 
       
  1343         can.compute = function(getterSetter, context, eventName) {
       
  1344             if (getterSetter && getterSetter.isComputed) {
       
  1345                 return getterSetter;
       
  1346             }
       
  1347             // stores the result of computeBinder
       
  1348             var computedData,
       
  1349                 // how many listeners to this this compute
       
  1350                 bindings = 0,
       
  1351                 // the computed object
       
  1352                 computed,
       
  1353                 // an object that keeps track if the computed is bound
       
  1354                 // onchanged needs to know this. It's possible a change happens and results in
       
  1355                 // something that unbinds the compute, it needs to not to try to recalculate who it
       
  1356                 // is listening to
       
  1357                 computeState = {
       
  1358                     bound: false,
       
  1359                     // true if this compute is calculated from other computes and observes
       
  1360                     hasDependencies: false
       
  1361                 },
       
  1362                 // The following functions are overwritten depending on how compute() is called
       
  1363                 // a method to setup listening
       
  1364                 on = function() {},
       
  1365                 // a method to teardown listening
       
  1366                 off = function() {},
       
  1367                 // the current cached value (only valid if bound = true)
       
  1368                 value,
       
  1369                 // how to read the value
       
  1370                 get = function() {
       
  1371                     return value
       
  1372                 },
       
  1373                 // sets the value
       
  1374                 set = function(newVal) {
       
  1375                     value = newVal;
       
  1376                 },
       
  1377                 // this compute can be a dependency of other computes
       
  1378                 canReadForChangeEvent = true;
       
  1379 
       
  1380             computed = function(newVal) {
       
  1381                 // setting ...
       
  1382                 if (arguments.length) {
       
  1383                     // save a reference to the old value
       
  1384                     var old = value;
       
  1385 
       
  1386                     // setter may return a value if 
       
  1387                     // setter is for a value maintained exclusively by this compute
       
  1388                     var setVal = set.call(context, newVal, old);
       
  1389 
       
  1390                     // if this has dependencies return the current value
       
  1391                     if (computed.hasDependencies) {
       
  1392                         return get.call(context);
       
  1393                     }
       
  1394 
       
  1395                     if (setVal === undefined) {
       
  1396                         // it's possible, like with the DOM, setting does not
       
  1397                         // fire a change event, so we must read
       
  1398                         value = get.call(context);
       
  1399                     } else {
       
  1400                         value = setVal;
       
  1401                     }
       
  1402                     // fire the change
       
  1403                     if (old !== value) {
       
  1404                         can.Observe.triggerBatch(computed, "change", [value, old]);
       
  1405                     }
       
  1406                     return value;
       
  1407                 } else {
       
  1408                     // Let others know to listen to changes in this compute
       
  1409                     if (can.Observe.__reading && canReadForChangeEvent) {
       
  1410                         can.Observe.__reading(computed, 'change');
       
  1411                     }
       
  1412                     // if we are bound, use the cached value
       
  1413                     if (computeState.bound) {
       
  1414                         return value;
       
  1415                     } else {
       
  1416                         return get.call(context);
       
  1417                     }
       
  1418                 }
       
  1419             }
       
  1420             if (typeof getterSetter === "function") {
       
  1421                 set = getterSetter;
       
  1422                 get = getterSetter;
       
  1423                 canReadForChangeEvent = eventName === false ? false : true;
       
  1424                 computed.hasDependencies = false;
       
  1425                 on = function(update) {
       
  1426                     computedData = computeBinder(getterSetter, context || this, update, computeState);
       
  1427                     computed.hasDependencies = computedData.isListening
       
  1428                     value = computedData.value;
       
  1429                 }
       
  1430                 off = function() {
       
  1431                     computedData && computedData.teardown();
       
  1432                 }
       
  1433             } else if (context) {
       
  1434 
       
  1435                 if (typeof context == "string") {
       
  1436                     // `can.compute(obj, "propertyName", [eventName])`
       
  1437 
       
  1438                     var propertyName = context,
       
  1439                         isObserve = getterSetter instanceof can.Observe;
       
  1440                     if (isObserve) {
       
  1441                         computed.hasDependencies = true;
       
  1442                     }
       
  1443                     get = function() {
       
  1444                         if (isObserve) {
       
  1445                             return getterSetter.attr(propertyName);
       
  1446                         } else {
       
  1447                             return getterSetter[propertyName];
       
  1448                         }
       
  1449                     }
       
  1450                     set = function(newValue) {
       
  1451                         if (isObserve) {
       
  1452                             getterSetter.attr(propertyName, newValue)
       
  1453                         } else {
       
  1454                             getterSetter[propertyName] = newValue;
       
  1455                         }
       
  1456                     }
       
  1457                     var handler;
       
  1458                     on = function(update) {
       
  1459                         handler = function() {
       
  1460                             update(get(), value)
       
  1461                         };
       
  1462                         can.bind.call(getterSetter, eventName || propertyName, handler)
       
  1463 
       
  1464                         // use getValueAndObserved because
       
  1465                         // we should not be indicating that some parent
       
  1466                         // reads this property if it happens to be binding on it
       
  1467                         value = getValueAndObserved(get).value
       
  1468                     }
       
  1469                     off = function() {
       
  1470                         can.unbind.call(getterSetter, eventName || propertyName, handler)
       
  1471                     }
       
  1472 
       
  1473                 } else {
       
  1474                     // `can.compute(initialValue, setter)`
       
  1475                     if (typeof context === "function") {
       
  1476                         value = getterSetter;
       
  1477                         set = context;
       
  1478                     } else {
       
  1479                         // `can.compute(initialValue,{get:, set:, on:, off:})`
       
  1480                         value = getterSetter;
       
  1481                         var options = context;
       
  1482                         get = options.get || get;
       
  1483                         set = options.set || set;
       
  1484                         on = options.on || on;
       
  1485                         off = options.off || off;
       
  1486                     }
       
  1487 
       
  1488                 }
       
  1489 
       
  1490 
       
  1491 
       
  1492             } else {
       
  1493                 // `can.compute(5)`
       
  1494                 value = getterSetter;
       
  1495             }
       
  1496 
       
  1497             computed.isComputed = true;
       
  1498 
       
  1499             can.cid(computed, "compute")
       
  1500 
       
  1501             var updater = function(newValue, oldValue) {
       
  1502                 value = newValue;
       
  1503                 // might need a way to look up new and oldVal
       
  1504                 can.Observe.triggerBatch(computed, "change", [newValue, oldValue])
       
  1505             }
       
  1506 
       
  1507             return can.extend(computed, {
       
  1508                     _bindsetup: function() {
       
  1509                         computeState.bound = true;
       
  1510                         // setup live-binding
       
  1511                         on.call(this, updater)
       
  1512                     },
       
  1513                     _bindteardown: function() {
       
  1514                         off.call(this, updater)
       
  1515                         computeState.bound = false;
       
  1516                     },
       
  1517 
       
  1518                     bind: can.bindAndSetup,
       
  1519 
       
  1520                     unbind: can.unbindAndTeardown
       
  1521                 });
       
  1522         };
       
  1523         can.compute.binder = computeBinder;
       
  1524         return can.compute;
       
  1525     })(__m3, __m8);
       
  1526 
       
  1527     // ## can/model/model.js
       
  1528     var __m10 = (function(can) {
       
  1529 
       
  1530         // ## model.js  
       
  1531         // `can.Model`  
       
  1532         // _A `can.Observe` that connects to a RESTful interface._
       
  1533         // Generic deferred piping function
       
  1534 
       
  1535         var pipe = function(def, model, func) {
       
  1536             var d = new can.Deferred();
       
  1537             def.then(function() {
       
  1538                 var args = can.makeArray(arguments);
       
  1539                 args[0] = model[func](args[0]);
       
  1540                 d.resolveWith(d, args);
       
  1541             }, function() {
       
  1542                 d.rejectWith(this, arguments);
       
  1543             });
       
  1544 
       
  1545             if (typeof def.abort === 'function') {
       
  1546                 d.abort = function() {
       
  1547                     return def.abort();
       
  1548                 }
       
  1549             }
       
  1550 
       
  1551             return d;
       
  1552         },
       
  1553             modelNum = 0,
       
  1554             ignoreHookup = /change.observe\d+/,
       
  1555             getId = function(inst) {
       
  1556                 // Instead of using attr, use __get for performance.
       
  1557                 // Need to set reading
       
  1558                 can.Observe.__reading && can.Observe.__reading(inst, inst.constructor.id)
       
  1559                 return inst.__get(inst.constructor.id);
       
  1560             },
       
  1561             // Ajax `options` generator function
       
  1562             ajax = function(ajaxOb, data, type, dataType, success, error) {
       
  1563 
       
  1564                 var params = {};
       
  1565 
       
  1566                 // If we get a string, handle it.
       
  1567                 if (typeof ajaxOb == "string") {
       
  1568                     // If there's a space, it's probably the type.
       
  1569                     var parts = ajaxOb.split(/\s+/);
       
  1570                     params.url = parts.pop();
       
  1571                     if (parts.length) {
       
  1572                         params.type = parts.pop();
       
  1573                     }
       
  1574                 } else {
       
  1575                     can.extend(params, ajaxOb);
       
  1576                 }
       
  1577 
       
  1578                 // If we are a non-array object, copy to a new attrs.
       
  1579                 params.data = typeof data == "object" && !can.isArray(data) ?
       
  1580                     can.extend(params.data || {}, data) : data;
       
  1581 
       
  1582                 // Get the url with any templated values filled out.
       
  1583                 params.url = can.sub(params.url, params.data, true);
       
  1584 
       
  1585                 return can.ajax(can.extend({
       
  1586                             type: type || "post",
       
  1587                             dataType: dataType || "json",
       
  1588                             success: success,
       
  1589                             error: error
       
  1590                         }, params));
       
  1591             },
       
  1592             makeRequest = function(self, type, success, error, method) {
       
  1593                 var args;
       
  1594                 // if we pass an array as `self` it it means we are coming from
       
  1595                 // the queued request, and we're passing already serialized data
       
  1596                 // self's signature will be: [self, serializedData]
       
  1597                 if (can.isArray(self)) {
       
  1598                     args = self[1];
       
  1599                     self = self[0];
       
  1600                 } else {
       
  1601                     args = self.serialize();
       
  1602                 }
       
  1603                 args = [args];
       
  1604                 var deferred,
       
  1605                     // The model.
       
  1606                     model = self.constructor,
       
  1607                     jqXHR;
       
  1608 
       
  1609                 // `destroy` does not need data.
       
  1610                 if (type == 'destroy') {
       
  1611                     args.shift();
       
  1612                 }
       
  1613                 // `update` and `destroy` need the `id`.
       
  1614                 if (type !== 'create') {
       
  1615                     args.unshift(getId(self));
       
  1616                 }
       
  1617 
       
  1618 
       
  1619                 jqXHR = model[type].apply(model, args);
       
  1620 
       
  1621                 deferred = jqXHR.pipe(function(data) {
       
  1622                     self[method || type + "d"](data, jqXHR);
       
  1623                     return self;
       
  1624                 });
       
  1625 
       
  1626                 // Hook up `abort`
       
  1627                 if (jqXHR.abort) {
       
  1628                     deferred.abort = function() {
       
  1629                         jqXHR.abort();
       
  1630                     };
       
  1631                 }
       
  1632 
       
  1633                 deferred.then(success, error);
       
  1634                 return deferred;
       
  1635             },
       
  1636 
       
  1637             // This object describes how to make an ajax request for each ajax method.  
       
  1638             // The available properties are:
       
  1639             //		`url` - The default url to use as indicated as a property on the model.
       
  1640             //		`type` - The default http request type
       
  1641             //		`data` - A method that takes the `arguments` and returns `data` used for ajax.
       
  1642 
       
  1643             ajaxMethods = {
       
  1644 
       
  1645                 create: {
       
  1646                     url: "_shortName",
       
  1647                     type: "post"
       
  1648                 },
       
  1649 
       
  1650                 update: {
       
  1651                     data: function(id, attrs) {
       
  1652                         attrs = attrs || {};
       
  1653                         var identity = this.id;
       
  1654                         if (attrs[identity] && attrs[identity] !== id) {
       
  1655                             attrs["new" + can.capitalize(id)] = attrs[identity];
       
  1656                             delete attrs[identity];
       
  1657                         }
       
  1658                         attrs[identity] = id;
       
  1659                         return attrs;
       
  1660                     },
       
  1661                     type: "put"
       
  1662                 },
       
  1663 
       
  1664                 destroy: {
       
  1665                     type: "delete",
       
  1666                     data: function(id) {
       
  1667                         var args = {};
       
  1668                         args.id = args[this.id] = id;
       
  1669                         return args;
       
  1670                     }
       
  1671                 },
       
  1672 
       
  1673                 findAll: {
       
  1674                     url: "_shortName"
       
  1675                 },
       
  1676 
       
  1677                 findOne: {}
       
  1678             },
       
  1679             // Makes an ajax request `function` from a string.
       
  1680             //		`ajaxMethod` - The `ajaxMethod` object defined above.
       
  1681             //		`str` - The string the user provided. Ex: `findAll: "/recipes.json"`.
       
  1682             ajaxMaker = function(ajaxMethod, str) {
       
  1683                 // Return a `function` that serves as the ajax method.
       
  1684                 return function(data) {
       
  1685                     // If the ajax method has it's own way of getting `data`, use that.
       
  1686                     data = ajaxMethod.data ?
       
  1687                         ajaxMethod.data.apply(this, arguments) :
       
  1688                     // Otherwise use the data passed in.
       
  1689                     data;
       
  1690                     // Return the ajax method with `data` and the `type` provided.
       
  1691                     return ajax(str || this[ajaxMethod.url || "_url"], data, ajaxMethod.type || "get")
       
  1692                 }
       
  1693             }
       
  1694 
       
  1695 
       
  1696 
       
  1697         can.Model = can.Observe({
       
  1698                 fullName: "can.Model",
       
  1699                 _reqs: 0,
       
  1700                 setup: function(base) {
       
  1701                     // create store here if someone wants to use model without inheriting from it
       
  1702                     this.store = {};
       
  1703                     can.Observe.setup.apply(this, arguments);
       
  1704                     // Set default list as model list
       
  1705                     if (!can.Model) {
       
  1706                         return;
       
  1707                     }
       
  1708                     this.List = ML({
       
  1709                             Observe: this
       
  1710                         }, {});
       
  1711                     var self = this,
       
  1712                         clean = can.proxy(this._clean, self);
       
  1713 
       
  1714 
       
  1715                     // go through ajax methods and set them up
       
  1716                     can.each(ajaxMethods, function(method, name) {
       
  1717                         // if an ajax method is not a function, it's either
       
  1718                         // a string url like findAll: "/recipes" or an
       
  1719                         // ajax options object like {url: "/recipes"}
       
  1720                         if (!can.isFunction(self[name])) {
       
  1721                             // use ajaxMaker to convert that into a function
       
  1722                             // that returns a deferred with the data
       
  1723                             self[name] = ajaxMaker(method, self[name]);
       
  1724                         }
       
  1725                         // check if there's a make function like makeFindAll
       
  1726                         // these take deferred function and can do special
       
  1727                         // behavior with it (like look up data in a store)
       
  1728                         if (self["make" + can.capitalize(name)]) {
       
  1729                             // pass the deferred method to the make method to get back
       
  1730                             // the "findAll" method.
       
  1731                             var newMethod = self["make" + can.capitalize(name)](self[name]);
       
  1732                             can.Construct._overwrite(self, base, name, function() {
       
  1733                                 // increment the numer of requests
       
  1734                                 can.Model._reqs++;
       
  1735                                 var def = newMethod.apply(this, arguments);
       
  1736                                 var then = def.then(clean, clean);
       
  1737                                 then.abort = def.abort;
       
  1738 
       
  1739                                 // attach abort to our then and return it
       
  1740                                 return then;
       
  1741                             })
       
  1742                         }
       
  1743                     });
       
  1744 
       
  1745                     if (self.fullName == "can.Model" || !self.fullName) {
       
  1746                         self.fullName = "Model" + (++modelNum);
       
  1747                     }
       
  1748                     // Add ajax converters.
       
  1749                     can.Model._reqs = 0;
       
  1750                     this._url = this._shortName + "/{" + this.id + "}"
       
  1751                 },
       
  1752                 _ajax: ajaxMaker,
       
  1753                 _makeRequest: makeRequest,
       
  1754                 _clean: function() {
       
  1755                     can.Model._reqs--;
       
  1756                     if (!can.Model._reqs) {
       
  1757                         for (var id in this.store) {
       
  1758                             if (!this.store[id]._bindings) {
       
  1759                                 delete this.store[id];
       
  1760                             }
       
  1761                         }
       
  1762                     }
       
  1763                     return arguments[0];
       
  1764                 },
       
  1765 
       
  1766                 models: function(instancesRawData, oldList) {
       
  1767                     // until "end of turn", increment reqs counter so instances will be added to the store
       
  1768                     can.Model._reqs++;
       
  1769                     if (!instancesRawData) {
       
  1770                         return;
       
  1771                     }
       
  1772 
       
  1773                     if (instancesRawData instanceof this.List) {
       
  1774                         return instancesRawData;
       
  1775                     }
       
  1776 
       
  1777                     // Get the list type.
       
  1778                     var self = this,
       
  1779                         tmp = [],
       
  1780                         res = oldList instanceof can.Observe.List ? oldList : new(self.List || ML),
       
  1781                         // Did we get an `array`?
       
  1782                         arr = can.isArray(instancesRawData),
       
  1783 
       
  1784                         // Did we get a model list?
       
  1785                         ml = (instancesRawData instanceof ML),
       
  1786 
       
  1787                         // Get the raw `array` of objects.
       
  1788                         raw = arr ?
       
  1789 
       
  1790                         // If an `array`, return the `array`.
       
  1791                         instancesRawData :
       
  1792 
       
  1793                         // Otherwise if a model list.
       
  1794                         (ml ?
       
  1795 
       
  1796                             // Get the raw objects from the list.
       
  1797                             instancesRawData.serialize() :
       
  1798 
       
  1799                             // Get the object's data.
       
  1800                             instancesRawData.data),
       
  1801                         i = 0;
       
  1802 
       
  1803 
       
  1804 
       
  1805                     if (res.length) {
       
  1806                         res.splice(0);
       
  1807                     }
       
  1808 
       
  1809                     can.each(raw, function(rawPart) {
       
  1810                         tmp.push(self.model(rawPart));
       
  1811                     });
       
  1812 
       
  1813                     // We only want one change event so push everything at once
       
  1814                     res.push.apply(res, tmp);
       
  1815 
       
  1816                     if (!arr) { // Push other stuff onto `array`.
       
  1817                         can.each(instancesRawData, function(val, prop) {
       
  1818                             if (prop !== 'data') {
       
  1819                                 res.attr(prop, val);
       
  1820                             }
       
  1821                         })
       
  1822                     }
       
  1823                     // at "end of turn", clean up the store
       
  1824                     setTimeout(can.proxy(this._clean, this), 1);
       
  1825                     return res;
       
  1826                 },
       
  1827 
       
  1828                 model: function(attributes) {
       
  1829                     if (!attributes) {
       
  1830                         return;
       
  1831                     }
       
  1832                     if (attributes instanceof this) {
       
  1833                         attributes = attributes.serialize();
       
  1834                     }
       
  1835                     var id = attributes[this.id],
       
  1836                         model = (id || id === 0) && this.store[id] ?
       
  1837                             this.store[id].attr(attributes, this.removeAttr || false) : new this(attributes);
       
  1838                     if (can.Model._reqs) {
       
  1839                         this.store[attributes[this.id]] = model;
       
  1840                     }
       
  1841                     return model;
       
  1842                 }
       
  1843             },
       
  1844 
       
  1845 
       
  1846             {
       
  1847 
       
  1848                 isNew: function() {
       
  1849                     var id = getId(this);
       
  1850                     return !(id || id === 0); // If `null` or `undefined`
       
  1851                 },
       
  1852 
       
  1853                 save: function(success, error) {
       
  1854                     return makeRequest(this, this.isNew() ? 'create' : 'update', success, error);
       
  1855                 },
       
  1856 
       
  1857                 destroy: function(success, error) {
       
  1858                     if (this.isNew()) {
       
  1859                         var self = this;
       
  1860                         var def = can.Deferred();
       
  1861                         def.then(success, error);
       
  1862                         return def.done(function(data) {
       
  1863                             self.destroyed(data)
       
  1864                         }).resolve(self);
       
  1865                     }
       
  1866                     return makeRequest(this, 'destroy', success, error, 'destroyed');
       
  1867                 },
       
  1868 
       
  1869                 _bindsetup: function() {
       
  1870                     this.constructor.store[this.__get(this.constructor.id)] = this;
       
  1871                     return can.Observe.prototype._bindsetup.apply(this, arguments);
       
  1872                 },
       
  1873 
       
  1874                 _bindteardown: function() {
       
  1875                     delete this.constructor.store[getId(this)];
       
  1876                     return can.Observe.prototype._bindteardown.apply(this, arguments)
       
  1877                 },
       
  1878                 // Change `id`.
       
  1879                 ___set: function(prop, val) {
       
  1880                     can.Observe.prototype.___set.call(this, prop, val)
       
  1881                     // If we add an `id`, move it to the store.
       
  1882                     if (prop === this.constructor.id && this._bindings) {
       
  1883                         this.constructor.store[getId(this)] = this;
       
  1884                     }
       
  1885                 }
       
  1886             });
       
  1887 
       
  1888         can.each({
       
  1889                 makeFindAll: "models",
       
  1890                 makeFindOne: "model",
       
  1891                 makeCreate: "model",
       
  1892                 makeUpdate: "model"
       
  1893             }, function(method, name) {
       
  1894                 can.Model[name] = function(oldMethod) {
       
  1895                     return function() {
       
  1896                         var args = can.makeArray(arguments),
       
  1897                             oldArgs = can.isFunction(args[1]) ? args.splice(0, 1) : args.splice(0, 2),
       
  1898                             def = pipe(oldMethod.apply(this, oldArgs), this, method);
       
  1899                         def.then(args[0], args[1]);
       
  1900                         // return the original promise
       
  1901                         return def;
       
  1902                     };
       
  1903                 };
       
  1904             });
       
  1905 
       
  1906         can.each([
       
  1907 
       
  1908                 "created",
       
  1909 
       
  1910                 "updated",
       
  1911 
       
  1912                 "destroyed"
       
  1913             ], function(funcName) {
       
  1914                 can.Model.prototype[funcName] = function(attrs) {
       
  1915                     var stub,
       
  1916                         constructor = this.constructor;
       
  1917 
       
  1918                     // Update attributes if attributes have been passed
       
  1919                     stub = attrs && typeof attrs == 'object' && this.attr(attrs.attr ? attrs.attr() : attrs);
       
  1920 
       
  1921                     // triggers change event that bubble's like
       
  1922                     // handler( 'change','1.destroyed' ). This is used
       
  1923                     // to remove items on destroyed from Model Lists.
       
  1924                     // but there should be a better way.
       
  1925                     can.trigger(this, "change", funcName)
       
  1926 
       
  1927 
       
  1928                     // Call event on the instance's Class
       
  1929                     can.trigger(constructor, funcName, this);
       
  1930                 };
       
  1931             });
       
  1932 
       
  1933         // Model lists are just like `Observe.List` except that when their items are 
       
  1934         // destroyed, it automatically gets removed from the list.
       
  1935 
       
  1936         var ML = can.Model.List = can.Observe.List({
       
  1937                 setup: function(params) {
       
  1938                     if (can.isPlainObject(params) && !can.isArray(params)) {
       
  1939                         can.Observe.List.prototype.setup.apply(this);
       
  1940                         this.replace(this.constructor.Observe.findAll(params))
       
  1941                     } else {
       
  1942                         can.Observe.List.prototype.setup.apply(this, arguments);
       
  1943                     }
       
  1944                 },
       
  1945                 _changes: function(ev, attr) {
       
  1946                     can.Observe.List.prototype._changes.apply(this, arguments);
       
  1947                     if (/\w+\.destroyed/.test(attr)) {
       
  1948                         var index = this.indexOf(ev.target);
       
  1949                         if (index != -1) {
       
  1950                             this.splice(index, 1);
       
  1951                         }
       
  1952                     }
       
  1953                 }
       
  1954             })
       
  1955 
       
  1956         return can.Model;
       
  1957     })(__m3, __m7);
       
  1958 
       
  1959     // ## can/view/view.js
       
  1960     var __m11 = (function(can) {
       
  1961         // ## view.js
       
  1962         // `can.view`  
       
  1963         // _Templating abstraction._
       
  1964 
       
  1965         var isFunction = can.isFunction,
       
  1966             makeArray = can.makeArray,
       
  1967             // Used for hookup `id`s.
       
  1968             hookupId = 1,
       
  1969 
       
  1970             $view = can.view = can.template = function(view, data, helpers, callback) {
       
  1971                 // If helpers is a `function`, it is actually a callback.
       
  1972                 if (isFunction(helpers)) {
       
  1973                     callback = helpers;
       
  1974                     helpers = undefined;
       
  1975                 }
       
  1976 
       
  1977                 var pipe = function(result) {
       
  1978                     return $view.frag(result);
       
  1979                 },
       
  1980                     // In case we got a callback, we need to convert the can.view.render
       
  1981                     // result to a document fragment
       
  1982                     wrapCallback = isFunction(callback) ? function(frag) {
       
  1983                         callback(pipe(frag));
       
  1984                     } : null,
       
  1985                     // Get the result.
       
  1986                     result = $view.render(view, data, helpers, wrapCallback),
       
  1987                     deferred = can.Deferred();
       
  1988 
       
  1989                 if (isFunction(result)) {
       
  1990                     return result;
       
  1991                 }
       
  1992 
       
  1993                 if (can.isDeferred(result)) {
       
  1994                     result.then(function(result, data) {
       
  1995                         deferred.resolve.call(deferred, pipe(result), data);
       
  1996                     }, function() {
       
  1997                         deferred.fail.apply(deferred, arguments);
       
  1998                     });
       
  1999                     return deferred;
       
  2000                 }
       
  2001 
       
  2002                 // Convert it into a dom frag.
       
  2003                 return pipe(result);
       
  2004             };
       
  2005 
       
  2006         can.extend($view, {
       
  2007                 // creates a frag and hooks it up all at once
       
  2008                 frag: function(result, parentNode) {
       
  2009                     return $view.hookup($view.fragment(result), parentNode);
       
  2010                 },
       
  2011 
       
  2012                 // simply creates a frag
       
  2013                 // this is used internally to create a frag
       
  2014                 // insert it
       
  2015                 // then hook it up
       
  2016                 fragment: function(result) {
       
  2017                     var frag = can.buildFragment(result, document.body);
       
  2018                     // If we have an empty frag...
       
  2019                     if (!frag.childNodes.length) {
       
  2020                         frag.appendChild(document.createTextNode(''));
       
  2021                     }
       
  2022                     return frag;
       
  2023                 },
       
  2024 
       
  2025                 // Convert a path like string into something that's ok for an `element` ID.
       
  2026                 toId: function(src) {
       
  2027                     return can.map(src.toString().split(/\/|\./g), function(part) {
       
  2028                         // Dont include empty strings in toId functions
       
  2029                         if (part) {
       
  2030                             return part;
       
  2031                         }
       
  2032                     }).join("_");
       
  2033                 },
       
  2034 
       
  2035                 hookup: function(fragment, parentNode) {
       
  2036                     var hookupEls = [],
       
  2037                         id,
       
  2038                         func;
       
  2039 
       
  2040                     // Get all `childNodes`.
       
  2041                     can.each(fragment.childNodes ? can.makeArray(fragment.childNodes) : fragment, function(node) {
       
  2042                         if (node.nodeType === 1) {
       
  2043                             hookupEls.push(node);
       
  2044                             hookupEls.push.apply(hookupEls, can.makeArray(node.getElementsByTagName('*')));
       
  2045                         }
       
  2046                     });
       
  2047 
       
  2048                     // Filter by `data-view-id` attribute.
       
  2049                     can.each(hookupEls, function(el) {
       
  2050                         if (el.getAttribute && (id = el.getAttribute('data-view-id')) && (func = $view.hookups[id])) {
       
  2051                             func(el, parentNode, id);
       
  2052                             delete $view.hookups[id];
       
  2053                             el.removeAttribute('data-view-id');
       
  2054                         }
       
  2055                     });
       
  2056 
       
  2057                     return fragment;
       
  2058                 },
       
  2059 
       
  2060 
       
  2061                 hookups: {},
       
  2062 
       
  2063 
       
  2064                 hook: function(cb) {
       
  2065                     $view.hookups[++hookupId] = cb;
       
  2066                     return " data-view-id='" + hookupId + "'";
       
  2067                 },
       
  2068 
       
  2069 
       
  2070                 cached: {},
       
  2071 
       
  2072                 cachedRenderers: {},
       
  2073 
       
  2074 
       
  2075                 cache: true,
       
  2076 
       
  2077 
       
  2078                 register: function(info) {
       
  2079                     this.types["." + info.suffix] = info;
       
  2080                 },
       
  2081 
       
  2082                 types: {},
       
  2083 
       
  2084 
       
  2085                 ext: ".ejs",
       
  2086 
       
  2087 
       
  2088                 registerScript: function() {},
       
  2089 
       
  2090 
       
  2091                 preload: function() {},
       
  2092 
       
  2093 
       
  2094                 render: function(view, data, helpers, callback) {
       
  2095                     // If helpers is a `function`, it is actually a callback.
       
  2096                     if (isFunction(helpers)) {
       
  2097                         callback = helpers;
       
  2098                         helpers = undefined;
       
  2099                     }
       
  2100 
       
  2101                     // See if we got passed any deferreds.
       
  2102                     var deferreds = getDeferreds(data);
       
  2103 
       
  2104                     if (deferreds.length) { // Does data contain any deferreds?
       
  2105                         // The deferred that resolves into the rendered content...
       
  2106                         var deferred = new can.Deferred(),
       
  2107                             dataCopy = can.extend({}, data);
       
  2108 
       
  2109                         // Add the view request to the list of deferreds.
       
  2110                         deferreds.push(get(view, true))
       
  2111 
       
  2112                         // Wait for the view and all deferreds to finish...
       
  2113                         can.when.apply(can, deferreds).then(function(resolved) {
       
  2114                             // Get all the resolved deferreds.
       
  2115                             var objs = makeArray(arguments),
       
  2116                                 // Renderer is the last index of the data.
       
  2117                                 renderer = objs.pop(),
       
  2118                                 // The result of the template rendering with data.
       
  2119                                 result;
       
  2120 
       
  2121                             // Make data look like the resolved deferreds.
       
  2122                             if (can.isDeferred(data)) {
       
  2123                                 dataCopy = usefulPart(resolved);
       
  2124                             } else {
       
  2125                                 // Go through each prop in data again and
       
  2126                                 // replace the defferreds with what they resolved to.
       
  2127                                 for (var prop in data) {
       
  2128                                     if (can.isDeferred(data[prop])) {
       
  2129                                         dataCopy[prop] = usefulPart(objs.shift());
       
  2130                                     }
       
  2131                                 }
       
  2132                             }
       
  2133 
       
  2134                             // Get the rendered result.
       
  2135                             result = renderer(dataCopy, helpers);
       
  2136 
       
  2137                             // Resolve with the rendered view.
       
  2138                             deferred.resolve(result, dataCopy);
       
  2139 
       
  2140                             // If there's a `callback`, call it back with the result.
       
  2141                             callback && callback(result, dataCopy);
       
  2142                         }, function() {
       
  2143                             deferred.reject.apply(deferred, arguments)
       
  2144                         });
       
  2145                         // Return the deferred...
       
  2146                         return deferred;
       
  2147                     } else {
       
  2148                         // No deferreds! Render this bad boy.
       
  2149                         var response,
       
  2150                             // If there's a `callback` function
       
  2151                             async = isFunction(callback),
       
  2152                             // Get the `view` type
       
  2153                             deferred = get(view, async);
       
  2154 
       
  2155                         // If we are `async`...
       
  2156                         if (async) {
       
  2157                             // Return the deferred
       
  2158                             response = deferred;
       
  2159                             // And fire callback with the rendered result.
       
  2160                             deferred.then(function(renderer) {
       
  2161                                 callback(data ? renderer(data, helpers) : renderer);
       
  2162                             })
       
  2163                         } else {
       
  2164                             // if the deferred is resolved, call the cached renderer instead
       
  2165                             // this is because it's possible, with recursive deferreds to
       
  2166                             // need to render a view while its deferred is _resolving_.  A _resolving_ deferred
       
  2167                             // is a deferred that was just resolved and is calling back it's success callbacks.
       
  2168                             // If a new success handler is called while resoliving, it does not get fired by
       
  2169                             // jQuery's deferred system.  So instead of adding a new callback
       
  2170                             // we use the cached renderer.
       
  2171                             // We also add __view_id on the deferred so we can look up it's cached renderer.
       
  2172                             // In the future, we might simply store either a deferred or the cached result.
       
  2173                             if (deferred.state() === "resolved" && deferred.__view_id) {
       
  2174                                 var currentRenderer = $view.cachedRenderers[deferred.__view_id];
       
  2175                                 return data ? currentRenderer(data, helpers) : currentRenderer;
       
  2176                             } else {
       
  2177                                 // Otherwise, the deferred is complete, so
       
  2178                                 // set response to the result of the rendering.
       
  2179                                 deferred.then(function(renderer) {
       
  2180                                     response = data ? renderer(data, helpers) : renderer;
       
  2181                                 });
       
  2182                             }
       
  2183                         }
       
  2184 
       
  2185                         return response;
       
  2186                     }
       
  2187                 },
       
  2188 
       
  2189 
       
  2190                 registerView: function(id, text, type, def) {
       
  2191                     // Get the renderer function.
       
  2192                     var func = (type || $view.types[$view.ext]).renderer(id, text);
       
  2193                     def = def || new can.Deferred();
       
  2194 
       
  2195                     // Cache if we are caching.
       
  2196                     if ($view.cache) {
       
  2197                         $view.cached[id] = def;
       
  2198                         def.__view_id = id;
       
  2199                         $view.cachedRenderers[id] = func;
       
  2200                     }
       
  2201 
       
  2202                     // Return the objects for the response's `dataTypes`
       
  2203                     // (in this case view).
       
  2204                     return def.resolve(func);
       
  2205                 }
       
  2206             });
       
  2207 
       
  2208         // Makes sure there's a template, if not, have `steal` provide a warning.
       
  2209         var checkText = function(text, url) {
       
  2210             if (!text.length) {
       
  2211 
       
  2212                 throw "can.view: No template or empty template:" + url;
       
  2213             }
       
  2214         },
       
  2215             // `Returns a `view` renderer deferred.  
       
  2216             // `url` - The url to the template.  
       
  2217             // `async` - If the ajax request should be asynchronous.  
       
  2218             // Returns a deferred.
       
  2219             get = function(url, async) {
       
  2220                 var suffix = url.match(/\.[\w\d]+$/),
       
  2221                     type,
       
  2222                     // If we are reading a script element for the content of the template,
       
  2223                     // `el` will be set to that script element.
       
  2224                     el,
       
  2225                     // A unique identifier for the view (used for caching).
       
  2226                     // This is typically derived from the element id or
       
  2227                     // the url for the template.
       
  2228                     id,
       
  2229                     // The ajax request used to retrieve the template content.
       
  2230                     jqXHR;
       
  2231 
       
  2232                 //If the url has a #, we assume we want to use an inline template
       
  2233                 //from a script element and not current page's HTML
       
  2234                 if (url.match(/^#/)) {
       
  2235                     url = url.substr(1);
       
  2236                 }
       
  2237                 // If we have an inline template, derive the suffix from the `text/???` part.
       
  2238                 // This only supports `<script>` tags.
       
  2239                 if (el = document.getElementById(url)) {
       
  2240                     suffix = "." + el.type.match(/\/(x\-)?(.+)/)[2];
       
  2241                 }
       
  2242 
       
  2243                 // If there is no suffix, add one.
       
  2244                 if (!suffix && !$view.cached[url]) {
       
  2245                     url += (suffix = $view.ext);
       
  2246                 }
       
  2247 
       
  2248                 if (can.isArray(suffix)) {
       
  2249                     suffix = suffix[0]
       
  2250                 }
       
  2251 
       
  2252                 // Convert to a unique and valid id.
       
  2253                 id = $view.toId(url);
       
  2254 
       
  2255                 // If an absolute path, use `steal` to get it.
       
  2256                 // You should only be using `//` if you are using `steal`.
       
  2257                 if (url.match(/^\/\//)) {
       
  2258                     var sub = url.substr(2);
       
  2259                     url = !window.steal ?
       
  2260                         sub :
       
  2261                         steal.config().root.mapJoin("" + steal.id(sub));
       
  2262                 }
       
  2263 
       
  2264                 // Set the template engine type.
       
  2265                 type = $view.types[suffix];
       
  2266 
       
  2267                 // If it is cached, 
       
  2268                 if ($view.cached[id]) {
       
  2269                     // Return the cached deferred renderer.
       
  2270                     return $view.cached[id];
       
  2271 
       
  2272                     // Otherwise if we are getting this from a `<script>` element.
       
  2273                 } else if (el) {
       
  2274                     // Resolve immediately with the element's `innerHTML`.
       
  2275                     return $view.registerView(id, el.innerHTML, type);
       
  2276                 } else {
       
  2277                     // Make an ajax request for text.
       
  2278                     var d = new can.Deferred();
       
  2279                     can.ajax({
       
  2280                             async: async,
       
  2281                             url: url,
       
  2282                             dataType: "text",
       
  2283                             error: function(jqXHR) {
       
  2284                                 checkText("", url);
       
  2285                                 d.reject(jqXHR);
       
  2286                             },
       
  2287                             success: function(text) {
       
  2288                                 // Make sure we got some text back.
       
  2289                                 checkText(text, url);
       
  2290                                 $view.registerView(id, text, type, d)
       
  2291                             }
       
  2292                         });
       
  2293                     return d;
       
  2294                 }
       
  2295             },
       
  2296             // Gets an `array` of deferreds from an `object`.
       
  2297             // This only goes one level deep.
       
  2298             getDeferreds = function(data) {
       
  2299                 var deferreds = [];
       
  2300 
       
  2301                 // pull out deferreds
       
  2302                 if (can.isDeferred(data)) {
       
  2303                     return [data]
       
  2304                 } else {
       
  2305                     for (var prop in data) {
       
  2306                         if (can.isDeferred(data[prop])) {
       
  2307                             deferreds.push(data[prop]);
       
  2308                         }
       
  2309                     }
       
  2310                 }
       
  2311                 return deferreds;
       
  2312             },
       
  2313             // Gets the useful part of a resolved deferred.
       
  2314             // This is for `model`s and `can.ajax` that resolve to an `array`.
       
  2315             usefulPart = function(resolved) {
       
  2316                 return can.isArray(resolved) && resolved[1] === 'success' ? resolved[0] : resolved
       
  2317             };
       
  2318 
       
  2319         //!steal-pluginify-remove-start
       
  2320         if (window.steal) {
       
  2321             steal.type("view js", function(options, success, error) {
       
  2322                 var type = $view.types["." + options.type],
       
  2323                     id = $view.toId(options.id);
       
  2324 
       
  2325                 options.text = "steal('" + (type.plugin || "can/view/" + options.type) + "',function(can){return " + "can.view.preload('" + id + "'," + options.text + ");\n})";
       
  2326                 success();
       
  2327             })
       
  2328         }
       
  2329         //!steal-pluginify-remove-end
       
  2330 
       
  2331         can.extend($view, {
       
  2332                 register: function(info) {
       
  2333                     this.types["." + info.suffix] = info;
       
  2334 
       
  2335                     //!steal-pluginify-remove-start
       
  2336                     if (window.steal) {
       
  2337                         steal.type(info.suffix + " view js", function(options, success, error) {
       
  2338                             var type = $view.types["." + options.type],
       
  2339                                 id = $view.toId(options.id + '');
       
  2340 
       
  2341                             options.text = type.script(id, options.text)
       
  2342                             success();
       
  2343                         })
       
  2344                     };
       
  2345                     //!steal-pluginify-remove-end
       
  2346 
       
  2347                     $view[info.suffix] = function(id, text) {
       
  2348                         if (!text) {
       
  2349                             // Return a nameless renderer
       
  2350                             var renderer = function() {
       
  2351                                 return $view.frag(renderer.render.apply(this, arguments));
       
  2352                             }
       
  2353                             renderer.render = function() {
       
  2354                                 var renderer = info.renderer(null, id);
       
  2355                                 return renderer.apply(renderer, arguments);
       
  2356                             }
       
  2357                             return renderer;
       
  2358                         }
       
  2359 
       
  2360                         $view.preload(id, info.renderer(id, text));
       
  2361                         return can.view(id);
       
  2362                     }
       
  2363                 },
       
  2364                 registerScript: function(type, id, src) {
       
  2365                     return "can.view.preload('" + id + "'," + $view.types["." + type].script(id, src) + ");";
       
  2366                 },
       
  2367                 preload: function(id, renderer) {
       
  2368                     $view.cached[id] = new can.Deferred().resolve(function(data, helpers) {
       
  2369                         return renderer.call(data, data, helpers);
       
  2370                     });
       
  2371 
       
  2372                     function frag() {
       
  2373                         return $view.frag(renderer.apply(this, arguments));
       
  2374                     }
       
  2375                     // expose the renderer for mustache
       
  2376                     frag.render = renderer;
       
  2377                     return frag;
       
  2378                 }
       
  2379 
       
  2380             });
       
  2381 
       
  2382         return can;
       
  2383     })(__m3);
       
  2384 
       
  2385     // ## can/view/elements.js
       
  2386     var __m14 = (function() {
       
  2387 
       
  2388         var elements = {
       
  2389             tagToContentPropMap: {
       
  2390                 option: "textContent" in document.createElement("option") ? "textContent" : "innerText",
       
  2391                 textarea: "value"
       
  2392             },
       
  2393 
       
  2394             attrMap: {
       
  2395                 "class": "className",
       
  2396                 "value": "value",
       
  2397                 "innerText": "innerText",
       
  2398                 "textContent": "textContent",
       
  2399                 "checked": true,
       
  2400                 "disabled": true,
       
  2401                 "readonly": true,
       
  2402                 "required": true
       
  2403             },
       
  2404             // elements whos default value we should set
       
  2405             defaultValue: ["input", "textarea"],
       
  2406             // a map of parent element to child elements
       
  2407             tagMap: {
       
  2408                 "": "span",
       
  2409                 table: "tbody",
       
  2410                 tr: "td",
       
  2411                 ol: "li",
       
  2412                 ul: "li",
       
  2413                 tbody: "tr",
       
  2414                 thead: "tr",
       
  2415                 tfoot: "tr",
       
  2416                 select: "option",
       
  2417                 optgroup: "option"
       
  2418             },
       
  2419             // a tag's parent element
       
  2420             reverseTagMap: {
       
  2421                 tr: "tbody",
       
  2422                 option: "select",
       
  2423                 td: "tr",
       
  2424                 th: "tr",
       
  2425                 li: "ul"
       
  2426             },
       
  2427 
       
  2428             getParentNode: function(el, defaultParentNode) {
       
  2429                 return defaultParentNode && el.parentNode.nodeType === 11 ? defaultParentNode : el.parentNode;
       
  2430             },
       
  2431             // set an attribute on an element
       
  2432             setAttr: function(el, attrName, val) {
       
  2433                 var tagName = el.nodeName.toString().toLowerCase(),
       
  2434                     prop = elements.attrMap[attrName];
       
  2435                 // if this is a special property
       
  2436                 if (prop === true) {
       
  2437                     el[attrName] = true;
       
  2438                 } else if (prop) {
       
  2439                     // set the value as true / false
       
  2440                     el[prop] = val;
       
  2441                     if (prop === "value" && can.inArray(tagName, elements.defaultValue) >= 0) {
       
  2442                         el.defaultValue = val;
       
  2443                     }
       
  2444                 } else {
       
  2445                     el.setAttribute(attrName, val);
       
  2446                 }
       
  2447             },
       
  2448             // gets the value of an attribute
       
  2449             getAttr: function(el, attrName) {
       
  2450                 // Default to a blank string for IE7/8
       
  2451                 return (elements.attrMap[attrName] && el[elements.attrMap[attrName]] ?
       
  2452                     el[elements.attrMap[attrName]] :
       
  2453                     el.getAttribute(attrName)) || '';
       
  2454             },
       
  2455             // removes the attribute
       
  2456             removeAttr: function(el, attrName) {
       
  2457                 if (elements.attrMap[attrName] === true) {
       
  2458                     el[attrName] = false;
       
  2459                 } else {
       
  2460                     el.removeAttribute(attrName);
       
  2461                 }
       
  2462             },
       
  2463             contentText: function(text) {
       
  2464                 if (typeof text == 'string') {
       
  2465                     return text;
       
  2466                 }
       
  2467                 // If has no value, return an empty string.
       
  2468                 if (!text && text !== 0) {
       
  2469                     return '';
       
  2470                 }
       
  2471                 return "" + text;
       
  2472             }
       
  2473         };
       
  2474 
       
  2475         return elements;
       
  2476     })();
       
  2477 
       
  2478     // ## can/view/scanner.js
       
  2479     var __m13 = (function(can, elements) {
       
  2480 
       
  2481         var newLine = /(\r|\n)+/g,
       
  2482             // Escapes characters starting with `\`.
       
  2483             clean = function(content) {
       
  2484                 return content
       
  2485                     .split('\\').join("\\\\")
       
  2486                     .split("\n").join("\\n")
       
  2487                     .split('"').join('\\"')
       
  2488                     .split("\t").join("\\t");
       
  2489             },
       
  2490             // Returns a tagName to use as a temporary placeholder for live content
       
  2491             // looks forward ... could be slow, but we only do it when necessary
       
  2492             getTag = function(tagName, tokens, i) {
       
  2493                 // if a tagName is provided, use that
       
  2494                 if (tagName) {
       
  2495                     return tagName;
       
  2496                 } else {
       
  2497                     // otherwise go searching for the next two tokens like "<",TAG
       
  2498                     while (i < tokens.length) {
       
  2499                         if (tokens[i] == "<" && elements.reverseTagMap[tokens[i + 1]]) {
       
  2500                             return elements.reverseTagMap[tokens[i + 1]];
       
  2501                         }
       
  2502                         i++;
       
  2503                     }
       
  2504                 }
       
  2505                 return '';
       
  2506             },
       
  2507             bracketNum = function(content) {
       
  2508                 return (--content.split("{").length) - (--content.split("}").length);
       
  2509             },
       
  2510             myEval = function(script) {
       
  2511                 eval(script);
       
  2512             },
       
  2513             attrReg = /([^\s]+)[\s]*=[\s]*$/,
       
  2514             // Commands for caching.
       
  2515             startTxt = 'var ___v1ew = [];',
       
  2516             finishTxt = "return ___v1ew.join('')",
       
  2517             put_cmd = "___v1ew.push(",
       
  2518             insert_cmd = put_cmd,
       
  2519             // Global controls (used by other functions to know where we are).
       
  2520             // Are we inside a tag?
       
  2521             htmlTag = null,
       
  2522             // Are we within a quote within a tag?
       
  2523             quote = null,
       
  2524             // What was the text before the current quote? (used to get the `attr` name)
       
  2525             beforeQuote = null,
       
  2526             // Whether a rescan is in progress
       
  2527             rescan = null,
       
  2528             // Used to mark where the element is.
       
  2529             status = function() {
       
  2530                 // `t` - `1`.
       
  2531                 // `h` - `0`.
       
  2532                 // `q` - String `beforeQuote`.
       
  2533                 return quote ? "'" + beforeQuote.match(attrReg)[1] + "'" : (htmlTag ? 1 : 0);
       
  2534             };
       
  2535 
       
  2536         can.view.Scanner = Scanner = function(options) {
       
  2537             // Set options on self
       
  2538             can.extend(this, {
       
  2539                     text: {},
       
  2540                     tokens: []
       
  2541                 }, options);
       
  2542 
       
  2543             // Cache a token lookup
       
  2544             this.tokenReg = [];
       
  2545             this.tokenSimple = {
       
  2546                 "<": "<",
       
  2547                 ">": ">",
       
  2548                 '"': '"',
       
  2549                 "'": "'"
       
  2550             };
       
  2551             this.tokenComplex = [];
       
  2552             this.tokenMap = {};
       
  2553             for (var i = 0, token; token = this.tokens[i]; i++) {
       
  2554 
       
  2555 
       
  2556                 // Save complex mappings (custom regexp)
       
  2557                 if (token[2]) {
       
  2558                     this.tokenReg.push(token[2]);
       
  2559                     this.tokenComplex.push({
       
  2560                             abbr: token[1],
       
  2561                             re: new RegExp(token[2]),
       
  2562                             rescan: token[3]
       
  2563                         });
       
  2564                 }
       
  2565                 // Save simple mappings (string only, no regexp)
       
  2566                 else {
       
  2567                     this.tokenReg.push(token[1]);
       
  2568                     this.tokenSimple[token[1]] = token[0];
       
  2569                 }
       
  2570                 this.tokenMap[token[0]] = token[1];
       
  2571             }
       
  2572 
       
  2573             // Cache the token registry.
       
  2574             this.tokenReg = new RegExp("(" + this.tokenReg.slice(0).concat(["<", ">", '"', "'"]).join("|") + ")", "g");
       
  2575         };
       
  2576 
       
  2577         Scanner.prototype = {
       
  2578 
       
  2579             helpers: [
       
  2580 
       
  2581                 {
       
  2582                     name: /\s*\(([\$\w]+)\)\s*->([^\n]*)/,
       
  2583                     fn: function(content) {
       
  2584                         var quickFunc = /\s*\(([\$\w]+)\)\s*->([^\n]*)/,
       
  2585                             parts = content.match(quickFunc);
       
  2586 
       
  2587                         return "can.proxy(function(__){var " + parts[1] + "=can.$(__);" + parts[2] + "}, this);";
       
  2588                     }
       
  2589                 }
       
  2590             ],
       
  2591 
       
  2592             scan: function(source, name) {
       
  2593                 var tokens = [],
       
  2594                     last = 0,
       
  2595                     simple = this.tokenSimple,
       
  2596                     complex = this.tokenComplex;
       
  2597 
       
  2598                 source = source.replace(newLine, "\n");
       
  2599                 if (this.transform) {
       
  2600                     source = this.transform(source);
       
  2601                 }
       
  2602                 source.replace(this.tokenReg, function(whole, part) {
       
  2603                     // offset is the second to last argument
       
  2604                     var offset = arguments[arguments.length - 2];
       
  2605 
       
  2606                     // if the next token starts after the last token ends
       
  2607                     // push what's in between
       
  2608                     if (offset > last) {
       
  2609                         tokens.push(source.substring(last, offset));
       
  2610                     }
       
  2611 
       
  2612                     // push the simple token (if there is one)
       
  2613                     if (simple[whole]) {
       
  2614                         tokens.push(whole);
       
  2615                     }
       
  2616                     // otherwise lookup complex tokens
       
  2617                     else {
       
  2618                         for (var i = 0, token; token = complex[i]; i++) {
       
  2619                             if (token.re.test(whole)) {
       
  2620                                 tokens.push(token.abbr);
       
  2621                                 // Push a rescan function if one exists
       
  2622                                 if (token.rescan) {
       
  2623                                     tokens.push(token.rescan(part));
       
  2624                                 }
       
  2625                                 break;
       
  2626                             }
       
  2627                         }
       
  2628                     }
       
  2629 
       
  2630                     // update the position of the last part of the last token
       
  2631                     last = offset + part.length;
       
  2632                 });
       
  2633 
       
  2634                 // if there's something at the end, add it
       
  2635                 if (last < source.length) {
       
  2636                     tokens.push(source.substr(last));
       
  2637                 }
       
  2638 
       
  2639                 var content = '',
       
  2640                     buff = [startTxt + (this.text.start || '')],
       
  2641                     // Helper `function` for putting stuff in the view concat.
       
  2642                     put = function(content, bonus) {
       
  2643                         buff.push(put_cmd, '"', clean(content), '"' + (bonus || '') + ');');
       
  2644                     },
       
  2645                     // A stack used to keep track of how we should end a bracket
       
  2646                     // `}`.  
       
  2647                     // Once we have a `<%= %>` with a `leftBracket`,
       
  2648                     // we store how the file should end here (either `))` or `;`).
       
  2649                     endStack = [],
       
  2650                     // The last token, used to remember which tag we are in.
       
  2651                     lastToken,
       
  2652                     // The corresponding magic tag.
       
  2653                     startTag = null,
       
  2654                     // Was there a magic tag inside an html tag?
       
  2655                     magicInTag = false,
       
  2656                     // The current tag name.
       
  2657                     tagName = '',
       
  2658                     // stack of tagNames
       
  2659                     tagNames = [],
       
  2660                     // Pop from tagNames?
       
  2661                     popTagName = false,
       
  2662                     // Declared here.
       
  2663                     bracketCount,
       
  2664                     i = 0,
       
  2665                     token,
       
  2666                     tmap = this.tokenMap;
       
  2667 
       
  2668                 // Reinitialize the tag state goodness.
       
  2669                 htmlTag = quote = beforeQuote = null;
       
  2670 
       
  2671                 for (;
       
  2672                     (token = tokens[i++]) !== undefined;) {
       
  2673                     if (startTag === null) {
       
  2674                         switch (token) {
       
  2675                             case tmap.left:
       
  2676                             case tmap.escapeLeft:
       
  2677                             case tmap.returnLeft:
       
  2678                                 magicInTag = htmlTag && 1;
       
  2679                             case tmap.commentLeft:
       
  2680                                 // A new line -- just add whatever content within a clean.  
       
  2681                                 // Reset everything.
       
  2682                                 startTag = token;
       
  2683                                 if (content.length) {
       
  2684                                     put(content);
       
  2685                                 }
       
  2686                                 content = '';
       
  2687                                 break;
       
  2688                             case tmap.escapeFull:
       
  2689                                 // This is a full line escape (a line that contains only whitespace and escaped logic)
       
  2690                                 // Break it up into escape left and right
       
  2691                                 magicInTag = htmlTag && 1;
       
  2692                                 rescan = 1;
       
  2693                                 startTag = tmap.escapeLeft;
       
  2694                                 if (content.length) {
       
  2695                                     put(content);
       
  2696                                 }
       
  2697                                 rescan = tokens[i++];
       
  2698                                 content = rescan.content || rescan;
       
  2699                                 if (rescan.before) {
       
  2700                                     put(rescan.before);
       
  2701                                 }
       
  2702                                 tokens.splice(i, 0, tmap.right);
       
  2703                                 break;
       
  2704                             case tmap.commentFull:
       
  2705                                 // Ignore full line comments.
       
  2706                                 break;
       
  2707                             case tmap.templateLeft:
       
  2708                                 content += tmap.left;
       
  2709                                 break;
       
  2710                             case '<':
       
  2711                                 // Make sure we are not in a comment.
       
  2712                                 if (tokens[i].indexOf("!--") !== 0) {
       
  2713                                     htmlTag = 1;
       
  2714                                     magicInTag = 0;
       
  2715                                 }
       
  2716                                 content += token;
       
  2717                                 break;
       
  2718                             case '>':
       
  2719                                 htmlTag = 0;
       
  2720                                 // content.substr(-1) doesn't work in IE7/8
       
  2721                                 var emptyElement = content.substr(content.length - 1) == "/" || content.substr(content.length - 2) == "--";
       
  2722                                 // if there was a magic tag
       
  2723                                 // or it's an element that has text content between its tags, 
       
  2724                                 // but content is not other tags add a hookup
       
  2725                                 // TODO: we should only add `can.EJS.pending()` if there's a magic tag 
       
  2726                                 // within the html tags.
       
  2727                                 if (magicInTag || !popTagName && elements.tagToContentPropMap[tagNames[tagNames.length - 1]]) {
       
  2728                                     // make sure / of /> is on the left of pending
       
  2729                                     if (emptyElement) {
       
  2730                                         put(content.substr(0, content.length - 1), ",can.view.pending(),\"/>\"");
       
  2731                                     } else {
       
  2732                                         put(content, ",can.view.pending(),\">\"");
       
  2733                                     }
       
  2734                                     content = '';
       
  2735                                     magicInTag = 0;
       
  2736                                 } else {
       
  2737                                     content += token;
       
  2738                                 }
       
  2739                                 // if it's a tag like <input/>
       
  2740                                 if (emptyElement || popTagName) {
       
  2741                                     // remove the current tag in the stack
       
  2742                                     tagNames.pop();
       
  2743                                     // set the current tag to the previous parent
       
  2744                                     tagName = tagNames[tagNames.length - 1];
       
  2745                                     // Don't pop next time
       
  2746                                     popTagName = false;
       
  2747                                 }
       
  2748                                 break;
       
  2749                             case "'":
       
  2750                             case '"':
       
  2751                                 // If we are in an html tag, finding matching quotes.
       
  2752                                 if (htmlTag) {
       
  2753                                     // We have a quote and it matches.
       
  2754                                     if (quote && quote === token) {
       
  2755                                         // We are exiting the quote.
       
  2756                                         quote = null;
       
  2757                                         // Otherwise we are creating a quote.
       
  2758                                         // TODO: does this handle `\`?
       
  2759                                     } else if (quote === null) {
       
  2760                                         quote = token;
       
  2761                                         beforeQuote = lastToken;
       
  2762                                     }
       
  2763                                 }
       
  2764                             default:
       
  2765                                 // Track the current tag
       
  2766                                 if (lastToken === '<') {
       
  2767                                     tagName = token.split(/\s/)[0];
       
  2768                                     if (tagName.indexOf("/") === 0 && tagNames[tagNames.length - 1] === tagName.substr(1)) {
       
  2769                                         // set tagName to the last tagName
       
  2770                                         // if there are no more tagNames, we'll rely on getTag.
       
  2771                                         tagName = tagNames[tagNames.length - 1];
       
  2772                                         popTagName = true;
       
  2773                                     } else {
       
  2774                                         tagNames.push(tagName);
       
  2775                                     }
       
  2776                                 }
       
  2777                                 content += token;
       
  2778                                 break;
       
  2779                         }
       
  2780                     } else {
       
  2781                         // We have a start tag.
       
  2782                         switch (token) {
       
  2783                             case tmap.right:
       
  2784                             case tmap.returnRight:
       
  2785                                 switch (startTag) {
       
  2786                                     case tmap.left:
       
  2787                                         // Get the number of `{ minus }`
       
  2788                                         bracketCount = bracketNum(content);
       
  2789 
       
  2790                                         // We are ending a block.
       
  2791                                         if (bracketCount == 1) {
       
  2792 
       
  2793                                             // We are starting on.
       
  2794                                             buff.push(insert_cmd, "can.view.txt(0,'" + getTag(tagName, tokens, i) + "'," + status() + ",this,function(){", startTxt, content);
       
  2795 
       
  2796                                             endStack.push({
       
  2797                                                     before: "",
       
  2798                                                     after: finishTxt + "}));\n"
       
  2799                                                 });
       
  2800                                         } else {
       
  2801 
       
  2802                                             // How are we ending this statement?
       
  2803                                             last = // If the stack has value and we are ending a block...
       
  2804                                             endStack.length && bracketCount == -1 ? // Use the last item in the block stack.
       
  2805                                             endStack.pop() : // Or use the default ending.
       
  2806                                             {
       
  2807                                                 after: ";"
       
  2808                                             };
       
  2809 
       
  2810                                             // If we are ending a returning block, 
       
  2811                                             // add the finish text which returns the result of the
       
  2812                                             // block.
       
  2813                                             if (last.before) {
       
  2814                                                 buff.push(last.before);
       
  2815                                             }
       
  2816                                             // Add the remaining content.
       
  2817                                             buff.push(content, ";", last.after);
       
  2818                                         }
       
  2819                                         break;
       
  2820                                     case tmap.escapeLeft:
       
  2821                                     case tmap.returnLeft:
       
  2822                                         // We have an extra `{` -> `block`.
       
  2823                                         // Get the number of `{ minus }`.
       
  2824                                         bracketCount = bracketNum(content);
       
  2825                                         // If we have more `{`, it means there is a block.
       
  2826                                         if (bracketCount) {
       
  2827                                             // When we return to the same # of `{` vs `}` end with a `doubleParent`.
       
  2828                                             endStack.push({
       
  2829                                                     before: finishTxt,
       
  2830                                                     after: "}));"
       
  2831                                                 });
       
  2832                                         }
       
  2833 
       
  2834                                         var escaped = startTag === tmap.escapeLeft ? 1 : 0,
       
  2835                                             commands = {
       
  2836                                                 insert: insert_cmd,
       
  2837                                                 tagName: getTag(tagName, tokens, i),
       
  2838                                                 status: status()
       
  2839                                             };
       
  2840 
       
  2841                                         for (var ii = 0; ii < this.helpers.length; ii++) {
       
  2842                                             // Match the helper based on helper
       
  2843                                             // regex name value
       
  2844                                             var helper = this.helpers[ii];
       
  2845                                             if (helper.name.test(content)) {
       
  2846                                                 content = helper.fn(content, commands);
       
  2847 
       
  2848                                                 // dont escape partials
       
  2849                                                 if (helper.name.source == /^>[\s]*\w*/.source) {
       
  2850                                                     escaped = 0;
       
  2851                                                 }
       
  2852                                                 break;
       
  2853                                             }
       
  2854                                         }
       
  2855 
       
  2856                                         // Handle special cases
       
  2857                                         if (typeof content == 'object') {
       
  2858                                             if (content.raw) {
       
  2859                                                 buff.push(content.raw);
       
  2860                                             }
       
  2861                                         } else {
       
  2862                                             // If we have `<%== a(function(){ %>` then we want
       
  2863                                             // `can.EJS.text(0,this, function(){ return a(function(){ var _v1ew = [];`.
       
  2864                                             buff.push(insert_cmd, "can.view.txt(" + escaped + ",'" + tagName + "'," + status() + ",this,function(){ " + (this.text.escape || '') + "return ", content,
       
  2865                                                 // If we have a block.
       
  2866                                                 bracketCount ?
       
  2867                                                 // Start with startTxt `"var _v1ew = [];"`.
       
  2868                                                 startTxt :
       
  2869                                                 // If not, add `doubleParent` to close push and text.
       
  2870                                                 "}));");
       
  2871                                         }
       
  2872 
       
  2873                                         if (rescan && rescan.after && rescan.after.length) {
       
  2874                                             put(rescan.after.length);
       
  2875                                             rescan = null;
       
  2876                                         }
       
  2877                                         break;
       
  2878                                 }
       
  2879                                 startTag = null;
       
  2880                                 content = '';
       
  2881                                 break;
       
  2882                             case tmap.templateLeft:
       
  2883                                 content += tmap.left;
       
  2884                                 break;
       
  2885                             default:
       
  2886                                 content += token;
       
  2887                                 break;
       
  2888                         }
       
  2889                     }
       
  2890                     lastToken = token;
       
  2891                 }
       
  2892 
       
  2893                 // Put it together...
       
  2894                 if (content.length) {
       
  2895                     // Should be `content.dump` in Ruby.
       
  2896                     put(content);
       
  2897                 }
       
  2898                 buff.push(";");
       
  2899 
       
  2900                 var template = buff.join(''),
       
  2901                     out = {
       
  2902                         out: 'with(_VIEW) { with (_CONTEXT) {' + template + " " + finishTxt + "}}"
       
  2903                     };
       
  2904                 // Use `eval` instead of creating a function, because it is easier to debug.
       
  2905                 myEval.call(out, 'this.fn = (function(_CONTEXT,_VIEW){' + out.out + '});\r\n//@ sourceURL=' + name + ".js");
       
  2906 
       
  2907                 return out;
       
  2908             }
       
  2909         };
       
  2910 
       
  2911         return Scanner;
       
  2912     })(__m11, __m14);
       
  2913 
       
  2914     // ## can/view/node_lists.js
       
  2915     var __m17 = (function(can) {
       
  2916 
       
  2917         // text node expando test
       
  2918         var canExpando = true;
       
  2919         try {
       
  2920             document.createTextNode('')._ = 0;
       
  2921         } catch (ex) {
       
  2922             canExpando = false;
       
  2923         }
       
  2924 
       
  2925         // a mapping of element ids to nodeList ids
       
  2926         var nodeMap = {},
       
  2927             // a mapping of ids to text nodes
       
  2928             textNodeMap = {},
       
  2929             // a mapping of nodeList ids to nodeList
       
  2930             nodeListMap = {},
       
  2931             expando = "ejs_" + Math.random(),
       
  2932             _id = 0,
       
  2933             id = function(node) {
       
  2934                 if (canExpando || node.nodeType !== 3) {
       
  2935                     if (node[expando]) {
       
  2936                         return node[expando];
       
  2937                     } else {
       
  2938                         return node[expando] = (node.nodeName ? "element_" : "obj_") + (++_id);
       
  2939                     }
       
  2940                 } else {
       
  2941                     for (var textNodeID in textNodeMap) {
       
  2942                         if (textNodeMap[textNodeID] === node) {
       
  2943                             return textNodeID;
       
  2944                         }
       
  2945                     }
       
  2946 
       
  2947                     textNodeMap["text_" + (++_id)] = node;
       
  2948                     return "text_" + _id;
       
  2949                 }
       
  2950             },
       
  2951             // removes a nodeListId from a node's nodeListIds
       
  2952             removeNodeListId = function(node, nodeListId) {
       
  2953                 var nodeListIds = nodeMap[id(node)];
       
  2954                 if (nodeListIds) {
       
  2955                     var index = can.inArray(nodeListId, nodeListIds);
       
  2956 
       
  2957                     if (index >= 0) {
       
  2958                         nodeListIds.splice(index, 1);
       
  2959                     }
       
  2960                     if (!nodeListIds.length) {
       
  2961                         delete nodeMap[id(node)];
       
  2962                     }
       
  2963                 }
       
  2964             },
       
  2965             addNodeListId = function(node, nodeListId) {
       
  2966                 var nodeListIds = nodeMap[id(node)];
       
  2967                 if (!nodeListIds) {
       
  2968                     nodeListIds = nodeMap[id(node)] = [];
       
  2969                 }
       
  2970                 nodeListIds.push(nodeListId);
       
  2971             };
       
  2972 
       
  2973         var nodeLists = {
       
  2974             id: id,
       
  2975             // replaces the contents of one node list with the nodes in another list
       
  2976             replace: function(oldNodeList, newNodes) {
       
  2977                 // for each node in the node list
       
  2978                 oldNodeList = can.makeArray(oldNodeList);
       
  2979 
       
  2980                 // try every set
       
  2981                 //can.each( oldNodeList, function(node){
       
  2982                 var node = oldNodeList[0]
       
  2983                 // for each nodeList the node is in
       
  2984                 can.each(can.makeArray(nodeMap[id(node)]), function(nodeListId) {
       
  2985 
       
  2986                     // if startNode to endNode is 
       
  2987                     // within list, replace that list
       
  2988                     // I think the problem is not the WHOLE part is being 
       
  2989                     // matched
       
  2990                     var nodeList = nodeListMap[nodeListId],
       
  2991                         startIndex = can.inArray(node, nodeList),
       
  2992                         endIndex = can.inArray(oldNodeList[oldNodeList.length - 1], nodeList);
       
  2993 
       
  2994 
       
  2995                     // remove this nodeListId from each node
       
  2996                     if (startIndex >= 0 && endIndex >= 0) {
       
  2997                         for (var i = startIndex; i <= endIndex; i++) {
       
  2998                             var n = nodeList[i];
       
  2999                             removeNodeListId(n, nodeListId);
       
  3000                         }
       
  3001                         // swap in new nodes into the nodeLIst
       
  3002                         nodeList.splice.apply(nodeList, [startIndex, endIndex - startIndex + 1].concat(newNodes));
       
  3003 
       
  3004                         // tell these new nodes they belong to the nodeList
       
  3005                         can.each(newNodes, function(node) {
       
  3006                             addNodeListId(node, nodeListId);
       
  3007                         });
       
  3008                     } else {
       
  3009                         nodeLists.unregister(nodeList);
       
  3010                     }
       
  3011                 });
       
  3012                 //});
       
  3013             },
       
  3014             // registers a list of nodes
       
  3015             register: function(nodeList) {
       
  3016                 var nLId = id(nodeList);
       
  3017                 nodeListMap[nLId] = nodeList;
       
  3018 
       
  3019                 can.each(nodeList, function(node) {
       
  3020                     addNodeListId(node, nLId);
       
  3021                 });
       
  3022 
       
  3023             },
       
  3024             // removes mappings
       
  3025             unregister: function(nodeList) {
       
  3026                 var nLId = id(nodeList);
       
  3027                 can.each(nodeList, function(node) {
       
  3028                     removeNodeListId(node, nLId);
       
  3029                 });
       
  3030                 delete nodeListMap[nLId];
       
  3031             },
       
  3032             nodeMap: nodeMap,
       
  3033             nodeListMap: nodeListMap
       
  3034         }
       
  3035         var ids = function(nodeList) {
       
  3036             return nodeList.map(function(n) {
       
  3037                 return id(n) + ":" + (n.innerHTML || n.nodeValue)
       
  3038             })
       
  3039         }
       
  3040         return nodeLists;
       
  3041 
       
  3042     })(__m3);
       
  3043 
       
  3044     // ## can/view/live.js
       
  3045     var __m16 = (function(can, elements, view, nodeLists) {
       
  3046         // ## live.js
       
  3047         // The live module provides live binding for computes
       
  3048         // and can.Observe.List.
       
  3049         // Currently, it's API is designed for `can/view/render`, but
       
  3050         // it could easily be used for other purposes.
       
  3051 
       
  3052         // ### Helper methods
       
  3053         // #### setup
       
  3054         // `setup(HTMLElement, bind(data), unbind(data)) -> data`
       
  3055         // Calls bind right away, but will call unbind
       
  3056         // if the element is "destroyed" (removed from the DOM).
       
  3057         var setup = function(el, bind, unbind) {
       
  3058             var teardown = function() {
       
  3059                 unbind(data)
       
  3060                 can.unbind.call(el, 'destroyed', teardown);
       
  3061             },
       
  3062                 data = {
       
  3063                     teardownCheck: function(parent) {
       
  3064                         if (!parent) {
       
  3065                             teardown();
       
  3066                         }
       
  3067                     }
       
  3068                 }
       
  3069 
       
  3070             can.bind.call(el, 'destroyed', teardown);
       
  3071             bind(data)
       
  3072             return data;
       
  3073         },
       
  3074             // #### listen
       
  3075             // Calls setup, but presets bind and unbind to 
       
  3076             // operate on a compute
       
  3077             listen = function(el, compute, change) {
       
  3078                 return setup(el, function() {
       
  3079                     compute.bind("change", change);
       
  3080                 }, function(data) {
       
  3081                     compute.unbind("change", change);
       
  3082                     if (data.nodeList) {
       
  3083                         nodeLists.unregister(data.nodeList);
       
  3084                     }
       
  3085                 });
       
  3086             },
       
  3087             // #### getAttributeParts
       
  3088             // Breaks up a string like foo='bar' into ["foo","'bar'""]
       
  3089             getAttributeParts = function(newVal) {
       
  3090                 return (newVal || "").replace(/['"]/g, '').split('=')
       
  3091             }
       
  3092             // #### insertElementsAfter
       
  3093             // Appends elements after the last item in oldElements.
       
  3094         insertElementsAfter = function(oldElements, newFrag) {
       
  3095             var last = oldElements[oldElements.length - 1];
       
  3096 
       
  3097             // Insert it in the `document` or `documentFragment`
       
  3098             if (last.nextSibling) {
       
  3099                 last.parentNode.insertBefore(newFrag, last.nextSibling);
       
  3100             } else {
       
  3101                 last.parentNode.appendChild(newFrag);
       
  3102             }
       
  3103         };
       
  3104 
       
  3105         var live = {
       
  3106             nodeLists: nodeLists,
       
  3107             list: function(el, list, func, context, parentNode) {
       
  3108                 // A mapping of the index to an array
       
  3109                 // of elements that represent the item.
       
  3110                 // Each array is registered so child or parent
       
  3111                 // live structures can update the elements
       
  3112                 var nodesMap = [],
       
  3113 
       
  3114                     add = function(ev, items, index) {
       
  3115 
       
  3116                         // Collect new html and mappings
       
  3117                         var frag = document.createDocumentFragment(),
       
  3118                             newMappings = [];
       
  3119                         can.each(items, function(item) {
       
  3120                             var itemHTML = func.call(context, item),
       
  3121                                 itemFrag = can.view.frag(itemHTML, parentNode);
       
  3122 
       
  3123                             newMappings.push(can.makeArray(itemFrag.childNodes));
       
  3124                             frag.appendChild(itemFrag);
       
  3125                         })
       
  3126 
       
  3127                         // Inserting at the end of the list
       
  3128                         if (!nodesMap[index]) {
       
  3129                             insertElementsAfter(
       
  3130                                 index == 0 ? [text] :
       
  3131                                 nodesMap[index - 1], frag)
       
  3132                         } else {
       
  3133                             var el = nodesMap[index][0];
       
  3134                             el.parentNode.insertBefore(frag, el)
       
  3135                         }
       
  3136                         // register each item
       
  3137                         can.each(newMappings, function(nodeList) {
       
  3138                             nodeLists.register(nodeList)
       
  3139                         });
       
  3140                         [].splice.apply(nodesMap, [index, 0].concat(newMappings));
       
  3141                     },
       
  3142                     remove = function(ev, items, index) {
       
  3143                         var removedMappings = nodesMap.splice(index, items.length),
       
  3144                             itemsToRemove = [];
       
  3145 
       
  3146                         can.each(removedMappings, function(nodeList) {
       
  3147                             // add items that we will remove all at once
       
  3148                             [].push.apply(itemsToRemove, nodeList)
       
  3149                             // Update any parent lists to remove these items
       
  3150                             nodeLists.replace(nodeList, []);
       
  3151                             // unregister the list
       
  3152                             nodeLists.unregister(nodeList);
       
  3153 
       
  3154                         });
       
  3155                         can.remove(can.$(itemsToRemove));
       
  3156                     },
       
  3157                     parentNode = elements.getParentNode(el, parentNode),
       
  3158                     text = document.createTextNode("");
       
  3159 
       
  3160                 // Setup binding and teardown to add and remove events
       
  3161                 setup(parentNode, function() {
       
  3162                     list.bind("add", add).bind("remove", remove)
       
  3163                 }, function() {
       
  3164                     list.unbind("add", add).unbind("remove", remove);
       
  3165                     can.each(nodesMap, function(nodeList) {
       
  3166                         nodeLists.unregister(nodeList);
       
  3167                     })
       
  3168                 })
       
  3169 
       
  3170                 insertElementsAfter([el], text);
       
  3171                 can.remove(can.$(el));
       
  3172                 add({}, list, 0);
       
  3173 
       
  3174             },
       
  3175             html: function(el, compute, parentNode) {
       
  3176                 var parentNode = elements.getParentNode(el, parentNode),
       
  3177 
       
  3178                     data = listen(parentNode, compute, function(ev, newVal, oldVal) {
       
  3179                         var attached = nodes[0].parentNode;
       
  3180                         // update the nodes in the DOM with the new rendered value
       
  3181                         if (attached) {
       
  3182                             makeAndPut(newVal);
       
  3183                         }
       
  3184                         data.teardownCheck(nodes[0].parentNode);
       
  3185                     });
       
  3186 
       
  3187                 var nodes,
       
  3188                     makeAndPut = function(val) {
       
  3189                         // create the fragment, but don't hook it up
       
  3190                         // we need to insert it into the document first
       
  3191                         var frag = can.view.frag(val, parentNode),
       
  3192                             // keep a reference to each node
       
  3193                             newNodes = can.makeArray(frag.childNodes);
       
  3194                         // Insert it in the `document` or `documentFragment`
       
  3195                         insertElementsAfter(nodes || [el], frag)
       
  3196                         // nodes hasn't been set yet
       
  3197                         if (!nodes) {
       
  3198                             can.remove(can.$(el));
       
  3199                             nodes = newNodes;
       
  3200                             // set the teardown nodeList
       
  3201                             data.nodeList = nodes;
       
  3202                             nodeLists.register(nodes);
       
  3203                         } else {
       
  3204                             // Update node Array's to point to new nodes
       
  3205                             // and then remove the old nodes.
       
  3206                             // It has to be in this order for Mootools
       
  3207                             // and IE because somehow, after an element
       
  3208                             // is removed from the DOM, it loses its
       
  3209                             // expando values.
       
  3210                             var nodesToRemove = can.makeArray(nodes);
       
  3211                             nodeLists.replace(nodes, newNodes);
       
  3212                             can.remove(can.$(nodesToRemove));
       
  3213                         }
       
  3214                     };
       
  3215                 makeAndPut(compute(), [el]);
       
  3216 
       
  3217             },
       
  3218             text: function(el, compute, parentNode) {
       
  3219                 var parent = elements.getParentNode(el, parentNode);
       
  3220 
       
  3221                 // setup listening right away so we don't have to re-calculate value
       
  3222                 var data = listen(el.parentNode !== parent ? el.parentNode : parent, compute, function(ev, newVal, oldVal) {
       
  3223                     // Sometimes this is 'unknown' in IE and will throw an exception if it is
       
  3224                     if (typeof node.nodeValue != 'unknown') {
       
  3225                         node.nodeValue = "" + newVal;
       
  3226                     }
       
  3227                     data.teardownCheck(node.parentNode);
       
  3228                 });
       
  3229 
       
  3230                 var node = document.createTextNode(compute());
       
  3231 
       
  3232                 if (el.parentNode !== parent) {
       
  3233                     parent = el.parentNode;
       
  3234                     parent.insertBefore(node, el);
       
  3235                     parent.removeChild(el);
       
  3236                 } else {
       
  3237                     parent.insertBefore(node, el);
       
  3238                     parent.removeChild(el);
       
  3239                 }
       
  3240             },
       
  3241             attributes: function(el, compute, currentValue) {
       
  3242                 var setAttrs = function(newVal) {
       
  3243                     var parts = getAttributeParts(newVal),
       
  3244                         newAttrName = parts.shift();
       
  3245 
       
  3246                     // Remove if we have a change and used to have an `attrName`.
       
  3247                     if ((newAttrName != attrName) && attrName) {
       
  3248                         elements.removeAttr(el, attrName);
       
  3249                     }
       
  3250                     // Set if we have a new `attrName`.
       
  3251                     if (newAttrName) {
       
  3252                         elements.setAttr(el, newAttrName, parts.join('='));
       
  3253                         attrName = newAttrName;
       
  3254                     }
       
  3255                 }
       
  3256 
       
  3257                 listen(el, compute, function(ev, newVal) {
       
  3258                     setAttrs(newVal)
       
  3259                 })
       
  3260                 // current value has been set
       
  3261                 if (arguments.length >= 3) {
       
  3262                     var attrName = getAttributeParts(currentValue)[0]
       
  3263                 } else {
       
  3264                     setAttrs(compute())
       
  3265                 }
       
  3266             },
       
  3267             attributePlaceholder: '__!!__',
       
  3268             attributeReplace: /__!!__/g,
       
  3269             attribute: function(el, attributeName, compute) {
       
  3270                 listen(el, compute, function(ev, newVal) {
       
  3271                     elements.setAttr(el, attributeName, hook.render());
       
  3272                 })
       
  3273 
       
  3274                 var wrapped = can.$(el),
       
  3275                     hooks;
       
  3276 
       
  3277                 // Get the list of hookups or create one for this element.
       
  3278                 // Hooks is a map of attribute names to hookup `data`s.
       
  3279                 // Each hookup data has:
       
  3280                 // `render` - A `function` to render the value of the attribute.
       
  3281                 // `funcs` - A list of hookup `function`s on that attribute.
       
  3282                 // `batchNum` - The last event `batchNum`, used for performance.
       
  3283                 hooks = can.data(wrapped, 'hooks');
       
  3284                 if (!hooks) {
       
  3285                     can.data(wrapped, 'hooks', hooks = {});
       
  3286                 }
       
  3287 
       
  3288                 // Get the attribute value.
       
  3289                 var attr = elements.getAttr(el, attributeName),
       
  3290                     // Split the attribute value by the template.
       
  3291                     // Only split out the first __!!__ so if we have multiple hookups in the same attribute, 
       
  3292                     // they will be put in the right spot on first render
       
  3293                     parts = attr.split(live.attributePlaceholder),
       
  3294                     goodParts = [],
       
  3295                     hook;
       
  3296                 goodParts.push(parts.shift(),
       
  3297                     parts.join(live.attributePlaceholder));
       
  3298 
       
  3299                 // If we already had a hookup for this attribute...
       
  3300                 if (hooks[attributeName]) {
       
  3301                     // Just add to that attribute's list of `function`s.
       
  3302                     hooks[attributeName].computes.push(compute);
       
  3303                 } else {
       
  3304                     // Create the hookup data.
       
  3305                     hooks[attributeName] = {
       
  3306                         render: function() {
       
  3307                             var i = 0,
       
  3308                                 // attr doesn't have a value in IE
       
  3309                                 newAttr = attr ? attr.replace(live.attributeReplace, function() {
       
  3310                                     return elements.contentText(hook.computes[i++]());
       
  3311                                 }) : elements.contentText(hook.computes[i++]());
       
  3312                             return newAttr;
       
  3313                         },
       
  3314                         computes: [compute],
       
  3315                         batchNum: undefined
       
  3316                     };
       
  3317                 }
       
  3318 
       
  3319                 // Save the hook for slightly faster performance.
       
  3320                 hook = hooks[attributeName];
       
  3321 
       
  3322                 // Insert the value in parts.
       
  3323                 goodParts.splice(1, 0, compute());
       
  3324 
       
  3325                 // Set the attribute.
       
  3326                 elements.setAttr(el, attributeName, goodParts.join(""));
       
  3327 
       
  3328             }
       
  3329         }
       
  3330         return live;
       
  3331 
       
  3332     })(__m3, __m14, __m11, __m17);
       
  3333 
       
  3334     // ## can/view/render.js
       
  3335     var __m15 = (function(can, elements, live) {
       
  3336 
       
  3337         var pendingHookups = [],
       
  3338             tagChildren = function(tagName) {
       
  3339                 var newTag = elements.tagMap[tagName] || "span";
       
  3340                 if (newTag === "span") {
       
  3341                     //innerHTML in IE doesn't honor leading whitespace after empty elements
       
  3342                     return "@@!!@@";
       
  3343                 }
       
  3344                 return "<" + newTag + ">" + tagChildren(newTag) + "</" + newTag + ">";
       
  3345             },
       
  3346             contentText = function(input, tag) {
       
  3347 
       
  3348                 // If it's a string, return.
       
  3349                 if (typeof input == 'string') {
       
  3350                     return input;
       
  3351                 }
       
  3352                 // If has no value, return an empty string.
       
  3353                 if (!input && input !== 0) {
       
  3354                     return '';
       
  3355                 }
       
  3356 
       
  3357                 // If it's an object, and it has a hookup method.
       
  3358                 var hook = (input.hookup &&
       
  3359 
       
  3360                     // Make a function call the hookup method.
       
  3361 
       
  3362                     function(el, id) {
       
  3363                         input.hookup.call(input, el, id);
       
  3364                     }) ||
       
  3365 
       
  3366                 // Or if it's a `function`, just use the input.
       
  3367                 (typeof input == 'function' && input);
       
  3368 
       
  3369                 // Finally, if there is a `function` to hookup on some dom,
       
  3370                 // add it to pending hookups.
       
  3371                 if (hook) {
       
  3372                     if (tag) {
       
  3373                         return "<" + tag + " " + can.view.hook(hook) + "></" + tag + ">"
       
  3374                     } else {
       
  3375                         pendingHookups.push(hook);
       
  3376                     }
       
  3377 
       
  3378                     return '';
       
  3379                 }
       
  3380 
       
  3381                 // Finally, if all else is `false`, `toString()` it.
       
  3382                 return "" + input;
       
  3383             },
       
  3384             // Returns escaped/sanatized content for anything other than a live-binding
       
  3385             contentEscape = function(txt) {
       
  3386                 return (typeof txt == 'string' || typeof txt == 'number') ?
       
  3387                     can.esc(txt) :
       
  3388                     contentText(txt);
       
  3389             };
       
  3390 
       
  3391         var current;
       
  3392 
       
  3393         can.extend(can.view, {
       
  3394                 live: live,
       
  3395                 setupLists: function() {
       
  3396 
       
  3397                     var old = can.view.lists,
       
  3398                         data;
       
  3399 
       
  3400                     can.view.lists = function(list, renderer) {
       
  3401                         data = {
       
  3402                             list: list,
       
  3403                             renderer: renderer
       
  3404                         }
       
  3405                     }
       
  3406                     return function() {
       
  3407                         can.view.lists = old;
       
  3408                         return data;
       
  3409                     }
       
  3410                 },
       
  3411                 pending: function() {
       
  3412                     // TODO, make this only run for the right tagName
       
  3413                     var hooks = pendingHookups.slice(0);
       
  3414                     lastHookups = hooks;
       
  3415                     pendingHookups = [];
       
  3416                     return can.view.hook(function(el) {
       
  3417                         can.each(hooks, function(fn) {
       
  3418                             fn(el);
       
  3419                         });
       
  3420                     });
       
  3421                 },
       
  3422 
       
  3423 
       
  3424                 txt: function(escape, tagName, status, self, func) {
       
  3425                     var listTeardown = can.view.setupLists(),
       
  3426                         emptyHandler = function() {},
       
  3427                         unbind = function() {
       
  3428                             compute.unbind("change", emptyHandler)
       
  3429                         };
       
  3430 
       
  3431                     var compute = can.compute(func, self, false);
       
  3432                     // bind to get and temporarily cache the value
       
  3433                     compute.bind("change", emptyHandler);
       
  3434                     // call the "wrapping" function and get the binding information
       
  3435                     var tag = (elements.tagMap[tagName] || "span"),
       
  3436                         listData = listTeardown(),
       
  3437                         value = compute();
       
  3438 
       
  3439 
       
  3440                     if (listData) {
       
  3441                         return "<" + tag + can.view.hook(function(el, parentNode) {
       
  3442                             live.list(el, listData.list, listData.renderer, self, parentNode);
       
  3443                         }) + "></" + tag + ">";
       
  3444                     }
       
  3445 
       
  3446                     // If we had no observes just return the value returned by func.
       
  3447                     if (!compute.hasDependencies) {
       
  3448                         unbind();
       
  3449                         return (escape || status !== 0 ? contentEscape : contentText)(value, status === 0 && tag);
       
  3450                     }
       
  3451 
       
  3452                     // the property (instead of innerHTML elements) to adjust. For
       
  3453                     // example options should use textContent
       
  3454                     var contentProp = elements.tagToContentPropMap[tagName];
       
  3455 
       
  3456 
       
  3457                     // The magic tag is outside or between tags.
       
  3458                     if (status === 0 && !contentProp) {
       
  3459                         // Return an element tag with a hookup in place of the content
       
  3460                         return "<" + tag + can.view.hook(
       
  3461                             escape ?
       
  3462                             // If we are escaping, replace the parentNode with 
       
  3463                             // a text node who's value is `func`'s return value.
       
  3464 
       
  3465                             function(el, parentNode) {
       
  3466                                 live.text(el, compute, parentNode);
       
  3467                                 unbind();
       
  3468                             } :
       
  3469                             // If we are not escaping, replace the parentNode with a
       
  3470                             // documentFragment created as with `func`'s return value.
       
  3471 
       
  3472                             function(el, parentNode) {
       
  3473                                 live.html(el, compute, parentNode);
       
  3474                                 unbind();
       
  3475                                 //children have to be properly nested HTML for buildFragment to work properly
       
  3476                             }) + ">" + tagChildren(tag) + "</" + tag + ">";
       
  3477                         // In a tag, but not in an attribute
       
  3478                     } else if (status === 1) {
       
  3479                         // remember the old attr name
       
  3480                         pendingHookups.push(function(el) {
       
  3481                             live.attributes(el, compute, compute());
       
  3482                             unbind();
       
  3483                         });
       
  3484                         return compute();
       
  3485                     } else { // In an attribute...
       
  3486                         var attributeName = status === 0 ? contentProp : status;
       
  3487                         // if the magic tag is inside the element, like `<option><% TAG %></option>`,
       
  3488                         // we add this hookup to the last element (ex: `option`'s) hookups.
       
  3489                         // Otherwise, the magic tag is in an attribute, just add to the current element's
       
  3490                         // hookups.
       
  3491                         (status === 0 ? lastHookups : pendingHookups).push(function(el) {
       
  3492                             live.attribute(el, attributeName, compute);
       
  3493                             unbind();
       
  3494                         });
       
  3495                         return live.attributePlaceholder;
       
  3496                     }
       
  3497                 }
       
  3498             });
       
  3499 
       
  3500         return can;
       
  3501     })(__m11, __m14, __m16, __m2);
       
  3502 
       
  3503     // ## can/view/ejs/ejs.js
       
  3504     var __m12 = (function(can) {
       
  3505         // ## ejs.js
       
  3506         // `can.EJS`  
       
  3507         // _Embedded JavaScript Templates._
       
  3508 
       
  3509         // Helper methods.
       
  3510         var extend = can.extend,
       
  3511             EJS = function(options) {
       
  3512                 // Supports calling EJS without the constructor
       
  3513                 // This returns a function that renders the template.
       
  3514                 if (this.constructor != EJS) {
       
  3515                     var ejs = new EJS(options);
       
  3516                     return function(data, helpers) {
       
  3517                         return ejs.render(data, helpers);
       
  3518                     };
       
  3519                 }
       
  3520                 // If we get a `function` directly, it probably is coming from
       
  3521                 // a `steal`-packaged view.
       
  3522                 if (typeof options == "function") {
       
  3523                     this.template = {
       
  3524                         fn: options
       
  3525                     };
       
  3526                     return;
       
  3527                 }
       
  3528                 // Set options on self.
       
  3529                 extend(this, options);
       
  3530                 this.template = this.scanner.scan(this.text, this.name);
       
  3531             };
       
  3532 
       
  3533         can.EJS = EJS;
       
  3534 
       
  3535 
       
  3536         EJS.prototype.
       
  3537 
       
  3538         render = function(object, extraHelpers) {
       
  3539             object = object || {};
       
  3540             return this.template.fn.call(object, object, new EJS.Helpers(object, extraHelpers || {}));
       
  3541         };
       
  3542 
       
  3543         extend(EJS.prototype, {
       
  3544 
       
  3545                 scanner: new can.view.Scanner({
       
  3546 
       
  3547                         tokens: [
       
  3548                             ["templateLeft", "<%%"], // Template
       
  3549                             ["templateRight", "%>"], // Right Template
       
  3550                             ["returnLeft", "<%=="], // Return Unescaped
       
  3551                             ["escapeLeft", "<%="], // Return Escaped
       
  3552                             ["commentLeft", "<%#"], // Comment
       
  3553                             ["left", "<%"], // Run --- this is hack for now
       
  3554                             ["right", "%>"], // Right -> All have same FOR Mustache ...
       
  3555                             ["returnRight", "%>"]
       
  3556                         ],
       
  3557 
       
  3558 
       
  3559                         transform: function(source) {
       
  3560                             return source.replace(/<%([\s\S]+?)%>/gm, function(whole, part) {
       
  3561                                 var brackets = [],
       
  3562                                     foundBracketPair,
       
  3563                                     i;
       
  3564 
       
  3565                                 // Look for brackets (for removing self-contained blocks)
       
  3566                                 part.replace(/[{}]/gm, function(bracket, offset) {
       
  3567                                     brackets.push([bracket, offset]);
       
  3568                                 });
       
  3569 
       
  3570                                 // Remove bracket pairs from the list of replacements
       
  3571                                 do {
       
  3572                                     foundBracketPair = false;
       
  3573                                     for (i = brackets.length - 2; i >= 0; i--) {
       
  3574                                         if (brackets[i][0] == '{' && brackets[i + 1][0] == '}') {
       
  3575                                             brackets.splice(i, 2);
       
  3576                                             foundBracketPair = true;
       
  3577                                             break;
       
  3578                                         }
       
  3579                                     }
       
  3580                                 } while (foundBracketPair);
       
  3581 
       
  3582                                 // Unmatched brackets found, inject EJS tags
       
  3583                                 if (brackets.length >= 2) {
       
  3584                                     var result = ['<%'],
       
  3585                                         bracket,
       
  3586                                         last = 0;
       
  3587                                     for (i = 0; bracket = brackets[i]; i++) {
       
  3588                                         result.push(part.substring(last, last = bracket[1]));
       
  3589                                         if ((bracket[0] == '{' && i < brackets.length - 1) || (bracket[0] == '}' && i > 0)) {
       
  3590                                             result.push(bracket[0] == '{' ? '{ %><% ' : ' %><% }');
       
  3591                                         } else {
       
  3592                                             result.push(bracket[0]);
       
  3593                                         }
       
  3594                                         ++last;
       
  3595                                     }
       
  3596                                     result.push(part.substring(last), '%>');
       
  3597                                     return result.join('');
       
  3598                                 }
       
  3599                                 // Otherwise return the original
       
  3600                                 else {
       
  3601                                     return '<%' + part + '%>';
       
  3602                                 }
       
  3603                             });
       
  3604                         }
       
  3605                     })
       
  3606             });
       
  3607 
       
  3608         EJS.Helpers = function(data, extras) {
       
  3609             this._data = data;
       
  3610             this._extras = extras;
       
  3611             extend(this, extras);
       
  3612         };
       
  3613 
       
  3614 
       
  3615         EJS.Helpers.prototype = {
       
  3616             // TODO Deprecated!!
       
  3617             list: function(list, cb) {
       
  3618 
       
  3619                 can.each(list, function(item, i) {
       
  3620                     cb(item, i, list)
       
  3621                 })
       
  3622             },
       
  3623             each: function(list, cb) {
       
  3624                 // Normal arrays don't get live updated
       
  3625                 if (can.isArray(list)) {
       
  3626                     this.list(list, cb);
       
  3627                 } else {
       
  3628                     can.view.lists(list, cb);
       
  3629                 }
       
  3630             }
       
  3631         };
       
  3632 
       
  3633         // Options for `steal`'s build.
       
  3634         can.view.register({
       
  3635                 suffix: "ejs",
       
  3636                 // returns a `function` that renders the view.
       
  3637                 script: function(id, src) {
       
  3638                     return "can.EJS(function(_CONTEXT,_VIEW) { " + new EJS({
       
  3639                             text: src,
       
  3640                             name: id
       
  3641                         }).template.out + " })";
       
  3642                 },
       
  3643                 renderer: function(id, text) {
       
  3644                     return EJS({
       
  3645                             text: text,
       
  3646                             name: id
       
  3647                         });
       
  3648                 }
       
  3649             });
       
  3650 
       
  3651         return can;
       
  3652     })(__m3, __m11, __m2, __m9, __m13, __m15);
       
  3653 
       
  3654     // ## can/control/control.js
       
  3655     var __m18 = (function(can) {
       
  3656         // ## control.js
       
  3657         // `can.Control`  
       
  3658         // _Controller_
       
  3659 
       
  3660         // Binds an element, returns a function that unbinds.
       
  3661         var bind = function(el, ev, callback) {
       
  3662 
       
  3663             can.bind.call(el, ev, callback);
       
  3664 
       
  3665             return function() {
       
  3666                 can.unbind.call(el, ev, callback);
       
  3667             };
       
  3668         },
       
  3669             isFunction = can.isFunction,
       
  3670             extend = can.extend,
       
  3671             each = can.each,
       
  3672             slice = [].slice,
       
  3673             paramReplacer = /\{([^\}]+)\}/g,
       
  3674             special = can.getObject("$.event.special", [can]) || {},
       
  3675 
       
  3676             // Binds an element, returns a function that unbinds.
       
  3677             delegate = function(el, selector, ev, callback) {
       
  3678                 can.delegate.call(el, selector, ev, callback);
       
  3679                 return function() {
       
  3680                     can.undelegate.call(el, selector, ev, callback);
       
  3681                 };
       
  3682             },
       
  3683 
       
  3684             // Calls bind or unbind depending if there is a selector.
       
  3685             binder = function(el, ev, callback, selector) {
       
  3686                 return selector ?
       
  3687                     delegate(el, can.trim(selector), ev, callback) :
       
  3688                     bind(el, ev, callback);
       
  3689             },
       
  3690 
       
  3691             basicProcessor;
       
  3692 
       
  3693         var Control = can.Control = can.Construct(
       
  3694 
       
  3695             {
       
  3696                 // Setup pre-processes which methods are event listeners.
       
  3697 
       
  3698                 setup: function() {
       
  3699 
       
  3700                     // Allow contollers to inherit "defaults" from super-classes as it 
       
  3701                     // done in `can.Construct`
       
  3702                     can.Construct.setup.apply(this, arguments);
       
  3703 
       
  3704                     // If you didn't provide a name, or are `control`, don't do anything.
       
  3705                     if (can.Control) {
       
  3706 
       
  3707                         // Cache the underscored names.
       
  3708                         var control = this,
       
  3709                             funcName;
       
  3710 
       
  3711                         // Calculate and cache actions.
       
  3712                         control.actions = {};
       
  3713                         for (funcName in control.prototype) {
       
  3714                             if (control._isAction(funcName)) {
       
  3715                                 control.actions[funcName] = control._action(funcName);
       
  3716                             }
       
  3717                         }
       
  3718                     }
       
  3719                 },
       
  3720 
       
  3721                 // Moves `this` to the first argument, wraps it with `jQuery` if it's an element
       
  3722                 _shifter: function(context, name) {
       
  3723 
       
  3724                     var method = typeof name == "string" ? context[name] : name;
       
  3725 
       
  3726                     if (!isFunction(method)) {
       
  3727                         method = context[method];
       
  3728                     }
       
  3729 
       
  3730                     return function() {
       
  3731                         context.called = name;
       
  3732                         return method.apply(context, [this.nodeName ? can.$(this) : this].concat(slice.call(arguments, 0)));
       
  3733                     };
       
  3734                 },
       
  3735 
       
  3736                 // Return `true` if is an action.
       
  3737 
       
  3738                 _isAction: function(methodName) {
       
  3739 
       
  3740                     var val = this.prototype[methodName],
       
  3741                         type = typeof val;
       
  3742                     // if not the constructor
       
  3743                     return (methodName !== 'constructor') &&
       
  3744                     // and is a function or links to a function
       
  3745                     (type == "function" || (type == "string" && isFunction(this.prototype[val]))) &&
       
  3746                     // and is in special, a processor, or has a funny character
       
  3747                     !! (special[methodName] || processors[methodName] || /[^\w]/.test(methodName));
       
  3748                 },
       
  3749                 // Takes a method name and the options passed to a control
       
  3750                 // and tries to return the data necessary to pass to a processor
       
  3751                 // (something that binds things).
       
  3752 
       
  3753                 _action: function(methodName, options) {
       
  3754 
       
  3755                     // If we don't have options (a `control` instance), we'll run this 
       
  3756                     // later.  
       
  3757                     paramReplacer.lastIndex = 0;
       
  3758                     if (options || !paramReplacer.test(methodName)) {
       
  3759                         // If we have options, run sub to replace templates `{}` with a
       
  3760                         // value from the options or the window
       
  3761                         var convertedName = options ? can.sub(methodName, [options, window]) : methodName;
       
  3762                         if (!convertedName) {
       
  3763                             return null;
       
  3764                         }
       
  3765                         // If a `{}` template resolves to an object, `convertedName` will be
       
  3766                         // an array
       
  3767                         var arr = can.isArray(convertedName),
       
  3768 
       
  3769                             // Get the name
       
  3770                             name = arr ? convertedName[1] : convertedName,
       
  3771 
       
  3772                             // Grab the event off the end
       
  3773                             parts = name.split(/\s+/g),
       
  3774                             event = parts.pop();
       
  3775 
       
  3776                         return {
       
  3777                             processor: processors[event] || basicProcessor,
       
  3778                             parts: [name, parts.join(" "), event],
       
  3779                             delegate: arr ? convertedName[0] : undefined
       
  3780                         };
       
  3781                     }
       
  3782                 },
       
  3783                 // An object of `{eventName : function}` pairs that Control uses to 
       
  3784                 // hook up events auto-magically.
       
  3785 
       
  3786                 processors: {},
       
  3787                 // A object of name-value pairs that act as default values for a 
       
  3788                 // control instance
       
  3789                 defaults: {}
       
  3790 
       
  3791             }, {
       
  3792 
       
  3793                 // Sets `this.element`, saves the control in `data, binds event
       
  3794                 // handlers.
       
  3795 
       
  3796                 setup: function(element, options) {
       
  3797 
       
  3798                     var cls = this.constructor,
       
  3799                         pluginname = cls.pluginName || cls._fullName,
       
  3800                         arr;
       
  3801 
       
  3802                     // Want the raw element here.
       
  3803                     this.element = can.$(element)
       
  3804 
       
  3805                     if (pluginname && pluginname !== 'can_control') {
       
  3806                         // Set element and `className` on element.
       
  3807                         this.element.addClass(pluginname);
       
  3808                     }
       
  3809 
       
  3810                     (arr = can.data(this.element, "controls")) || can.data(this.element, "controls", arr = []);
       
  3811                     arr.push(this);
       
  3812 
       
  3813                     // Option merging.
       
  3814 
       
  3815                     this.options = extend({}, cls.defaults, options);
       
  3816 
       
  3817                     // Bind all event handlers.
       
  3818                     this.on();
       
  3819 
       
  3820                     // Gets passed into `init`.
       
  3821 
       
  3822                     return [this.element, this.options];
       
  3823                 },
       
  3824 
       
  3825                 on: function(el, selector, eventName, func) {
       
  3826                     if (!el) {
       
  3827 
       
  3828                         // Adds bindings.
       
  3829                         this.off();
       
  3830 
       
  3831                         // Go through the cached list of actions and use the processor 
       
  3832                         // to bind
       
  3833                         var cls = this.constructor,
       
  3834                             bindings = this._bindings,
       
  3835                             actions = cls.actions,
       
  3836                             element = this.element,
       
  3837                             destroyCB = can.Control._shifter(this, "destroy"),
       
  3838                             funcName, ready;
       
  3839 
       
  3840                         for (funcName in actions) {
       
  3841                             // Only push if we have the action and no option is `undefined`
       
  3842                             if (actions.hasOwnProperty(funcName) &&
       
  3843                                 (ready = actions[funcName] || cls._action(funcName, this.options))) {
       
  3844                                 bindings.push(ready.processor(ready.delegate || element,
       
  3845                                         ready.parts[2], ready.parts[1], funcName, this));
       
  3846                             }
       
  3847                         }
       
  3848 
       
  3849 
       
  3850                         // Setup to be destroyed...  
       
  3851                         // don't bind because we don't want to remove it.
       
  3852                         can.bind.call(element, "destroyed", destroyCB);
       
  3853                         bindings.push(function(el) {
       
  3854                             can.unbind.call(el, "destroyed", destroyCB);
       
  3855                         });
       
  3856                         return bindings.length;
       
  3857                     }
       
  3858 
       
  3859                     if (typeof el == 'string') {
       
  3860                         func = eventName;
       
  3861                         eventName = selector;
       
  3862                         selector = el;
       
  3863                         el = this.element;
       
  3864                     }
       
  3865 
       
  3866                     if (func === undefined) {
       
  3867                         func = eventName;
       
  3868                         eventName = selector;
       
  3869                         selector = null;
       
  3870                     }
       
  3871 
       
  3872                     if (typeof func == 'string') {
       
  3873                         func = can.Control._shifter(this, func);
       
  3874                     }
       
  3875 
       
  3876                     this._bindings.push(binder(el, eventName, func, selector));
       
  3877 
       
  3878                     return this._bindings.length;
       
  3879                 },
       
  3880                 // Unbinds all event handlers on the controller.
       
  3881 
       
  3882                 off: function() {
       
  3883                     var el = this.element[0]
       
  3884                     each(this._bindings || [], function(value) {
       
  3885                         value(el);
       
  3886                     });
       
  3887                     // Adds bindings.
       
  3888                     this._bindings = [];
       
  3889                 },
       
  3890                 // Prepares a `control` for garbage collection
       
  3891 
       
  3892                 destroy: function() {
       
  3893                     //Control already destroyed
       
  3894                     if (this.element === null) {
       
  3895 
       
  3896                         return;
       
  3897                     }
       
  3898                     var Class = this.constructor,
       
  3899                         pluginName = Class.pluginName || Class._fullName,
       
  3900                         controls;
       
  3901 
       
  3902                     // Unbind bindings.
       
  3903                     this.off();
       
  3904 
       
  3905                     if (pluginName && pluginName !== 'can_control') {
       
  3906                         // Remove the `className`.
       
  3907                         this.element.removeClass(pluginName);
       
  3908                     }
       
  3909 
       
  3910                     // Remove from `data`.
       
  3911                     controls = can.data(this.element, "controls");
       
  3912                     controls.splice(can.inArray(this, controls), 1);
       
  3913 
       
  3914                     can.trigger(this, "destroyed"); // In case we want to know if the `control` is removed.
       
  3915 
       
  3916                     this.element = null;
       
  3917                 }
       
  3918             });
       
  3919 
       
  3920         var processors = can.Control.processors,
       
  3921             // Processors do the binding.
       
  3922             // They return a function that unbinds when called.  
       
  3923             // The basic processor that binds events.
       
  3924             basicProcessor = function(el, event, selector, methodName, control) {
       
  3925                 return binder(el, event, can.Control._shifter(control, methodName), selector);
       
  3926             };
       
  3927 
       
  3928         // Set common events to be processed as a `basicProcessor`
       
  3929         each(["change", "click", "contextmenu", "dblclick", "keydown", "keyup",
       
  3930                 "keypress", "mousedown", "mousemove", "mouseout", "mouseover",
       
  3931                 "mouseup", "reset", "resize", "scroll", "select", "submit", "focusin",
       
  3932                 "focusout", "mouseenter", "mouseleave",
       
  3933                 // #104 - Add touch events as default processors
       
  3934                 // TOOD feature detect?
       
  3935                 "touchstart", "touchmove", "touchcancel", "touchend", "touchleave"
       
  3936             ], function(v) {
       
  3937                 processors[v] = basicProcessor;
       
  3938             });
       
  3939 
       
  3940         return Control;
       
  3941     })(__m3, __m1);
       
  3942 
       
  3943     // ## can/util/string/deparam/deparam.js
       
  3944     var __m20 = (function(can) {
       
  3945 
       
  3946         // ## deparam.js  
       
  3947         // `can.deparam`  
       
  3948         // _Takes a string of name value pairs and returns a Object literal that represents those params._
       
  3949         var digitTest = /^\d+$/,
       
  3950             keyBreaker = /([^\[\]]+)|(\[\])/g,
       
  3951             paramTest = /([^?#]*)(#.*)?$/,
       
  3952             prep = function(str) {
       
  3953                 return decodeURIComponent(str.replace(/\+/g, " "));
       
  3954             };
       
  3955 
       
  3956 
       
  3957         can.extend(can, {
       
  3958 
       
  3959                 deparam: function(params) {
       
  3960 
       
  3961                     var data = {},
       
  3962                         pairs, lastPart;
       
  3963 
       
  3964                     if (params && paramTest.test(params)) {
       
  3965 
       
  3966                         pairs = params.split('&'),
       
  3967 
       
  3968                         can.each(pairs, function(pair) {
       
  3969 
       
  3970                             var parts = pair.split('='),
       
  3971                                 key = prep(parts.shift()),
       
  3972                                 value = prep(parts.join("=")),
       
  3973                                 current = data;
       
  3974 
       
  3975                             if (key) {
       
  3976                                 parts = key.match(keyBreaker);
       
  3977 
       
  3978                                 for (var j = 0, l = parts.length - 1; j < l; j++) {
       
  3979                                     if (!current[parts[j]]) {
       
  3980                                         // If what we are pointing to looks like an `array`
       
  3981                                         current[parts[j]] = digitTest.test(parts[j + 1]) || parts[j + 1] == "[]" ? [] : {};
       
  3982                                     }
       
  3983                                     current = current[parts[j]];
       
  3984                                 }
       
  3985                                 lastPart = parts.pop();
       
  3986                                 if (lastPart == "[]") {
       
  3987                                     current.push(value);
       
  3988                                 } else {
       
  3989                                     current[lastPart] = value;
       
  3990                                 }
       
  3991                             }
       
  3992                         });
       
  3993                     }
       
  3994                     return data;
       
  3995                 }
       
  3996             });
       
  3997         return can;
       
  3998     })(__m3, __m2);
       
  3999 
       
  4000     // ## can/route/route.js
       
  4001     var __m19 = (function(can) {
       
  4002 
       
  4003         // ## route.js  
       
  4004         // `can.route`  
       
  4005         // _Helps manage browser history (and client state) by synchronizing the 
       
  4006         // `window.location.hash` with a `can.Observe`._  
       
  4007         // Helper methods used for matching routes.
       
  4008         var
       
  4009         // `RegExp` used to match route variables of the type ':name'.
       
  4010         // Any word character or a period is matched.
       
  4011         matcher = /\:([\w\.]+)/g,
       
  4012             // Regular expression for identifying &amp;key=value lists.
       
  4013             paramsMatcher = /^(?:&[^=]+=[^&]*)+/,
       
  4014             // Converts a JS Object into a list of parameters that can be 
       
  4015             // inserted into an html element tag.
       
  4016             makeProps = function(props) {
       
  4017                 var tags = [];
       
  4018                 can.each(props, function(val, name) {
       
  4019                     tags.push((name === 'className' ? 'class' : name) + '="' +
       
  4020                         (name === "href" ? val : can.esc(val)) + '"');
       
  4021                 });
       
  4022                 return tags.join(" ");
       
  4023             },
       
  4024             // Checks if a route matches the data provided. If any route variable
       
  4025             // is not present in the data, the route does not match. If all route
       
  4026             // variables are present in the data, the number of matches is returned 
       
  4027             // to allow discerning between general and more specific routes. 
       
  4028             matchesData = function(route, data) {
       
  4029                 var count = 0,
       
  4030                     i = 0,
       
  4031                     defaults = {};
       
  4032                 // look at default values, if they match ...
       
  4033                 for (var name in route.defaults) {
       
  4034                     if (route.defaults[name] === data[name]) {
       
  4035                         // mark as matched
       
  4036                         defaults[name] = 1;
       
  4037                         count++;
       
  4038                     }
       
  4039                 }
       
  4040                 for (; i < route.names.length; i++) {
       
  4041                     if (!data.hasOwnProperty(route.names[i])) {
       
  4042                         return -1;
       
  4043                     }
       
  4044                     if (!defaults[route.names[i]]) {
       
  4045                         count++;
       
  4046                     }
       
  4047 
       
  4048                 }
       
  4049 
       
  4050                 return count;
       
  4051             },
       
  4052             onready = !0,
       
  4053             location = window.location,
       
  4054             wrapQuote = function(str) {
       
  4055                 return (str + '').replace(/([.?*+\^$\[\]\\(){}|\-])/g, "\\$1");
       
  4056             },
       
  4057             each = can.each,
       
  4058             extend = can.extend;
       
  4059 
       
  4060         can.route = function(url, defaults) {
       
  4061             defaults = defaults || {};
       
  4062             // Extract the variable names and replace with `RegExp` that will match
       
  4063             // an atual URL with values.
       
  4064             var names = [],
       
  4065                 test = url.replace(matcher, function(whole, name, i) {
       
  4066                     names.push(name);
       
  4067                     var next = "\\" + (url.substr(i + whole.length, 1) || can.route._querySeparator);
       
  4068                     // a name without a default value HAS to have a value
       
  4069                     // a name that has a default value can be empty
       
  4070                     // The `\\` is for string-escaping giving single `\` for `RegExp` escaping.
       
  4071                     return "([^" + next + "]" + (defaults[name] ? "*" : "+") + ")";
       
  4072                 });
       
  4073 
       
  4074             // Add route in a form that can be easily figured out.
       
  4075             can.route.routes[url] = {
       
  4076                 // A regular expression that will match the route when variable values 
       
  4077                 // are present; i.e. for `:page/:type` the `RegExp` is `/([\w\.]*)/([\w\.]*)/` which
       
  4078                 // will match for any value of `:page` and `:type` (word chars or period).
       
  4079                 test: new RegExp("^" + test + "($|" + wrapQuote(can.route._querySeparator) + ")"),
       
  4080                 // The original URL, same as the index for this entry in routes.
       
  4081                 route: url,
       
  4082                 // An `array` of all the variable names in this route.
       
  4083                 names: names,
       
  4084                 // Default values provided for the variables.
       
  4085                 defaults: defaults,
       
  4086                 // The number of parts in the URL separated by `/`.
       
  4087                 length: url.split('/').length
       
  4088             };
       
  4089             return can.route;
       
  4090         };
       
  4091 
       
  4092 
       
  4093         extend(can.route, {
       
  4094 
       
  4095                 _querySeparator: '&',
       
  4096                 _paramsMatcher: paramsMatcher,
       
  4097 
       
  4098 
       
  4099                 param: function(data, _setRoute) {
       
  4100                     // Check if the provided data keys match the names in any routes;
       
  4101                     // Get the one with the most matches.
       
  4102                     var route,
       
  4103                         // Need to have at least 1 match.
       
  4104                         matches = 0,
       
  4105                         matchCount,
       
  4106                         routeName = data.route,
       
  4107                         propCount = 0;
       
  4108 
       
  4109                     delete data.route;
       
  4110 
       
  4111                     each(data, function() {
       
  4112                         propCount++;
       
  4113                     });
       
  4114                     // Otherwise find route.
       
  4115                     each(can.route.routes, function(temp, name) {
       
  4116                         // best route is the first with all defaults matching
       
  4117 
       
  4118 
       
  4119                         matchCount = matchesData(temp, data);
       
  4120                         if (matchCount > matches) {
       
  4121                             route = temp;
       
  4122                             matches = matchCount;
       
  4123                         }
       
  4124                         if (matchCount >= propCount) {
       
  4125                             return false;
       
  4126                         }
       
  4127                     });
       
  4128                     // If we have a route name in our `can.route` data, and it's
       
  4129                     // just as good as what currently matches, use that
       
  4130                     if (can.route.routes[routeName] && matchesData(can.route.routes[routeName], data) === matches) {
       
  4131                         route = can.route.routes[routeName];
       
  4132                     }
       
  4133                     // If this is match...
       
  4134                     if (route) {
       
  4135                         var cpy = extend({}, data),
       
  4136                             // Create the url by replacing the var names with the provided data.
       
  4137                             // If the default value is found an empty string is inserted.
       
  4138                             res = route.route.replace(matcher, function(whole, name) {
       
  4139                                 delete cpy[name];
       
  4140                                 return data[name] === route.defaults[name] ? "" : encodeURIComponent(data[name]);
       
  4141                             }),
       
  4142                             after;
       
  4143                         // Remove matching default values
       
  4144                         each(route.defaults, function(val, name) {
       
  4145                             if (cpy[name] === val) {
       
  4146                                 delete cpy[name];
       
  4147                             }
       
  4148                         });
       
  4149 
       
  4150                         // The remaining elements of data are added as 
       
  4151                         // `&amp;` separated parameters to the url.
       
  4152                         after = can.param(cpy);
       
  4153                         // if we are paraming for setting the hash
       
  4154                         // we also want to make sure the route value is updated
       
  4155                         if (_setRoute) {
       
  4156                             can.route.attr('route', route.route);
       
  4157                         }
       
  4158                         return res + (after ? can.route._querySeparator + after : "");
       
  4159                     }
       
  4160                     // If no route was found, there is no hash URL, only paramters.
       
  4161                     return can.isEmptyObject(data) ? "" : can.route._querySeparator + can.param(data);
       
  4162                 },
       
  4163 
       
  4164                 deparam: function(url) {
       
  4165                     // See if the url matches any routes by testing it against the `route.test` `RegExp`.
       
  4166                     // By comparing the URL length the most specialized route that matches is used.
       
  4167                     var route = {
       
  4168                         length: -1
       
  4169                     };
       
  4170                     each(can.route.routes, function(temp, name) {
       
  4171                         if (temp.test.test(url) && temp.length > route.length) {
       
  4172                             route = temp;
       
  4173                         }
       
  4174                     });
       
  4175                     // If a route was matched.
       
  4176                     if (route.length > -1) {
       
  4177 
       
  4178                         var // Since `RegExp` backreferences are used in `route.test` (parens)
       
  4179                         // the parts will contain the full matched string and each variable (back-referenced) value.
       
  4180                         parts = url.match(route.test),
       
  4181                             // Start will contain the full matched string; parts contain the variable values.
       
  4182                             start = parts.shift(),
       
  4183                             // The remainder will be the `&amp;key=value` list at the end of the URL.
       
  4184                             remainder = url.substr(start.length - (parts[parts.length - 1] === can.route._querySeparator ? 1 : 0)),
       
  4185                             // If there is a remainder and it contains a `&amp;key=value` list deparam it.
       
  4186                             obj = (remainder && can.route._paramsMatcher.test(remainder)) ? can.deparam(remainder.slice(1)) : {};
       
  4187 
       
  4188                         // Add the default values for this route.
       
  4189                         obj = extend(true, {}, route.defaults, obj);
       
  4190                         // Overwrite each of the default values in `obj` with those in 
       
  4191                         // parts if that part is not empty.
       
  4192                         each(parts, function(part, i) {
       
  4193                             if (part && part !== can.route._querySeparator) {
       
  4194                                 obj[route.names[i]] = decodeURIComponent(part);
       
  4195                             }
       
  4196                         });
       
  4197                         obj.route = route.route;
       
  4198                         return obj;
       
  4199                     }
       
  4200                     // If no route was matched, it is parsed as a `&amp;key=value` list.
       
  4201                     if (url.charAt(0) !== can.route._querySeparator) {
       
  4202                         url = can.route._querySeparator + url;
       
  4203                     }
       
  4204                     return can.route._paramsMatcher.test(url) ? can.deparam(url.slice(1)) : {};
       
  4205                 },
       
  4206 
       
  4207                 data: new can.Observe({}),
       
  4208 
       
  4209                 routes: {},
       
  4210 
       
  4211                 ready: function(val) {
       
  4212                     if (val === false) {
       
  4213                         onready = val;
       
  4214                     }
       
  4215                     if (val === true || onready === true) {
       
  4216                         can.route._setup();
       
  4217                         setState();
       
  4218                     }
       
  4219                     return can.route;
       
  4220                 },
       
  4221 
       
  4222                 url: function(options, merge) {
       
  4223                     if (merge) {
       
  4224                         options = extend({}, curParams, options)
       
  4225                     }
       
  4226                     return "#!" + can.route.param(options);
       
  4227                 },
       
  4228 
       
  4229                 link: function(name, options, props, merge) {
       
  4230                     return "<a " + makeProps(
       
  4231                         extend({
       
  4232                                 href: can.route.url(options, merge)
       
  4233                             }, props)) + ">" + name + "</a>";
       
  4234                 },
       
  4235 
       
  4236                 current: function(options) {
       
  4237                     return location.hash == "#!" + can.route.param(options)
       
  4238                 },
       
  4239                 _setup: function() {
       
  4240                     // If the hash changes, update the `can.route.data`.
       
  4241                     can.bind.call(window, 'hashchange', setState);
       
  4242                 },
       
  4243                 _getHash: function() {
       
  4244                     return location.href.split(/#!?/)[1] || "";
       
  4245                 },
       
  4246                 _setHash: function(serialized) {
       
  4247                     var path = (can.route.param(serialized, true));
       
  4248                     location.hash = "#!" + path;
       
  4249                     return path;
       
  4250                 }
       
  4251             });
       
  4252 
       
  4253 
       
  4254         // The functions in the following list applied to `can.route` (e.g. `can.route.attr('...')`) will
       
  4255         // instead act on the `can.route.data` observe.
       
  4256         each(['bind', 'unbind', 'delegate', 'undelegate', 'attr', 'removeAttr'], function(name) {
       
  4257             can.route[name] = function() {
       
  4258                 // `delegate` and `undelegate` require
       
  4259                 // the `can/observe/delegate` plugin
       
  4260                 if (!can.route.data[name]) {
       
  4261                     return;
       
  4262                 }
       
  4263 
       
  4264                 return can.route.data[name].apply(can.route.data, arguments);
       
  4265             }
       
  4266         })
       
  4267 
       
  4268         var // A ~~throttled~~ debounced function called multiple times will only fire once the
       
  4269         // timer runs down. Each call resets the timer.
       
  4270         timer,
       
  4271             // Intermediate storage for `can.route.data`.
       
  4272             curParams,
       
  4273             // Deparameterizes the portion of the hash of interest and assign the
       
  4274             // values to the `can.route.data` removing existing values no longer in the hash.
       
  4275             // setState is called typically by hashchange which fires asynchronously
       
  4276             // So it's possible that someone started changing the data before the 
       
  4277             // hashchange event fired.  For this reason, it will not set the route data
       
  4278             // if the data is changing or the hash already matches the hash that was set.
       
  4279             setState = can.route.setState = function() {
       
  4280                 var hash = can.route._getHash();
       
  4281                 curParams = can.route.deparam(hash);
       
  4282 
       
  4283                 // if the hash data is currently changing, or
       
  4284                 // the hash is what we set it to anyway, do NOT change the hash
       
  4285                 if (!changingData || hash !== lastHash) {
       
  4286                     can.route.attr(curParams, true);
       
  4287                 }
       
  4288             },
       
  4289             // The last hash caused by a data change
       
  4290             lastHash,
       
  4291             // Are data changes pending that haven't yet updated the hash
       
  4292             changingData;
       
  4293 
       
  4294         // If the `can.route.data` changes, update the hash.
       
  4295         // Using `.serialize()` retrieves the raw data contained in the `observable`.
       
  4296         // This function is ~~throttled~~ debounced so it only updates once even if multiple values changed.
       
  4297         // This might be able to use batchNum and avoid this.
       
  4298         can.route.bind("change", function(ev, attr) {
       
  4299             // indicate that data is changing
       
  4300             changingData = 1;
       
  4301             clearTimeout(timer);
       
  4302             timer = setTimeout(function() {
       
  4303                 // indicate that the hash is set to look like the data
       
  4304                 changingData = 0;
       
  4305                 var serialized = can.route.data.serialize();
       
  4306 
       
  4307                 lastHash = can.route._setHash(serialized);
       
  4308             }, 1);
       
  4309         });
       
  4310         // `onready` event...
       
  4311         can.bind.call(document, "ready", can.route.ready);
       
  4312 
       
  4313         // Libraries other than jQuery don't execute the document `ready` listener
       
  4314         // if we are already DOM ready
       
  4315         if ((document.readyState === 'complete' || document.readyState === "interactive") && onready) {
       
  4316             can.route.ready();
       
  4317         }
       
  4318 
       
  4319         // extend route to have a similar property 
       
  4320         // that is often checked in mustache to determine
       
  4321         // an object's observability
       
  4322         can.route.constructor.canMakeObserve = can.Observe.canMakeObserve;
       
  4323 
       
  4324         return can.route;
       
  4325     })(__m3, __m7, __m20);
       
  4326 
       
  4327     // ## can/control/route/route.js
       
  4328     var __m21 = (function(can) {
       
  4329 
       
  4330         // ## control/route.js  
       
  4331         // _Controller route integration._
       
  4332 
       
  4333         can.Control.processors.route = function(el, event, selector, funcName, controller) {
       
  4334             selector = selector || "";
       
  4335             can.route(selector);
       
  4336             var batchNum,
       
  4337                 check = function(ev, attr, how) {
       
  4338                     if (can.route.attr('route') === (selector) &&
       
  4339                         (ev.batchNum === undefined || ev.batchNum !== batchNum)) {
       
  4340 
       
  4341                         batchNum = ev.batchNum;
       
  4342 
       
  4343                         var d = can.route.attr();
       
  4344                         delete d.route;
       
  4345                         if (can.isFunction(controller[funcName])) {
       
  4346                             controller[funcName](d);
       
  4347                         } else {
       
  4348                             controller[controller[funcName]](d);
       
  4349                         }
       
  4350 
       
  4351                     }
       
  4352                 };
       
  4353             can.route.bind('change', check);
       
  4354             return function() {
       
  4355                 can.route.unbind('change', check);
       
  4356             };
       
  4357         };
       
  4358 
       
  4359         return can;
       
  4360     })(__m3, __m19, __m18);
       
  4361 
       
  4362     // ## can/util/object/object.js
       
  4363     var __m23 = (function(can) {
       
  4364 
       
  4365         var isArray = can.isArray,
       
  4366             // essentially returns an object that has all the must have comparisons ...
       
  4367             // must haves, do not return true when provided undefined
       
  4368             cleanSet = function(obj, compares) {
       
  4369                 var copy = can.extend({}, obj);
       
  4370                 for (var prop in copy) {
       
  4371                     var compare = compares[prop] === undefined ? compares["*"] : compares[prop];
       
  4372                     if (same(copy[prop], undefined, compare)) {
       
  4373                         delete copy[prop]
       
  4374                     }
       
  4375                 }
       
  4376                 return copy;
       
  4377             },
       
  4378             propCount = function(obj) {
       
  4379                 var count = 0;
       
  4380                 for (var prop in obj) count++;
       
  4381                 return count;
       
  4382             };
       
  4383 
       
  4384         can.Object = {};
       
  4385 
       
  4386         var same = can.Object.same = function(a, b, compares, aParent, bParent, deep) {
       
  4387             var aType = typeof a,
       
  4388                 aArray = isArray(a),
       
  4389                 comparesType = typeof compares,
       
  4390                 compare;
       
  4391 
       
  4392             if (comparesType == 'string' || compares === null) {
       
  4393                 compares = compareMethods[compares];
       
  4394                 comparesType = 'function'
       
  4395             }
       
  4396             if (comparesType == 'function') {
       
  4397                 return compares(a, b, aParent, bParent)
       
  4398             }
       
  4399             compares = compares || {};
       
  4400 
       
  4401             if (a instanceof Date) {
       
  4402                 return a === b;
       
  4403             }
       
  4404             if (deep === -1) {
       
  4405                 return aType === 'object' || a === b;
       
  4406             }
       
  4407             if (aType !== typeof b || aArray !== isArray(b)) {
       
  4408                 return false;
       
  4409             }
       
  4410             if (a === b) {
       
  4411                 return true;
       
  4412             }
       
  4413             if (aArray) {
       
  4414                 if (a.length !== b.length) {
       
  4415                     return false;
       
  4416                 }
       
  4417                 for (var i = 0; i < a.length; i++) {
       
  4418                     compare = compares[i] === undefined ? compares["*"] : compares[i]
       
  4419                     if (!same(a[i], b[i], a, b, compare)) {
       
  4420                         return false;
       
  4421                     }
       
  4422                 };
       
  4423                 return true;
       
  4424             } else if (aType === "object" || aType === 'function') {
       
  4425                 var bCopy = can.extend({}, b);
       
  4426                 for (var prop in a) {
       
  4427                     compare = compares[prop] === undefined ? compares["*"] : compares[prop];
       
  4428                     if (!same(a[prop], b[prop], compare, a, b, deep === false ? -1 : undefined)) {
       
  4429                         return false;
       
  4430                     }
       
  4431                     delete bCopy[prop];
       
  4432                 }
       
  4433                 // go through bCopy props ... if there is no compare .. return false
       
  4434                 for (prop in bCopy) {
       
  4435                     if (compares[prop] === undefined || !same(undefined, b[prop], compares[prop], a, b, deep === false ? -1 : undefined)) {
       
  4436                         return false;
       
  4437                     }
       
  4438                 }
       
  4439                 return true;
       
  4440             }
       
  4441             return false;
       
  4442         };
       
  4443 
       
  4444         can.Object.subsets = function(checkSet, sets, compares) {
       
  4445             var len = sets.length,
       
  4446                 subsets = [],
       
  4447                 checkPropCount = propCount(checkSet),
       
  4448                 setLength;
       
  4449 
       
  4450             for (var i = 0; i < len; i++) {
       
  4451                 //check this subset
       
  4452                 var set = sets[i];
       
  4453                 if (can.Object.subset(checkSet, set, compares)) {
       
  4454                     subsets.push(set)
       
  4455                 }
       
  4456             }
       
  4457             return subsets;
       
  4458         };
       
  4459 
       
  4460         can.Object.subset = function(subset, set, compares) {
       
  4461             // go through set {type: 'folder'} and make sure every property
       
  4462             // is in subset {type: 'folder', parentId :5}
       
  4463             // then make sure that set has fewer properties
       
  4464             // make sure we are only checking 'important' properties
       
  4465             // in subset (ones that have to have a value)
       
  4466 
       
  4467             var setPropCount = 0,
       
  4468                 compares = compares || {};
       
  4469 
       
  4470             for (var prop in set) {
       
  4471 
       
  4472                 if (!same(subset[prop], set[prop], compares[prop], subset, set)) {
       
  4473                     return false;
       
  4474                 }
       
  4475             }
       
  4476             return true;
       
  4477         }
       
  4478 
       
  4479         var compareMethods = {
       
  4480             "null": function() {
       
  4481                 return true;
       
  4482             },
       
  4483             i: function(a, b) {
       
  4484                 return ("" + a).toLowerCase() == ("" + b).toLowerCase()
       
  4485             }
       
  4486         }
       
  4487 
       
  4488         return can.Object;
       
  4489 
       
  4490     })(__m3);
       
  4491 
       
  4492     // ## can/observe/backup/backup.js
       
  4493     var __m22 = (function(can) {
       
  4494         var flatProps = function(a) {
       
  4495             var obj = {};
       
  4496             for (var prop in a) {
       
  4497                 if (typeof a[prop] !== 'object' || a[prop] === null || a[prop] instanceof Date) {
       
  4498                     obj[prop] = a[prop]
       
  4499                 }
       
  4500             }
       
  4501             return obj;
       
  4502         };
       
  4503 
       
  4504         can.extend(can.Observe.prototype, {
       
  4505 
       
  4506 
       
  4507                 backup: function() {
       
  4508                     this._backupStore = this._attrs();
       
  4509                     return this;
       
  4510                 },
       
  4511 
       
  4512 
       
  4513                 isDirty: function(checkAssociations) {
       
  4514                     return this._backupStore && !can.Object.same(this._attrs(),
       
  4515                         this._backupStore,
       
  4516                         undefined,
       
  4517                         undefined,
       
  4518                         undefined, !! checkAssociations);
       
  4519                 },
       
  4520 
       
  4521 
       
  4522                 restore: function(restoreAssociations) {
       
  4523                     var props = restoreAssociations ? this._backupStore : flatProps(this._backupStore)
       
  4524 
       
  4525                     if (this.isDirty(restoreAssociations)) {
       
  4526                         this._attrs(props);
       
  4527                     }
       
  4528 
       
  4529                     return this;
       
  4530                 }
       
  4531 
       
  4532             })
       
  4533 
       
  4534         return can.Observe;
       
  4535     })(__m3, __m7, __m23);
       
  4536 
       
  4537     window['can'] = __m5;
       
  4538 })();