ende 0.4.25 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (87) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +3 -2
  3. data/component.json +0 -1
  4. data/lib/assets/javascripts/aura/extensions/domain.js.coffee +55 -0
  5. data/lib/assets/javascripts/aura/extensions/models.js.coffee.erb +13 -4
  6. data/lib/assets/javascripts/aura/extensions/platform.js.coffee +8 -2
  7. data/lib/assets/javascripts/aura/extensions/rivets.js.coffee +10 -21
  8. data/lib/assets/javascripts/aura/extensions/stamps/stampit.js +242 -568
  9. data/lib/assets/javascripts/aura/extensions/widget/composable.js.coffee +18 -35
  10. data/lib/assets/javascripts/config/load_components.js.coffee +7 -5
  11. data/lib/assets/javascripts/widgets/attachable/main.js.coffee +77 -0
  12. data/lib/assets/javascripts/widgets/list/presenter.js.coffee +4 -5
  13. data/lib/assets/javascripts/widgets/support/adapters/olark.js +1 -1
  14. data/lib/assets/javascripts/widgets/tray/main.js.coffee +22 -16
  15. data/lib/assets/javascripts/widgets/viewer/main.js.coffee +4 -8
  16. data/lib/assets/javascripts/widgets/viewer/plugins/scopable.js.coffee +1 -7
  17. data/lib/ende/version.rb +1 -1
  18. data/vendor/assets/components/ende_build.js +463 -5150
  19. data/vendor/components/indefinido-indemma/build/development.js +2 -2
  20. data/vendor/components/indefinido-indemma/build/release.js +4 -5
  21. data/vendor/components/indefinido-indemma/build/test.js +2 -2
  22. data/vendor/components/indefinido-indemma/component.json +1 -0
  23. data/vendor/components/indefinido-indemma/lib/record/restfulable.js +2 -3
  24. data/vendor/components/indefinido-indemma/lib/record/validatable.js +2 -2
  25. data/vendor/components/indefinido-indemma/src/lib/record/restfulable.coffee +3 -9
  26. data/vendor/components/indefinido-indemma/src/lib/record/validatable.coffee +3 -3
  27. data/vendor/components/indefinido-observable/component.json +3 -7
  28. data/vendor/components/indefinido-observable/lib/observable.js +19 -9
  29. metadata +4 -60
  30. data/build/build.css +0 -111
  31. data/vendor/assets/javascripts/stampit/stampit.js +0 -392
  32. data/vendor/components/indefinido-observable/.gitignore +0 -15
  33. data/vendor/components/indefinido-observable/.ruby-gemset +0 -1
  34. data/vendor/components/indefinido-observable/.ruby-version +0 -1
  35. data/vendor/components/indefinido-observable/Gemfile +0 -13
  36. data/vendor/components/indefinido-observable/Guardfile +0 -39
  37. data/vendor/components/indefinido-observable/History.md +0 -0
  38. data/vendor/components/indefinido-observable/Readme.md +0 -116
  39. data/vendor/components/indefinido-observable/build/build.js +0 -14798
  40. data/vendor/components/indefinido-observable/build/development.js +0 -339
  41. data/vendor/components/indefinido-observable/build/release.js +0 -14937
  42. data/vendor/components/indefinido-observable/build/test.js +0 -339
  43. data/vendor/components/indefinido-observable/components/chaijs-chai/component.json +0 -46
  44. data/vendor/components/indefinido-observable/components/chaijs-chai/index.js +0 -1
  45. data/vendor/components/indefinido-observable/components/chaijs-chai/lib/chai/assertion.js +0 -132
  46. data/vendor/components/indefinido-observable/components/chaijs-chai/lib/chai/core/assertions.js +0 -1270
  47. data/vendor/components/indefinido-observable/components/chaijs-chai/lib/chai/error.js +0 -60
  48. data/vendor/components/indefinido-observable/components/chaijs-chai/lib/chai/interface/assert.js +0 -1060
  49. data/vendor/components/indefinido-observable/components/chaijs-chai/lib/chai/interface/expect.js +0 -12
  50. data/vendor/components/indefinido-observable/components/chaijs-chai/lib/chai/interface/should.js +0 -76
  51. data/vendor/components/indefinido-observable/components/chaijs-chai/lib/chai/utils/addChainableMethod.js +0 -94
  52. data/vendor/components/indefinido-observable/components/chaijs-chai/lib/chai/utils/addMethod.js +0 -37
  53. data/vendor/components/indefinido-observable/components/chaijs-chai/lib/chai/utils/addProperty.js +0 -40
  54. data/vendor/components/indefinido-observable/components/chaijs-chai/lib/chai/utils/eql.js +0 -124
  55. data/vendor/components/indefinido-observable/components/chaijs-chai/lib/chai/utils/flag.js +0 -32
  56. data/vendor/components/indefinido-observable/components/chaijs-chai/lib/chai/utils/getActual.js +0 -19
  57. data/vendor/components/indefinido-observable/components/chaijs-chai/lib/chai/utils/getEnumerableProperties.js +0 -25
  58. data/vendor/components/indefinido-observable/components/chaijs-chai/lib/chai/utils/getMessage.js +0 -49
  59. data/vendor/components/indefinido-observable/components/chaijs-chai/lib/chai/utils/getName.js +0 -20
  60. data/vendor/components/indefinido-observable/components/chaijs-chai/lib/chai/utils/getPathValue.js +0 -102
  61. data/vendor/components/indefinido-observable/components/chaijs-chai/lib/chai/utils/getProperties.js +0 -35
  62. data/vendor/components/indefinido-observable/components/chaijs-chai/lib/chai/utils/index.js +0 -108
  63. data/vendor/components/indefinido-observable/components/chaijs-chai/lib/chai/utils/inspect.js +0 -316
  64. data/vendor/components/indefinido-observable/components/chaijs-chai/lib/chai/utils/objDisplay.js +0 -48
  65. data/vendor/components/indefinido-observable/components/chaijs-chai/lib/chai/utils/overwriteMethod.js +0 -51
  66. data/vendor/components/indefinido-observable/components/chaijs-chai/lib/chai/utils/overwriteProperty.js +0 -54
  67. data/vendor/components/indefinido-observable/components/chaijs-chai/lib/chai/utils/test.js +0 -26
  68. data/vendor/components/indefinido-observable/components/chaijs-chai/lib/chai/utils/transferFlags.js +0 -44
  69. data/vendor/components/indefinido-observable/components/chaijs-chai/lib/chai/utils/type.js +0 -45
  70. data/vendor/components/indefinido-observable/components/chaijs-chai/lib/chai.js +0 -79
  71. data/vendor/components/indefinido-observable/components/cjohansen-sinon/sinon.js +0 -4290
  72. data/vendor/components/indefinido-observable/components/component-jquery/component.json +0 -14
  73. data/vendor/components/indefinido-observable/components/component-jquery/index.js +0 -9601
  74. data/vendor/components/indefinido-observable/components/kapit-observe-shim/component.json +0 -11
  75. data/vendor/components/indefinido-observable/components/kapit-observe-utils/component.json +0 -13
  76. data/vendor/components/indefinido-observable/karma.conf.js +0 -92
  77. data/vendor/components/indefinido-observable/spec/legacy/observable_spec.js +0 -126
  78. data/vendor/components/indefinido-observable/spec/observable_spec.js +0 -92
  79. data/vendor/components/indefinido-observable/spec/spec_helper.js +0 -8
  80. data/vendor/components/indefinido-observable/spec/vendor/accessors_spec.js +0 -63
  81. data/vendor/components/indefinido-observable/src/lib/adapters/rivets.js.coffee +0 -15
  82. data/vendor/components/indefinido-observable/src/spec/legacy/observable_spec.coffee +0 -132
  83. data/vendor/components/indefinido-observable/src/spec/observable_spec.coffee +0 -85
  84. data/vendor/components/indefinido-observable/src/spec/spec_helper.coffee +0 -5
  85. data/vendor/components/indefinido-observable/src/spec/vendor/accessors_spec.coffee +0 -59
  86. data/vendor/components/indefinido-observable/vendor/spec/boot.js +0 -104
  87. data/vendor/components/indefinido-observable/vendor/spec/jasmine.js +0 -2054
@@ -272,7 +272,7 @@ require.register("indemma/lib/record/rest.js", Function("exports, require, modul
272
272
  "var $, data_for, request;\n\n$ = require('jquery');\n\nmodule.exports = {\n get: function(data) {\n return request.call(this, 'get', (this._id ? \"\" + this.route + \"/\" + this._id : this.route), data);\n },\n put: function(data) {\n return request.call(this, 'put', (this._id ? \"\" + this.route + \"/\" + this._id : this.route), data);\n },\n post: function(data) {\n return request.call(this, 'post', this.route, data);\n },\n \"delete\": function(data) {\n return request.call(this, 'delete', (this._id ? \"\" + this.route + \"/\" + this._id : this.route), data);\n }\n};\n\ndata_for = function(data) {\n var param_name;\n\n param_name = this.resource.param_name || this.resource.toString();\n if (!data && this.json) {\n data = {};\n data[param_name] = this.json();\n }\n if (data && data[param_name]) {\n delete data[param_name]['id'];\n delete data[param_name]['_id'];\n }\n return data;\n};\n\nrequest = function(method, url, data) {\n data = data_for.call(this, data);\n return $.ajax({\n url: url,\n data: data,\n type: method,\n dataType: 'json',\n context: this\n });\n};\n//@ sourceURL=indemma/lib/record/rest.js"
273
273
  ));
