luca 0.9.42 → 0.9.65
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.
- data/CHANGELOG +50 -9
- data/Gemfile +1 -0
- data/Gemfile.lock +2 -0
- data/README.md +5 -0
- data/assets/javascripts/dependencies/underscore-min.js +5 -31
- data/lib/generators/luca/application/application_generator.rb +71 -0
- data/lib/generators/luca/application/templates/controller.rb +6 -0
- data/lib/generators/luca/application/templates/index.html.erb +7 -0
- data/lib/generators/luca/application/templates/index.html.haml +6 -0
- data/lib/generators/luca/application/templates/javascripts/application.js +28 -0
- data/lib/generators/luca/application/templates/javascripts/application.js.coffee +20 -0
- data/lib/generators/luca/application/templates/javascripts/config.js +15 -0
- data/lib/generators/luca/application/templates/javascripts/config.js.coffee +9 -0
- data/lib/generators/luca/application/templates/javascripts/dependencies.js +5 -0
- data/lib/generators/luca/application/templates/javascripts/dependencies.js.coffee +5 -0
- data/lib/generators/luca/application/templates/javascripts/index.js +9 -0
- data/lib/generators/luca/application/templates/javascripts/index.js.coffee +9 -0
- data/lib/generators/luca/application/templates/javascripts/main.js +8 -0
- data/lib/generators/luca/application/templates/javascripts/main.js.coffee +3 -0
- data/lib/generators/luca/application/templates/javascripts/main.jst.ejs +1 -0
- data/lib/generators/luca/application/templates/javascripts/router.js +12 -0
- data/lib/generators/luca/application/templates/javascripts/router.js.coffee +7 -0
- data/lib/luca/rails/version.rb +1 -1
- data/spec/components/collection_view_spec.coffee +59 -0
- data/spec/components/multi_collection_view_spec.coffee +5 -0
- data/{src/templates/components/form_alert → spec/components/pagination_control_spec.coffee} +0 -0
- data/spec/components/table_view_spec.coffee +17 -0
- data/spec/core/container_spec.coffee +127 -5
- data/spec/core/model_spec.coffee +21 -3
- data/spec/define_spec.coffee +19 -0
- data/spec/mixin_spec.coffee +49 -0
- data/spec/modules/filterable_spec.coffee +25 -0
- data/spec/modules/paginatable_spec.coffee +0 -0
- data/spec/modules/state_model_spec.coffee +0 -0
- data/src/components/application.coffee +52 -38
- data/src/components/collection_view.coffee +118 -45
- data/src/components/fields/checkbox_field.coffee +2 -2
- data/src/components/fields/file_upload_field.coffee +0 -3
- data/src/components/fields/hidden_field.coffee +0 -3
- data/src/components/fields/label_field.coffee +1 -4
- data/src/components/fields/select_field.coffee +6 -6
- data/src/components/fields/text_area_field.coffee +1 -0
- data/src/components/fields/text_field.coffee +4 -0
- data/src/components/fields/type_ahead_field.coffee +5 -9
- data/src/components/form_view.coffee +28 -23
- data/src/components/multi_collection_view.coffee +121 -0
- data/src/components/pagination_control.coffee +106 -0
- data/src/components/table_view.coffee +22 -13
- data/src/containers/card_view.coffee +44 -11
- data/src/containers/panel_toolbar.coffee +88 -82
- data/src/containers/tab_view.coffee +3 -3
- data/src/core/collection.coffee +11 -4
- data/src/core/container.coffee +206 -122
- data/src/core/field.coffee +13 -10
- data/src/core/model.coffee +23 -27
- data/src/core/registry.coffee +42 -29
- data/src/core/view.coffee +63 -149
- data/src/define.coffee +91 -19
- data/src/framework.coffee +11 -9
- data/src/managers/collection_manager.coffee +24 -8
- data/src/modules/application_event_bindings.coffee +19 -0
- data/src/modules/collection_event_bindings.coffee +26 -0
- data/src/modules/deferrable.coffee +3 -1
- data/src/modules/dom_helpers.coffee +49 -0
- data/src/modules/enhanced_properties.coffee +23 -0
- data/src/modules/filterable.coffee +82 -0
- data/src/modules/grid_layout.coffee +13 -1
- data/src/modules/{load_mask.coffee → loadmaskable.coffee} +10 -4
- data/src/modules/modal_view.coffee +38 -0
- data/src/modules/paginatable.coffee +87 -0
- data/src/modules/state_model.coffee +16 -0
- data/src/modules/templating.coffee +8 -0
- data/src/plugins/events.coffee +30 -2
- data/src/templates/components/bootstrap_form_controls.jst.ejs +10 -0
- data/src/templates/components/collection_loader_view.jst.ejs +6 -0
- data/src/templates/components/form_alert.jst.ejs +4 -0
- data/src/templates/components/grid_view.jst.ejs +11 -0
- data/src/templates/components/grid_view_empty_text.jst.ejs +3 -0
- data/src/templates/components/load_mask.jst.ejs +5 -0
- data/src/templates/components/nav_bar.jst.ejs +4 -0
- data/src/templates/components/pagination.jst.ejs +10 -0
- data/src/templates/containers/basic.jst.ejs +1 -0
- data/src/templates/containers/tab_selector_container.jst.ejs +12 -0
- data/src/templates/containers/tab_view.jst.ejs +2 -0
- data/src/templates/containers/toolbar_wrapper.jst.ejs +1 -0
- data/src/templates/fields/button_field.jst.ejs +2 -0
- data/src/templates/fields/button_field_link.jst.ejs +6 -0
- data/src/templates/fields/checkbox_array.jst.ejs +4 -0
- data/src/templates/fields/checkbox_array_item.jst.ejs +3 -0
- data/src/templates/fields/checkbox_field.jst.ejs +10 -0
- data/src/templates/fields/file_upload_field.jst.ejs +10 -0
- data/src/templates/fields/hidden_field.jst.ejs +1 -0
- data/src/templates/fields/select_field.jst.ejs +11 -0
- data/src/templates/fields/text_area_field.jst.ejs +11 -0
- data/src/templates/fields/text_field.jst.ejs +16 -0
- data/src/templates/table_view.jst.ejs +4 -0
- data/src/tools/console.coffee +51 -21
- data/src/util.coffee +17 -4
- data/vendor/assets/javascripts/luca-ui-base.js +5304 -0
- data/vendor/assets/javascripts/luca-ui-bootstrap.js +9 -0
- data/vendor/assets/javascripts/luca-ui-development-tools.js +52 -24
- data/vendor/assets/javascripts/luca-ui-development-tools.min.js +1 -1
- data/vendor/assets/javascripts/luca-ui-full.js +1700 -595
- data/vendor/assets/javascripts/luca-ui-full.min.js +7 -6
- data/vendor/assets/javascripts/luca-ui-spec.js +6815 -0
- data/vendor/assets/javascripts/luca-ui-templates.js +92 -24
- data/vendor/assets/javascripts/luca-ui.js +1695 -564
- data/vendor/assets/javascripts/luca-ui.min.js +4 -4
- metadata +69 -28
- data/src/templates/components/bootstrap_form_controls.luca +0 -7
- data/src/templates/components/collection_loader_view.luca +0 -5
- data/src/templates/components/form_alert.luca +0 -3
- data/src/templates/components/grid_view.luca +0 -7
- data/src/templates/components/grid_view_empty_text.luca +0 -3
- data/src/templates/components/load_mask.luca +0 -3
- data/src/templates/components/nav_bar.luca +0 -2
- data/src/templates/containers/basic.luca +0 -1
- data/src/templates/containers/tab_selector_container.luca +0 -8
- data/src/templates/containers/tab_view.luca +0 -2
- data/src/templates/containers/toolbar_wrapper.luca +0 -1
- data/src/templates/fields/button_field.luca +0 -2
- data/src/templates/fields/button_field_link.luca +0 -5
- data/src/templates/fields/checkbox_array.luca +0 -4
- data/src/templates/fields/checkbox_array_item.luca +0 -4
- data/src/templates/fields/checkbox_field.luca +0 -9
- data/src/templates/fields/file_upload_field.luca +0 -8
- data/src/templates/fields/hidden_field.luca +0 -1
- data/src/templates/fields/select_field.luca +0 -8
- data/src/templates/fields/text_area_field.luca +0 -8
- data/src/templates/fields/text_field.luca +0 -17
- data/src/templates/sample/contents.luca +0 -1
- data/src/templates/sample/welcome.luca +0 -1
- data/src/templates/table_view.luca +0 -4
data/CHANGELOG
CHANGED
|
@@ -85,26 +85,26 @@
|
|
|
85
85
|
0.9.1
|
|
86
86
|
- Bugfix Release
|
|
87
87
|
|
|
88
|
-
0.9.2
|
|
88
|
+
0.9.2
|
|
89
89
|
- FormView has errorMessage, successMessage methods which use twitter bootstrap alerts as flash message
|
|
90
90
|
- FormView toolbar accepts new options: true, both, bottom, or top
|
|
91
91
|
- Luca.Collection has a property @remoteFiltering which makes applyFilter always use remote fetch
|
|
92
92
|
- Bugfix in GridView collection change handler
|
|
93
93
|
- Added Luca.isViewPrototype, Luca.isModelPrototype, Luca.isCollectionPrototype helpers
|
|
94
94
|
- Added configuration option to control auto registration of components with the registry
|
|
95
|
-
- Added Luca.parentClass and Luca.inheritanceChain methods for inspecting a component or prototype
|
|
95
|
+
- Added Luca.parentClass and Luca.inheritanceChain methods for inspecting a component or prototype
|
|
96
96
|
- Changed single instance tracking mechanism on CollectionManager. Will throw an error if more than one
|
|
97
97
|
is created without specifying a name.
|
|
98
98
|
- Added Luca.getCollectionManager() helper as an Alias for Luca.CollectionManager.get()
|
|
99
99
|
- Luca.getApplication() and Luca.getCollectionManager() accept a name argument
|
|
100
100
|
- Classes like Luca.Application and Luca.CollectionManager which normally are singletons
|
|
101
|
-
can have more than one instance if a unique name is given
|
|
101
|
+
can have more than one instance if a unique name is given
|
|
102
102
|
|
|
103
103
|
0.9.3
|
|
104
104
|
- CardViews and Controllers set data attributes on their elements for the active card / page
|
|
105
105
|
- Added convenience methods to container 'pluck', 'invoke'
|
|
106
106
|
- Added methods to Controller for ease of autogenerating routes
|
|
107
|
-
- Added beforeInitialize hook on Luca.View
|
|
107
|
+
- Added beforeInitialize hook on Luca.View
|
|
108
108
|
- Luca.View can now automatically configure state machine models by passing `stateful:true`
|
|
109
109
|
in your view definition.
|
|
110
110
|
- Containers will respond to getter attributes set on their components, by defining a getter
|
|
@@ -118,9 +118,9 @@
|
|
|
118
118
|
- adding a Luca.PageController component as an alias for Controller
|
|
119
119
|
|
|
120
120
|
0.9.33
|
|
121
|
-
- added gridSpan property to Luca.View. This will automatically add the span class for you to snap your view to the grid.
|
|
121
|
+
- added gridSpan property to Luca.View. This will automatically add the span class for you to snap your view to the grid.
|
|
122
122
|
Accepts a number 0-12.
|
|
123
|
-
- fixed a bug in CardView.componentElements method with bodyClassName being present
|
|
123
|
+
- fixed a bug in CardView.componentElements method with bodyClassName being present
|
|
124
124
|
- Added LabelView component. A form field which just displays a value.
|
|
125
125
|
|
|
126
126
|
0.9.35
|
|
@@ -134,12 +134,53 @@
|
|
|
134
134
|
|
|
135
135
|
0.9.4
|
|
136
136
|
- Luca::Template can now configure its namespace, removing duplicate sprockets class
|
|
137
|
-
- Luca.Application triggers page:change and sub:page:change events
|
|
137
|
+
- Luca.Application triggers page:change and sub:page:change events
|
|
138
138
|
- Luca.Viewport gets enable / disable method for fluid and fullscreen mode
|
|
139
139
|
- Add configurability to fullscreen behavior on viewport
|
|
140
140
|
|
|
141
141
|
0.9.41
|
|
142
142
|
- Changed asset pipeline payload so that luca-ui uses the index convention
|
|
143
143
|
|
|
144
|
-
0.9.42
|
|
145
|
-
- Added TableView component, which inherits from Luca.components.CollectionView
|
|
144
|
+
0.9.42
|
|
145
|
+
- Added TableView component, which inherits from Luca.components.CollectionView
|
|
146
|
+
- Expose ways of customizing Luca.View internals.
|
|
147
|
+
- Added support for @template property on Luca.View. Behaves the same as @bodyTemplate
|
|
148
|
+
|
|
149
|
+
0.9.45
|
|
150
|
+
- Luca.decorate( componentPrototype ).with( mixinName ), Luca.mixin( mixinName )
|
|
151
|
+
- View mixins use _initializer methods
|
|
152
|
+
- FilterableView mixin for CollectionView classes
|
|
153
|
+
- Added Rails Generator for Luca.Application skeleton. ( thanks @nick-desteffen )
|
|
154
|
+
- Adds ability to pass a function reference as a component. The container will call the function, in
|
|
155
|
+
the context of the container, and use the returned object as the component definition template
|
|
156
|
+
- Adds a defaults property to containers. This will apply the values as defaults to each component.
|
|
157
|
+
- Adds Luca.EventsExt an optional core extension which provides additional event binding sugar
|
|
158
|
+
- Fixes to CollectionView
|
|
159
|
+
- Improved container / component bindings via html data attributes
|
|
160
|
+
- bugfixes in CardView
|
|
161
|
+
|
|
162
|
+
0.9.5
|
|
163
|
+
- Luca.Model gets a 'read' method which will a getter function,
|
|
164
|
+
or get an attribute for the given property you are trying to 'read'
|
|
165
|
+
- CollectionView is modifiable through several mixins:
|
|
166
|
+
- Filterable
|
|
167
|
+
- Paginatable
|
|
168
|
+
- Loadmaskable
|
|
169
|
+
- Introduces component definition helpers: extends,
|
|
170
|
+
behavesAs, triggers, defaultsTo which allow for a more
|
|
171
|
+
"literate" component definiton style
|
|
172
|
+
- View helpers moved into mixins:
|
|
173
|
+
- StateModel
|
|
174
|
+
- EnhancedProperties
|
|
175
|
+
- CollectionEventBindings
|
|
176
|
+
- ApplicationEventBindings
|
|
177
|
+
- Changed syntax for @componentEvents configuration on Luca.core.Container.
|
|
178
|
+
- now accepts role, name, or getter method
|
|
179
|
+
- now accepts * for component, to bind to the same event on all components
|
|
180
|
+
|
|
181
|
+
0.9.65
|
|
182
|
+
- Luca.core.Container components can now be configured with a @container property
|
|
183
|
+
which accepts any valid CSS selector so long as it is scoped within that container view's @$el.
|
|
184
|
+
Previously required an element with a specific ID which made it harder to build extendable components
|
|
185
|
+
with specific render targets
|
|
186
|
+
|
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
|
@@ -39,6 +39,7 @@ GEM
|
|
|
39
39
|
rack (1.3.5)
|
|
40
40
|
rack-protection (1.1.4)
|
|
41
41
|
rack
|
|
42
|
+
rake (0.9.2.2)
|
|
42
43
|
rb-fsevent (0.9.1)
|
|
43
44
|
ruby_parser (2.3.1)
|
|
44
45
|
sexp_processor (~> 3.0)
|
|
@@ -70,6 +71,7 @@ DEPENDENCIES
|
|
|
70
71
|
guard-sprockets2
|
|
71
72
|
haml
|
|
72
73
|
pry
|
|
74
|
+
rake
|
|
73
75
|
rb-fsevent (>= 0.9.1)
|
|
74
76
|
sass (>= 3.1.10)
|
|
75
77
|
sinatra
|
data/README.md
CHANGED
|
@@ -70,6 +70,11 @@ Or you can just use the dependencies we rely on. Latest backbone.js, underscore
|
|
|
70
70
|
</html>
|
|
71
71
|
```
|
|
72
72
|
|
|
73
|
+
## Rails Generator
|
|
74
|
+
To generate Luca application skeleton run:
|
|
75
|
+
`rails generate luca:application <app_name>`
|
|
76
|
+
This will generate a controller, view, route, and the Luca application structure under assets/javascripts/<app_name>
|
|
77
|
+
|
|
73
78
|
## Interactive Documentation and Examples
|
|
74
79
|
|
|
75
80
|
[View the Sandbox](http://datapimp.com/luca)
|
|
@@ -1,31 +1,5 @@
|
|
|
1
|
-
//
|
|
2
|
-
//
|
|
3
|
-
//
|
|
4
|
-
//
|
|
5
|
-
// Oliver Steele's Functional, and John Resig's Micro-Templating.
|
|
6
|
-
// For all details and documentation:
|
|
7
|
-
// http://documentcloud.github.com/underscore
|
|
8
|
-
(function(){function q(a,c,d){if(a===c)return a!==0||1/a==1/c;if(a==null||c==null)return a===c;if(a._chain)a=a._wrapped;if(c._chain)c=c._wrapped;if(a.isEqual&&b.isFunction(a.isEqual))return a.isEqual(c);if(c.isEqual&&b.isFunction(c.isEqual))return c.isEqual(a);var e=l.call(a);if(e!=l.call(c))return false;switch(e){case "[object String]":return a==String(c);case "[object Number]":return a!=+a?c!=+c:a==0?1/a==1/c:a==+c;case "[object Date]":case "[object Boolean]":return+a==+c;case "[object RegExp]":return a.source==
|
|
9
|
-
c.source&&a.global==c.global&&a.multiline==c.multiline&&a.ignoreCase==c.ignoreCase}if(typeof a!="object"||typeof c!="object")return false;for(var f=d.length;f--;)if(d[f]==a)return true;d.push(a);var f=0,g=true;if(e=="[object Array]"){if(f=a.length,g=f==c.length)for(;f--;)if(!(g=f in a==f in c&&q(a[f],c[f],d)))break}else{if("constructor"in a!="constructor"in c||a.constructor!=c.constructor)return false;for(var h in a)if(b.has(a,h)&&(f++,!(g=b.has(c,h)&&q(a[h],c[h],d))))break;if(g){for(h in c)if(b.has(c,
|
|
10
|
-
h)&&!f--)break;g=!f}}d.pop();return g}var r=this,G=r._,n={},k=Array.prototype,o=Object.prototype,i=k.slice,H=k.unshift,l=o.toString,I=o.hasOwnProperty,w=k.forEach,x=k.map,y=k.reduce,z=k.reduceRight,A=k.filter,B=k.every,C=k.some,p=k.indexOf,D=k.lastIndexOf,o=Array.isArray,J=Object.keys,s=Function.prototype.bind,b=function(a){return new m(a)};if(typeof exports!=="undefined"){if(typeof module!=="undefined"&&module.exports)exports=module.exports=b;exports._=b}else r._=b;b.VERSION="1.3.1";var j=b.each=
|
|
11
|
-
b.forEach=function(a,c,d){if(a!=null)if(w&&a.forEach===w)a.forEach(c,d);else if(a.length===+a.length)for(var e=0,f=a.length;e<f;e++){if(e in a&&c.call(d,a[e],e,a)===n)break}else for(e in a)if(b.has(a,e)&&c.call(d,a[e],e,a)===n)break};b.map=b.collect=function(a,c,b){var e=[];if(a==null)return e;if(x&&a.map===x)return a.map(c,b);j(a,function(a,g,h){e[e.length]=c.call(b,a,g,h)});if(a.length===+a.length)e.length=a.length;return e};b.reduce=b.foldl=b.inject=function(a,c,d,e){var f=arguments.length>2;a==
|
|
12
|
-
null&&(a=[]);if(y&&a.reduce===y)return e&&(c=b.bind(c,e)),f?a.reduce(c,d):a.reduce(c);j(a,function(a,b,i){f?d=c.call(e,d,a,b,i):(d=a,f=true)});if(!f)throw new TypeError("Reduce of empty array with no initial value");return d};b.reduceRight=b.foldr=function(a,c,d,e){var f=arguments.length>2;a==null&&(a=[]);if(z&&a.reduceRight===z)return e&&(c=b.bind(c,e)),f?a.reduceRight(c,d):a.reduceRight(c);var g=b.toArray(a).reverse();e&&!f&&(c=b.bind(c,e));return f?b.reduce(g,c,d,e):b.reduce(g,c)};b.find=b.detect=
|
|
13
|
-
function(a,c,b){var e;E(a,function(a,g,h){if(c.call(b,a,g,h))return e=a,true});return e};b.filter=b.select=function(a,c,b){var e=[];if(a==null)return e;if(A&&a.filter===A)return a.filter(c,b);j(a,function(a,g,h){c.call(b,a,g,h)&&(e[e.length]=a)});return e};b.reject=function(a,c,b){var e=[];if(a==null)return e;j(a,function(a,g,h){c.call(b,a,g,h)||(e[e.length]=a)});return e};b.every=b.all=function(a,c,b){var e=true;if(a==null)return e;if(B&&a.every===B)return a.every(c,b);j(a,function(a,g,h){if(!(e=
|
|
14
|
-
e&&c.call(b,a,g,h)))return n});return e};var E=b.some=b.any=function(a,c,d){c||(c=b.identity);var e=false;if(a==null)return e;if(C&&a.some===C)return a.some(c,d);j(a,function(a,b,h){if(e||(e=c.call(d,a,b,h)))return n});return!!e};b.include=b.contains=function(a,c){var b=false;if(a==null)return b;return p&&a.indexOf===p?a.indexOf(c)!=-1:b=E(a,function(a){return a===c})};b.invoke=function(a,c){var d=i.call(arguments,2);return b.map(a,function(a){return(b.isFunction(c)?c||a:a[c]).apply(a,d)})};b.pluck=
|
|
15
|
-
function(a,c){return b.map(a,function(a){return a[c]})};b.max=function(a,c,d){if(!c&&b.isArray(a))return Math.max.apply(Math,a);if(!c&&b.isEmpty(a))return-Infinity;var e={computed:-Infinity};j(a,function(a,b,h){b=c?c.call(d,a,b,h):a;b>=e.computed&&(e={value:a,computed:b})});return e.value};b.min=function(a,c,d){if(!c&&b.isArray(a))return Math.min.apply(Math,a);if(!c&&b.isEmpty(a))return Infinity;var e={computed:Infinity};j(a,function(a,b,h){b=c?c.call(d,a,b,h):a;b<e.computed&&(e={value:a,computed:b})});
|
|
16
|
-
return e.value};b.shuffle=function(a){var b=[],d;j(a,function(a,f){f==0?b[0]=a:(d=Math.floor(Math.random()*(f+1)),b[f]=b[d],b[d]=a)});return b};b.sortBy=function(a,c,d){return b.pluck(b.map(a,function(a,b,g){return{value:a,criteria:c.call(d,a,b,g)}}).sort(function(a,b){var c=a.criteria,d=b.criteria;return c<d?-1:c>d?1:0}),"value")};b.groupBy=function(a,c){var d={},e=b.isFunction(c)?c:function(a){return a[c]};j(a,function(a,b){var c=e(a,b);(d[c]||(d[c]=[])).push(a)});return d};b.sortedIndex=function(a,
|
|
17
|
-
c,d){d||(d=b.identity);for(var e=0,f=a.length;e<f;){var g=e+f>>1;d(a[g])<d(c)?e=g+1:f=g}return e};b.toArray=function(a){return!a?[]:a.toArray?a.toArray():b.isArray(a)?i.call(a):b.isArguments(a)?i.call(a):b.values(a)};b.size=function(a){return b.toArray(a).length};b.first=b.head=function(a,b,d){return b!=null&&!d?i.call(a,0,b):a[0]};b.initial=function(a,b,d){return i.call(a,0,a.length-(b==null||d?1:b))};b.last=function(a,b,d){return b!=null&&!d?i.call(a,Math.max(a.length-b,0)):a[a.length-1]};b.rest=
|
|
18
|
-
b.tail=function(a,b,d){return i.call(a,b==null||d?1:b)};b.compact=function(a){return b.filter(a,function(a){return!!a})};b.flatten=function(a,c){return b.reduce(a,function(a,e){if(b.isArray(e))return a.concat(c?e:b.flatten(e));a[a.length]=e;return a},[])};b.without=function(a){return b.difference(a,i.call(arguments,1))};b.uniq=b.unique=function(a,c,d){var d=d?b.map(a,d):a,e=[];b.reduce(d,function(d,g,h){if(0==h||(c===true?b.last(d)!=g:!b.include(d,g)))d[d.length]=g,e[e.length]=a[h];return d},[]);
|
|
19
|
-
return e};b.union=function(){return b.uniq(b.flatten(arguments,true))};b.intersection=b.intersect=function(a){var c=i.call(arguments,1);return b.filter(b.uniq(a),function(a){return b.every(c,function(c){return b.indexOf(c,a)>=0})})};b.difference=function(a){var c=b.flatten(i.call(arguments,1));return b.filter(a,function(a){return!b.include(c,a)})};b.zip=function(){for(var a=i.call(arguments),c=b.max(b.pluck(a,"length")),d=Array(c),e=0;e<c;e++)d[e]=b.pluck(a,""+e);return d};b.indexOf=function(a,c,
|
|
20
|
-
d){if(a==null)return-1;var e;if(d)return d=b.sortedIndex(a,c),a[d]===c?d:-1;if(p&&a.indexOf===p)return a.indexOf(c);for(d=0,e=a.length;d<e;d++)if(d in a&&a[d]===c)return d;return-1};b.lastIndexOf=function(a,b){if(a==null)return-1;if(D&&a.lastIndexOf===D)return a.lastIndexOf(b);for(var d=a.length;d--;)if(d in a&&a[d]===b)return d;return-1};b.range=function(a,b,d){arguments.length<=1&&(b=a||0,a=0);for(var d=arguments[2]||1,e=Math.max(Math.ceil((b-a)/d),0),f=0,g=Array(e);f<e;)g[f++]=a,a+=d;return g};
|
|
21
|
-
var F=function(){};b.bind=function(a,c){var d,e;if(a.bind===s&&s)return s.apply(a,i.call(arguments,1));if(!b.isFunction(a))throw new TypeError;e=i.call(arguments,2);return d=function(){if(!(this instanceof d))return a.apply(c,e.concat(i.call(arguments)));F.prototype=a.prototype;var b=new F,g=a.apply(b,e.concat(i.call(arguments)));return Object(g)===g?g:b}};b.bindAll=function(a){var c=i.call(arguments,1);c.length==0&&(c=b.functions(a));j(c,function(c){a[c]=b.bind(a[c],a)});return a};b.memoize=function(a,
|
|
22
|
-
c){var d={};c||(c=b.identity);return function(){var e=c.apply(this,arguments);return b.has(d,e)?d[e]:d[e]=a.apply(this,arguments)}};b.delay=function(a,b){var d=i.call(arguments,2);return setTimeout(function(){return a.apply(a,d)},b)};b.defer=function(a){return b.delay.apply(b,[a,1].concat(i.call(arguments,1)))};b.throttle=function(a,c){var d,e,f,g,h,i=b.debounce(function(){h=g=false},c);return function(){d=this;e=arguments;var b;f||(f=setTimeout(function(){f=null;h&&a.apply(d,e);i()},c));g?h=true:
|
|
23
|
-
a.apply(d,e);i();g=true}};b.debounce=function(a,b){var d;return function(){var e=this,f=arguments;clearTimeout(d);d=setTimeout(function(){d=null;a.apply(e,f)},b)}};b.once=function(a){var b=false,d;return function(){if(b)return d;b=true;return d=a.apply(this,arguments)}};b.wrap=function(a,b){return function(){var d=[a].concat(i.call(arguments,0));return b.apply(this,d)}};b.compose=function(){var a=arguments;return function(){for(var b=arguments,d=a.length-1;d>=0;d--)b=[a[d].apply(this,b)];return b[0]}};
|
|
24
|
-
b.after=function(a,b){return a<=0?b():function(){if(--a<1)return b.apply(this,arguments)}};b.keys=J||function(a){if(a!==Object(a))throw new TypeError("Invalid object");var c=[],d;for(d in a)b.has(a,d)&&(c[c.length]=d);return c};b.values=function(a){return b.map(a,b.identity)};b.functions=b.methods=function(a){var c=[],d;for(d in a)b.isFunction(a[d])&&c.push(d);return c.sort()};b.extend=function(a){j(i.call(arguments,1),function(b){for(var d in b)a[d]=b[d]});return a};b.defaults=function(a){j(i.call(arguments,
|
|
25
|
-
1),function(b){for(var d in b)a[d]==null&&(a[d]=b[d])});return a};b.clone=function(a){return!b.isObject(a)?a:b.isArray(a)?a.slice():b.extend({},a)};b.tap=function(a,b){b(a);return a};b.isEqual=function(a,b){return q(a,b,[])};b.isEmpty=function(a){if(b.isArray(a)||b.isString(a))return a.length===0;for(var c in a)if(b.has(a,c))return false;return true};b.isElement=function(a){return!!(a&&a.nodeType==1)};b.isArray=o||function(a){return l.call(a)=="[object Array]"};b.isObject=function(a){return a===Object(a)};
|
|
26
|
-
b.isArguments=function(a){return l.call(a)=="[object Arguments]"};if(!b.isArguments(arguments))b.isArguments=function(a){return!(!a||!b.has(a,"callee"))};b.isFunction=function(a){return l.call(a)=="[object Function]"};b.isString=function(a){return l.call(a)=="[object String]"};b.isNumber=function(a){return l.call(a)=="[object Number]"};b.isNaN=function(a){return a!==a};b.isBoolean=function(a){return a===true||a===false||l.call(a)=="[object Boolean]"};b.isDate=function(a){return l.call(a)=="[object Date]"};
|
|
27
|
-
b.isRegExp=function(a){return l.call(a)=="[object RegExp]"};b.isNull=function(a){return a===null};b.isUndefined=function(a){return a===void 0};b.has=function(a,b){return I.call(a,b)};b.noConflict=function(){r._=G;return this};b.identity=function(a){return a};b.times=function(a,b,d){for(var e=0;e<a;e++)b.call(d,e)};b.escape=function(a){return(""+a).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'").replace(/\//g,"/")};b.mixin=function(a){j(b.functions(a),
|
|
28
|
-
function(c){K(c,b[c]=a[c])})};var L=0;b.uniqueId=function(a){var b=L++;return a?a+b:b};b.templateSettings={evaluate:/<%([\s\S]+?)%>/g,interpolate:/<%=([\s\S]+?)%>/g,escape:/<%-([\s\S]+?)%>/g};var t=/.^/,u=function(a){return a.replace(/\\\\/g,"\\").replace(/\\'/g,"'")};b.template=function(a,c){var d=b.templateSettings,d="var __p=[],print=function(){__p.push.apply(__p,arguments);};with(obj||{}){__p.push('"+a.replace(/\\/g,"\\\\").replace(/'/g,"\\'").replace(d.escape||t,function(a,b){return"',_.escape("+
|
|
29
|
-
u(b)+"),'"}).replace(d.interpolate||t,function(a,b){return"',"+u(b)+",'"}).replace(d.evaluate||t,function(a,b){return"');"+u(b).replace(/[\r\n\t]/g," ")+";__p.push('"}).replace(/\r/g,"\\r").replace(/\n/g,"\\n").replace(/\t/g,"\\t")+"');}return __p.join('');",e=new Function("obj","_",d);return c?e(c,b):function(a){return e.call(this,a,b)}};b.chain=function(a){return b(a).chain()};var m=function(a){this._wrapped=a};b.prototype=m.prototype;var v=function(a,c){return c?b(a).chain():a},K=function(a,c){m.prototype[a]=
|
|
30
|
-
function(){var a=i.call(arguments);H.call(a,this._wrapped);return v(c.apply(b,a),this._chain)}};b.mixin(b);j("pop,push,reverse,shift,sort,splice,unshift".split(","),function(a){var b=k[a];m.prototype[a]=function(){var d=this._wrapped;b.apply(d,arguments);var e=d.length;(a=="shift"||a=="splice")&&e===0&&delete d[0];return v(d,this._chain)}});j(["concat","join","slice"],function(a){var b=k[a];m.prototype[a]=function(){return v(b.apply(this._wrapped,arguments),this._chain)}});m.prototype.chain=function(){this._chain=
|
|
31
|
-
true;return this};m.prototype.value=function(){return this._wrapped}}).call(this);
|
|
1
|
+
// Underscore.js 1.4.2
|
|
2
|
+
// http://underscorejs.org
|
|
3
|
+
// (c) 2009-2012 Jeremy Ashkenas, DocumentCloud Inc.
|
|
4
|
+
// Underscore may be freely distributed under the MIT license.
|
|
5
|
+
(function(){var e=this,t=e._,n={},r=Array.prototype,i=Object.prototype,s=Function.prototype,o=r.push,u=r.slice,a=r.concat,f=r.unshift,l=i.toString,c=i.hasOwnProperty,h=r.forEach,p=r.map,d=r.reduce,v=r.reduceRight,m=r.filter,g=r.every,y=r.some,b=r.indexOf,w=r.lastIndexOf,E=Array.isArray,S=Object.keys,x=s.bind,T=function(e){if(e instanceof T)return e;if(!(this instanceof T))return new T(e);this._wrapped=e};typeof exports!="undefined"?(typeof module!="undefined"&&module.exports&&(exports=module.exports=T),exports._=T):e._=T,T.VERSION="1.4.2";var N=T.each=T.forEach=function(e,t,r){if(e==null)return;if(h&&e.forEach===h)e.forEach(t,r);else if(e.length===+e.length){for(var i=0,s=e.length;i<s;i++)if(t.call(r,e[i],i,e)===n)return}else for(var o in e)if(T.has(e,o)&&t.call(r,e[o],o,e)===n)return};T.map=T.collect=function(e,t,n){var r=[];return e==null?r:p&&e.map===p?e.map(t,n):(N(e,function(e,i,s){r[r.length]=t.call(n,e,i,s)}),r)},T.reduce=T.foldl=T.inject=function(e,t,n,r){var i=arguments.length>2;e==null&&(e=[]);if(d&&e.reduce===d)return r&&(t=T.bind(t,r)),i?e.reduce(t,n):e.reduce(t);N(e,function(e,s,o){i?n=t.call(r,n,e,s,o):(n=e,i=!0)});if(!i)throw new TypeError("Reduce of empty array with no initial value");return n},T.reduceRight=T.foldr=function(e,t,n,r){var i=arguments.length>2;e==null&&(e=[]);if(v&&e.reduceRight===v)return r&&(t=T.bind(t,r)),arguments.length>2?e.reduceRight(t,n):e.reduceRight(t);var s=e.length;if(s!==+s){var o=T.keys(e);s=o.length}N(e,function(u,a,f){a=o?o[--s]:--s,i?n=t.call(r,n,e[a],a,f):(n=e[a],i=!0)});if(!i)throw new TypeError("Reduce of empty array with no initial value");return n},T.find=T.detect=function(e,t,n){var r;return C(e,function(e,i,s){if(t.call(n,e,i,s))return r=e,!0}),r},T.filter=T.select=function(e,t,n){var r=[];return e==null?r:m&&e.filter===m?e.filter(t,n):(N(e,function(e,i,s){t.call(n,e,i,s)&&(r[r.length]=e)}),r)},T.reject=function(e,t,n){var r=[];return e==null?r:(N(e,function(e,i,s){t.call(n,e,i,s)||(r[r.length]=e)}),r)},T.every=T.all=function(e,t,r){t||(t=T.identity);var i=!0;return e==null?i:g&&e.every===g?e.every(t,r):(N(e,function(e,s,o){if(!(i=i&&t.call(r,e,s,o)))return n}),!!i)};var C=T.some=T.any=function(e,t,r){t||(t=T.identity);var i=!1;return e==null?i:y&&e.some===y?e.some(t,r):(N(e,function(e,s,o){if(i||(i=t.call(r,e,s,o)))return n}),!!i)};T.contains=T.include=function(e,t){var n=!1;return e==null?n:b&&e.indexOf===b?e.indexOf(t)!=-1:(n=C(e,function(e){return e===t}),n)},T.invoke=function(e,t){var n=u.call(arguments,2);return T.map(e,function(e){return(T.isFunction(t)?t:e[t]).apply(e,n)})},T.pluck=function(e,t){return T.map(e,function(e){return e[t]})},T.where=function(e,t){return T.isEmpty(t)?[]:T.filter(e,function(e){for(var n in t)if(t[n]!==e[n])return!1;return!0})},T.max=function(e,t,n){if(!t&&T.isArray(e)&&e[0]===+e[0]&&e.length<65535)return Math.max.apply(Math,e);if(!t&&T.isEmpty(e))return-Infinity;var r={computed:-Infinity};return N(e,function(e,i,s){var o=t?t.call(n,e,i,s):e;o>=r.computed&&(r={value:e,computed:o})}),r.value},T.min=function(e,t,n){if(!t&&T.isArray(e)&&e[0]===+e[0]&&e.length<65535)return Math.min.apply(Math,e);if(!t&&T.isEmpty(e))return Infinity;var r={computed:Infinity};return N(e,function(e,i,s){var o=t?t.call(n,e,i,s):e;o<r.computed&&(r={value:e,computed:o})}),r.value},T.shuffle=function(e){var t,n=0,r=[];return N(e,function(e){t=T.random(n++),r[n-1]=r[t],r[t]=e}),r};var k=function(e){return T.isFunction(e)?e:function(t){return t[e]}};T.sortBy=function(e,t,n){var r=k(t);return T.pluck(T.map(e,function(e,t,i){return{value:e,index:t,criteria:r.call(n,e,t,i)}}).sort(function(e,t){var n=e.criteria,r=t.criteria;if(n!==r){if(n>r||n===void 0)return 1;if(n<r||r===void 0)return-1}return e.index<t.index?-1:1}),"value")};var L=function(e,t,n,r){var i={},s=k(t);return N(e,function(t,o){var u=s.call(n,t,o,e);r(i,u,t)}),i};T.groupBy=function(e,t,n){return L(e,t,n,function(e,t,n){(T.has(e,t)?e[t]:e[t]=[]).push(n)})},T.countBy=function(e,t,n){return L(e,t,n,function(e,t,n){T.has(e,t)||(e[t]=0),e[t]++})},T.sortedIndex=function(e,t,n,r){n=n==null?T.identity:k(n);var i=n.call(r,t),s=0,o=e.length;while(s<o){var u=s+o>>>1;n.call(r,e[u])<i?s=u+1:o=u}return s},T.toArray=function(e){return e?e.length===+e.length?u.call(e):T.values(e):[]},T.size=function(e){return e.length===+e.length?e.length:T.keys(e).length},T.first=T.head=T.take=function(e,t,n){return t!=null&&!n?u.call(e,0,t):e[0]},T.initial=function(e,t,n){return u.call(e,0,e.length-(t==null||n?1:t))},T.last=function(e,t,n){return t!=null&&!n?u.call(e,Math.max(e.length-t,0)):e[e.length-1]},T.rest=T.tail=T.drop=function(e,t,n){return u.call(e,t==null||n?1:t)},T.compact=function(e){return T.filter(e,function(e){return!!e})};var A=function(e,t,n){return N(e,function(e){T.isArray(e)?t?o.apply(n,e):A(e,t,n):n.push(e)}),n};T.flatten=function(e,t){return A(e,t,[])},T.without=function(e){return T.difference(e,u.call(arguments,1))},T.uniq=T.unique=function(e,t,n,r){var i=n?T.map(e,n,r):e,s=[],o=[];return N(i,function(n,r){if(t?!r||o[o.length-1]!==n:!T.contains(o,n))o.push(n),s.push(e[r])}),s},T.union=function(){return T.uniq(a.apply(r,arguments))},T.intersection=function(e){var t=u.call(arguments,1);return T.filter(T.uniq(e),function(e){return T.every(t,function(t){return T.indexOf(t,e)>=0})})},T.difference=function(e){var t=a.apply(r,u.call(arguments,1));return T.filter(e,function(e){return!T.contains(t,e)})},T.zip=function(){var e=u.call(arguments),t=T.max(T.pluck(e,"length")),n=new Array(t);for(var r=0;r<t;r++)n[r]=T.pluck(e,""+r);return n},T.object=function(e,t){var n={};for(var r=0,i=e.length;r<i;r++)t?n[e[r]]=t[r]:n[e[r][0]]=e[r][1];return n},T.indexOf=function(e,t,n){if(e==null)return-1;var r=0,i=e.length;if(n){if(typeof n!="number")return r=T.sortedIndex(e,t),e[r]===t?r:-1;r=n<0?Math.max(0,i+n):n}if(b&&e.indexOf===b)return e.indexOf(t,n);for(;r<i;r++)if(e[r]===t)return r;return-1},T.lastIndexOf=function(e,t,n){if(e==null)return-1;var r=n!=null;if(w&&e.lastIndexOf===w)return r?e.lastIndexOf(t,n):e.lastIndexOf(t);var i=r?n:e.length;while(i--)if(e[i]===t)return i;return-1},T.range=function(e,t,n){arguments.length<=1&&(t=e||0,e=0),n=arguments[2]||1;var r=Math.max(Math.ceil((t-e)/n),0),i=0,s=new Array(r);while(i<r)s[i++]=e,e+=n;return s};var O=function(){};T.bind=function(t,n){var r,i;if(t.bind===x&&x)return x.apply(t,u.call(arguments,1));if(!T.isFunction(t))throw new TypeError;return i=u.call(arguments,2),r=function(){if(this instanceof r){O.prototype=t.prototype;var e=new O,s=t.apply(e,i.concat(u.call(arguments)));return Object(s)===s?s:e}return t.apply(n,i.concat(u.call(arguments)))}},T.bindAll=function(e){var t=u.call(arguments,1);return t.length==0&&(t=T.functions(e)),N(t,function(t){e[t]=T.bind(e[t],e)}),e},T.memoize=function(e,t){var n={};return t||(t=T.identity),function(){var r=t.apply(this,arguments);return T.has(n,r)?n[r]:n[r]=e.apply(this,arguments)}},T.delay=function(e,t){var n=u.call(arguments,2);return setTimeout(function(){return e.apply(null,n)},t)},T.defer=function(e){return T.delay.apply(T,[e,1].concat(u.call(arguments,1)))},T.throttle=function(e,t){var n,r,i,s,o,u,a=T.debounce(function(){o=s=!1},t);return function(){n=this,r=arguments;var f=function(){i=null,o&&(u=e.apply(n,r)),a()};return i||(i=setTimeout(f,t)),s?o=!0:(s=!0,u=e.apply(n,r)),a(),u}},T.debounce=function(e,t,n){var r,i;return function(){var s=this,o=arguments,u=function(){r=null,n||(i=e.apply(s,o))},a=n&&!r;return clearTimeout(r),r=setTimeout(u,t),a&&(i=e.apply(s,o)),i}},T.once=function(e){var t=!1,n;return function(){return t?n:(t=!0,n=e.apply(this,arguments),e=null,n)}},T.wrap=function(e,t){return function(){var n=[e];return o.apply(n,arguments),t.apply(this,n)}},T.compose=function(){var e=arguments;return function(){var t=arguments;for(var n=e.length-1;n>=0;n--)t=[e[n].apply(this,t)];return t[0]}},T.after=function(e,t){return e<=0?t():function(){if(--e<1)return t.apply(this,arguments)}},T.keys=S||function(e){if(e!==Object(e))throw new TypeError("Invalid object");var t=[];for(var n in e)T.has(e,n)&&(t[t.length]=n);return t},T.values=function(e){var t=[];for(var n in e)T.has(e,n)&&t.push(e[n]);return t},T.pairs=function(e){var t=[];for(var n in e)T.has(e,n)&&t.push([n,e[n]]);return t},T.invert=function(e){var t={};for(var n in e)T.has(e,n)&&(t[e[n]]=n);return t},T.functions=T.methods=function(e){var t=[];for(var n in e)T.isFunction(e[n])&&t.push(n);return t.sort()},T.extend=function(e){return N(u.call(arguments,1),function(t){for(var n in t)e[n]=t[n]}),e},T.pick=function(e){var t={},n=a.apply(r,u.call(arguments,1));return N(n,function(n){n in e&&(t[n]=e[n])}),t},T.omit=function(e){var t={},n=a.apply(r,u.call(arguments,1));for(var i in e)T.contains(n,i)||(t[i]=e[i]);return t},T.defaults=function(e){return N(u.call(arguments,1),function(t){for(var n in t)e[n]==null&&(e[n]=t[n])}),e},T.clone=function(e){return T.isObject(e)?T.isArray(e)?e.slice():T.extend({},e):e},T.tap=function(e,t){return t(e),e};var M=function(e,t,n,r){if(e===t)return e!==0||1/e==1/t;if(e==null||t==null)return e===t;e instanceof T&&(e=e._wrapped),t instanceof T&&(t=t._wrapped);var i=l.call(e);if(i!=l.call(t))return!1;switch(i){case"[object String]":return e==String(t);case"[object Number]":return e!=+e?t!=+t:e==0?1/e==1/t:e==+t;case"[object Date]":case"[object Boolean]":return+e==+t;case"[object RegExp]":return e.source==t.source&&e.global==t.global&&e.multiline==t.multiline&&e.ignoreCase==t.ignoreCase}if(typeof e!="object"||typeof t!="object")return!1;var s=n.length;while(s--)if(n[s]==e)return r[s]==t;n.push(e),r.push(t);var o=0,u=!0;if(i=="[object Array]"){o=e.length,u=o==t.length;if(u)while(o--)if(!(u=M(e[o],t[o],n,r)))break}else{var a=e.constructor,f=t.constructor;if(a!==f&&!(T.isFunction(a)&&a instanceof a&&T.isFunction(f)&&f instanceof f))return!1;for(var c in e)if(T.has(e,c)){o++;if(!(u=T.has(t,c)&&M(e[c],t[c],n,r)))break}if(u){for(c in t)if(T.has(t,c)&&!(o--))break;u=!o}}return n.pop(),r.pop(),u};T.isEqual=function(e,t){return M(e,t,[],[])},T.isEmpty=function(e){if(e==null)return!0;if(T.isArray(e)||T.isString(e))return e.length===0;for(var t in e)if(T.has(e,t))return!1;return!0},T.isElement=function(e){return!!e&&e.nodeType===1},T.isArray=E||function(e){return l.call(e)=="[object Array]"},T.isObject=function(e){return e===Object(e)},N(["Arguments","Function","String","Number","Date","RegExp"],function(e){T["is"+e]=function(t){return l.call(t)=="[object "+e+"]"}}),T.isArguments(arguments)||(T.isArguments=function(e){return!!e&&!!T.has(e,"callee")}),typeof /./!="function"&&(T.isFunction=function(e){return typeof e=="function"}),T.isFinite=function(e){return T.isNumber(e)&&isFinite(e)},T.isNaN=function(e){return T.isNumber(e)&&e!=+e},T.isBoolean=function(e){return e===!0||e===!1||l.call(e)=="[object Boolean]"},T.isNull=function(e){return e===null},T.isUndefined=function(e){return e===void 0},T.has=function(e,t){return c.call(e,t)},T.noConflict=function(){return e._=t,this},T.identity=function(e){return e},T.times=function(e,t,n){for(var r=0;r<e;r++)t.call(n,r)},T.random=function(e,t){return t==null&&(t=e,e=0),e+(0|Math.random()*(t-e+1))};var _={escape:{"&":"&","<":"<",">":">",'"':""","'":"'","/":"/"}};_.unescape=T.invert(_.escape);var D={escape:new RegExp("["+T.keys(_.escape).join("")+"]","g"),unescape:new RegExp("("+T.keys(_.unescape).join("|")+")","g")};T.each(["escape","unescape"],function(e){T[e]=function(t){return t==null?"":(""+t).replace(D[e],function(t){return _[e][t]})}}),T.result=function(e,t){if(e==null)return null;var n=e[t];return T.isFunction(n)?n.call(e):n},T.mixin=function(e){N(T.functions(e),function(t){var n=T[t]=e[t];T.prototype[t]=function(){var e=[this._wrapped];return o.apply(e,arguments),F.call(this,n.apply(T,e))}})};var P=0;T.uniqueId=function(e){var t=P++;return e?e+t:t},T.templateSettings={evaluate:/<%([\s\S]+?)%>/g,interpolate:/<%=([\s\S]+?)%>/g,escape:/<%-([\s\S]+?)%>/g};var H=/(.)^/,B={"'":"'","\\":"\\","\r":"r","\n":"n"," ":"t","\u2028":"u2028","\u2029":"u2029"},j=/\\|'|\r|\n|\t|\u2028|\u2029/g;T.template=function(e,t,n){n=T.defaults({},n,T.templateSettings);var r=new RegExp([(n.escape||H).source,(n.interpolate||H).source,(n.evaluate||H).source].join("|")+"|$","g"),i=0,s="__p+='";e.replace(r,function(t,n,r,o,u){s+=e.slice(i,u).replace(j,function(e){return"\\"+B[e]}),s+=n?"'+\n((__t=("+n+"))==null?'':_.escape(__t))+\n'":r?"'+\n((__t=("+r+"))==null?'':__t)+\n'":o?"';\n"+o+"\n__p+='":"",i=u+t.length}),s+="';\n",n.variable||(s="with(obj||{}){\n"+s+"}\n"),s="var __t,__p='',__j=Array.prototype.join,print=function(){__p+=__j.call(arguments,'');};\n"+s+"return __p;\n";try{var o=new Function(n.variable||"obj","_",s)}catch(u){throw u.source=s,u}if(t)return o(t,T);var a=function(e){return o.call(this,e,T)};return a.source="function("+(n.variable||"obj")+"){\n"+s+"}",a},T.chain=function(e){return T(e).chain()};var F=function(e){return this._chain?T(e).chain():e};T.mixin(T),N(["pop","push","reverse","shift","sort","splice","unshift"],function(e){var t=r[e];T.prototype[e]=function(){var n=this._wrapped;return t.apply(n,arguments),(e=="shift"||e=="splice")&&n.length===0&&delete n[0],F.call(this,n)}}),N(["concat","join","slice"],function(e){var t=r[e];T.prototype[e]=function(){return F.call(this,t.apply(this._wrapped,arguments))}}),T.extend(T.prototype,{chain:function(){return this._chain=!0,this},value:function(){return this._wrapped}})}).call(this);
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
require 'rails/generators'
|
|
2
|
+
|
|
3
|
+
module Luca
|
|
4
|
+
module Generators
|
|
5
|
+
class ApplicationGenerator < ::Rails::Generators::Base
|
|
6
|
+
source_root File.expand_path('../templates', __FILE__)
|
|
7
|
+
|
|
8
|
+
desc "Generate a base Luca application"
|
|
9
|
+
|
|
10
|
+
argument :application_name, :type => :string, :default => "luca_app"
|
|
11
|
+
|
|
12
|
+
def generate_controller
|
|
13
|
+
template "controller.rb", "app/controllers/#{application_name}_controller.rb"
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def generate_view
|
|
17
|
+
template "index.html.#{template_extension}", "app/views/#{application_name}/index.html.#{template_extension}"
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def generate_route
|
|
21
|
+
sentinel = /\.routes\.draw do(?:\s*\|map\|)?\s*$/
|
|
22
|
+
routing_code = "get '/#{application_name}', :to => '#{application_name}#index'"
|
|
23
|
+
|
|
24
|
+
in_root do
|
|
25
|
+
inject_into_file 'config/routes.rb', "\n #{routing_code}\n", { :after => sentinel, :verbose => false }
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def generate_javascript
|
|
30
|
+
file_extension = javascript_extension == :coffee ? "js.coffee" : "js"
|
|
31
|
+
template "javascripts/application.#{file_extension}", "app/assets/javascripts/#{application_name}/application.#{file_extension}"
|
|
32
|
+
template "javascripts/dependencies.#{file_extension}", "app/assets/javascripts/#{application_name}/dependencies.#{file_extension}"
|
|
33
|
+
template "javascripts/index.#{file_extension}", "app/assets/javascripts/#{application_name}/index.#{file_extension}"
|
|
34
|
+
template "javascripts/router.#{file_extension}", "app/assets/javascripts/#{application_name}/router.#{file_extension}"
|
|
35
|
+
template "javascripts/main.#{file_extension}", "app/assets/javascripts/#{application_name}/views/main.#{file_extension}"
|
|
36
|
+
template "javascripts/config.#{file_extension}", "app/assets/javascripts/#{application_name}/config.#{file_extension}"
|
|
37
|
+
template "javascripts/main.jst.ejs", "app/assets/javascripts/#{application_name}/templates/main.jst.ejs"
|
|
38
|
+
|
|
39
|
+
empty_directory_with_gitkeep("app/assets/javascripts/#{application_name}/models")
|
|
40
|
+
empty_directory_with_gitkeep("app/assets/javascripts/#{application_name}/collections")
|
|
41
|
+
empty_directory_with_gitkeep("app/assets/javascripts/#{application_name}/util")
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
private
|
|
45
|
+
|
|
46
|
+
def application_class_name
|
|
47
|
+
application_name.underscore.camelize
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def javascript_namespace
|
|
51
|
+
application_class_name.gsub("::", "")
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def template_extension
|
|
55
|
+
::Rails.configuration.app_generators.rails[:template_engine] || :erb
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def javascript_extension
|
|
59
|
+
::Rails.configuration.app_generators.rails[:javascript_engine] || :js
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def empty_directory_with_gitkeep(destination)
|
|
63
|
+
empty_directory(destination)
|
|
64
|
+
create_file("#{destination}/.gitkeep")
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
(function() {
|
|
2
|
+
|
|
3
|
+
_.def('<%= javascript_namespace %>.Application')["extends"]('Luca.Application')["with"]({
|
|
4
|
+
name: 'FoobarApp',
|
|
5
|
+
autoBoot: false,
|
|
6
|
+
router: "<%= javascript_namespace %>.Router",
|
|
7
|
+
el: '#viewport',
|
|
8
|
+
components: [
|
|
9
|
+
{
|
|
10
|
+
ctype: 'controller',
|
|
11
|
+
name: 'pages',
|
|
12
|
+
components: [
|
|
13
|
+
{
|
|
14
|
+
type: "main",
|
|
15
|
+
name: "main"
|
|
16
|
+
}
|
|
17
|
+
]
|
|
18
|
+
}
|
|
19
|
+
]
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
$(function() {
|
|
23
|
+
Luca.Collection.bootstrap(window.<%= javascript_namespace %>Bootstrap);
|
|
24
|
+
window.<%= javascript_namespace %>App = new <%= javascript_namespace %>.Application();
|
|
25
|
+
return <%= javascript_namespace %>App.boot();
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
}).call(this);
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
_.def('<%= javascript_namespace %>.Application').extends('Luca.Application').with
|
|
2
|
+
|
|
3
|
+
name: '<%= javascript_namespace %>App'
|
|
4
|
+
autoBoot: false
|
|
5
|
+
router: "<%= javascript_namespace %>.Router"
|
|
6
|
+
el: '#viewport'
|
|
7
|
+
|
|
8
|
+
components:[
|
|
9
|
+
ctype: 'controller'
|
|
10
|
+
name: 'pages'
|
|
11
|
+
components:[
|
|
12
|
+
type: "main"
|
|
13
|
+
name: "main"
|
|
14
|
+
]
|
|
15
|
+
]
|
|
16
|
+
|
|
17
|
+
$ ->
|
|
18
|
+
Luca.Collection.bootstrap( window.<%= javascript_namespace %>Bootstrap )
|
|
19
|
+
window.<%= javascript_namespace %>App = new <%= javascript_namespace %>.Application()
|
|
20
|
+
<%= javascript_namespace %>App.boot()
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
(function() {
|
|
2
|
+
|
|
3
|
+
window.<%= javascript_namespace %> = {
|
|
4
|
+
views: {},
|
|
5
|
+
collections: {},
|
|
6
|
+
models: {},
|
|
7
|
+
util: {},
|
|
8
|
+
components: {}
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
Luca.registry.addNamespace('<%= javascript_namespace %>.views');
|
|
12
|
+
|
|
13
|
+
Luca.Collection.namespace = <%= javascript_namespace %>.collections;
|
|
14
|
+
|
|
15
|
+
}).call(this);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<h1><%= javascript_namespace %></h1>
|
data/lib/luca/rails/version.rb
CHANGED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
describe 'The Collection View', ->
|
|
2
|
+
beforeEach ->
|
|
3
|
+
@collection = new Luca.Collection([
|
|
4
|
+
id: 1, attr: "value_one", filter: "value"
|
|
5
|
+
,
|
|
6
|
+
id: 2, attr: "value_two", filter: "value"
|
|
7
|
+
],
|
|
8
|
+
model: Luca.Model)
|
|
9
|
+
|
|
10
|
+
@view = new Luca.components.CollectionView
|
|
11
|
+
itemTagName: "li"
|
|
12
|
+
itemClassName: "custom-class"
|
|
13
|
+
itemProperty: 'attr'
|
|
14
|
+
collection: @collection
|
|
15
|
+
filterable:
|
|
16
|
+
query:
|
|
17
|
+
filter: "value"
|
|
18
|
+
options:
|
|
19
|
+
sortBy: "filter"
|
|
20
|
+
|
|
21
|
+
@view.render()
|
|
22
|
+
|
|
23
|
+
it "should provide access to the query", ->
|
|
24
|
+
expect( @view.getQuery() ).toBeDefined()
|
|
25
|
+
|
|
26
|
+
it "should provide access to the query options", ->
|
|
27
|
+
expect( @view.getQueryOptions() ).toBeDefined()
|
|
28
|
+
|
|
29
|
+
it "should combine filter and pagination in the options hash", ->
|
|
30
|
+
@view.setPage(5)
|
|
31
|
+
@view.applyFilter({filter:"value"},{sortBy:'filter'})
|
|
32
|
+
|
|
33
|
+
options = @view.getQueryOptions()
|
|
34
|
+
query = @view.getQuery()
|
|
35
|
+
|
|
36
|
+
expect( options.page ).toEqual 5
|
|
37
|
+
expect( options.sortBy ).toEqual 'filter'
|
|
38
|
+
expect( query.filter ).toEqual 'value'
|
|
39
|
+
|
|
40
|
+
it "should render the attributes in the specified list elements", ->
|
|
41
|
+
expect( @view.$html() ).toContain('value_one')
|
|
42
|
+
|
|
43
|
+
it "should render each of the attributes", ->
|
|
44
|
+
expect( @view.$('li.custom-class').length ).toEqual 2
|
|
45
|
+
|
|
46
|
+
it "should locate a dom element by luca model id", ->
|
|
47
|
+
expect( @view.locateItemElement(2).html() ).toContain('value_two')
|
|
48
|
+
|
|
49
|
+
it "should refresh the view when a model is added", ->
|
|
50
|
+
@view.collection.add(attr:"value_three",id:3)
|
|
51
|
+
expect( @view ).toHaveTriggered('after:refresh')
|
|
52
|
+
|
|
53
|
+
it "should refresh the view when a model is removed", ->
|
|
54
|
+
@view.collection.remove( @view.collection.at(0) )
|
|
55
|
+
expect( @view ).toHaveTriggered('after:refresh')
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
describe 'The Collection Multi View component', ->
|
|
2
|
+
it "should share a single collection among multiple collection views", ->
|
|
3
|
+
it "should toggle visibility of one or more views", ->
|
|
4
|
+
it "should share pagination state across the multiple views", ->
|
|
5
|
+
it "should share filter state across the multiple views", ->
|
|
File without changes
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
describe 'The Table View', ->
|
|
2
|
+
beforeEach ->
|
|
3
|
+
@tableView = new Luca.components.TableView
|
|
4
|
+
collection: new Luca.Collection
|
|
5
|
+
columns:[
|
|
6
|
+
"column_one"
|
|
7
|
+
"column_two"
|
|
8
|
+
]
|
|
9
|
+
|
|
10
|
+
$('body').append( @tableView.render() )
|
|
11
|
+
|
|
12
|
+
it 'should accept strings for column config', ->
|
|
13
|
+
expect( @tableView.columns[0].reader ).toEqual("column_one")
|
|
14
|
+
|
|
15
|
+
it 'should automatically determine a missing header config', ->
|
|
16
|
+
expect( @tableView.columns[0].header ).toBeDefined()
|
|
17
|
+
|