//////////////////////////////////////////////////////////////////////////
//                                                                      //
// This is a generated file. You can view the original                  //
// source in your browser if your browser supports source maps.         //
//                                                                      //
// If you are using Chrome, open the Developer Tools and click the gear //
// icon in its lower right corner. In the General Settings panel, turn  //
// on 'Enable source maps'.                                             //
//                                                                      //
// If you are using Firefox 23, go to `about:config` and set the        //
// `devtools.debugger.source-maps-enabled` preference to true.          //
// (The preference should be on by default in Firefox 24; versions      //
// older than 23 do not support source maps.)                           //
//                                                                      //
//////////////////////////////////////////////////////////////////////////


(function () {

/* Imports */
var Meteor = Package.meteor.Meteor;
var _ = Package.underscore._;
var Tracker = Package.tracker.Tracker;
var Deps = Package.tracker.Deps;
var EJSON = Package.ejson.EJSON;

/* Package-scope variables */
var ReactiveDict;

(function () {

//////////////////////////////////////////////////////////////////////////////////////////
//                                                                                      //
// packages/reactive-dict/reactive-dict.js                                              //
//                                                                                      //
//////////////////////////////////////////////////////////////////////////////////////////
                                                                                        //
// XXX come up with a serialization method which canonicalizes object key               // 1
// order, which would allow us to use objects as values for equals.                     // 2
var stringify = function (value) {                                                      // 3
  if (value === undefined)                                                              // 4
    return 'undefined';                                                                 // 5
  return EJSON.stringify(value);                                                        // 6
};                                                                                      // 7
var parse = function (serialized) {                                                     // 8
  if (serialized === undefined || serialized === 'undefined')                           // 9
    return undefined;                                                                   // 10
  return EJSON.parse(serialized);                                                       // 11
};                                                                                      // 12
                                                                                        // 13
// XXX COMPAT WITH 0.9.1 : accept migrationData instead of dictName                     // 14
ReactiveDict = function (dictName) {                                                    // 15
  // this.keys: key -> value                                                            // 16
  if (dictName) {                                                                       // 17
    if (typeof dictName === 'string') {                                                 // 18
      // the normal case, argument is a string name.                                    // 19
      // _registerDictForMigrate will throw an error on duplicate name.                 // 20
      ReactiveDict._registerDictForMigrate(dictName, this);                             // 21
      this.keys = ReactiveDict._loadMigratedDict(dictName) || {};                       // 22
    } else if (typeof dictName === 'object') {                                          // 23
      // back-compat case: dictName is actually migrationData                           // 24
      this.keys = dictName;                                                             // 25
    } else {                                                                            // 26
      throw new Error("Invalid ReactiveDict argument: " + dictName);                    // 27
    }                                                                                   // 28
  } else {                                                                              // 29
    // no name given; no migration will be performed                                    // 30
    this.keys = {};                                                                     // 31
  }                                                                                     // 32
                                                                                        // 33
  this.keyDeps = {}; // key -> Dependency                                               // 34
  this.keyValueDeps = {}; // key -> Dependency                                          // 35
};                                                                                      // 36
                                                                                        // 37
_.extend(ReactiveDict.prototype, {                                                      // 38
  // set() began as a key/value method, but we are now overloading it                   // 39
  // to take an object of key/value pairs, similar to backbone                          // 40
  // http://backbonejs.org/#Model-set                                                   // 41
                                                                                        // 42
  set: function (keyOrObject, value) {                                                  // 43
    var self = this;                                                                    // 44
                                                                                        // 45
    if ((typeof keyOrObject === 'object') && (value === undefined)) {                   // 46
      self._setObject(keyOrObject);                                                     // 47
      return;                                                                           // 48
    }                                                                                   // 49
    // the input isn't an object, so it must be a key                                   // 50
    // and we resume with the rest of the function                                      // 51
    var key = keyOrObject;                                                              // 52
                                                                                        // 53
    value = stringify(value);                                                           // 54
                                                                                        // 55
    var oldSerializedValue = 'undefined';                                               // 56
    if (_.has(self.keys, key)) oldSerializedValue = self.keys[key];                     // 57
    if (value === oldSerializedValue)                                                   // 58
      return;                                                                           // 59
    self.keys[key] = value;                                                             // 60
                                                                                        // 61
    var changed = function (v) {                                                        // 62
      v && v.changed();                                                                 // 63
    };                                                                                  // 64
                                                                                        // 65
    changed(self.keyDeps[key]);                                                         // 66
    if (self.keyValueDeps[key]) {                                                       // 67
      changed(self.keyValueDeps[key][oldSerializedValue]);                              // 68
      changed(self.keyValueDeps[key][value]);                                           // 69
    }                                                                                   // 70
  },                                                                                    // 71
                                                                                        // 72
  setDefault: function (key, value) {                                                   // 73
    var self = this;                                                                    // 74
    // for now, explicitly check for undefined, since there is no                       // 75
    // ReactiveDict.clear().  Later we might have a ReactiveDict.clear(), in which case // 76
    // we should check if it has the key.                                               // 77
    if (self.keys[key] === undefined) {                                                 // 78
      self.set(key, value);                                                             // 79
    }                                                                                   // 80
  },                                                                                    // 81
                                                                                        // 82
  get: function (key) {                                                                 // 83
    var self = this;                                                                    // 84
    self._ensureKey(key);                                                               // 85
    self.keyDeps[key].depend();                                                         // 86
    return parse(self.keys[key]);                                                       // 87
  },                                                                                    // 88
                                                                                        // 89
  equals: function (key, value) {                                                       // 90
    var self = this;                                                                    // 91
                                                                                        // 92
    // Mongo.ObjectID is in the 'mongo' package                                         // 93
    var ObjectID = null;                                                                // 94
    if (typeof Mongo !== 'undefined') {                                                 // 95
      ObjectID = Mongo.ObjectID;                                                        // 96
    }                                                                                   // 97
                                                                                        // 98
    // We don't allow objects (or arrays that might include objects) for                // 99
    // .equals, because JSON.stringify doesn't canonicalize object key                  // 100
    // order. (We can make equals have the right return value by parsing the            // 101
    // current value and using EJSON.equals, but we won't have a canonical              // 102
    // element of keyValueDeps[key] to store the dependency.) You can still use         // 103
    // "EJSON.equals(reactiveDict.get(key), value)".                                    // 104
    //                                                                                  // 105
    // XXX we could allow arrays as long as we recursively check that there             // 106
    // are no objects                                                                   // 107
    if (typeof value !== 'string' &&                                                    // 108
        typeof value !== 'number' &&                                                    // 109
        typeof value !== 'boolean' &&                                                   // 110
        typeof value !== 'undefined' &&                                                 // 111
        !(value instanceof Date) &&                                                     // 112
        !(ObjectID && value instanceof ObjectID) &&                                     // 113
        value !== null)                                                                 // 114
      throw new Error("ReactiveDict.equals: value must be scalar");                     // 115
    var serializedValue = stringify(value);                                             // 116
                                                                                        // 117
    if (Tracker.active) {                                                               // 118
      self._ensureKey(key);                                                             // 119
                                                                                        // 120
      if (! _.has(self.keyValueDeps[key], serializedValue))                             // 121
        self.keyValueDeps[key][serializedValue] = new Tracker.Dependency;               // 122
                                                                                        // 123
      var isNew = self.keyValueDeps[key][serializedValue].depend();                     // 124
      if (isNew) {                                                                      // 125
        Tracker.onInvalidate(function () {                                              // 126
          // clean up [key][serializedValue] if it's now empty, so we don't             // 127
          // use O(n) memory for n = values seen ever                                   // 128
          if (! self.keyValueDeps[key][serializedValue].hasDependents())                // 129
            delete self.keyValueDeps[key][serializedValue];                             // 130
        });                                                                             // 131
      }                                                                                 // 132
    }                                                                                   // 133
                                                                                        // 134
    var oldValue = undefined;                                                           // 135
    if (_.has(self.keys, key)) oldValue = parse(self.keys[key]);                        // 136
    return EJSON.equals(oldValue, value);                                               // 137
  },                                                                                    // 138
                                                                                        // 139
  _setObject: function (object) {                                                       // 140
    var self = this;                                                                    // 141
                                                                                        // 142
    _.each(object, function (value, key){                                               // 143
      self.set(key, value);                                                             // 144
    });                                                                                 // 145
  },                                                                                    // 146
                                                                                        // 147
  _ensureKey: function (key) {                                                          // 148
    var self = this;                                                                    // 149
    if (!(key in self.keyDeps)) {                                                       // 150
      self.keyDeps[key] = new Tracker.Dependency;                                       // 151
      self.keyValueDeps[key] = {};                                                      // 152
    }                                                                                   // 153
  },                                                                                    // 154
                                                                                        // 155
  // Get a JSON value that can be passed to the constructor to                          // 156
  // create a new ReactiveDict with the same contents as this one                       // 157
  _getMigrationData: function () {                                                      // 158
    // XXX sanitize and make sure it's JSONible?                                        // 159
    return this.keys;                                                                   // 160
  }                                                                                     // 161
});                                                                                     // 162
                                                                                        // 163
//////////////////////////////////////////////////////////////////////////////////////////

}).call(this);






(function () {

//////////////////////////////////////////////////////////////////////////////////////////
//                                                                                      //
// packages/reactive-dict/migration.js                                                  //
//                                                                                      //
//////////////////////////////////////////////////////////////////////////////////////////
                                                                                        //
ReactiveDict._migratedDictData = {}; // name -> data                                    // 1
ReactiveDict._dictsToMigrate = {}; // name -> ReactiveDict                              // 2
                                                                                        // 3
ReactiveDict._loadMigratedDict = function (dictName) {                                  // 4
  if (_.has(ReactiveDict._migratedDictData, dictName))                                  // 5
    return ReactiveDict._migratedDictData[dictName];                                    // 6
                                                                                        // 7
  return null;                                                                          // 8
};                                                                                      // 9
                                                                                        // 10
ReactiveDict._registerDictForMigrate = function (dictName, dict) {                      // 11
  if (_.has(ReactiveDict._dictsToMigrate, dictName))                                    // 12
    throw new Error("Duplicate ReactiveDict name: " + dictName);                        // 13
                                                                                        // 14
  ReactiveDict._dictsToMigrate[dictName] = dict;                                        // 15
};                                                                                      // 16
                                                                                        // 17
if (Meteor.isClient && Package.reload) {                                                // 18
  // Put old migrated data into ReactiveDict._migratedDictData,                         // 19
  // where it can be accessed by ReactiveDict._loadMigratedDict.                        // 20
  var migrationData = Package.reload.Reload._migrationData('reactive-dict');            // 21
  if (migrationData && migrationData.dicts)                                             // 22
    ReactiveDict._migratedDictData = migrationData.dicts;                               // 23
                                                                                        // 24
  // On migration, assemble the data from all the dicts that have been                  // 25
  // registered.                                                                        // 26
  Package.reload.Reload._onMigrate('reactive-dict', function () {                       // 27
    var dictsToMigrate = ReactiveDict._dictsToMigrate;                                  // 28
    var dataToMigrate = {};                                                             // 29
                                                                                        // 30
    for (var dictName in dictsToMigrate)                                                // 31
      dataToMigrate[dictName] = dictsToMigrate[dictName]._getMigrationData();           // 32
                                                                                        // 33
    return [true, {dicts: dataToMigrate}];                                              // 34
  });                                                                                   // 35
}                                                                                       // 36
                                                                                        // 37
//////////////////////////////////////////////////////////////////////////////////////////

}).call(this);


/* Exports */
if (typeof Package === 'undefined') Package = {};
Package['reactive-dict'] = {
  ReactiveDict: ReactiveDict
};

})();