274
274
  require.register("indemma/lib/record/restfulable.js", Function("exports, require, module",
275
- "var $, merge, model, observable, record, rest, restful, root, type, util,\n __slice = [].slice;\n\nmerge = require('assimilate').withStrategy('deep');\n\ntype = require('type');\n\nobservable = require('observable').mixin;\n\n$ = require('jquery');\n\nrest = require('./rest.js');\n\nroot = typeof exports !== \"undefined\" && exports !== null ? exports : this;\n\nutil = {\n model: {\n map: function(records) {\n var record, _i, _len, _results;\n\n _results = [];\n for (_i = 0, _len = records.length; _i < _len; _i++) {\n record = records[_i];\n _results.push(this(record));\n }\n return _results;\n }\n }\n};\n\nrestful = {\n model: {\n create: function() {\n var attributes, callback, params, record, savings, _i, _j, _len;\n\n params = 2 <= arguments.length ? __slice.call(arguments, 0, _i = arguments.length - 1) : (_i = 0, []), callback = arguments[_i++];\n if (!arguments.length) {\n throw new TypeError(\"No arguments provided for \" + this.resource + \".create\");\n }\n if (typeof callback !== 'function') {\n params.push(callback);\n callback = void 0;\n }\n if (!params.length) {\n params.unshift({});\n }\n savings = [];\n for (_j = 0, _len = params.length; _j < _len; _j++) {\n attributes = params[_j];\n record = this(attributes);\n record.dirty = true;\n savings.push(record.save(callback));\n }\n return $.when.apply($, savings);\n },\n every: function(conditions, doned, failed) {\n if (conditions == null) {\n conditions = {};\n }\n if (typeof conditions === 'function') {\n doned = conditions;\n conditions = {};\n }\n return $.when(rest.get.call(this, conditions)).then(util.model.map).done(doned).fail(failed);\n },\n first: function(conditions, callback) {\n var namespaced;\n\n if (conditions == null) {\n conditions = {};\n }\n if (typeof conditions === 'function') {\n callback = conditions;\n conditions = {};\n }\n namespaced = conditions[this.resource] || {};\n namespaced.limit = 1;\n namespaced.order = 'desc';\n return this.every(conditions, callback);\n },\n get: function(action, data) {\n var default_route, old_route, payload, promise, resource;\n\n if (data == null) {\n data = {};\n }\n old_route = this.route;\n default_route = '/';\n if (this.resource.scope != null) {\n default_route += this.resource.scope + '/';\n }\n default_route += this.resource.singular ? this.resource.name : model.pluralize(this.resource.name);\n if (default_route !== this.route) {\n this.route = default_route;\n }\n if (action) {\n Object.defineProperty(this, 'route', {\n value: \"\" + default_route + \"/\" + action,\n configurable: true\n });\n }\n resource = data.resource;\n if (data && data.json) {\n data = data.json();\n }\n if (resource != null) {\n payload = data;\n data = {};\n data[resource] = payload;\n }\n promise = rest.get.call(this, data);\n Object.defineProperty(this, 'route', {\n value: old_route,\n configurable: true\n });\n return promise;\n },\n put: rest.put,\n \"delete\": rest[\"delete\"]\n },\n record: {\n ready: function(callback) {\n return callback.call(this);\n },\n reload: function() {\n var data, param, params, promise, _i, _len;\n\n params = 1 <= arguments.length ? __slice.call(arguments, 0) : [];\n data = params.pop();\n if (type(data) !== 'object') {\n params.push(data);\n }\n promise = rest.get.call(this, data || {});\n promise.done(this.assign_attributes);\n promise.fail(this.failed);\n this.reloading = promise;\n this.ready = function() {\n console.warn(\"resource.ready was deprecated, please use resource.reloading.done\");\n return promise.done.apply(promise, arguments);\n };\n for (_i = 0, _len = params.length; _i < _len; _i++) {\n param = params[_i];\n promise.done(param);\n }\n return promise;\n },\n assign_attributes: function(attributes) {\n var association, association_attributes, association_name, associations_attributes, attribute, message, name, singular_resource, _i, _j, _k, _l, _len, _len1, _len2, _len3, _len4, _m, _ref, _ref1, _ref2, _ref3, _ref4, _ref5, _results;\n\n _ref = model[this.resource.toString()].has_many;\n for (_i = 0, _len = _ref.length; _i < _len; _i++) {\n association_name = _ref[_i];\n associations_attributes = attributes[association_name + \"_attributes\"] || attributes[association_name];\n delete attributes[association_name];\n delete attributes[association_name + '_attributes'];\n association = this[association_name];\n if (association == null) {\n message = \"Association '\" + association_name + \"' not found. \\n\";\n message += \"For record with resource \" + this.resource + \". \\n\";\n message += \"Probably defined on server side but not on client side.\\n\";\n message += \"Skipping association assignment!\";\n console.warn(message);\n continue;\n }\n if (association.length) {\n Array.prototype.splice.call(association, 0);\n }\n if (!((associations_attributes != null) && associations_attributes.length)) {\n continue;\n }\n singular_resource = model.singularize(association_name);\n for (_j = 0, _len1 = associations_attributes.length; _j < _len1; _j++) {\n association_attributes = associations_attributes[_j];\n _ref1 = model[singular_resource].has_many;\n for (_k = 0, _len2 = _ref1.length; _k < _len2; _k++) {\n association_name = _ref1[_k];\n association_attributes[\"\" + association_name + \"_attributes\"] = association_attributes[association_name];\n delete association_attributes[association_name];\n }\n }\n association.add.apply(association, associations_attributes);\n }\n _ref2 = model[this.resource.toString()].has_one;\n for (_l = 0, _len3 = _ref2.length; _l < _len3; _l++) {\n association_name = _ref2[_l];\n association_attributes = attributes[association_name];\n delete attributes[association_name];\n delete attributes[association_name + \"_attributes\"];\n if (association_attributes) {\n this[association_name] = this[\"build_\" + association_name](association_attributes);\n }\n }\n _ref3 = model[this.resource.toString()].belongs_to;\n for (_m = 0, _len4 = _ref3.length; _m < _len4; _m++) {\n association_name = _ref3[_m];\n association_attributes = (_ref4 = (_ref5 = attributes[association_name]) != null ? typeof _ref5.json === \"function\" ? _ref5.json() : void 0 : void 0) != null ? _ref4 : attributes[association_name];\n delete attributes[association_name];\n delete attributes[association_name + \"_attributes\"];\n if (association_attributes) {\n this[association_name] = this[\"build_\" + association_name](association_attributes);\n }\n }\n _results = [];\n for (name in attributes) {\n attribute = attributes[name];\n if (attribute !== this[name]) {\n if (type(attribute) === 'object') {\n if (JSON.stringify(attribute) !== JSON.stringify(this[name])) {\n _results.push(this[name] = attributes[name]);\n } else {\n _results.push(void 0);\n }\n } else {\n _results.push(this[name] = attributes[name]);\n }\n }\n }\n return _results;\n },\n destroy: function(doned, failed, data) {\n var promise;\n\n if (!((this.id != null) || (this._id != null))) {\n throw new Error('Can\\'t delete record without id!');\n }\n promise = rest[\"delete\"].call(this, data);\n promise.done(this.destroyed);\n promise.fail(this.failed);\n promise.done(doned);\n promise.fail(failed);\n return promise;\n },\n saving: false,\n salvation: null,\n save: function(doned, failed, data) {\n var lock, salvation;\n\n lock = JSON.stringify(this.json());\n if (this.saving) {\n if (this.lock === lock) {\n return this.salvation;\n } else {\n this.salvation.abort();\n }\n }\n this.lock = lock;\n if (!this.dirty) {\n salvation = $.Deferred().resolveWith(this, null);\n }\n this.saving = true;\n salvation || (salvation = rest[this._id ? 'put' : 'post'].call(this, data));\n this.salvation = salvation;\n salvation.done(this.saved);\n salvation.fail(this.failed);\n salvation.always(function() {\n return this.saving = false;\n });\n salvation.done(doned);\n salvation.fail(failed);\n return salvation;\n },\n saved: function(data) {\n var callback, _i, _len, _ref, _results;\n\n if (this.lock === JSON.stringify(this.json())) {\n this.dirty = false;\n delete this.lock;\n }\n if (data != null) {\n this.assign_attributes(data);\n }\n if (this.after_save) {\n _ref = this.after_save;\n _results = [];\n for (_i = 0, _len = _ref.length; _i < _len; _i++) {\n callback = _ref[_i];\n throw \"Not supported after_save callback: \" + callback;\n }\n return _results;\n }\n },\n failed: function(xhr, error, status) {\n var attribute_name, definition, e, message, messages, payload, _i, _len, _ref;\n\n payload = xhr.responseJSON;\n try {\n payload || (payload = JSON.parse(xhr.responseText));\n } catch (_error) {\n e = _error;\n }\n payload || (payload = xhr.responseText);\n switch (xhr.status) {\n case 0:\n message = status || xhr.statusText;\n switch (message) {\n case 'abort':\n console.info(\"salvation probably aborted\");\n break;\n case 'error':\n console.info(\"server probably unreachable\");\n break;\n default:\n throw new Error('Unhandled status code for xhr');\n }\n break;\n case 422:\n definition = model[this.resource.toString()];\n _ref = payload.errors;\n for (attribute_name in _ref) {\n messages = _ref[attribute_name];\n if (!definition.associations) {\n definition.associations = definition.has_one.concat(definition.has_many.concat(definition.belongs_to));\n }\n if (!(this.hasOwnProperty(attribute_name) || definition.hasOwnProperty(attribute_name) || definition.associations.indexOf(attribute_name) !== -1 || attribute_name === 'base')) {\n message = \"Server returned an validation error message for a attribute that is not defined in your model.\\n\";\n message += \"The attribute was '\" + attribute_name + \"', the model resource was '\" + this.resource + \"'.\\n\";\n message += \"The model definition keys were '\" + (JSON.stringify(Object.keys(definition))) + \"'.\\n\";\n message += \"Please remove server validation, or update your model definition.\";\n throw new TypeError(message);\n }\n for (_i = 0, _len = messages.length; _i < _len; _i++) {\n message = messages[_i];\n this.errors.add(attribute_name, 'server', {\n server_message: message\n });\n }\n }\n break;\n default:\n message = \"Fail in \" + this.resource + \".save:\\n\";\n message += \"Record: \" + this + \"\\n\";\n message += \"Status: \" + status + \" (\" + (payload || xhr).status + \")\\n\";\n message += \"Error : \" + (payload.error || payload.message || payload);\n console.log(message);\n }\n return this.saving = false;\n },\n toString: function() {\n var e, name, property, serialized;\n\n serialized = {};\n serialized[this.resource] = this.json();\n try {\n return JSON.stringify(serialized);\n } catch (_error) {\n e = _error;\n console.warn(\"restfulable.toString: Failed to stringify record: \" + e.message + \". retrying...\");\n for (name in serialized) {\n property = serialized[name];\n if (typeof property === 'object') {\n delete serialized[name];\n }\n }\n return JSON.stringify(serialized);\n }\n },\n json: function(options) {\n var definition, json, method, name, nature, nested, value, _ref, _ref1;\n\n if (options == null) {\n options = {};\n }\n json = {};\n definition = model[this.resource.toString()];\n for (name in this) {\n if (observable.ignores.indexOf(name) !== -1) {\n continue;\n }\n nested = this.nested_attributes.indexOf(name) !== -1;\n if (!nested && (definition.belongs_to.indexOf(name) !== -1 || definition.has_one.indexOf(name) !== -1 || definition.has_many.indexOf(name) !== -1)) {\n continue;\n }\n value = this[name];\n if (value == null) {\n continue;\n }\n nature = type(value);\n if (nature === 'function') {\n continue;\n }\n if (nature === 'object' || nature === 'element') {\n if (nested) {\n if (!value.json) {\n console.warn(\"json: Tryied to serialize nested attribute '\" + name + \"' without serialization method!\");\n continue;\n }\n json[\"\" + name + \"_attributes\"] = value.json(options[name]);\n } else if ((value.toJSON != null) || (value.json != null)) {\n if (value.resource) {\n continue;\n }\n if (value.json != null) {\n json[name] = value.json(options[name]);\n } else {\n json[name] = value.toJSON(options[name]);\n }\n } else {\n continue;\n }\n } else {\n json[name] = value;\n }\n }\n json = observable.unobserve(json);\n _ref1 = (_ref = options.methods) != null ? _ref : {};\n for (name in _ref1) {\n value = _ref1[name];\n method = this[name];\n if (typeof method === 'function') {\n json[name] = method();\n } else {\n json[name] = method;\n }\n }\n delete json.dirty;\n delete json.resource;\n delete json.route;\n delete json.initial_route;\n delete json.after_initialize;\n delete json.before_initialize;\n delete json.parent_resource;\n delete json.nested_attributes;\n delete json.reloading;\n delete json.ready;\n delete json.saving;\n delete json.salvation;\n delete json.sustained;\n delete json.element;\n delete json[\"default\"];\n delete json.lock;\n delete json.validated;\n delete json.validation;\n delete json.errors;\n return json;\n }\n }\n};\n\nrestful.toJSON = restful.json;\n\nmodel = window.model;\n\nrecord = window.record;\n\nmodel.restfulable = true;\n\nrecord.mix(function(recordable) {\n return merge(recordable, restful.record);\n});\n\nmodel.mix(function(modelable) {\n return merge(modelable, restful.model);\n});\n\nmodel.associable && model.associable.mix(function(singular_association, plural_association) {\n plural_association.get = function() {\n if (this.parent != null) {\n this.route || (this.route = \"\" + this.parent.route + \"/\" + this.parent._id + \"/\" + (model.pluralize(this.resource.name)));\n }\n return rest.get.apply(this, arguments);\n };\n return plural_association.post = function() {\n if (this.parent != null) {\n this.route || (this.route = \"\" + this.parent.route + \"/\" + this.parent._id + \"/\" + (model.pluralize(this.resource.name)));\n }\n return rest.post.apply(this, arguments);\n };\n});\n//@ sourceURL=indemma/lib/record/restfulable.js"
275
+ "var $, merge, model, observable, record, rest, restful, root, type, util,\n __slice = [].slice;\n\nmerge = require('assimilate').withStrategy('deep');\n\ntype = require('type');\n\nobservable = require('observable').mixin;\n\n$ = require('jquery');\n\nrest = require('./rest.js');\n\nroot = typeof exports !== \"undefined\" && exports !== null ? exports : this;\n\nutil = {\n model: {\n map: function(records) {\n var record, _i, _len, _results;\n\n _results = [];\n for (_i = 0, _len = records.length; _i < _len; _i++) {\n record = records[_i];\n _results.push(this(record));\n }\n return _results;\n }\n }\n};\n\nrestful = {\n model: {\n create: function() {\n var attributes, callback, params, record, savings, _i, _j, _len;\n\n params = 2 <= arguments.length ? __slice.call(arguments, 0, _i = arguments.length - 1) : (_i = 0, []), callback = arguments[_i++];\n if (!arguments.length) {\n throw new TypeError(\"No arguments provided for \" + this.resource + \".create\");\n }\n if (typeof callback !== 'function') {\n params.push(callback);\n callback = void 0;\n }\n if (!params.length) {\n params.unshift({});\n }\n savings = [];\n for (_j = 0, _len = params.length; _j < _len; _j++) {\n attributes = params[_j];\n record = this(attributes);\n record.dirty = true;\n savings.push(record.save(callback));\n }\n return $.when.apply($, savings);\n },\n every: function(conditions, doned, failed) {\n if (conditions == null) {\n conditions = {};\n }\n if (typeof conditions === 'function') {\n doned = conditions;\n conditions = {};\n }\n return $.when(rest.get.call(this, conditions)).then(util.model.map).done(doned).fail(failed);\n },\n first: function(conditions, callback) {\n var namespaced;\n\n if (conditions == null) {\n conditions = {};\n }\n if (typeof conditions === 'function') {\n callback = conditions;\n conditions = {};\n }\n namespaced = conditions[this.resource] || {};\n namespaced.limit = 1;\n namespaced.order = 'desc';\n return this.every(conditions, callback);\n },\n get: function(action, data) {\n var default_route, old_route, payload, promise, resource;\n\n if (data == null) {\n data = {};\n }\n old_route = this.route;\n default_route = '';\n if (this.resource.scope != null) {\n default_route += this.resource.scope + '/';\n }\n default_route += this.resource.singular ? this.resource.name : model.pluralize(this.resource.name);\n if (default_route !== this.route) {\n this.route = default_route;\n }\n if (action) {\n Object.defineProperty(this, 'route', {\n value: \"\" + default_route + \"/\" + action,\n configurable: true\n });\n }\n resource = data.resource;\n if (data && data.json) {\n data = data.json();\n }\n if (resource != null) {\n payload = data;\n data = {};\n data[resource] = payload;\n }\n promise = rest.get.call(this, data);\n Object.defineProperty(this, 'route', {\n value: old_route,\n configurable: true\n });\n return promise;\n },\n put: rest.put,\n \"delete\": rest[\"delete\"]\n },\n record: {\n ready: function(callback) {\n return callback.call(this);\n },\n reload: function() {\n var data, param, params, promise, _i, _len;\n\n params = 1 <= arguments.length ? __slice.call(arguments, 0) : [];\n data = params.pop();\n if (type(data) !== 'object') {\n params.push(data);\n }\n promise = rest.get.call(this, data || {});\n promise.done(this.assign_attributes);\n promise.fail(this.failed);\n this.reloading = promise;\n this.ready = function() {\n console.warn(\"resource.ready was deprecated, please use resource.reloading.done\");\n return promise.done.apply(promise, arguments);\n };\n for (_i = 0, _len = params.length; _i < _len; _i++) {\n param = params[_i];\n promise.done(param);\n }\n return promise;\n },\n assign_attributes: function(attributes) {\n var association, association_attributes, association_name, associations_attributes, attribute, message, name, singular_resource, _i, _j, _k, _l, _len, _len1, _len2, _len3, _len4, _m, _ref, _ref1, _ref2, _ref3, _ref4, _ref5, _results;\n\n _ref = model[this.resource.toString()].has_many;\n for (_i = 0, _len = _ref.length; _i < _len; _i++) {\n association_name = _ref[_i];\n associations_attributes = attributes[association_name];\n delete attributes[association_name];\n association = this[association_name];\n if (association == null) {\n message = \"Association '\" + association_name + \"' not found. \\n\";\n message += \"For record with resource \" + this.resource + \". \\n\";\n message += \"Probably defined on server side but not on client side.\\n\";\n message += \"Skipping association assignment!\";\n console.warn(message);\n continue;\n }\n if (association.length) {\n Array.prototype.splice.call(association, 0);\n }\n if (!((associations_attributes != null) && associations_attributes.length)) {\n continue;\n }\n singular_resource = model.singularize(association_name);\n for (_j = 0, _len1 = associations_attributes.length; _j < _len1; _j++) {\n association_attributes = associations_attributes[_j];\n _ref1 = model[singular_resource].has_many;\n for (_k = 0, _len2 = _ref1.length; _k < _len2; _k++) {\n association_name = _ref1[_k];\n association_attributes[\"\" + association_name + \"_attributes\"] = association_attributes[association_name];\n delete association_attributes[association_name];\n }\n }\n association.add.apply(association, associations_attributes);\n }\n _ref2 = model[this.resource.toString()].has_one;\n for (_l = 0, _len3 = _ref2.length; _l < _len3; _l++) {\n association_name = _ref2[_l];\n association_attributes = attributes[association_name];\n delete attributes[association_name];\n delete attributes[association_name + \"_attributes\"];\n if (association_attributes) {\n this[association_name] = this[\"build_\" + association_name](association_attributes);\n }\n }\n _ref3 = model[this.resource.toString()].belongs_to;\n for (_m = 0, _len4 = _ref3.length; _m < _len4; _m++) {\n association_name = _ref3[_m];\n association_attributes = (_ref4 = (_ref5 = attributes[association_name]) != null ? typeof _ref5.json === \"function\" ? _ref5.json() : void 0 : void 0) != null ? _ref4 : attributes[association_name];\n delete attributes[association_name];\n delete attributes[association_name + \"_attributes\"];\n if (association_attributes) {\n this[association_name] = this[\"build_\" + association_name](association_attributes);\n }\n }\n _results = [];\n for (name in attributes) {\n attribute = attributes[name];\n if (attribute !== this[name]) {\n if (type(attribute) === 'object') {\n if (JSON.stringify(attribute) !== JSON.stringify(this[name])) {\n _results.push(this[name] = attributes[name]);\n } else {\n _results.push(void 0);\n }\n } else {\n _results.push(this[name] = attributes[name]);\n }\n }\n }\n return _results;\n },\n destroy: function(doned, failed, data) {\n var promise;\n\n if (!((this.id != null) || (this._id != null))) {\n throw new Error('Can\\'t delete record without id!');\n }\n promise = rest[\"delete\"].call(this, data);\n promise.done(this.destroyed);\n promise.fail(this.failed);\n promise.done(doned);\n promise.fail(failed);\n return promise;\n },\n saving: false,\n salvation: null,\n save: function(doned, failed, data) {\n var lock, salvation;\n\n lock = JSON.stringify(this.json());\n if (this.saving) {\n if (this.lock === lock) {\n return this.salvation;\n } else {\n this.salvation.abort();\n }\n }\n this.lock = lock;\n if (!this.dirty) {\n salvation = $.Deferred().resolveWith(this, null);\n }\n this.saving = true;\n salvation || (salvation = rest[this._id ? 'put' : 'post'].call(this, data));\n this.salvation = salvation;\n salvation.done(this.saved);\n salvation.fail(this.failed);\n salvation.always(function() {\n return this.saving = false;\n });\n salvation.done(doned);\n salvation.fail(failed);\n return salvation;\n },\n saved: function(data) {\n var callback, _i, _len, _ref, _results;\n\n if (this.lock === JSON.stringify(this.json())) {\n this.dirty = false;\n delete this.lock;\n }\n if (data != null) {\n this.assign_attributes(data);\n }\n if (this.after_save) {\n _ref = this.after_save;\n _results = [];\n for (_i = 0, _len = _ref.length; _i < _len; _i++) {\n callback = _ref[_i];\n throw \"Not supported after_save callback: \" + callback;\n }\n return _results;\n }\n },\n failed: function(xhr, error, status) {\n var attribute_name, definition, e, message, messages, payload, _i, _len, _ref;\n\n payload = xhr.responseJSON;\n try {\n payload || (payload = JSON.parse(xhr.responseText));\n } catch (_error) {\n e = _error;\n }\n payload || (payload = xhr.responseText);\n switch (xhr.status) {\n case 0:\n message = status || xhr.statusText;\n switch (message) {\n case 'abort':\n console.info(\"salvation probably aborted\");\n break;\n case 'error':\n console.info(\"server probably unreachable\");\n break;\n default:\n throw new Error('Unhandled status code for xhr');\n }\n break;\n case 422:\n definition = model[this.resource.toString()];\n _ref = payload.errors;\n for (attribute_name in _ref) {\n messages = _ref[attribute_name];\n if (!definition.associations) {\n definition.associations = definition.has_one.concat(definition.has_many.concat(definition.belongs_to));\n }\n if (!(this.hasOwnProperty(attribute_name) || definition.hasOwnProperty(attribute_name) || definition.associations.indexOf(attribute_name) !== -1 || attribute_name === 'base')) {\n message = \"Server returned an validation error message for a attribute that is not defined in your model.\\n\";\n message += \"The attribute was '\" + attribute_name + \"', the model resource was '\" + this.resource + \"'.\\n\";\n message += \"The model definition keys were '\" + (JSON.stringify(Object.keys(definition))) + \"'.\\n\";\n message += \"Please remove server validation, or update your model definition.\";\n throw new TypeError(message);\n }\n for (_i = 0, _len = messages.length; _i < _len; _i++) {\n message = messages[_i];\n this.errors.add(attribute_name, 'server', {\n server_message: message\n });\n }\n }\n break;\n default:\n message = \"Fail in \" + this.resource + \".save:\\n\";\n message += \"Record: \" + this + \"\\n\";\n message += \"Status: \" + status + \" (\" + (payload || xhr).status + \")\\n\";\n message += \"Error : \" + (payload.error || payload.message || payload);\n console.log(message);\n }\n return this.saving = false;\n },\n toString: function() {\n var e, name, property, serialized;\n\n serialized = {};\n serialized[this.resource] = this.json();\n try {\n return JSON.stringify(serialized);\n } catch (_error) {\n e = _error;\n console.warn(\"restfulable.toString: Failed to stringify record: \" + e.message + \". retrying...\");\n for (name in serialized) {\n property = serialized[name];\n if (typeof property === 'object') {\n delete serialized[name];\n }\n }\n return JSON.stringify(serialized);\n }\n },\n json: function(options) {\n var definition, json, method, name, nature, nested, value, _ref, _ref1;\n\n if (options == null) {\n options = {};\n }\n json = {};\n definition = model[this.resource.toString()];\n for (name in this) {\n if (observable.ignores.indexOf(name) !== -1) {\n continue;\n }\n nested = this.nested_attributes.indexOf(name) !== -1;\n if (!nested && (definition.belongs_to.indexOf(name) !== -1 || definition.has_one.indexOf(name) !== -1 || definition.has_many.indexOf(name) !== -1)) {\n continue;\n }\n value = this[name];\n if (value == null) {\n continue;\n }\n nature = type(value);\n if (nature === 'function') {\n continue;\n }\n if (nature === 'object' || nature === 'element') {\n if (nested) {\n if (!value.json) {\n console.warn(\"json: Tryied to serialize nested attribute '\" + name + \"' without serialization method!\");\n continue;\n }\n json[\"\" + name + \"_attributes\"] = value.json(options[name]);\n } else if ((value.toJSON != null) || (value.json != null)) {\n if (value.resource) {\n continue;\n }\n if (value.json != null) {\n json[name] = value.json(options[name]);\n } else {\n json[name] = value.toJSON(options[name]);\n }\n } else {\n continue;\n }\n } else {\n json[name] = value;\n }\n }\n json = observable.unobserve(json);\n _ref1 = (_ref = options.methods) != null ? _ref : {};\n for (name in _ref1) {\n value = _ref1[name];\n method = this[name];\n if (typeof method === 'function') {\n json[name] = method();\n } else {\n json[name] = method;\n }\n }\n delete json.dirty;\n delete json.resource;\n delete json.route;\n delete json.initial_route;\n delete json.after_initialize;\n delete json.before_initialize;\n delete json.parent_resource;\n delete json.nested_attributes;\n delete json.reloading;\n delete json.ready;\n delete json.saving;\n delete json.salvation;\n delete json.sustained;\n delete json.element;\n delete json[\"default\"];\n delete json.lock;\n delete json.validated;\n delete json.validation;\n delete json.errors;\n return json;\n }\n }\n};\n\nrestful.toJSON = restful.json;\n\nmodel = window.model;\n\nrecord = window.record;\n\nmodel.restfulable = true;\n\nrecord.mix(function(recordable) {\n return merge(recordable, restful.record);\n});\n\nmodel.mix(function(modelable) {\n return merge(modelable, restful.model);\n});\n\nmodel.associable && model.associable.mix(function(singular_association, plural_association) {\n plural_association.get = function() {\n if (this.parent != null) {\n this.route || (this.route = \"\" + this.parent.route + \"/\" + this.parent._id + \"/\" + (model.pluralize(this.resource.name)));\n }\n return rest.get.apply(this, arguments);\n };\n return plural_association.post = function() {\n if (this.parent != null) {\n this.route || (this.route = \"\" + this.parent.route + \"/\" + this.parent._id + \"/\" + (model.pluralize(this.resource.name)));\n }\n return rest.post.apply(this, arguments);\n };\n});\n//@ sourceURL=indemma/lib/record/restfulable.js"
276
276
  ));
277
277
  require.register("indemma/lib/record/scopable.js", Function("exports, require, module",
278
278
  "var $, builders, defaults, extend, merge, model, observable, record, rest, scopable, stampit, util,\n __slice = [].slice;\n\nrequire('./restfulable');\n\nrequire('./resource');\n\nstampit = require('../../vendor/stampit');\n\nextend = require('assimilate');\n\nobservable = require('observable').mixin;\n\nmerge = extend.withStrategy('deep');\n\n$ = require('jquery');\n\nrest = require('./rest');\n\nutil = {\n model: {\n map: function(records) {\n var index, record, _i, _len, _results;\n\n _results = [];\n for (index = _i = 0, _len = records.length; _i < _len; index = ++_i) {\n record = records[index];\n _results.push((this.build || this).call(this, record));\n }\n return _results;\n }\n }\n};\n\nscopable = {\n builder: stampit().enclose(function() {\n return stampit.mixIn(function(name, type) {\n var builder;\n\n if ($.type(type) === 'function') {\n this[\"$\" + name] = type() || new type;\n type = $.type(this[\"$\" + name]);\n } else {\n this[\"$\" + name] = defaults[type] || type;\n }\n if ($.type(type) !== 'string') {\n type = $.type(type);\n }\n builder = builders[type];\n if (builder == null) {\n throw \"Unknown scope type: '\" + type + \"', For model with resource: '\" + this.resource + \"'\";\n }\n this.scope.declared.push(name);\n return this[name] = builder({\n name: name\n });\n }, {\n data: {},\n then: [],\n fail: [],\n declared: [],\n fetch: function(data, done, fail) {\n var deferred, scope;\n\n if (typeof data === 'function') {\n done = data;\n data = {};\n }\n scope = extend({}, this.scope.data);\n observable.unobserve(scope);\n if (scope.noned != null) {\n deferred = $.Deferred();\n deferred.resolveWith(this, [[]]);\n } else {\n deferred = rest.get.call(this, extend(scope, data));\n }\n deferred.then(util.model.map).done(this.scope.then.concat([done])).fail(this.scope.fail.concat([fail]));\n this.scope.clear();\n return deferred;\n },\n clear: function() {\n this.data = {};\n return this.callbacks = [];\n }\n });\n }),\n base: stampit().state({\n name: 'unamed_scope'\n }),\n record: {\n failed: function(xhr, error, status) {\n var e, message, payload;\n\n payload = xhr.responseJSON;\n try {\n payload || (payload = JSON.parse(xhr.responseText));\n } catch (_error) {\n e = _error;\n }\n payload || (payload = xhr.responseText);\n switch (xhr.status) {\n case 422:\n this.valid = false;\n return this.errors = payload.errors;\n default:\n message = \"Fail in \" + this.resource + \".save:\\n\";\n message += \"Record: \" + this + \"\\n\";\n message += \"Status: \" + status + \" (\" + (payload.status || xhr.status) + \")\\n\";\n message += \"Error : \" + (payload.error || payload.message || payload);\n }\n return console.error(message);\n }\n },\n model: {\n none: function() {\n this.scope.data.noned = true;\n return this;\n },\n fetch: function(data, done, fail) {\n if (typeof data === 'function') {\n done = data;\n data = null;\n }\n return this.scope.fetch.call(this, data, done, fail);\n },\n forward_scopes_to_associations: function() {\n var associated_factory, associated_resource, association, association_name, factory, scope, _i, _j, _len, _len1, _ref, _ref1;\n\n factory = model[this.resource.name];\n _ref = factory.has_many;\n for (_i = 0, _len = _ref.length; _i < _len; _i++) {\n association_name = _ref[_i];\n associated_resource = model.singularize(association_name);\n associated_factory = model[associated_resource];\n if (!model[associated_resource]) {\n console.warn(\"Associated factory not found for associated resource: \" + associated_resource);\n continue;\n }\n association = this[association_name];\n association.scope = scopable.builder(association);\n _ref1 = associated_factory.scope.declared;\n for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) {\n scope = _ref1[_j];\n association.scope(scope, associated_factory[\"$\" + scope]);\n }\n }\n return true;\n }\n },\n after_mix: function() {\n var name, property, type, _results;\n\n this.scope = scopable.builder(this);\n _results = [];\n for (property in this) {\n type = this[property];\n if (property.charAt(0) === '$') {\n name = property.substring(1);\n _results.push(this.scope(name, type));\n } else {\n _results.push(void 0);\n }\n }\n return _results;\n }\n};\n\nbuilders = {\n string: stampit().enclose(function() {\n var base;\n\n base = scopable.base(this);\n return stampit.mixIn(function() {\n var callbacks, value, _base, _name;\n\n value = arguments[0], callbacks = 2 <= arguments.length ? __slice.call(arguments, 1) : [];\n callbacks.length && (this.scope.then = this.scope.then.concat(callbacks));\n (_base = this.scope.data)[_name = base.name] || (_base[_name] = value != null ? value : this[\"$\" + base.name]);\n return this;\n });\n }),\n boolean: stampit().enclose(function() {\n var base;\n\n base = scopable.base(this);\n return stampit.mixIn(function() {\n var callbacks, value, _base, _name;\n\n value = arguments[0], callbacks = 2 <= arguments.length ? __slice.call(arguments, 1) : [];\n callbacks.length && (this.scope.then = this.scope.then.concat(callbacks));\n (_base = this.scope.data)[_name = base.name] || (_base[_name] = value != null ? value : this[\"$\" + base.name]);\n return this;\n });\n }),\n array: stampit().enclose(function() {\n var base;\n\n base = scopable.base(this);\n return stampit.mixIn(function() {\n var values, _base, _name;\n\n values = 1 <= arguments.length ? __slice.call(arguments, 0) : [];\n (_base = this.scope.data)[_name = base.name] || (_base[_name] = values != null ? values : this[\"$\" + base.name]);\n return this;\n });\n })\n};\n\ndefaults = {\n boolean: true,\n array: []\n};\n\nmodel = window.model;\n\nrecord = window.record;\n\nmodel.scopable = true;\n\nmodel.mix(function(modelable) {\n merge(modelable, scopable.model);\n return modelable.after_mix.push(scopable.after_mix);\n});\n\nif (model.associable) {\n model.mix(function(modelable) {\n return modelable.record.after_initialize.push(function() {\n return scopable.model.forward_scopes_to_associations.call(this);\n });\n });\n model.associable.mix(function(singular_association, plural_association) {\n plural_association.every = plural_association.reload = function(data, done, fail) {\n var promises, reload;\n\n if (this.parent != null) {\n this.route || (this.route = \"\" + this.parent.route + \"/\" + this.parent._id + \"/\" + (model.pluralize(this.resource)));\n }\n promises = [];\n if (typeof data === 'function') {\n done = data;\n data = void 0;\n }\n promises.push(this.scope.fetch.call(this, data, null, scopable.record.failed));\n reload = $.when.apply(jQuery, promises);\n reload.done(function(records, status) {\n var association_name, create, index, singular_resource, target, _i, _j, _k, _len, _len1, _len2, _ref;\n\n if (!records.length) {\n if (this.length) {\n Array.prototype.splice.call(this, 0);\n }\n return true;\n }\n singular_resource = model.singularize(this.resource);\n for (_i = 0, _len = records.length; _i < _len; _i++) {\n record = records[_i];\n _ref = model[singular_resource].has_many;\n for (_j = 0, _len1 = _ref.length; _j < _len1; _j++) {\n association_name = _ref[_j];\n record[\"\" + association_name + \"_attributes\"] = record[association_name];\n delete record[association_name];\n }\n }\n create = [];\n for (index = _k = 0, _len2 = records.length; _k < _len2; index = ++_k) {\n record = records[index];\n if (target = this.find(record._id)) {\n target.assign_attributes(record);\n } else {\n create.push(record);\n }\n }\n this.add.apply(this, create);\n records.splice(0);\n return records.push.apply(records, this);\n });\n reload.done(done);\n reload.fail(fail);\n return reload;\n };\n return plural_association.each = function(callback) {\n var _this = this;\n\n if (this.parent != null) {\n this.route || (this.route = \"\" + this.parent.route + \"/\" + this.parent._id + \"/\" + (model.pluralize(this.resource)));\n }\n return this.get().done(function(records) {\n var _i, _len, _results;\n\n _results = [];\n for (_i = 0, _len = _this.length; _i < _len; _i++) {\n record = _this[_i];\n _results.push(callback(record));\n }\n return _results;\n });\n };\n });\n}\n//@ sourceURL=indemma/lib/record/scopable.js"
@@ -305,7 +305,7 @@ require.register("indemma/lib/record/validations/cpf.js", Function("exports, req
305
305
  "var composed, cpfable, stampit;\n\nstampit = require('../../../vendor/stampit');\n\ncpfable = stampit({\n validate_format: function(value) {\n var c, d1, dv, i, v, _i, _j;\n\n value = value.replace(/[\\.\\-]/g, \"\");\n if (value.length < 11) {\n return false;\n }\n if (value.match(/^(0+|1+|2+|3+|4+|5+|6+|7+|8+|9+)$/)) {\n return false;\n }\n c = value.substr(0, 9);\n dv = value.substr(9, 2);\n d1 = 0;\n v = false;\n i = 0;\n for (i = _i = 0; _i <= 9; i = ++_i) {\n d1 += c.charAt(i) * (10 - i);\n }\n if (d1 === 0) {\n return false;\n }\n d1 = 11 - (d1 % 11);\n if (d1 > 9) {\n d1 = 0;\n }\n if (+dv.charAt(0) !== d1) {\n return false;\n }\n d1 *= 2;\n for (i = _j = 0; _j <= 9; i = ++_j) {\n d1 += c.charAt(i) * (11 - i);\n }\n d1 = 11 - (d1 % 11);\n if (d1 > 9) {\n d1 = 0;\n }\n if (+dv.charAt(1) !== d1) {\n return false;\n }\n return true;\n },\n validate_each: function(record, attribute, value) {\n if (value && !this.validate_format(value)) {\n return record.errors.add(attribute, 'cpf', this.options);\n }\n }\n});\n\ncomposed = stampit.compose(require('./validatorable'), cpfable);\n\ncomposed.definition_key = 'validates_cpf_format';\n\nmodule.exports = composed;\n//@ sourceURL=indemma/lib/record/validations/cpf.js"
306
306
  ));
307
307
  require.register("indemma/lib/record/validatable.js", Function("exports, require, module",
308
- "var errorsable, extensions, initializers, manager, messages, observable, root, stampit, type;\n\nrequire('./translationable');\n\nroot = typeof exports !== \"undefined\" && exports !== null ? exports : this;\n\nstampit = require('../../vendor/stampit');\n\nobservable = require('observable').mixin;\n\ntype = require('type');\n\nmessages = {\n blank: function(attribute_name) {\n attribute_name = this.human_attribute_name(attribute_name);\n return \"O campo \" + attribute_name + \" não pode ficar em branco.\";\n },\n cpf: function(attribute_name) {\n attribute_name = this.human_attribute_name(attribute_name);\n return \"O campo \" + attribute_name + \" não está válido.\";\n },\n confirmation: function(attribute_name) {\n var confirmation_attribute_name;\n\n confirmation_attribute_name = this.human_attribute_name(attribute_name);\n attribute_name = this.human_attribute_name(attribute_name.replace('_confirmation', ''));\n return \"O campo \" + attribute_name + \" não está de acordo com o campo \" + confirmation_attribute_name + \".\";\n },\n associated: function(attribute_name) {\n attribute_name = this.human_attribute_name(attribute_name);\n return \"O registro associado \" + attribute_name + \" não é válido.\";\n },\n server: function(attribute_name, options) {\n if (attribute_name === 'base') {\n return options.server_message;\n } else {\n attribute_name = this.human_attribute_name(attribute_name);\n return \"\" + attribute_name + \" \" + options.server_message + \".\";\n }\n },\n type: function(attribute_name, options) {\n attribute_name = this.human_attribute_name(attribute_name);\n return \"O campo \" + attribute_name + \" não está válido.\";\n }\n};\n\nerrorsable = stampit({\n add: function(attribute_name, message_key, options) {\n var translator;\n\n this.push([attribute_name, message_key, options]);\n this.messages[attribute_name] = '';\n translator = messages[message_key];\n if (translator != null) {\n return this.messages[attribute_name] += translator.call(this.model, attribute_name, options);\n } else {\n return this.messages[attribute_name] += message_key;\n }\n },\n clear: function() {\n var attribute_name, _results;\n\n if (this.length) {\n this.length = 0;\n _results = [];\n for (attribute_name in this.messages) {\n _results.push(this.messages[attribute_name] = null);\n }\n return _results;\n }\n },\n push: Array.prototype.push,\n splice: Array.prototype.splice,\n indexOf: Array.prototype.indexOf\n}, {\n model: null,\n messages: null,\n length: 0\n}, function() {\n this.messages = {};\n return this;\n});\n\ninitializers = {\n define_triggers: function() {\n this.errors = errorsable({\n model: model[this.resource]\n });\n this.before('save', function() {\n if (this.save) {\n return this.validate();\n }\n });\n this.validated = false;\n this.subscribe('dirty', function(value) {\n return value && (this.validated = false);\n });\n return Object.defineProperty(this, 'valid', {\n get: function() {\n this.validate();\n if (this.validation.state() === 'resolved') {\n return !this.errors.length;\n } else {\n return null;\n }\n },\n set: function() {\n throw new TypeError(\"You can't set the value for the valid property.\");\n },\n enumerable: false\n });\n },\n create_validators: function(definitions) {\n var definition, name, validator, validator_options, _ref, _results;\n\n this.validators = [];\n _ref = manager.validators;\n _results = [];\n for (name in _ref) {\n validator = _ref[name];\n definition = definitions[validator.definition_key];\n if (definition) {\n if (type(definition) !== 'array') {\n definition = [definition];\n }\n _results.push((function() {\n var _i, _len, _results1;\n\n _results1 = [];\n for (_i = 0, _len = definition.length; _i < _len; _i++) {\n validator_options = definition[_i];\n if (type(validator_options) !== 'object') {\n validator_options = {\n attribute_name: validator_options\n };\n }\n validator_options.model = this;\n this.validators.push(validator(validator_options));\n _results1.push(delete definitions[validator.definition_key]);\n }\n return _results1;\n }).call(this));\n } else {\n _results.push(void 0);\n }\n }\n return _results;\n }\n};\n\nextensions = {\n model: {\n validators: null\n },\n record: {\n validate_attribute: function(attribute, doned, failed) {\n var results, validation, validator, _i, _len, _ref;\n\n this.errors.messages[attribute] = null;\n results = [this, attribute];\n _ref = model[this.resource.toString()].validators;\n for (_i = 0, _len = _ref.length; _i < _len; _i++) {\n validator = _ref[_i];\n if (validator.attribute_name === attribute) {\n results.push(validator.validate_each(this, validator.attribute_name, this[validator.attribute_name]));\n }\n }\n validation = jQuery.when.apply(jQuery, results);\n validation.done(doned);\n validation.fail(failed);\n return validation;\n },\n validate: function(doned, failed) {\n var results, validator, _i, _len, _ref;\n\n if (this.validated) {\n return this.validation;\n }\n this.errors.clear();\n results = [this];\n _ref = model[this.resource.toString()].validators;\n for (_i = 0, _len = _ref.length; _i < _len; _i++) {\n validator = _ref[_i];\n results.push(validator.validate_each(this, validator.attribute_name, this[validator.attribute_name]));\n }\n this.validation = jQuery.when.apply(jQuery, results);\n this.validation.done(doned);\n this.validation.fail(failed);\n return this.validation.done(function(record) {\n var old_dirty;\n\n old_dirty = record.dirty;\n record.dirty = null;\n record.validated || (record.validated = true);\n record.observed.dirty = old_dirty;\n return record;\n });\n }\n }\n};\n\nmanager = {\n validators: {}\n};\n\nmodel.mix(function(modelable) {\n jQuery.extend(modelable, extensions.model);\n jQuery.extend(modelable.record, extensions.record);\n modelable.after_mix.unshift(initializers.create_validators);\n modelable.record.after_initialize.push(initializers.define_triggers);\n return model.validators = manager.validators;\n});\n\nmanager.validators.confirmation = require('./validations/confirmation');\n\nmanager.validators.associated = require('./validations/associated');\n\nmanager.validators.presence = require('./validations/presence');\n\nmanager.validators.remote = require('./validations/remote');\n\nmanager.validators.type = require('./validations/type');\n\nmanager.validators.cpf = require('./validations/cpf');\n//@ sourceURL=indemma/lib/record/validatable.js"
308
+ "var errorsable, extensions, initializers, manager, messages, observable, root, stampit, type;\n\nrequire('./translationable');\n\nroot = typeof exports !== \"undefined\" && exports !== null ? exports : this;\n\nstampit = require('../../vendor/stampit');\n\nobservable = require('observable').mixin;\n\ntype = require('type');\n\nmessages = {\n blank: function(attribute_name) {\n attribute_name = this.human_attribute_name(attribute_name);\n return \"O campo \" + attribute_name + \" não pode ficar em branco.\";\n },\n cpf: function(attribute_name) {\n attribute_name = this.human_attribute_name(attribute_name);\n return \"O campo \" + attribute_name + \" não está válido.\";\n },\n confirmation: function(attribute_name) {\n var confirmation_attribute_name;\n\n confirmation_attribute_name = this.human_attribute_name(attribute_name);\n attribute_name = this.human_attribute_name(attribute_name.replace('_confirmation', ''));\n return \"O campo \" + attribute_name + \" não está de acordo com o campo \" + confirmation_attribute_name + \".\";\n },\n associated: function(attribute_name) {\n attribute_name = this.human_attribute_name(attribute_name);\n return \"O registro associado \" + attribute_name + \" não é válido.\";\n },\n server: function(attribute_name, options) {\n if (attribute_name === 'base') {\n return options.server_message;\n } else {\n attribute_name = this.human_attribute_name(attribute_name);\n return \"\" + attribute_name + \" \" + options.server_message + \".\";\n }\n },\n type: function(attribute_name, options) {\n attribute_name = this.human_attribute_name(attribute_name);\n return \"O campo \" + attribute_name + \" não está válido.\";\n }\n};\n\nerrorsable = stampit({\n add: function(attribute_name, message_key, options) {\n var translator;\n\n this.push([attribute_name, message_key, options]);\n this.messages[attribute_name] = '';\n translator = messages[message_key];\n if (translator != null) {\n return this.messages[attribute_name] += translator.call(this.model, attribute_name, options);\n } else {\n return this.messages[attribute_name] += message_key;\n }\n },\n clear: function() {\n var attribute_name, _results;\n\n if (this.length) {\n this.length = 0;\n _results = [];\n for (attribute_name in this.messages) {\n _results.push(this.messages[attribute_name] = null);\n }\n return _results;\n }\n },\n push: Array.prototype.push,\n splice: Array.prototype.splice,\n indexOf: Array.prototype.indexOf\n}, {\n model: null,\n messages: null,\n length: 0\n}, function() {\n this.messages = {};\n return this;\n});\n\ninitializers = {\n define_triggers: function() {\n this.errors = errorsable({\n model: model[this.resource]\n });\n this.before('save', function() {\n if (this.save) {\n return this.validate();\n }\n });\n this.validated = false;\n this.subscribe('dirty', function(value) {\n return value && (this.validated = false);\n });\n return Object.defineProperty(this, 'valid', {\n get: function() {\n this.validate();\n if (this.validation.state() === 'resolved') {\n return !this.errors.length;\n } else {\n return null;\n }\n },\n set: function() {\n throw new TypeError(\"You can't set the value for the valid property.\");\n },\n enumerable: false\n });\n },\n create_validators: function(definitions) {\n var definition, name, validator, validator_options, _ref, _results;\n\n this.validators = [];\n _ref = manager.validators;\n _results = [];\n for (name in _ref) {\n validator = _ref[name];\n definition = definitions[validator.definition_key];\n if (definition) {\n if (type(definition) !== 'array') {\n definition = [definition];\n }\n _results.push((function() {\n var _i, _len, _results1;\n\n _results1 = [];\n for (_i = 0, _len = definition.length; _i < _len; _i++) {\n validator_options = definition[_i];\n if (type(validator_options) !== 'object') {\n validator_options = {\n attribute_name: validator_options\n };\n }\n validator_options.model = this;\n this.validators.push(validator(validator_options));\n _results1.push(delete definitions[validator.definition_key]);\n }\n return _results1;\n }).call(this));\n } else {\n _results.push(void 0);\n }\n }\n return _results;\n }\n};\n\nextensions = {\n model: {\n validators: null\n },\n record: {\n validate_attribute: function(attribute, doned, failed) {\n var results, validation, validator, _i, _len, _ref;\n\n this.errors.messages[attribute] = null;\n results = [this, attribute];\n _ref = model[this.resource.toString()].validators;\n for (_i = 0, _len = _ref.length; _i < _len; _i++) {\n validator = _ref[_i];\n if (validator.attribute_name === attribute) {\n results.push(validator.validate_each(this, validator.attribute_name, this[validator.attribute_name]));\n }\n }\n validation = jQuery.when.apply(jQuery, results);\n validation.done(doned);\n validation.fail(failed);\n return validation;\n },\n validate: function(doned, failed) {\n var results, validator, _i, _len, _ref;\n\n if (this.validated && !this.dirty) {\n return this.validation;\n }\n this.errors.clear();\n results = [this];\n _ref = model[this.resource.toString()].validators;\n for (_i = 0, _len = _ref.length; _i < _len; _i++) {\n validator = _ref[_i];\n results.push(validator.validate_each(this, validator.attribute_name, this[validator.attribute_name]));\n }\n this.validation = jQuery.when.apply(jQuery, results);\n this.validation.done(doned);\n this.validation.fail(failed);\n return this.validation.done(function(record) {\n var old_dirty;\n\n old_dirty = record.dirty;\n record.dirty = null;\n record.validated || (record.validated = true);\n record.dirty = old_dirty;\n return record;\n });\n }\n }\n};\n\nmanager = {\n validators: {}\n};\n\nmodel.mix(function(modelable) {\n jQuery.extend(modelable, extensions.model);\n jQuery.extend(modelable.record, extensions.record);\n modelable.after_mix.unshift(initializers.create_validators);\n modelable.record.after_initialize.push(initializers.define_triggers);\n return model.validators = manager.validators;\n});\n\nmanager.validators.confirmation = require('./validations/confirmation');\n\nmanager.validators.associated = require('./validations/associated');\n\nmanager.validators.presence = require('./validations/presence');\n\nmanager.validators.remote = require('./validations/remote');\n\nmanager.validators.type = require('./validations/type');\n\nmanager.validators.cpf = require('./validations/cpf');\n//@ sourceURL=indemma/lib/record/validatable.js"
309
309
  ));
310
310
  require.register("indemma/lib/extensions/rivets.js", Function("exports, require, module",
311
311
  "var root;\n\nroot = typeof exports !== \"undefined\" && exports !== null ? exports : this;\n\nmodel.rivets = function() {\n var model_extensions;\n\n model_extensions = {\n record: {\n tie: function(element) {\n var lasso;\n\n lasso = {};\n lasso[this.resource] = this;\n return rivets.bind(element, lasso);\n }\n },\n preloadData: true\n };\n return model.mix(function(modelable) {\n return $.extend(true, modelable, model_extensions);\n });\n};\n//@ sourceURL=indemma/lib/extensions/rivets.js"
@@ -20879,7 +20879,7 @@ restful = {
20879
20879
  data = {};
20880
20880
  }
20881
20881
  old_route = this.route;
20882
- default_route = '/';
20882
+ default_route = '';
20883
20883
  if (this.resource.scope != null) {
20884
20884
  default_route += this.resource.scope + '/';
20885
20885
  }
@@ -20944,9 +20944,8 @@ restful = {
20944
20944
  _ref = model[this.resource.toString()].has_many;
20945
20945
  for (_i = 0, _len = _ref.length; _i < _len; _i++) {
20946
20946
  association_name = _ref[_i];
20947
- associations_attributes = attributes[association_name + "_attributes"] || attributes[association_name];
20947
+ associations_attributes = attributes[association_name];
20948
20948
  delete attributes[association_name];
20949
- delete attributes[association_name + '_attributes'];
20950
20949
  association = this[association_name];
20951
20950
  if (association == null) {
20952
20951
  message = "Association '" + association_name + "' not found. \n";
@@ -22039,7 +22038,7 @@ extensions = {
22039
22038
  validate: function(doned, failed) {
22040
22039
  var results, validator, _i, _len, _ref;
22041
22040
 
22042
- if (this.validated) {
22041
+ if (this.validated && !this.dirty) {
22043
22042
  return this.validation;
22044
22043
  }
22045
22044
  this.errors.clear();
@@ -22058,7 +22057,7 @@ extensions = {
22058
22057
  old_dirty = record.dirty;
22059
22058
  record.dirty = null;
22060
22059
  record.validated || (record.validated = true);
22061
- record.observed.dirty = old_dirty;
22060
+ record.dirty = old_dirty;
22062
22061
  return record;
22063
22062
  });
22064
22063
  }
@@ -272,7 +272,7 @@ require.register("indemma/lib/record/rest.js", Function("exports, require, modul
272
272
  "var $, data_for, request;\n\n$ = require('jquery');\n\nmodule.exports = {\n get: function(data) {\n return request.call(this, 'get', (this._id ? \"\" + this.route + \"/\" + this._id : this.route), data);\n },\n put: function(data) {\n return request.call(this, 'put', (this._id ? \"\" + this.route + \"/\" + this._id : this.route), data);\n },\n post: function(data) {\n return request.call(this, 'post', this.route, data);\n },\n \"delete\": function(data) {\n return request.call(this, 'delete', (this._id ? \"\" + this.route + \"/\" + this._id : this.route), data);\n }\n};\n\ndata_for = function(data) {\n var param_name;\n\n param_name = this.resource.param_name || this.resource.toString();\n if (!data && this.json) {\n data = {};\n data[param_name] = this.json();\n }\n if (data && data[param_name]) {\n delete data[param_name]['id'];\n delete data[param_name]['_id'];\n }\n return data;\n};\n\nrequest = function(method, url, data) {\n data = data_for.call(this, data);\n return $.ajax({\n url: url,\n data: data,\n type: method,\n dataType: 'json',\n context: this\n });\n};\n//@ sourceURL=indemma/lib/record/rest.js"
273
273
  ));
274
274
  require.register("indemma/lib/record/restfulable.js", Function("exports, require, module",
275
- "var $, merge, model, observable, record, rest, restful, root, type, util,\n __slice = [].slice;\n\nmerge = require('assimilate').withStrategy('deep');\n\ntype = require('type');\n\nobservable = require('observable').mixin;\n\n$ = require('jquery');\n\nrest = require('./rest.js');\n\nroot = typeof exports !== \"undefined\" && exports !== null ? exports : this;\n\nutil = {\n model: {\n map: function(records) {\n var record, _i, _len, _results;\n\n _results = [];\n for (_i = 0, _len = records.length; _i < _len; _i++) {\n record = records[_i];\n _results.push(this(record));\n }\n return _results;\n }\n }\n};\n\nrestful = {\n model: {\n create: function() {\n var attributes, callback, params, record, savings, _i, _j, _len;\n\n params = 2 <= arguments.length ? __slice.call(arguments, 0, _i = arguments.length - 1) : (_i = 0, []), callback = arguments[_i++];\n if (!arguments.length) {\n throw new TypeError(\"No arguments provided for \" + this.resource + \".create\");\n }\n if (typeof callback !== 'function') {\n params.push(callback);\n callback = void 0;\n }\n if (!params.length) {\n params.unshift({});\n }\n savings = [];\n for (_j = 0, _len = params.length; _j < _len; _j++) {\n attributes = params[_j];\n record = this(attributes);\n record.dirty = true;\n savings.push(record.save(callback));\n }\n return $.when.apply($, savings);\n },\n every: function(conditions, doned, failed) {\n if (conditions == null) {\n conditions = {};\n }\n if (typeof conditions === 'function') {\n doned = conditions;\n conditions = {};\n }\n return $.when(rest.get.call(this, conditions)).then(util.model.map).done(doned).fail(failed);\n },\n first: function(conditions, callback) {\n var namespaced;\n\n if (conditions == null) {\n conditions = {};\n }\n if (typeof conditions === 'function') {\n callback = conditions;\n conditions = {};\n }\n namespaced = conditions[this.resource] || {};\n namespaced.limit = 1;\n namespaced.order = 'desc';\n return this.every(conditions, callback);\n },\n get: function(action, data) {\n var default_route, old_route, payload, promise, resource;\n\n if (data == null) {\n data = {};\n }\n old_route = this.route;\n default_route = '/';\n if (this.resource.scope != null) {\n default_route += this.resource.scope + '/';\n }\n default_route += this.resource.singular ? this.resource.name : model.pluralize(this.resource.name);\n if (default_route !== this.route) {\n this.route = default_route;\n }\n if (action) {\n Object.defineProperty(this, 'route', {\n value: \"\" + default_route + \"/\" + action,\n configurable: true\n });\n }\n resource = data.resource;\n if (data && data.json) {\n data = data.json();\n }\n if (resource != null) {\n payload = data;\n data = {};\n data[resource] = payload;\n }\n promise = rest.get.call(this, data);\n Object.defineProperty(this, 'route', {\n value: old_route,\n configurable: true\n });\n return promise;\n },\n put: rest.put,\n \"delete\": rest[\"delete\"]\n },\n record: {\n ready: function(callback) {\n return callback.call(this);\n },\n reload: function() {\n var data, param, params, promise, _i, _len;\n\n params = 1 <= arguments.length ? __slice.call(arguments, 0) : [];\n data = params.pop();\n if (type(data) !== 'object') {\n params.push(data);\n }\n promise = rest.get.call(this, data || {});\n promise.done(this.assign_attributes);\n promise.fail(this.failed);\n this.reloading = promise;\n this.ready = function() {\n console.warn(\"resource.ready was deprecated, please use resource.reloading.done\");\n return promise.done.apply(promise, arguments);\n };\n for (_i = 0, _len = params.length; _i < _len; _i++) {\n param = params[_i];\n promise.done(param);\n }\n return promise;\n },\n assign_attributes: function(attributes) {\n var association, association_attributes, association_name, associations_attributes, attribute, message, name, singular_resource, _i, _j, _k, _l, _len, _len1, _len2, _len3, _len4, _m, _ref, _ref1, _ref2, _ref3, _ref4, _ref5, _results;\n\n _ref = model[this.resource.toString()].has_many;\n for (_i = 0, _len = _ref.length; _i < _len; _i++) {\n association_name = _ref[_i];\n associations_attributes = attributes[association_name + \"_attributes\"] || attributes[association_name];\n delete attributes[association_name];\n delete attributes[association_name + '_attributes'];\n association = this[association_name];\n if (association == null) {\n message = \"Association '\" + association_name + \"' not found. \\n\";\n message += \"For record with resource \" + this.resource + \". \\n\";\n message += \"Probably defined on server side but not on client side.\\n\";\n message += \"Skipping association assignment!\";\n console.warn(message);\n continue;\n }\n if (association.length) {\n Array.prototype.splice.call(association, 0);\n }\n if (!((associations_attributes != null) && associations_attributes.length)) {\n continue;\n }\n singular_resource = model.singularize(association_name);\n for (_j = 0, _len1 = associations_attributes.length; _j < _len1; _j++) {\n association_attributes = associations_attributes[_j];\n _ref1 = model[singular_resource].has_many;\n for (_k = 0, _len2 = _ref1.length; _k < _len2; _k++) {\n association_name = _ref1[_k];\n association_attributes[\"\" + association_name + \"_attributes\"] = association_attributes[association_name];\n delete association_attributes[association_name];\n }\n }\n association.add.apply(association, associations_attributes);\n }\n _ref2 = model[this.resource.toString()].has_one;\n for (_l = 0, _len3 = _ref2.length; _l < _len3; _l++) {\n association_name = _ref2[_l];\n association_attributes = attributes[association_name];\n delete attributes[association_name];\n delete attributes[association_name + \"_attributes\"];\n if (association_attributes) {\n this[association_name] = this[\"build_\" + association_name](association_attributes);\n }\n }\n _ref3 = model[this.resource.toString()].belongs_to;\n for (_m = 0, _len4 = _ref3.length; _m < _len4; _m++) {\n association_name = _ref3[_m];\n association_attributes = (_ref4 = (_ref5 = attributes[association_name]) != null ? typeof _ref5.json === \"function\" ? _ref5.json() : void 0 : void 0) != null ? _ref4 : attributes[association_name];\n delete attributes[association_name];\n delete attributes[association_name + \"_attributes\"];\n if (association_attributes) {\n this[association_name] = this[\"build_\" + association_name](association_attributes);\n }\n }\n _results = [];\n for (name in attributes) {\n attribute = attributes[name];\n if (attribute !== this[name]) {\n if (type(attribute) === 'object') {\n if (JSON.stringify(attribute) !== JSON.stringify(this[name])) {\n _results.push(this[name] = attributes[name]);\n } else {\n _results.push(void 0);\n }\n } else {\n _results.push(this[name] = attributes[name]);\n }\n }\n }\n return _results;\n },\n destroy: function(doned, failed, data) {\n var promise;\n\n if (!((this.id != null) || (this._id != null))) {\n throw new Error('Can\\'t delete record without id!');\n }\n promise = rest[\"delete\"].call(this, data);\n promise.done(this.destroyed);\n promise.fail(this.failed);\n promise.done(doned);\n promise.fail(failed);\n return promise;\n },\n saving: false,\n salvation: null,\n save: function(doned, failed, data) {\n var lock, salvation;\n\n lock = JSON.stringify(this.json());\n if (this.saving) {\n if (this.lock === lock) {\n return this.salvation;\n } else {\n this.salvation.abort();\n }\n }\n this.lock = lock;\n if (!this.dirty) {\n salvation = $.Deferred().resolveWith(this, null);\n }\n this.saving = true;\n salvation || (salvation = rest[this._id ? 'put' : 'post'].call(this, data));\n this.salvation = salvation;\n salvation.done(this.saved);\n salvation.fail(this.failed);\n salvation.always(function() {\n return this.saving = false;\n });\n salvation.done(doned);\n salvation.fail(failed);\n return salvation;\n },\n saved: function(data) {\n var callback, _i, _len, _ref, _results;\n\n if (this.lock === JSON.stringify(this.json())) {\n this.dirty = false;\n delete this.lock;\n }\n if (data != null) {\n this.assign_attributes(data);\n }\n if (this.after_save) {\n _ref = this.after_save;\n _results = [];\n for (_i = 0, _len = _ref.length; _i < _len; _i++) {\n callback = _ref[_i];\n throw \"Not supported after_save callback: \" + callback;\n }\n return _results;\n }\n },\n failed: function(xhr, error, status) {\n var attribute_name, definition, e, message, messages, payload, _i, _len, _ref;\n\n payload = xhr.responseJSON;\n try {\n payload || (payload = JSON.parse(xhr.responseText));\n } catch (_error) {\n e = _error;\n }\n payload || (payload = xhr.responseText);\n switch (xhr.status) {\n case 0:\n message = status || xhr.statusText;\n switch (message) {\n case 'abort':\n console.info(\"salvation probably aborted\");\n break;\n case 'error':\n console.info(\"server probably unreachable\");\n break;\n default:\n throw new Error('Unhandled status code for xhr');\n }\n break;\n case 422:\n definition = model[this.resource.toString()];\n _ref = payload.errors;\n for (attribute_name in _ref) {\n messages = _ref[attribute_name];\n if (!definition.associations) {\n definition.associations = definition.has_one.concat(definition.has_many.concat(definition.belongs_to));\n }\n if (!(this.hasOwnProperty(attribute_name) || definition.hasOwnProperty(attribute_name) || definition.associations.indexOf(attribute_name) !== -1 || attribute_name === 'base')) {\n message = \"Server returned an validation error message for a attribute that is not defined in your model.\\n\";\n message += \"The attribute was '\" + attribute_name + \"', the model resource was '\" + this.resource + \"'.\\n\";\n message += \"The model definition keys were '\" + (JSON.stringify(Object.keys(definition))) + \"'.\\n\";\n message += \"Please remove server validation, or update your model definition.\";\n throw new TypeError(message);\n }\n for (_i = 0, _len = messages.length; _i < _len; _i++) {\n message = messages[_i];\n this.errors.add(attribute_name, 'server', {\n server_message: message\n });\n }\n }\n break;\n default:\n message = \"Fail in \" + this.resource + \".save:\\n\";\n message += \"Record: \" + this + \"\\n\";\n message += \"Status: \" + status + \" (\" + (payload || xhr).status + \")\\n\";\n message += \"Error : \" + (payload.error || payload.message || payload);\n console.log(message);\n }\n return this.saving = false;\n },\n toString: function() {\n var e, name, property, serialized;\n\n serialized = {};\n serialized[this.resource] = this.json();\n try {\n return JSON.stringify(serialized);\n } catch (_error) {\n e = _error;\n console.warn(\"restfulable.toString: Failed to stringify record: \" + e.message + \". retrying...\");\n for (name in serialized) {\n property = serialized[name];\n if (typeof property === 'object') {\n delete serialized[name];\n }\n }\n return JSON.stringify(serialized);\n }\n },\n json: function(options) {\n var definition, json, method, name, nature, nested, value, _ref, _ref1;\n\n if (options == null) {\n options = {};\n }\n json = {};\n definition = model[this.resource.toString()];\n for (name in this) {\n if (observable.ignores.indexOf(name) !== -1) {\n continue;\n }\n nested = this.nested_attributes.indexOf(name) !== -1;\n if (!nested && (definition.belongs_to.indexOf(name) !== -1 || definition.has_one.indexOf(name) !== -1 || definition.has_many.indexOf(name) !== -1)) {\n continue;\n }\n value = this[name];\n if (value == null) {\n continue;\n }\n nature = type(value);\n if (nature === 'function') {\n continue;\n }\n if (nature === 'object' || nature === 'element') {\n if (nested) {\n if (!value.json) {\n console.warn(\"json: Tryied to serialize nested attribute '\" + name + \"' without serialization method!\");\n continue;\n }\n json[\"\" + name + \"_attributes\"] = value.json(options[name]);\n } else if ((value.toJSON != null) || (value.json != null)) {\n if (value.resource) {\n continue;\n }\n if (value.json != null) {\n json[name] = value.json(options[name]);\n } else {\n json[name] = value.toJSON(options[name]);\n }\n } else {\n continue;\n }\n } else {\n json[name] = value;\n }\n }\n json = observable.unobserve(json);\n _ref1 = (_ref = options.methods) != null ? _ref : {};\n for (name in _ref1) {\n value = _ref1[name];\n method = this[name];\n if (typeof method === 'function') {\n json[name] = method();\n } else {\n json[name] = method;\n }\n }\n delete json.dirty;\n delete json.resource;\n delete json.route;\n delete json.initial_route;\n delete json.after_initialize;\n delete json.before_initialize;\n delete json.parent_resource;\n delete json.nested_attributes;\n delete json.reloading;\n delete json.ready;\n delete json.saving;\n delete json.salvation;\n delete json.sustained;\n delete json.element;\n delete json[\"default\"];\n delete json.lock;\n delete json.validated;\n delete json.validation;\n delete json.errors;\n return json;\n }\n }\n};\n\nrestful.toJSON = restful.json;\n\nmodel = window.model;\n\nrecord = window.record;\n\nmodel.restfulable = true;\n\nrecord.mix(function(recordable) {\n return merge(recordable, restful.record);\n});\n\nmodel.mix(function(modelable) {\n return merge(modelable, restful.model);\n});\n\nmodel.associable && model.associable.mix(function(singular_association, plural_association) {\n plural_association.get = function() {\n if (this.parent != null) {\n this.route || (this.route = \"\" + this.parent.route + \"/\" + this.parent._id + \"/\" + (model.pluralize(this.resource.name)));\n }\n return rest.get.apply(this, arguments);\n };\n return plural_association.post = function() {\n if (this.parent != null) {\n this.route || (this.route = \"\" + this.parent.route + \"/\" + this.parent._id + \"/\" + (model.pluralize(this.resource.name)));\n }\n return rest.post.apply(this, arguments);\n };\n});\n//@ sourceURL=indemma/lib/record/restfulable.js"
275
+ "var $, merge, model, observable, record, rest, restful, root, type, util,\n __slice = [].slice;\n\nmerge = require('assimilate').withStrategy('deep');\n\ntype = require('type');\n\nobservable = require('observable').mixin;\n\n$ = require('jquery');\n\nrest = require('./rest.js');\n\nroot = typeof exports !== \"undefined\" && exports !== null ? exports : this;\n\nutil = {\n model: {\n map: function(records) {\n var record, _i, _len, _results;\n\n _results = [];\n for (_i = 0, _len = records.length; _i < _len; _i++) {\n record = records[_i];\n _results.push(this(record));\n }\n return _results;\n }\n }\n};\n\nrestful = {\n model: {\n create: function() {\n var attributes, callback, params, record, savings, _i, _j, _len;\n\n params = 2 <= arguments.length ? __slice.call(arguments, 0, _i = arguments.length - 1) : (_i = 0, []), callback = arguments[_i++];\n if (!arguments.length) {\n throw new TypeError(\"No arguments provided for \" + this.resource + \".create\");\n }\n if (typeof callback !== 'function') {\n params.push(callback);\n callback = void 0;\n }\n if (!params.length) {\n params.unshift({});\n }\n savings = [];\n for (_j = 0, _len = params.length; _j < _len; _j++) {\n attributes = params[_j];\n record = this(attributes);\n record.dirty = true;\n savings.push(record.save(callback));\n }\n return $.when.apply($, savings);\n },\n every: function(conditions, doned, failed) {\n if (conditions == null) {\n conditions = {};\n }\n if (typeof conditions === 'function') {\n doned = conditions;\n conditions = {};\n }\n return $.when(rest.get.call(this, conditions)).then(util.model.map).done(doned).fail(failed);\n },\n first: function(conditions, callback) {\n var namespaced;\n\n if (conditions == null) {\n conditions = {};\n }\n if (typeof conditions === 'function') {\n callback = conditions;\n conditions = {};\n }\n namespaced = conditions[this.resource] || {};\n namespaced.limit = 1;\n namespaced.order = 'desc';\n return this.every(conditions, callback);\n },\n get: function(action, data) {\n var default_route, old_route, payload, promise, resource;\n\n if (data == null) {\n data = {};\n }\n old_route = this.route;\n default_route = '';\n if (this.resource.scope != null) {\n default_route += this.resource.scope + '/';\n }\n default_route += this.resource.singular ? this.resource.name : model.pluralize(this.resource.name);\n if (default_route !== this.route) {\n this.route = default_route;\n }\n if (action) {\n Object.defineProperty(this, 'route', {\n value: \"\" + default_route + \"/\" + action,\n configurable: true\n });\n }\n resource = data.resource;\n if (data && data.json) {\n data = data.json();\n }\n if (resource != null) {\n payload = data;\n data = {};\n data[resource] = payload;\n }\n promise = rest.get.call(this, data);\n Object.defineProperty(this, 'route', {\n value: old_route,\n configurable: true\n });\n return promise;\n },\n put: rest.put,\n \"delete\": rest[\"delete\"]\n },\n record: {\n ready: function(callback) {\n return callback.call(this);\n },\n reload: function() {\n var data, param, params, promise, _i, _len;\n\n params = 1 <= arguments.length ? __slice.call(arguments, 0) : [];\n data = params.pop();\n if (type(data) !== 'object') {\n params.push(data);\n }\n promise = rest.get.call(this, data || {});\n promise.done(this.assign_attributes);\n promise.fail(this.failed);\n this.reloading = promise;\n this.ready = function() {\n console.warn(\"resource.ready was deprecated, please use resource.reloading.done\");\n return promise.done.apply(promise, arguments);\n };\n for (_i = 0, _len = params.length; _i < _len; _i++) {\n param = params[_i];\n promise.done(param);\n }\n return promise;\n },\n assign_attributes: function(attributes) {\n var association, association_attributes, association_name, associations_attributes, attribute, message, name, singular_resource, _i, _j, _k, _l, _len, _len1, _len2, _len3, _len4, _m, _ref, _ref1, _ref2, _ref3, _ref4, _ref5, _results;\n\n _ref = model[this.resource.toString()].has_many;\n for (_i = 0, _len = _ref.length; _i < _len; _i++) {\n association_name = _ref[_i];\n associations_attributes = attributes[association_name];\n delete attributes[association_name];\n association = this[association_name];\n if (association == null) {\n message = \"Association '\" + association_name + \"' not found. \\n\";\n message += \"For record with resource \" + this.resource + \". \\n\";\n message += \"Probably defined on server side but not on client side.\\n\";\n message += \"Skipping association assignment!\";\n console.warn(message);\n continue;\n }\n if (association.length) {\n Array.prototype.splice.call(association, 0);\n }\n if (!((associations_attributes != null) && associations_attributes.length)) {\n continue;\n }\n singular_resource = model.singularize(association_name);\n for (_j = 0, _len1 = associations_attributes.length; _j < _len1; _j++) {\n association_attributes = associations_attributes[_j];\n _ref1 = model[singular_resource].has_many;\n for (_k = 0, _len2 = _ref1.length; _k < _len2; _k++) {\n association_name = _ref1[_k];\n association_attributes[\"\" + association_name + \"_attributes\"] = association_attributes[association_name];\n delete association_attributes[association_name];\n }\n }\n association.add.apply(association, associations_attributes);\n }\n _ref2 = model[this.resource.toString()].has_one;\n for (_l = 0, _len3 = _ref2.length; _l < _len3; _l++) {\n association_name = _ref2[_l];\n association_attributes = attributes[association_name];\n delete attributes[association_name];\n delete attributes[association_name + \"_attributes\"];\n if (association_attributes) {\n this[association_name] = this[\"build_\" + association_name](association_attributes);\n }\n }\n _ref3 = model[this.resource.toString()].belongs_to;\n for (_m = 0, _len4 = _ref3.length; _m < _len4; _m++) {\n association_name = _ref3[_m];\n association_attributes = (_ref4 = (_ref5 = attributes[association_name]) != null ? typeof _ref5.json === \"function\" ? _ref5.json() : void 0 : void 0) != null ? _ref4 : attributes[association_name];\n delete attributes[association_name];\n delete attributes[association_name + \"_attributes\"];\n if (association_attributes) {\n this[association_name] = this[\"build_\" + association_name](association_attributes);\n }\n }\n _results = [];\n for (name in attributes) {\n attribute = attributes[name];\n if (attribute !== this[name]) {\n if (type(attribute) === 'object') {\n if (JSON.stringify(attribute) !== JSON.stringify(this[name])) {\n _results.push(this[name] = attributes[name]);\n } else {\n _results.push(void 0);\n }\n } else {\n _results.push(this[name] = attributes[name]);\n }\n }\n }\n return _results;\n },\n destroy: function(doned, failed, data) {\n var promise;\n\n if (!((this.id != null) || (this._id != null))) {\n throw new Error('Can\\'t delete record without id!');\n }\n promise = rest[\"delete\"].call(this, data);\n promise.done(this.destroyed);\n promise.fail(this.failed);\n promise.done(doned);\n promise.fail(failed);\n return promise;\n },\n saving: false,\n salvation: null,\n save: function(doned, failed, data) {\n var lock, salvation;\n\n lock = JSON.stringify(this.json());\n if (this.saving) {\n if (this.lock === lock) {\n return this.salvation;\n } else {\n this.salvation.abort();\n }\n }\n this.lock = lock;\n if (!this.dirty) {\n salvation = $.Deferred().resolveWith(this, null);\n }\n this.saving = true;\n salvation || (salvation = rest[this._id ? 'put' : 'post'].call(this, data));\n this.salvation = salvation;\n salvation.done(this.saved);\n salvation.fail(this.failed);\n salvation.always(function() {\n return this.saving = false;\n });\n salvation.done(doned);\n salvation.fail(failed);\n return salvation;\n },\n saved: function(data) {\n var callback, _i, _len, _ref, _results;\n\n if (this.lock === JSON.stringify(this.json())) {\n this.dirty = false;\n delete this.lock;\n }\n if (data != null) {\n this.assign_attributes(data);\n }\n if (this.after_save) {\n _ref = this.after_save;\n _results = [];\n for (_i = 0, _len = _ref.length; _i < _len; _i++) {\n callback = _ref[_i];\n throw \"Not supported after_save callback: \" + callback;\n }\n return _results;\n }\n },\n failed: function(xhr, error, status) {\n var attribute_name, definition, e, message, messages, payload, _i, _len, _ref;\n\n payload = xhr.responseJSON;\n try {\n payload || (payload = JSON.parse(xhr.responseText));\n } catch (_error) {\n e = _error;\n }\n payload || (payload = xhr.responseText);\n switch (xhr.status) {\n case 0:\n message = status || xhr.statusText;\n switch (message) {\n case 'abort':\n console.info(\"salvation probably aborted\");\n break;\n case 'error':\n console.info(\"server probably unreachable\");\n break;\n default:\n throw new Error('Unhandled status code for xhr');\n }\n break;\n case 422:\n definition = model[this.resource.toString()];\n _ref = payload.errors;\n for (attribute_name in _ref) {\n messages = _ref[attribute_name];\n if (!definition.associations) {\n definition.associations = definition.has_one.concat(definition.has_many.concat(definition.belongs_to));\n }\n if (!(this.hasOwnProperty(attribute_name) || definition.hasOwnProperty(attribute_name) || definition.associations.indexOf(attribute_name) !== -1 || attribute_name === 'base')) {\n message = \"Server returned an validation error message for a attribute that is not defined in your model.\\n\";\n message += \"The attribute was '\" + attribute_name + \"', the model resource was '\" + this.resource + \"'.\\n\";\n message += \"The model definition keys were '\" + (JSON.stringify(Object.keys(definition))) + \"'.\\n\";\n message += \"Please remove server validation, or update your model definition.\";\n throw new TypeError(message);\n }\n for (_i = 0, _len = messages.length; _i < _len; _i++) {\n message = messages[_i];\n this.errors.add(attribute_name, 'server', {\n server_message: message\n });\n }\n }\n break;\n default:\n message = \"Fail in \" + this.resource + \".save:\\n\";\n message += \"Record: \" + this + \"\\n\";\n message += \"Status: \" + status + \" (\" + (payload || xhr).status + \")\\n\";\n message += \"Error : \" + (payload.error || payload.message || payload);\n console.log(message);\n }\n return this.saving = false;\n },\n toString: function() {\n var e, name, property, serialized;\n\n serialized = {};\n serialized[this.resource] = this.json();\n try {\n return JSON.stringify(serialized);\n } catch (_error) {\n e = _error;\n console.warn(\"restfulable.toString: Failed to stringify record: \" + e.message + \". retrying...\");\n for (name in serialized) {\n property = serialized[name];\n if (typeof property === 'object') {\n delete serialized[name];\n }\n }\n return JSON.stringify(serialized);\n }\n },\n json: function(options) {\n var definition, json, method, name, nature, nested, value, _ref, _ref1;\n\n if (options == null) {\n options = {};\n }\n json = {};\n definition = model[this.resource.toString()];\n for (name in this) {\n if (observable.ignores.indexOf(name) !== -1) {\n continue;\n }\n nested = this.nested_attributes.indexOf(name) !== -1;\n if (!nested && (definition.belongs_to.indexOf(name) !== -1 || definition.has_one.indexOf(name) !== -1 || definition.has_many.indexOf(name) !== -1)) {\n continue;\n }\n value = this[name];\n if (value == null) {\n continue;\n }\n nature = type(value);\n if (nature === 'function') {\n continue;\n }\n if (nature === 'object' || nature === 'element') {\n if (nested) {\n if (!value.json) {\n console.warn(\"json: Tryied to serialize nested attribute '\" + name + \"' without serialization method!\");\n continue;\n }\n json[\"\" + name + \"_attributes\"] = value.json(options[name]);\n } else if ((value.toJSON != null) || (value.json != null)) {\n if (value.resource) {\n continue;\n }\n if (value.json != null) {\n json[name] = value.json(options[name]);\n } else {\n json[name] = value.toJSON(options[name]);\n }\n } else {\n continue;\n }\n } else {\n json[name] = value;\n }\n }\n json = observable.unobserve(json);\n _ref1 = (_ref = options.methods) != null ? _ref : {};\n for (name in _ref1) {\n value = _ref1[name];\n method = this[name];\n if (typeof method === 'function') {\n json[name] = method();\n } else {\n json[name] = method;\n }\n }\n delete json.dirty;\n delete json.resource;\n delete json.route;\n delete json.initial_route;\n delete json.after_initialize;\n delete json.before_initialize;\n delete json.parent_resource;\n delete json.nested_attributes;\n delete json.reloading;\n delete json.ready;\n delete json.saving;\n delete json.salvation;\n delete json.sustained;\n delete json.element;\n delete json[\"default\"];\n delete json.lock;\n delete json.validated;\n delete json.validation;\n delete json.errors;\n return json;\n }\n }\n};\n\nrestful.toJSON = restful.json;\n\nmodel = window.model;\n\nrecord = window.record;\n\nmodel.restfulable = true;\n\nrecord.mix(function(recordable) {\n return merge(recordable, restful.record);\n});\n\nmodel.mix(function(modelable) {\n return merge(modelable, restful.model);\n});\n\nmodel.associable && model.associable.mix(function(singular_association, plural_association) {\n plural_association.get = function() {\n if (this.parent != null) {\n this.route || (this.route = \"\" + this.parent.route + \"/\" + this.parent._id + \"/\" + (model.pluralize(this.resource.name)));\n }\n return rest.get.apply(this, arguments);\n };\n return plural_association.post = function() {\n if (this.parent != null) {\n this.route || (this.route = \"\" + this.parent.route + \"/\" + this.parent._id + \"/\" + (model.pluralize(this.resource.name)));\n }\n return rest.post.apply(this, arguments);\n };\n});\n//@ sourceURL=indemma/lib/record/restfulable.js"
276
276
  ));
277
277
  require.register("indemma/lib/record/scopable.js", Function("exports, require, module",
278
278
  "var $, builders, defaults, extend, merge, model, observable, record, rest, scopable, stampit, util,\n __slice = [].slice;\n\nrequire('./restfulable');\n\nrequire('./resource');\n\nstampit = require('../../vendor/stampit');\n\nextend = require('assimilate');\n\nobservable = require('observable').mixin;\n\nmerge = extend.withStrategy('deep');\n\n$ = require('jquery');\n\nrest = require('./rest');\n\nutil = {\n model: {\n map: function(records) {\n var index, record, _i, _len, _results;\n\n _results = [];\n for (index = _i = 0, _len = records.length; _i < _len; index = ++_i) {\n record = records[index];\n _results.push((this.build || this).call(this, record));\n }\n return _results;\n }\n }\n};\n\nscopable = {\n builder: stampit().enclose(function() {\n return stampit.mixIn(function(name, type) {\n var builder;\n\n if ($.type(type) === 'function') {\n this[\"$\" + name] = type() || new type;\n type = $.type(this[\"$\" + name]);\n } else {\n this[\"$\" + name] = defaults[type] || type;\n }\n if ($.type(type) !== 'string') {\n type = $.type(type);\n }\n builder = builders[type];\n if (builder == null) {\n throw \"Unknown scope type: '\" + type + \"', For model with resource: '\" + this.resource + \"'\";\n }\n this.scope.declared.push(name);\n return this[name] = builder({\n name: name\n });\n }, {\n data: {},\n then: [],\n fail: [],\n declared: [],\n fetch: function(data, done, fail) {\n var deferred, scope;\n\n if (typeof data === 'function') {\n done = data;\n data = {};\n }\n scope = extend({}, this.scope.data);\n observable.unobserve(scope);\n if (scope.noned != null) {\n deferred = $.Deferred();\n deferred.resolveWith(this, [[]]);\n } else {\n deferred = rest.get.call(this, extend(scope, data));\n }\n deferred.then(util.model.map).done(this.scope.then.concat([done])).fail(this.scope.fail.concat([fail]));\n this.scope.clear();\n return deferred;\n },\n clear: function() {\n this.data = {};\n return this.callbacks = [];\n }\n });\n }),\n base: stampit().state({\n name: 'unamed_scope'\n }),\n record: {\n failed: function(xhr, error, status) {\n var e, message, payload;\n\n payload = xhr.responseJSON;\n try {\n payload || (payload = JSON.parse(xhr.responseText));\n } catch (_error) {\n e = _error;\n }\n payload || (payload = xhr.responseText);\n switch (xhr.status) {\n case 422:\n this.valid = false;\n return this.errors = payload.errors;\n default:\n message = \"Fail in \" + this.resource + \".save:\\n\";\n message += \"Record: \" + this + \"\\n\";\n message += \"Status: \" + status + \" (\" + (payload.status || xhr.status) + \")\\n\";\n message += \"Error : \" + (payload.error || payload.message || payload);\n }\n return console.error(message);\n }\n },\n model: {\n none: function() {\n this.scope.data.noned = true;\n return this;\n },\n fetch: function(data, done, fail) {\n if (typeof data === 'function') {\n done = data;\n data = null;\n }\n return this.scope.fetch.call(this, data, done, fail);\n },\n forward_scopes_to_associations: function() {\n var associated_factory, associated_resource, association, association_name, factory, scope, _i, _j, _len, _len1, _ref, _ref1;\n\n factory = model[this.resource.name];\n _ref = factory.has_many;\n for (_i = 0, _len = _ref.length; _i < _len; _i++) {\n association_name = _ref[_i];\n associated_resource = model.singularize(association_name);\n associated_factory = model[associated_resource];\n if (!model[associated_resource]) {\n console.warn(\"Associated factory not found for associated resource: \" + associated_resource);\n continue;\n }\n association = this[association_name];\n association.scope = scopable.builder(association);\n _ref1 = associated_factory.scope.declared;\n for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) {\n scope = _ref1[_j];\n association.scope(scope, associated_factory[\"$\" + scope]);\n }\n }\n return true;\n }\n },\n after_mix: function() {\n var name, property, type, _results;\n\n this.scope = scopable.builder(this);\n _results = [];\n for (property in this) {\n type = this[property];\n if (property.charAt(0) === '$') {\n name = property.substring(1);\n _results.push(this.scope(name, type));\n } else {\n _results.push(void 0);\n }\n }\n return _results;\n }\n};\n\nbuilders = {\n string: stampit().enclose(function() {\n var base;\n\n base = scopable.base(this);\n return stampit.mixIn(function() {\n var callbacks, value, _base, _name;\n\n value = arguments[0], callbacks = 2 <= arguments.length ? __slice.call(arguments, 1) : [];\n callbacks.length && (this.scope.then = this.scope.then.concat(callbacks));\n (_base = this.scope.data)[_name = base.name] || (_base[_name] = value != null ? value : this[\"$\" + base.name]);\n return this;\n });\n }),\n boolean: stampit().enclose(function() {\n var base;\n\n base = scopable.base(this);\n return stampit.mixIn(function() {\n var callbacks, value, _base, _name;\n\n value = arguments[0], callbacks = 2 <= arguments.length ? __slice.call(arguments, 1) : [];\n callbacks.length && (this.scope.then = this.scope.then.concat(callbacks));\n (_base = this.scope.data)[_name = base.name] || (_base[_name] = value != null ? value : this[\"$\" + base.name]);\n return this;\n });\n }),\n array: stampit().enclose(function() {\n var base;\n\n base = scopable.base(this);\n return stampit.mixIn(function() {\n var values, _base, _name;\n\n values = 1 <= arguments.length ? __slice.call(arguments, 0) : [];\n (_base = this.scope.data)[_name = base.name] || (_base[_name] = values != null ? values : this[\"$\" + base.name]);\n return this;\n });\n })\n};\n\ndefaults = {\n boolean: true,\n array: []\n};\n\nmodel = window.model;\n\nrecord = window.record;\n\nmodel.scopable = true;\n\nmodel.mix(function(modelable) {\n merge(modelable, scopable.model);\n return modelable.after_mix.push(scopable.after_mix);\n});\n\nif (model.associable) {\n model.mix(function(modelable) {\n return modelable.record.after_initialize.push(function() {\n return scopable.model.forward_scopes_to_associations.call(this);\n });\n });\n model.associable.mix(function(singular_association, plural_association) {\n plural_association.every = plural_association.reload = function(data, done, fail) {\n var promises, reload;\n\n if (this.parent != null) {\n this.route || (this.route = \"\" + this.parent.route + \"/\" + this.parent._id + \"/\" + (model.pluralize(this.resource)));\n }\n promises = [];\n if (typeof data === 'function') {\n done = data;\n data = void 0;\n }\n promises.push(this.scope.fetch.call(this, data, null, scopable.record.failed));\n reload = $.when.apply(jQuery, promises);\n reload.done(function(records, status) {\n var association_name, create, index, singular_resource, target, _i, _j, _k, _len, _len1, _len2, _ref;\n\n if (!records.length) {\n if (this.length) {\n Array.prototype.splice.call(this, 0);\n }\n return true;\n }\n singular_resource = model.singularize(this.resource);\n for (_i = 0, _len = records.length; _i < _len; _i++) {\n record = records[_i];\n _ref = model[singular_resource].has_many;\n for (_j = 0, _len1 = _ref.length; _j < _len1; _j++) {\n association_name = _ref[_j];\n record[\"\" + association_name + \"_attributes\"] = record[association_name];\n delete record[association_name];\n }\n }\n create = [];\n for (index = _k = 0, _len2 = records.length; _k < _len2; index = ++_k) {\n record = records[index];\n if (target = this.find(record._id)) {\n target.assign_attributes(record);\n } else {\n create.push(record);\n }\n }\n this.add.apply(this, create);\n records.splice(0);\n return records.push.apply(records, this);\n });\n reload.done(done);\n reload.fail(fail);\n return reload;\n };\n return plural_association.each = function(callback) {\n var _this = this;\n\n if (this.parent != null) {\n this.route || (this.route = \"\" + this.parent.route + \"/\" + this.parent._id + \"/\" + (model.pluralize(this.resource)));\n }\n return this.get().done(function(records) {\n var _i, _len, _results;\n\n _results = [];\n for (_i = 0, _len = _this.length; _i < _len; _i++) {\n record = _this[_i];\n _results.push(callback(record));\n }\n return _results;\n });\n };\n });\n}\n//@ sourceURL=indemma/lib/record/scopable.js"
@@ -305,7 +305,7 @@ require.register("indemma/lib/record/validations/cpf.js", Function("exports, req
305
305
  "var composed, cpfable, stampit;\n\nstampit = require('../../../vendor/stampit');\n\ncpfable = stampit({\n validate_format: function(value) {\n var c, d1, dv, i, v, _i, _j;\n\n value = value.replace(/[\\.\\-]/g, \"\");\n if (value.length < 11) {\n return false;\n }\n if (value.match(/^(0+|1+|2+|3+|4+|5+|6+|7+|8+|9+)$/)) {\n return false;\n }\n c = value.substr(0, 9);\n dv = value.substr(9, 2);\n d1 = 0;\n v = false;\n i = 0;\n for (i = _i = 0; _i <= 9; i = ++_i) {\n d1 += c.charAt(i) * (10 - i);\n }\n if (d1 === 0) {\n return false;\n }\n d1 = 11 - (d1 % 11);\n if (d1 > 9) {\n d1 = 0;\n }\n if (+dv.charAt(0) !== d1) {\n return false;\n }\n d1 *= 2;\n for (i = _j = 0; _j <= 9; i = ++_j) {\n d1 += c.charAt(i) * (11 - i);\n }\n d1 = 11 - (d1 % 11);\n if (d1 > 9) {\n d1 = 0;\n }\n if (+dv.charAt(1) !== d1) {\n return false;\n }\n return true;\n },\n validate_each: function(record, attribute, value) {\n if (value && !this.validate_format(value)) {\n return record.errors.add(attribute, 'cpf', this.options);\n }\n }\n});\n\ncomposed = stampit.compose(require('./validatorable'), cpfable);\n\ncomposed.definition_key = 'validates_cpf_format';\n\nmodule.exports = composed;\n//@ sourceURL=indemma/lib/record/validations/cpf.js"
306
306
  ));
307
307
  require.register("indemma/lib/record/validatable.js", Function("exports, require, module",
308
- "var errorsable, extensions, initializers, manager, messages, observable, root, stampit, type;\n\nrequire('./translationable');\n\nroot = typeof exports !== \"undefined\" && exports !== null ? exports : this;\n\nstampit = require('../../vendor/stampit');\n\nobservable = require('observable').mixin;\n\ntype = require('type');\n\nmessages = {\n blank: function(attribute_name) {\n attribute_name = this.human_attribute_name(attribute_name);\n return \"O campo \" + attribute_name + \" não pode ficar em branco.\";\n },\n cpf: function(attribute_name) {\n attribute_name = this.human_attribute_name(attribute_name);\n return \"O campo \" + attribute_name + \" não está válido.\";\n },\n confirmation: function(attribute_name) {\n var confirmation_attribute_name;\n\n confirmation_attribute_name = this.human_attribute_name(attribute_name);\n attribute_name = this.human_attribute_name(attribute_name.replace('_confirmation', ''));\n return \"O campo \" + attribute_name + \" não está de acordo com o campo \" + confirmation_attribute_name + \".\";\n },\n associated: function(attribute_name) {\n attribute_name = this.human_attribute_name(attribute_name);\n return \"O registro associado \" + attribute_name + \" não é válido.\";\n },\n server: function(attribute_name, options) {\n if (attribute_name === 'base') {\n return options.server_message;\n } else {\n attribute_name = this.human_attribute_name(attribute_name);\n return \"\" + attribute_name + \" \" + options.server_message + \".\";\n }\n },\n type: function(attribute_name, options) {\n attribute_name = this.human_attribute_name(attribute_name);\n return \"O campo \" + attribute_name + \" não está válido.\";\n }\n};\n\nerrorsable = stampit({\n add: function(attribute_name, message_key, options) {\n var translator;\n\n this.push([attribute_name, message_key, options]);\n this.messages[attribute_name] = '';\n translator = messages[message_key];\n if (translator != null) {\n return this.messages[attribute_name] += translator.call(this.model, attribute_name, options);\n } else {\n return this.messages[attribute_name] += message_key;\n }\n },\n clear: function() {\n var attribute_name, _results;\n\n if (this.length) {\n this.length = 0;\n _results = [];\n for (attribute_name in this.messages) {\n _results.push(this.messages[attribute_name] = null);\n }\n return _results;\n }\n },\n push: Array.prototype.push,\n splice: Array.prototype.splice,\n indexOf: Array.prototype.indexOf\n}, {\n model: null,\n messages: null,\n length: 0\n}, function() {\n this.messages = {};\n return this;\n});\n\ninitializers = {\n define_triggers: function() {\n this.errors = errorsable({\n model: model[this.resource]\n });\n this.before('save', function() {\n if (this.save) {\n return this.validate();\n }\n });\n this.validated = false;\n this.subscribe('dirty', function(value) {\n return value && (this.validated = false);\n });\n return Object.defineProperty(this, 'valid', {\n get: function() {\n this.validate();\n if (this.validation.state() === 'resolved') {\n return !this.errors.length;\n } else {\n return null;\n }\n },\n set: function() {\n throw new TypeError(\"You can't set the value for the valid property.\");\n },\n enumerable: false\n });\n },\n create_validators: function(definitions) {\n var definition, name, validator, validator_options, _ref, _results;\n\n this.validators = [];\n _ref = manager.validators;\n _results = [];\n for (name in _ref) {\n validator = _ref[name];\n definition = definitions[validator.definition_key];\n if (definition) {\n if (type(definition) !== 'array') {\n definition = [definition];\n }\n _results.push((function() {\n var _i, _len, _results1;\n\n _results1 = [];\n for (_i = 0, _len = definition.length; _i < _len; _i++) {\n validator_options = definition[_i];\n if (type(validator_options) !== 'object') {\n validator_options = {\n attribute_name: validator_options\n };\n }\n validator_options.model = this;\n this.validators.push(validator(validator_options));\n _results1.push(delete definitions[validator.definition_key]);\n }\n return _results1;\n }).call(this));\n } else {\n _results.push(void 0);\n }\n }\n return _results;\n }\n};\n\nextensions = {\n model: {\n validators: null\n },\n record: {\n validate_attribute: function(attribute, doned, failed) {\n var results, validation, validator, _i, _len, _ref;\n\n this.errors.messages[attribute] = null;\n results = [this, attribute];\n _ref = model[this.resource.toString()].validators;\n for (_i = 0, _len = _ref.length; _i < _len; _i++) {\n validator = _ref[_i];\n if (validator.attribute_name === attribute) {\n results.push(validator.validate_each(this, validator.attribute_name, this[validator.attribute_name]));\n }\n }\n validation = jQuery.when.apply(jQuery, results);\n validation.done(doned);\n validation.fail(failed);\n return validation;\n },\n validate: function(doned, failed) {\n var results, validator, _i, _len, _ref;\n\n if (this.validated) {\n return this.validation;\n }\n this.errors.clear();\n results = [this];\n _ref = model[this.resource.toString()].validators;\n for (_i = 0, _len = _ref.length; _i < _len; _i++) {\n validator = _ref[_i];\n results.push(validator.validate_each(this, validator.attribute_name, this[validator.attribute_name]));\n }\n this.validation = jQuery.when.apply(jQuery, results);\n this.validation.done(doned);\n this.validation.fail(failed);\n return this.validation.done(function(record) {\n var old_dirty;\n\n old_dirty = record.dirty;\n record.dirty = null;\n record.validated || (record.validated = true);\n record.observed.dirty = old_dirty;\n return record;\n });\n }\n }\n};\n\nmanager = {\n validators: {}\n};\n\nmodel.mix(function(modelable) {\n jQuery.extend(modelable, extensions.model);\n jQuery.extend(modelable.record, extensions.record);\n modelable.after_mix.unshift(initializers.create_validators);\n modelable.record.after_initialize.push(initializers.define_triggers);\n return model.validators = manager.validators;\n});\n\nmanager.validators.confirmation = require('./validations/confirmation');\n\nmanager.validators.associated = require('./validations/associated');\n\nmanager.validators.presence = require('./validations/presence');\n\nmanager.validators.remote = require('./validations/remote');\n\nmanager.validators.type = require('./validations/type');\n\nmanager.validators.cpf = require('./validations/cpf');\n//@ sourceURL=indemma/lib/record/validatable.js"
308
+ "var errorsable, extensions, initializers, manager, messages, observable, root, stampit, type;\n\nrequire('./translationable');\n\nroot = typeof exports !== \"undefined\" && exports !== null ? exports : this;\n\nstampit = require('../../vendor/stampit');\n\nobservable = require('observable').mixin;\n\ntype = require('type');\n\nmessages = {\n blank: function(attribute_name) {\n attribute_name = this.human_attribute_name(attribute_name);\n return \"O campo \" + attribute_name + \" não pode ficar em branco.\";\n },\n cpf: function(attribute_name) {\n attribute_name = this.human_attribute_name(attribute_name);\n return \"O campo \" + attribute_name + \" não está válido.\";\n },\n confirmation: function(attribute_name) {\n var confirmation_attribute_name;\n\n confirmation_attribute_name = this.human_attribute_name(attribute_name);\n attribute_name = this.human_attribute_name(attribute_name.replace('_confirmation', ''));\n return \"O campo \" + attribute_name + \" não está de acordo com o campo \" + confirmation_attribute_name + \".\";\n },\n associated: function(attribute_name) {\n attribute_name = this.human_attribute_name(attribute_name);\n return \"O registro associado \" + attribute_name + \" não é válido.\";\n },\n server: function(attribute_name, options) {\n if (attribute_name === 'base') {\n return options.server_message;\n } else {\n attribute_name = this.human_attribute_name(attribute_name);\n return \"\" + attribute_name + \" \" + options.server_message + \".\";\n }\n },\n type: function(attribute_name, options) {\n attribute_name = this.human_attribute_name(attribute_name);\n return \"O campo \" + attribute_name + \" não está válido.\";\n }\n};\n\nerrorsable = stampit({\n add: function(attribute_name, message_key, options) {\n var translator;\n\n this.push([attribute_name, message_key, options]);\n this.messages[attribute_name] = '';\n translator = messages[message_key];\n if (translator != null) {\n return this.messages[attribute_name] += translator.call(this.model, attribute_name, options);\n } else {\n return this.messages[attribute_name] += message_key;\n }\n },\n clear: function() {\n var attribute_name, _results;\n\n if (this.length) {\n this.length = 0;\n _results = [];\n for (attribute_name in this.messages) {\n _results.push(this.messages[attribute_name] = null);\n }\n return _results;\n }\n },\n push: Array.prototype.push,\n splice: Array.prototype.splice,\n indexOf: Array.prototype.indexOf\n}, {\n model: null,\n messages: null,\n length: 0\n}, function() {\n this.messages = {};\n return this;\n});\n\ninitializers = {\n define_triggers: function() {\n this.errors = errorsable({\n model: model[this.resource]\n });\n this.before('save', function() {\n if (this.save) {\n return this.validate();\n }\n });\n this.validated = false;\n this.subscribe('dirty', function(value) {\n return value && (this.validated = false);\n });\n return Object.defineProperty(this, 'valid', {\n get: function() {\n this.validate();\n if (this.validation.state() === 'resolved') {\n return !this.errors.length;\n } else {\n return null;\n }\n },\n set: function() {\n throw new TypeError(\"You can't set the value for the valid property.\");\n },\n enumerable: false\n });\n },\n create_validators: function(definitions) {\n var definition, name, validator, validator_options, _ref, _results;\n\n this.validators = [];\n _ref = manager.validators;\n _results = [];\n for (name in _ref) {\n validator = _ref[name];\n definition = definitions[validator.definition_key];\n if (definition) {\n if (type(definition) !== 'array') {\n definition = [definition];\n }\n _results.push((function() {\n var _i, _len, _results1;\n\n _results1 = [];\n for (_i = 0, _len = definition.length; _i < _len; _i++) {\n validator_options = definition[_i];\n if (type(validator_options) !== 'object') {\n validator_options = {\n attribute_name: validator_options\n };\n }\n validator_options.model = this;\n this.validators.push(validator(validator_options));\n _results1.push(delete definitions[validator.definition_key]);\n }\n return _results1;\n }).call(this));\n } else {\n _results.push(void 0);\n }\n }\n return _results;\n }\n};\n\nextensions = {\n model: {\n validators: null\n },\n record: {\n validate_attribute: function(attribute, doned, failed) {\n var results, validation, validator, _i, _len, _ref;\n\n this.errors.messages[attribute] = null;\n results = [this, attribute];\n _ref = model[this.resource.toString()].validators;\n for (_i = 0, _len = _ref.length; _i < _len; _i++) {\n validator = _ref[_i];\n if (validator.attribute_name === attribute) {\n results.push(validator.validate_each(this, validator.attribute_name, this[validator.attribute_name]));\n }\n }\n validation = jQuery.when.apply(jQuery, results);\n validation.done(doned);\n validation.fail(failed);\n return validation;\n },\n validate: function(doned, failed) {\n var results, validator, _i, _len, _ref;\n\n if (this.validated && !this.dirty) {\n return this.validation;\n }\n this.errors.clear();\n results = [this];\n _ref = model[this.resource.toString()].validators;\n for (_i = 0, _len = _ref.length; _i < _len; _i++) {\n validator = _ref[_i];\n results.push(validator.validate_each(this, validator.attribute_name, this[validator.attribute_name]));\n }\n this.validation = jQuery.when.apply(jQuery, results);\n this.validation.done(doned);\n this.validation.fail(failed);\n return this.validation.done(function(record) {\n var old_dirty;\n\n old_dirty = record.dirty;\n record.dirty = null;\n record.validated || (record.validated = true);\n record.dirty = old_dirty;\n return record;\n });\n }\n }\n};\n\nmanager = {\n validators: {}\n};\n\nmodel.mix(function(modelable) {\n jQuery.extend(modelable, extensions.model);\n jQuery.extend(modelable.record, extensions.record);\n modelable.after_mix.unshift(initializers.create_validators);\n modelable.record.after_initialize.push(initializers.define_triggers);\n return model.validators = manager.validators;\n});\n\nmanager.validators.confirmation = require('./validations/confirmation');\n\nmanager.validators.associated = require('./validations/associated');\n\nmanager.validators.presence = require('./validations/presence');\n\nmanager.validators.remote = require('./validations/remote');\n\nmanager.validators.type = require('./validations/type');\n\nmanager.validators.cpf = require('./validations/cpf');\n//@ sourceURL=indemma/lib/record/validatable.js"
309
309
  ));
310
310
  require.register("indemma/lib/extensions/rivets.js", Function("exports, require, module",
311
311
  "var root;\n\nroot = typeof exports !== \"undefined\" && exports !== null ? exports : this;\n\nmodel.rivets = function() {\n var model_extensions;\n\n model_extensions = {\n record: {\n tie: function(element) {\n var lasso;\n\n lasso = {};\n lasso[this.resource] = this;\n return rivets.bind(element, lasso);\n }\n },\n preloadData: true\n };\n return model.mix(function(modelable) {\n return $.extend(true, modelable, model_extensions);\n });\n};\n//@ sourceURL=indemma/lib/extensions/rivets.js"
@@ -10,6 +10,7 @@
10
10
  "component/bind": "*",
11
11
  "component/jquery": "*",
12
12
  "indefinido/observable": "*",
13
+
13
14
  "indefinido/advisable": "*"
14
15
  },
15
16
  "development": {},
@@ -85,7 +85,7 @@ restful = {
85
85
  data = {};
86
86
  }
87
87
  old_route = this.route;
88
- default_route = '/';
88
+ default_route = '';
89
89
  if (this.resource.scope != null) {
90
90
  default_route += this.resource.scope + '/';
91
91
  }
@@ -150,9 +150,8 @@ restful = {
150
150
  _ref = model[this.resource.toString()].has_many;
151
151
  for (_i = 0, _len = _ref.length; _i < _len; _i++) {
152
152
  association_name = _ref[_i];
153
- associations_attributes = attributes[association_name + "_attributes"] || attributes[association_name];
153
+ associations_attributes = attributes[association_name];
154
154
  delete attributes[association_name];
155
- delete attributes[association_name + '_attributes'];
156
155
  association = this[association_name];
157
156
  if (association == null) {
158
157
  message = "Association '" + association_name + "' not found. \n";
@@ -173,7 +173,7 @@ extensions = {
173
173
  validate: function(doned, failed) {
174
174
  var results, validator, _i, _len, _ref;
175
175
 
176
- if (this.validated) {
176
+ if (this.validated && !this.dirty) {
177
177
  return this.validation;
178
178
  }
179
179
  this.errors.clear();
@@ -192,7 +192,7 @@ extensions = {
192
192
  old_dirty = record.dirty;
193
193
  record.dirty = null;
194
194
  record.validated || (record.validated = true);
195
- record.observed.dirty = old_dirty;
195
+ record.dirty = old_dirty;
196
196
  return record;
197
197
  });
198
198
  }
@@ -65,7 +65,7 @@ restful =
65
65
  old_route = @route
66
66
 
67
67
  # TODO extract route generation concern
68
- default_route = '/'
68
+ default_route = ''
69
69
  default_route += @resource.scope + '/' if @resource.scope?
70
70
  default_route += if @resource.singular then @resource.name else model.pluralize @resource.name
71
71
 
@@ -122,22 +122,16 @@ restful =
122
122
 
123
123
  promise
124
124
 
125
-
126
- # TODO sufix association attributes with '_attributes' and remove
127
- # double checking in this method
128
125
  assign_attributes: (attributes) ->
129
126
 
130
127
  # TODO only set associations on nested attributes!
131
128
  # First assign has_many associations
132
129
  # TODO implement setter on has_many association and move this code there
133
130
  for association_name in model[@resource.toString()].has_many
134
- associations_attributes = attributes[association_name + "_attributes"] or attributes[association_name]
131
+ associations_attributes = attributes[association_name]
135
132
 
136
133
  # TODO copy attributes object and don't change it inside the assignment method
137
- # TODO sufix association attributes with '_attributes' and remove
138
- # double checking in this method
139
134
  delete attributes[association_name] # Remove loaded json data
140
- delete attributes[association_name + '_attributes'] # Remove loaded json data
141
135
 
142
136
  # Clear current stored cache on this association
143
137
  # TODO implement setter on this association and let user to set
@@ -164,7 +158,7 @@ restful =
164
158
  for association_attributes in associations_attributes
165
159
 
166
160
  # TODO only nest specified nested attributes on model definition
167
- # TODO create special deserialization method on plural association
161
+ # TODO create special deserialization method no plural association
168
162
  # TODO check if we need to nest attributes in other association types
169
163
  for association_name in model[singular_resource].has_many
170
164
  association_attributes["#{association_name}_attributes"] = association_attributes[association_name]
@@ -158,7 +158,7 @@ extensions =
158
158
  validation
159
159
 
160
160
  validate: (doned, failed) ->
161
- return @validation if @validated
161
+ return @validation if @validated and not @dirty
162
162
 
163
163
  @errors.clear()
164
164
  results = [@]
@@ -181,8 +181,8 @@ extensions =
181
181
 
182
182
  record.validated ||= true
183
183
 
184
- # Restore dirty state, without publishing changes
185
- record.observed.dirty = old_dirty
184
+ # Restore dirty state
185
+ record.dirty = old_dirty
186
186
 
187
187
  record
188
188
 
@@ -8,21 +8,17 @@
8
8
  "component/jquery": "*"
9
9
  },
10
10
  "development": {
11
- "chaijs/chai": "*"
11
+ "chaijs/chai": "*",
12
+ "components/cjohansen-sinon/sinon.js": "*"
12
13
  },
13
14
  "license": "WTFPL",
14
15
  "scripts": [
15
- "components/cjohansen-sinon/sinon.js",
16
-
17
16
  "index.js",
18
-
19
17
  "lib/observable.js",
20
-
21
18
  "lib/adapters/rivets.js",
22
-
23
19
  "vendor/shims/accessors.js",
24
20
  "vendor/shims/accessors-legacy.js",
25
21
  "vendor/shims/array.indexOf.js",
26
22
  "vendor/shims/object.create.js"
27
23
  ]
28
- }
24
+ }
@@ -223,21 +223,31 @@ generator = {
223
223
  },
224
224
 
225
225
  observable_for: function (object) {
226
+ var toJSON;
227
+
226
228
  Object.defineProperty(object, 'observed', {
227
229
  configurable: true,
228
230
  enumerable: false,
229
231
  value: {}
230
232
  });
231
233
 
232
- // TODO call the current object.toJSON after this method
233
- return Object.defineProperty(object, 'toJSON', {
234
- enumerable: false,
235
- value: function () {
236
- // TODO remove underscore dependency
237
- return observable.unobserve(_.omit(this, observable.ignores));
238
- // old_to_json()
239
- }
240
- });
234
+ // TODO remove json in favor of the toJSON convention
235
+ toJSON = object.json || object.toJSON
236
+
237
+ if (toJSON) {
238
+ return Object.defineProperty(object, 'toJSON', {
239
+ enumerable: false,
240
+ value: function () {
241
+ var json;
242
+
243
+ // TODO remove underscore dependency
244
+ // TODO ? move toJSON and observed to other methods
245
+ json = toJSON.apply(this, arguments);
246
+ return observable.unobserve(_.omit(json, observable.ignores, ['toJSON', 'observed']));
247
+ }
248
+ });
249
+
250
+ }
241
251
  },
242
252
 
243
253
  // TODO improve readability