├── .meteor
├── .gitignore
├── release
├── platforms
├── .finished-upgraders
├── .id
├── packages
└── versions
├── server
├── publications.cjsx
├── methods
│ └── bundle.cjsx
├── data_auth.cjsx
└── seeds.cjsx
├── client
├── style
│ ├── bundler.css
│ ├── imports
│ │ ├── _imports.sass
│ │ └── _media-queries.sass
│ ├── common
│ │ ├── footer.sass
│ │ ├── icon-button.sass
│ │ └── header.sass
│ ├── home
│ │ ├── carousel.sass
│ │ ├── bundle-thumbnail.sass
│ │ ├── bundle-list.sass
│ │ └── home.sass
│ ├── admin
│ │ ├── main.sass
│ │ └── index.sass
│ ├── auth
│ │ ├── login.sass
│ │ └── signup.sass
│ └── style.sass
├── models
│ ├── bundle.cjsx
│ └── model
│ │ └── model.cjsx
├── components
│ ├── common
│ │ ├── footer.cjsx
│ │ ├── icon-button.cjsx
│ │ └── header.cjsx
│ ├── home
│ │ ├── carousel.cjsx
│ │ ├── bundle-thumbnail.cjsx
│ │ ├── bundle-list.cjsx
│ │ └── home.cjsx
│ ├── admin
│ │ ├── main.cjsx
│ │ ├── index.cjsx
│ │ └── create.cjsx
│ ├── mixins
│ │ └── validation.cjsx
│ ├── app.cjsx
│ └── auth
│ │ ├── login.cjsx
│ │ └── signup.cjsx
├── bundler.cjsx
├── bundler.html
├── actions.cjsx
├── stores
│ ├── errors_store.cjsx
│ ├── bundle_store.cjsx
│ └── authentication_store.cjsx
└── router.cjsx
├── public
├── images
│ └── hero.jpg
└── fonts
│ ├── glyphicons-halflings-regular.eot
│ ├── glyphicons-halflings-regular.ttf
│ ├── glyphicons-halflings-regular.woff
│ ├── glyphicons-halflings-regular.woff2
│ └── glyphicons-halflings-regular.svg
├── lib
├── namespace.cjsx
├── builders.cjsx
├── classnames.js
└── vendor
│ ├── css
│ └── normalize.css
│ └── js
│ └── reflux.js
├── scss.json
└── collections
└── bundles.cjsx
/.meteor/.gitignore:
--------------------------------------------------------------------------------
1 | local
2 |
--------------------------------------------------------------------------------
/server/publications.cjsx:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/.meteor/release:
--------------------------------------------------------------------------------
1 | METEOR@1.1.0.2
2 |
--------------------------------------------------------------------------------
/.meteor/platforms:
--------------------------------------------------------------------------------
1 | server
2 | browser
3 |
--------------------------------------------------------------------------------
/client/style/bundler.css:
--------------------------------------------------------------------------------
1 | /* CSS declarations go here */
2 |
--------------------------------------------------------------------------------
/client/style/imports/_imports.sass:
--------------------------------------------------------------------------------
1 | @import "media-queries"
2 |
--------------------------------------------------------------------------------
/client/style/common/footer.sass:
--------------------------------------------------------------------------------
1 | @import "imports"
2 |
3 | .footer
4 | padding: 15px 10px
5 |
--------------------------------------------------------------------------------
/client/models/bundle.cjsx:
--------------------------------------------------------------------------------
1 | class Models.Bundle extends Models.Model
2 | method: 'createBundle'
3 |
--------------------------------------------------------------------------------
/client/style/home/carousel.sass:
--------------------------------------------------------------------------------
1 | @import "imports"
2 |
3 | .carousel
4 | img
5 | width: 100%
6 |
--------------------------------------------------------------------------------
/public/images/hero.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StephenGrider/bundler/master/public/images/hero.jpg
--------------------------------------------------------------------------------
/lib/namespace.cjsx:
--------------------------------------------------------------------------------
1 | @Stores = {}
2 | @Components = {}
3 | @Collections = {}
4 | @Mixins = {}
5 | @Models = {}
6 |
--------------------------------------------------------------------------------
/scss.json:
--------------------------------------------------------------------------------
1 | {
2 | "enableAutoprefixer": true,
3 | "includePaths": [
4 | "client/style/imports"
5 | ]
6 | }
7 |
--------------------------------------------------------------------------------
/public/fonts/glyphicons-halflings-regular.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StephenGrider/bundler/master/public/fonts/glyphicons-halflings-regular.eot
--------------------------------------------------------------------------------
/public/fonts/glyphicons-halflings-regular.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StephenGrider/bundler/master/public/fonts/glyphicons-halflings-regular.ttf
--------------------------------------------------------------------------------
/public/fonts/glyphicons-halflings-regular.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StephenGrider/bundler/master/public/fonts/glyphicons-halflings-regular.woff
--------------------------------------------------------------------------------
/public/fonts/glyphicons-halflings-regular.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/StephenGrider/bundler/master/public/fonts/glyphicons-halflings-regular.woff2
--------------------------------------------------------------------------------
/client/models/model/model.cjsx:
--------------------------------------------------------------------------------
1 | class Models.Model
2 | constructor: ->
3 | @attrs = {}
4 |
5 | save: (callback) ->
6 | Meteor.call @method, @attrs, callback
7 |
--------------------------------------------------------------------------------
/server/methods/bundle.cjsx:
--------------------------------------------------------------------------------
1 | Meteor.methods
2 | createBundle: (attrs) ->
3 | Collections.Bundles.insert attrs
4 |
5 | editBundle: ->
6 |
7 | deleteBundle: ->
8 |
--------------------------------------------------------------------------------
/client/style/admin/main.sass:
--------------------------------------------------------------------------------
1 | @import "imports"
2 |
3 | .admin-main
4 | .table-header
5 | display: flex
6 | justify-content: flex-end
7 | margin: 0 10px 10px
8 |
--------------------------------------------------------------------------------
/client/components/common/footer.cjsx:
--------------------------------------------------------------------------------
1 | Utils.createComponent ->
2 | name: 'Footer'
3 |
4 | render: ->
5 | return
8 |
--------------------------------------------------------------------------------
/client/bundler.cjsx:
--------------------------------------------------------------------------------
1 | if Meteor.isClient
2 | Meteor.startup ->
3 | Utils.buildStores()
4 | Utils.buildComponents()
5 |
6 | Actions.indexBundle()
7 |
8 | _.defer Router.start
9 |
--------------------------------------------------------------------------------
/client/bundler.html:
--------------------------------------------------------------------------------
1 |
2 | bundler
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/client/components/home/carousel.cjsx:
--------------------------------------------------------------------------------
1 | Utils.createComponent ->
2 | name: 'Carousel'
3 |
4 | render: ->
5 |
6 | I am a carousel
7 |
8 |
--------------------------------------------------------------------------------
/client/components/admin/main.cjsx:
--------------------------------------------------------------------------------
1 | Utils.createComponent ->
2 | name: 'Admin.Main'
3 |
4 | render: ->
5 |
6 | {@props.children}
7 |
8 |
--------------------------------------------------------------------------------
/client/style/common/icon-button.sass:
--------------------------------------------------------------------------------
1 | .icon-button
2 | .badge
3 | color: white
4 | background-color: transparent
5 | padding-right: 3px
6 | padding-left: 3px
7 |
8 | span:last-of-type
9 | padding-right: 5px
10 |
--------------------------------------------------------------------------------
/client/actions.cjsx:
--------------------------------------------------------------------------------
1 | @Actions = Reflux.createActions [
2 | 'indexBundle',
3 | 'getBundle',
4 | 'createBundle',
5 | 'removeBundle',
6 | 'createUser',
7 | 'logoutUser',
8 | 'loginUser',
9 | 'clearErrors',
10 | 'addError'
11 | ]
12 |
--------------------------------------------------------------------------------
/client/style/imports/_media-queries.sass:
--------------------------------------------------------------------------------
1 | @mixin largescreen
2 | @media(max-width: 1024px)
3 | @content
4 |
5 | @mixin mediumscreen
6 | @media(max-width: 768px)
7 | @content
8 |
9 | @mixin smallscreen
10 | @media(max-width: 568px)
11 | @content
12 |
--------------------------------------------------------------------------------
/client/components/mixins/validation.cjsx:
--------------------------------------------------------------------------------
1 | Mixins.Validation =
2 | componentWillMount: ->
3 | Actions.clearErrors()
4 |
5 | errors: ->
6 | return null unless @state.error
7 |
8 |
9 | {@state.error?.reason}
10 |
11 |
--------------------------------------------------------------------------------
/client/style/home/bundle-thumbnail.sass:
--------------------------------------------------------------------------------
1 | @import "imports"
2 |
3 | .bundle-thumbnail
4 | display: inline-block
5 | background: #FEFEFE
6 | border: 2px solid #FAFAFA
7 | margin: 0 2px 15px
8 | min-width: 100%
9 | column-break-inside: avoid
10 | padding: 15px
11 | padding-bottom: 5px
12 |
--------------------------------------------------------------------------------
/.meteor/.finished-upgraders:
--------------------------------------------------------------------------------
1 | # This file contains information which helps Meteor properly upgrade your
2 | # app when you run 'meteor update'. You should check it into version control
3 | # with your project.
4 |
5 | notices-for-0.9.0
6 | notices-for-0.9.1
7 | 0.9.4-platform-file
8 | notices-for-facebook-graph-api-2
9 |
--------------------------------------------------------------------------------
/client/style/home/bundle-list.sass:
--------------------------------------------------------------------------------
1 | @import "imports"
2 |
3 | .bundle-list
4 | column-count: 4
5 | column-gap: 15px
6 | column-fill: auto
7 |
8 | @include largescreen
9 | column-count: 3
10 |
11 | @include mediumscreen
12 | column-count: 2
13 |
14 | @include smallscreen
15 | column-count: 1
16 |
--------------------------------------------------------------------------------
/client/components/home/bundle-thumbnail.cjsx:
--------------------------------------------------------------------------------
1 | Utils.createComponent ->
2 | name: 'BundleThumbnail'
3 |
4 | render: ->
5 |
6 |
![]()
7 |
8 |
{@props.title}
9 |
10 |
11 |
--------------------------------------------------------------------------------
/client/stores/errors_store.cjsx:
--------------------------------------------------------------------------------
1 | Utils.createStore ->
2 | name: 'Errors'
3 | listenables: Actions
4 | error: null
5 |
6 | onAddError: (error) ->
7 | @error = error
8 | @emitChange()
9 |
10 | onClearErrors: ->
11 | @error = null
12 | @emitChange()
13 |
14 | emitChange: ->
15 | @trigger error: @error
16 |
--------------------------------------------------------------------------------
/client/components/home/bundle-list.cjsx:
--------------------------------------------------------------------------------
1 | Utils.createComponent ->
2 | name: 'BundleList'
3 |
4 | render: ->
5 |
6 | {@thumbnails()}
7 |
8 |
9 | thumbnails: ->
10 | for bundle in @props.bundles
11 |
12 |
--------------------------------------------------------------------------------
/collections/bundles.cjsx:
--------------------------------------------------------------------------------
1 | @Collections.Bundles = new Mongo.Collection 'bundles'
2 |
3 | Bundle = new SimpleSchema
4 | title:
5 | type: String
6 | max: 200
7 | # youtubeId:
8 | # type: String
9 | # createdBy:
10 | # type: String
11 | # likes:
12 | # type: Number
13 |
14 | @Collections.Bundles.attachSchema Bundle
15 |
--------------------------------------------------------------------------------
/.meteor/.id:
--------------------------------------------------------------------------------
1 | # This file contains a token that is unique to your project.
2 | # Check it into your repository along with the rest of this directory.
3 | # It can be used for purposes such as:
4 | # - ensuring you don't accidentally deploy one app on top of another
5 | # - providing package authors with aggregated statistics
6 |
7 | 8eak8a1l76mxrqnpo69
8 |
--------------------------------------------------------------------------------
/client/components/common/icon-button.cjsx:
--------------------------------------------------------------------------------
1 | Utils.createComponent ->
2 | name: 'IconButton'
3 |
4 | render: ->
5 |
11 |
--------------------------------------------------------------------------------
/server/data_auth.cjsx:
--------------------------------------------------------------------------------
1 | sameAuthor: (userId, document) ->
2 | userId is document.createdBy
3 |
4 | Collections.Bundles.allow
5 | insert: (userId, document) ->
6 | sameAuthor userId, document
7 |
8 | update: (userId, document) ->
9 | sameAuthor userId, document
10 |
11 | remove: (userId, document) ->
12 | sameAuthor userId, document
13 |
--------------------------------------------------------------------------------
/client/style/admin/index.sass:
--------------------------------------------------------------------------------
1 | @import "imports"
2 |
3 | .admin-index
4 | padding-left: 0
5 |
6 | li
7 | display: block
8 | border: 1px solid #eee
9 | border-bottom: none
10 | display: flex
11 | padding: 10px
12 | flex-direction: row
13 | justify-content: space-between
14 |
15 | li:last-of-type
16 | border-bottom: 1px solid #eee
17 |
--------------------------------------------------------------------------------
/client/style/auth/login.sass:
--------------------------------------------------------------------------------
1 | @import "imports"
2 |
3 | .authentication-login
4 | display: flex
5 | justify-content: center
6 | align-items: center
7 |
8 | input
9 | outline-width: 0
10 | padding: 2px
11 |
12 | form > div
13 | margin-bottom: 10px
14 |
15 | label
16 | width: 70px
17 |
18 | button
19 | display: block
20 | margin: auto
21 |
--------------------------------------------------------------------------------
/client/style/auth/signup.sass:
--------------------------------------------------------------------------------
1 | @import "imports"
2 |
3 | .authentication-signup
4 | display: flex
5 | justify-content: center
6 | align-items: center
7 |
8 | input
9 | outline-width: 0
10 | padding: 2px
11 |
12 | form > div
13 | margin-bottom: 10px
14 |
15 | label
16 | width: 120px
17 |
18 | button
19 | display: block
20 | margin: auto
21 |
--------------------------------------------------------------------------------
/client/style/home/home.sass:
--------------------------------------------------------------------------------
1 | @import "imports"
2 |
3 | .app-content
4 | section
5 | margin-bottom: 70px
6 |
7 | section .row-wrapper
8 | max-width: 70em
9 | margin: 0 auto
10 |
11 | .notes
12 | display: flex
13 | flex-direction: row
14 | flex-wrap: wrap
15 | justify-content: space-between
16 |
17 | .thumbnail
18 | width: 300px
19 | margin-bottom: 0
20 | text-align: center
21 |
--------------------------------------------------------------------------------
/.meteor/packages:
--------------------------------------------------------------------------------
1 | # Meteor packages used by this project, one per line.
2 | # Check this file (and the other files in this directory) into your repository.
3 | #
4 | # 'meteor add' and 'meteor remove' will edit this file for you,
5 | # but you can also edit it by hand.
6 |
7 | meteor-platform
8 | autopublish
9 | insecure
10 | jhartma:cjsx
11 | reactrouter:react-router
12 | aldeed:collection2
13 | accounts-base
14 | accounts-password
15 | fourseven:scss
16 |
--------------------------------------------------------------------------------
/client/components/app.cjsx:
--------------------------------------------------------------------------------
1 | Utils.createComponent ->
2 | name: 'App'
3 | mixins: [
4 | Reflux.connect Stores.Authentication
5 | ReactRouter.Navigation
6 | ]
7 |
8 | componentWillMount: ->
9 | window.navigate = @transitionTo
10 |
11 | render: ->
12 | content = @props.children or
13 |
14 |
15 |
16 | {content}
17 |
18 |
19 |
--------------------------------------------------------------------------------
/client/style/common/header.sass:
--------------------------------------------------------------------------------
1 | @import "imports"
2 |
3 | .header
4 | display: flex
5 | justify-content: space-between
6 | align-items: center
7 | flex-wrap: wrap
8 |
9 | @include mediumscreen
10 | justify-content: center
11 | text-align: center
12 |
13 | h1
14 | display: inline-block
15 |
16 | .nav-button-wrapper
17 | display: flex
18 |
19 | .nav-button
20 | margin-left: 25px
21 | font-size: 16px
22 |
23 | @include mediumscreen
24 | text-align: center
25 | min-width: 100%
26 |
27 | .nav-button
28 | min-width: 20%
29 | margin: auto
30 |
--------------------------------------------------------------------------------
/server/seeds.cjsx:
--------------------------------------------------------------------------------
1 | bundles = [
2 | title: 'Awesome Kit1'
3 | ,
4 | title: 'Awesome Kit2'
5 | ,
6 | title: 'Awesome Kit3'
7 | ,
8 | title: 'Awesome Kit4'
9 | ,
10 | title: 'Awesome Kit5'
11 | ,
12 | title: 'Awesome Kit6'
13 | ,
14 | title: 'Awesome Kit7'
15 | ,
16 | title: 'Awesome Kit8'
17 | ,
18 | title: 'Awesome Kit9'
19 | ,
20 | title: 'Awesome Kit10'
21 | ,
22 | title: 'Awesome Kit11'
23 | ,
24 | title: 'Awesome Kit12'
25 | ]
26 |
27 | if @Collections.Bundles.find().fetch().length < 3
28 | for bundle in bundles
29 | @Collections.Bundles.insert bundle
30 |
--------------------------------------------------------------------------------
/client/stores/bundle_store.cjsx:
--------------------------------------------------------------------------------
1 | Utils.createStore ->
2 | name: 'Bundle'
3 | data: []
4 | listenables: Actions
5 |
6 | getInitialState: ->
7 | bundles: @data
8 |
9 | init: ->
10 | @collection = Collections.Bundles
11 | Tracker.autorun @onIndexBundle
12 |
13 | fetchAll: ->
14 | @data = @collection.find().fetch()
15 | @emitChange()
16 |
17 | onIndexBundle: ->
18 | @fetchAll()
19 |
20 | onCreateBundle: (model) ->
21 | model.save (error) ->
22 | if error
23 | Actions.addError error
24 | else
25 | navigate '/admin/index'
26 | Actions.clearErrors()
27 |
28 | onRemoveBundle: (id) ->
29 | @collection.remove id
30 |
31 | emitChange: ->
32 | @trigger bundles: @data
33 |
--------------------------------------------------------------------------------
/lib/builders.cjsx:
--------------------------------------------------------------------------------
1 | @Utils = {}
2 |
3 | do =>
4 | _storeSpecs = []
5 | _componentSpecs = []
6 |
7 | Utils.createComponent = (spec) ->
8 | _componentSpecs.push spec
9 |
10 | Utils.buildComponents = ->
11 | for spec in _componentSpecs
12 | spec = spec()
13 | namespace = spec.name.split '.'
14 | if namespace.length is 2
15 | Components[namespace[0]] ||= {}
16 | Components[namespace[0]][namespace[1]] = React.createClass spec
17 | else
18 | Components[spec.name] = React.createClass spec
19 |
20 | Utils.createStore = (spec) ->
21 | _storeSpecs.push spec
22 |
23 | Utils.buildStores = ->
24 | for spec in _storeSpecs
25 | spec = spec()
26 | Stores[spec.name] = Reflux.createStore spec
27 |
--------------------------------------------------------------------------------
/client/router.cjsx:
--------------------------------------------------------------------------------
1 | {Router, Route, @Link} = ReactRouter
2 | {history} = ReactRouter.lib.BrowserHistory
3 |
4 | requireAuth = (nextState, transition) ->
5 | unless Meteor.user()
6 | transition.to '/login'
7 |
8 | requireAdmin = (transition) ->
9 |
10 | @Router =
11 | start: ->
12 | React.render
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 | , document.body
22 |
--------------------------------------------------------------------------------
/client/style/style.sass:
--------------------------------------------------------------------------------
1 | @import "imports"
2 |
3 | html
4 | height: 100%
5 |
6 | .no-gutter
7 | margin-left: -15px
8 | margin-right: -15px
9 |
10 | @include mediumscreen
11 | margin-left: -40px
12 | margin-right: -40px
13 |
14 | .bundler-app
15 | display: flex
16 | height: 100%
17 | flex-direction: column
18 |
19 | .header,
20 | .footer
21 | flex: none
22 |
23 | .app-container
24 | display: flex
25 | flex: 1 0 auto
26 | flex-direction: column
27 | padding: 0 15px
28 |
29 | .header
30 | order: -1
31 |
32 | .app-content
33 | flex: 1
34 | margin-top: 15px
35 |
36 | .app-left-nav
37 | padding: 1em
38 |
39 | @include mediumscreen
40 | .app-container
41 | flex-direction: row
42 |
43 | .app-content
44 | padding: 0 20px
45 | margin: 0
46 |
47 | .app-left-nav
48 | flex: 0 0 12em
49 |
--------------------------------------------------------------------------------
/client/components/admin/index.cjsx:
--------------------------------------------------------------------------------
1 | Utils.createComponent ->
2 | name: 'Admin.Index'
3 | mixins: [ Reflux.connect Stores.Bundle ]
4 |
5 | render: ->
6 |
7 | {@tableHeader()}
8 |
9 | {@renderBundle bundle for bundle in @state.bundles}
10 |
11 |
12 |
13 | renderBundle: (bundle) ->
14 |
15 | {bundle.title}
16 |
20 |
21 |
22 | tableHeader: ->
23 |
24 |
25 |
26 | Add
27 |
28 |
29 |
30 |
31 | onRemoveClick: (_id) ->
32 | Actions.removeBundle _id
33 |
--------------------------------------------------------------------------------
/client/stores/authentication_store.cjsx:
--------------------------------------------------------------------------------
1 | Utils.createStore ->
2 | name: 'Authentication'
3 | listenables: Actions
4 |
5 | init: ->
6 | Tracker.autorun @emitChange
7 | @emitChange()
8 |
9 | getInitialState: ->
10 | user: null
11 |
12 | onGetUser: ->
13 | @emitChange()
14 |
15 | onLoginUser: (props) ->
16 | { email, password } = props
17 | Meteor.loginWithPassword email, password, @onAuthenticationSuccess
18 |
19 | onLogoutUser: ->
20 | Meteor.logout()
21 |
22 | onCreateUser: (props) ->
23 | Actions.clearErrors()
24 | Accounts.createUser _.pick(props, 'email', 'username', 'password'),
25 | @onAuthenticationSuccess
26 |
27 | onAuthenticationSuccess: (error) ->
28 | if error
29 | Actions.addError error
30 | else
31 | navigate '/'
32 | @emitChange()
33 | Actions.clearErrors()
34 |
35 | emitChange: ->
36 | @trigger user: Meteor.user()
37 |
--------------------------------------------------------------------------------
/client/components/admin/create.cjsx:
--------------------------------------------------------------------------------
1 | Utils.createComponent ->
2 | name: 'Admin.Create'
3 | mixins: [
4 | Reflux.connect Stores.Errors
5 | Mixins.Validation
6 | ]
7 |
8 | getInitialState: ->
9 | bundle: new Models.Bundle
10 |
11 | render: ->
12 | console.log @state
13 |
14 |
New Bundle
15 |
21 |
22 |
23 | input: (property, label) ->
24 |
25 |
26 |
31 |
32 |
33 | handleChange: (property, event) ->
34 | @state.bundle.attrs[property] = event.target.value
35 | @setState bundle: @state.bundle
36 |
37 | handleSubmit: (e) ->
38 | e.preventDefault()
39 | Actions.createBundle @state.bundle
40 |
--------------------------------------------------------------------------------
/client/components/common/header.cjsx:
--------------------------------------------------------------------------------
1 | Utils.createComponent ->
2 | name: 'Header'
3 |
4 | render: ->
5 | return
18 |
19 | authenticationLink: ->
20 | if @props.user
21 | [
22 |
23 | Account
24 |
25 |
26 | Log Out
27 |
28 | ]
29 | else
30 | [
31 |
32 | Log in
33 |
34 |
35 | Sign up
36 |
37 | ]
38 |
39 | handleLogoutClick: ->
40 | Actions.logoutUser()
41 |
--------------------------------------------------------------------------------
/lib/classnames.js:
--------------------------------------------------------------------------------
1 | /*!
2 | Copyright (c) 2015 Jed Watson.
3 | Licensed under the MIT License (MIT), see
4 | http://jedwatson.github.io/classnames
5 | */
6 |
7 | if(Meteor.isClient){
8 | (function () {
9 | 'use strict';
10 |
11 | function classNames () {
12 |
13 | var classes = '';
14 |
15 | for (var i = 0; i < arguments.length; i++) {
16 | var arg = arguments[i];
17 | if (!arg) continue;
18 |
19 | var argType = typeof arg;
20 |
21 | if ('string' === argType || 'number' === argType) {
22 | classes += ' ' + arg;
23 |
24 | } else if (Array.isArray(arg)) {
25 | classes += ' ' + classNames.apply(null, arg);
26 |
27 | } else if ('object' === argType) {
28 | for (var key in arg) {
29 | if (arg.hasOwnProperty(key) && arg[key]) {
30 | classes += ' ' + key;
31 | }
32 | }
33 | }
34 | }
35 |
36 | return classes.substr(1);
37 | }
38 |
39 | if (typeof module !== 'undefined' && module.exports) {
40 | module.exports = classNames;
41 | } else if (typeof define === 'function' && typeof define.amd === 'object' && define.amd){
42 | // AMD. Register as an anonymous module.
43 | define(function () {
44 | return classNames;
45 | });
46 | } else {
47 | window.classNames = classNames;
48 | }
49 |
50 | }());
51 | }
52 |
--------------------------------------------------------------------------------
/client/components/auth/login.cjsx:
--------------------------------------------------------------------------------
1 | Utils.createComponent ->
2 | name: 'Authentication.Login'
3 | mixins: [
4 | Reflux.connect Stores.Errors
5 | Mixins.Validation
6 | ]
7 |
8 | getInitialState: ->
9 | email: ''
10 | password: ''
11 |
12 | render: ->
13 |
14 |
38 |
39 |
40 | handleSubmit: (e) ->
41 | e.preventDefault()
42 | Actions.clearErrors()
43 | Actions.loginUser @state
44 |
45 | handleChange: (prop, event) ->
46 | state = {}
47 | state[prop] = event.target.value
48 | @setState state
49 |
--------------------------------------------------------------------------------
/client/components/home/home.cjsx:
--------------------------------------------------------------------------------
1 | Utils.createComponent ->
2 | name: 'Home'
3 | mixins: [ Reflux.connect Stores.Bundle ]
4 |
5 | componentDidMount: ->
6 | Actions.indexBundle()
7 |
8 | render: ->
9 |
10 |
13 |
14 |
15 | {@notes()}
16 |
17 |
18 |
21 |
22 |
23 | notes: ->
24 | for note, i in @_notes()
25 |
26 |
27 |
{note.headline}
28 |
29 |
30 |
31 | onChange: (event, payload) ->
32 | @setState bundles: payload
33 |
34 | _notes: ->
35 | [
36 | {
37 | headline: 'Something'
38 | text: 'This is a great site This is a great site This is a great site'
39 | image: ''
40 | }
41 | {
42 | headline: 'Something'
43 | text: 'This is a great site This is a great site This is a great site'
44 | image: ''
45 | }
46 | {
47 | headline: 'Something'
48 | text: 'This is a great site This is a great site This is a great site'
49 | image: ''
50 | }
51 | ]
52 |
--------------------------------------------------------------------------------
/.meteor/versions:
--------------------------------------------------------------------------------
1 | accounts-base@1.2.0
2 | accounts-password@1.1.1
3 | aldeed:collection2@2.3.3
4 | aldeed:simple-schema@1.3.3
5 | autopublish@1.0.3
6 | autoupdate@1.2.1
7 | babel-compiler@5.8.3_1
8 | babel-runtime@0.1.2
9 | base64@1.0.3
10 | binary-heap@1.0.3
11 | blaze@2.1.2
12 | blaze-tools@1.0.3
13 | boilerplate-generator@1.0.3
14 | callback-hook@1.0.3
15 | check@1.0.5
16 | coffeescript@1.0.6
17 | cosmos:browserify@0.5.0
18 | ddp@1.1.0
19 | deps@1.0.7
20 | ejson@1.0.6
21 | email@1.0.6
22 | fastclick@1.0.3
23 | fourseven:scss@3.2.0
24 | geojson-utils@1.0.3
25 | html-tools@1.0.4
26 | htmljs@1.0.4
27 | http@1.1.0
28 | id-map@1.0.3
29 | insecure@1.0.3
30 | jhartma:cjsx@2.4.1
31 | jquery@1.11.3_2
32 | json@1.0.3
33 | jsx@0.1.5
34 | launch-screen@1.0.2
35 | livedata@1.0.13
36 | localstorage@1.0.3
37 | logging@1.0.7
38 | meteor@1.1.6
39 | meteor-platform@1.2.2
40 | minifiers@1.1.5
41 | minimongo@1.0.8
42 | mobile-status-bar@1.0.3
43 | mongo@1.1.0
44 | npm-bcrypt@0.7.8_2
45 | observe-sequence@1.0.6
46 | ordered-dict@1.0.3
47 | random@1.0.3
48 | react@0.1.4
49 | react-meteor-data@0.1.2
50 | react-runtime@0.13.3_2
51 | react-runtime-dev@0.13.3_2
52 | react-runtime-prod@0.13.3_1
53 | reactive-dict@1.1.0
54 | reactive-var@1.0.5
55 | reactrouter:react-router@0.1.2
56 | reload@1.1.3
57 | retry@1.0.3
58 | routepolicy@1.0.5
59 | service-configuration@1.0.4
60 | session@1.1.0
61 | sha@1.0.3
62 | spacebars@1.0.6
63 | spacebars-compiler@1.0.6
64 | srp@1.0.3
65 | templating@1.1.1
66 | tracker@1.0.7
67 | ui@1.0.6
68 | underscore@1.0.3
69 | url@1.0.4
70 | webapp@1.2.0
71 | webapp-hashing@1.0.3
72 |
--------------------------------------------------------------------------------
/client/components/auth/signup.cjsx:
--------------------------------------------------------------------------------
1 | Utils.createComponent ->
2 | name: 'Authentication.Signup'
3 | mixins: [
4 | Reflux.connect Stores.Errors
5 | Mixins.Validation
6 | ]
7 |
8 | getInitialState: ->
9 | username: ''
10 | email: ''
11 | password: ''
12 | passwordConfirm: ''
13 |
14 | render: ->
15 |
16 |
60 |
61 |
62 | handleSubmit: (e) ->
63 | e.preventDefault()
64 | Actions.createUser @state
65 |
66 | handleChange: (prop, event) ->
67 | state = {}
68 | state[prop] = event.target.value
69 | @setState state
70 |
--------------------------------------------------------------------------------
/lib/vendor/css/normalize.css:
--------------------------------------------------------------------------------
1 | /*! normalize.css v3.0.2 | MIT License | git.io/normalize */
2 |
3 | /**
4 | * 1. Set default font family to sans-serif.
5 | * 2. Prevent iOS text size adjust after orientation change, without disabling
6 | * user zoom.
7 | */
8 |
9 | html {
10 | font-family: sans-serif; /* 1 */
11 | -ms-text-size-adjust: 100%; /* 2 */
12 | -webkit-text-size-adjust: 100%; /* 2 */
13 | }
14 |
15 | /**
16 | * Remove default margin.
17 | */
18 |
19 | body {
20 | margin: 0;
21 | }
22 |
23 | /* HTML5 display definitions
24 | ========================================================================== */
25 |
26 | /**
27 | * Correct `block` display not defined for any HTML5 element in IE 8/9.
28 | * Correct `block` display not defined for `details` or `summary` in IE 10/11
29 | * and Firefox.
30 | * Correct `block` display not defined for `main` in IE 11.
31 | */
32 |
33 | article,
34 | aside,
35 | details,
36 | figcaption,
37 | figure,
38 | footer,
39 | header,
40 | hgroup,
41 | main,
42 | menu,
43 | nav,
44 | section,
45 | summary {
46 | display: block;
47 | }
48 |
49 | /**
50 | * 1. Correct `inline-block` display not defined in IE 8/9.
51 | * 2. Normalize vertical alignment of `progress` in Chrome, Firefox, and Opera.
52 | */
53 |
54 | audio,
55 | canvas,
56 | progress,
57 | video {
58 | display: inline-block; /* 1 */
59 | vertical-align: baseline; /* 2 */
60 | }
61 |
62 | /**
63 | * Prevent modern browsers from displaying `audio` without controls.
64 | * Remove excess height in iOS 5 devices.
65 | */
66 |
67 | audio:not([controls]) {
68 | display: none;
69 | height: 0;
70 | }
71 |
72 | /**
73 | * Address `[hidden]` styling not present in IE 8/9/10.
74 | * Hide the `template` element in IE 8/9/11, Safari, and Firefox < 22.
75 | */
76 |
77 | [hidden],
78 | template {
79 | display: none;
80 | }
81 |
82 | /* Links
83 | ========================================================================== */
84 |
85 | /**
86 | * Remove the gray background color from active links in IE 10.
87 | */
88 |
89 | a {
90 | background-color: transparent;
91 | }
92 |
93 | /**
94 | * Improve readability when focused and also mouse hovered in all browsers.
95 | */
96 |
97 | a:active,
98 | a:hover {
99 | outline: 0;
100 | }
101 |
102 | /* Text-level semantics
103 | ========================================================================== */
104 |
105 | /**
106 | * Address styling not present in IE 8/9/10/11, Safari, and Chrome.
107 | */
108 |
109 | abbr[title] {
110 | border-bottom: 1px dotted;
111 | }
112 |
113 | /**
114 | * Address style set to `bolder` in Firefox 4+, Safari, and Chrome.
115 | */
116 |
117 | b,
118 | strong {
119 | font-weight: bold;
120 | }
121 |
122 | /**
123 | * Address styling not present in Safari and Chrome.
124 | */
125 |
126 | dfn {
127 | font-style: italic;
128 | }
129 |
130 | /**
131 | * Address variable `h1` font-size and margin within `section` and `article`
132 | * contexts in Firefox 4+, Safari, and Chrome.
133 | */
134 |
135 | h1 {
136 | font-size: 2em;
137 | margin: 0.67em 0;
138 | }
139 |
140 | /**
141 | * Address styling not present in IE 8/9.
142 | */
143 |
144 | mark {
145 | background: #ff0;
146 | color: #000;
147 | }
148 |
149 | /**
150 | * Address inconsistent and variable font size in all browsers.
151 | */
152 |
153 | small {
154 | font-size: 80%;
155 | }
156 |
157 | /**
158 | * Prevent `sub` and `sup` affecting `line-height` in all browsers.
159 | */
160 |
161 | sub,
162 | sup {
163 | font-size: 75%;
164 | line-height: 0;
165 | position: relative;
166 | vertical-align: baseline;
167 | }
168 |
169 | sup {
170 | top: -0.5em;
171 | }
172 |
173 | sub {
174 | bottom: -0.25em;
175 | }
176 |
177 | /* Embedded content
178 | ========================================================================== */
179 |
180 | /**
181 | * Remove border when inside `a` element in IE 8/9/10.
182 | */
183 |
184 | img {
185 | border: 0;
186 | }
187 |
188 | /**
189 | * Correct overflow not hidden in IE 9/10/11.
190 | */
191 |
192 | svg:not(:root) {
193 | overflow: hidden;
194 | }
195 |
196 | /* Grouping content
197 | ========================================================================== */
198 |
199 | /**
200 | * Address margin not present in IE 8/9 and Safari.
201 | */
202 |
203 | figure {
204 | margin: 1em 40px;
205 | }
206 |
207 | /**
208 | * Address differences between Firefox and other browsers.
209 | */
210 |
211 | hr {
212 | -moz-box-sizing: content-box;
213 | box-sizing: content-box;
214 | height: 0;
215 | }
216 |
217 | /**
218 | * Contain overflow in all browsers.
219 | */
220 |
221 | pre {
222 | overflow: auto;
223 | }
224 |
225 | /**
226 | * Address odd `em`-unit font size rendering in all browsers.
227 | */
228 |
229 | code,
230 | kbd,
231 | pre,
232 | samp {
233 | font-family: monospace, monospace;
234 | font-size: 1em;
235 | }
236 |
237 | /* Forms
238 | ========================================================================== */
239 |
240 | /**
241 | * Known limitation: by default, Chrome and Safari on OS X allow very limited
242 | * styling of `select`, unless a `border` property is set.
243 | */
244 |
245 | /**
246 | * 1. Correct color not being inherited.
247 | * Known issue: affects color of disabled elements.
248 | * 2. Correct font properties not being inherited.
249 | * 3. Address margins set differently in Firefox 4+, Safari, and Chrome.
250 | */
251 |
252 | button,
253 | input,
254 | optgroup,
255 | select,
256 | textarea {
257 | color: inherit; /* 1 */
258 | font: inherit; /* 2 */
259 | margin: 0; /* 3 */
260 | }
261 |
262 | /**
263 | * Address `overflow` set to `hidden` in IE 8/9/10/11.
264 | */
265 |
266 | button {
267 | overflow: visible;
268 | }
269 |
270 | /**
271 | * Address inconsistent `text-transform` inheritance for `button` and `select`.
272 | * All other form control elements do not inherit `text-transform` values.
273 | * Correct `button` style inheritance in Firefox, IE 8/9/10/11, and Opera.
274 | * Correct `select` style inheritance in Firefox.
275 | */
276 |
277 | button,
278 | select {
279 | text-transform: none;
280 | }
281 |
282 | /**
283 | * 1. Avoid the WebKit bug in Android 4.0.* where (2) destroys native `audio`
284 | * and `video` controls.
285 | * 2. Correct inability to style clickable `input` types in iOS.
286 | * 3. Improve usability and consistency of cursor style between image-type
287 | * `input` and others.
288 | */
289 |
290 | button,
291 | html input[type="button"], /* 1 */
292 | input[type="reset"],
293 | input[type="submit"] {
294 | -webkit-appearance: button; /* 2 */
295 | cursor: pointer; /* 3 */
296 | }
297 |
298 | /**
299 | * Re-set default cursor for disabled elements.
300 | */
301 |
302 | button[disabled],
303 | html input[disabled] {
304 | cursor: default;
305 | }
306 |
307 | /**
308 | * Remove inner padding and border in Firefox 4+.
309 | */
310 |
311 | button::-moz-focus-inner,
312 | input::-moz-focus-inner {
313 | border: 0;
314 | padding: 0;
315 | }
316 |
317 | /**
318 | * Address Firefox 4+ setting `line-height` on `input` using `!important` in
319 | * the UA stylesheet.
320 | */
321 |
322 | input {
323 | line-height: normal;
324 | }
325 |
326 | /**
327 | * It's recommended that you don't attempt to style these elements.
328 | * Firefox's implementation doesn't respect box-sizing, padding, or width.
329 | *
330 | * 1. Address box sizing set to `content-box` in IE 8/9/10.
331 | * 2. Remove excess padding in IE 8/9/10.
332 | */
333 |
334 | input[type="checkbox"],
335 | input[type="radio"] {
336 | box-sizing: border-box; /* 1 */
337 | padding: 0; /* 2 */
338 | }
339 |
340 | /**
341 | * Fix the cursor style for Chrome's increment/decrement buttons. For certain
342 | * `font-size` values of the `input`, it causes the cursor style of the
343 | * decrement button to change from `default` to `text`.
344 | */
345 |
346 | input[type="number"]::-webkit-inner-spin-button,
347 | input[type="number"]::-webkit-outer-spin-button {
348 | height: auto;
349 | }
350 |
351 | /**
352 | * 1. Address `appearance` set to `searchfield` in Safari and Chrome.
353 | * 2. Address `box-sizing` set to `border-box` in Safari and Chrome
354 | * (include `-moz` to future-proof).
355 | */
356 |
357 | input[type="search"] {
358 | -webkit-appearance: textfield; /* 1 */
359 | -moz-box-sizing: content-box;
360 | -webkit-box-sizing: content-box; /* 2 */
361 | box-sizing: content-box;
362 | }
363 |
364 | /**
365 | * Remove inner padding and search cancel button in Safari and Chrome on OS X.
366 | * Safari (but not Chrome) clips the cancel button when the search input has
367 | * padding (and `textfield` appearance).
368 | */
369 |
370 | input[type="search"]::-webkit-search-cancel-button,
371 | input[type="search"]::-webkit-search-decoration {
372 | -webkit-appearance: none;
373 | }
374 |
375 | /**
376 | * Define consistent border, margin, and padding.
377 | */
378 |
379 | fieldset {
380 | border: 1px solid #c0c0c0;
381 | margin: 0 2px;
382 | padding: 0.35em 0.625em 0.75em;
383 | }
384 |
385 | /**
386 | * 1. Correct `color` not being inherited in IE 8/9/10/11.
387 | * 2. Remove padding so people aren't caught out if they zero out fieldsets.
388 | */
389 |
390 | legend {
391 | border: 0; /* 1 */
392 | padding: 0; /* 2 */
393 | }
394 |
395 | /**
396 | * Remove default vertical scrollbar in IE 8/9/10/11.
397 | */
398 |
399 | textarea {
400 | overflow: auto;
401 | }
402 |
403 | /**
404 | * Don't inherit the `font-weight` (applied by a rule above).
405 | * NOTE: the default cannot safely be changed in Chrome and Safari on OS X.
406 | */
407 |
408 | optgroup {
409 | font-weight: bold;
410 | }
411 |
412 | /* Tables
413 | ========================================================================== */
414 |
415 | /**
416 | * Remove most spacing between table cells.
417 | */
418 |
419 | table {
420 | border-collapse: collapse;
421 | border-spacing: 0;
422 | }
423 |
424 | td,
425 | th {
426 | padding: 0;
427 | }
428 |
--------------------------------------------------------------------------------
/lib/vendor/js/reflux.js:
--------------------------------------------------------------------------------
1 | (function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.Reflux = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o= 0 &&
588 | this.children.indexOf('failed') >= 0;
589 |
590 | if (!canHandlePromise){
591 | throw new Error('Publisher must have "completed" and "failed" child publishers');
592 | }
593 |
594 | promise.then(function(response) {
595 | return me.completed(response);
596 | }, function(error) {
597 | return me.failed(error);
598 | });
599 | },
600 |
601 | /**
602 | * Subscribes the given callback for action triggered, which should
603 | * return a promise that in turn is passed to `this.promise`
604 | *
605 | * @param {Function} callback The callback to register as event handler
606 | */
607 | listenAndPromise: function(callback, bindContext) {
608 | var me = this;
609 | bindContext = bindContext || this;
610 | this.willCallPromise = (this.willCallPromise || 0) + 1;
611 |
612 | var removeListen = this.listen(function() {
613 |
614 | if (!callback) {
615 | throw new Error('Expected a function returning a promise but got ' + callback);
616 | }
617 |
618 | var args = arguments,
619 | promise = callback.apply(bindContext, args);
620 | return me.promise.call(me, promise);
621 | }, bindContext);
622 |
623 | return function () {
624 | me.willCallPromise--;
625 | removeListen.call(me);
626 | };
627 |
628 | },
629 |
630 | /**
631 | * Publishes an event using `this.emitter` (if `shouldEmit` agrees)
632 | */
633 | trigger: function() {
634 | var args = arguments,
635 | pre = this.preEmit.apply(this, args);
636 | args = pre === undefined ? args : _.isArguments(pre) ? pre : [].concat(pre);
637 | if (this.shouldEmit.apply(this, args)) {
638 | this.emitter.emit(this.eventLabel, args);
639 | }
640 | },
641 |
642 | /**
643 | * Tries to publish the event on the next tick
644 | */
645 | triggerAsync: function(){
646 | var args = arguments,me = this;
647 | _.nextTick(function() {
648 | me.trigger.apply(me, args);
649 | });
650 | },
651 |
652 | /**
653 | * Returns a Promise for the triggered action
654 | *
655 | * @return {Promise}
656 | * Resolved by completed child action.
657 | * Rejected by failed child action.
658 | * If listenAndPromise'd, then promise associated to this trigger.
659 | * Otherwise, the promise is for next child action completion.
660 | */
661 | triggerPromise: function(){
662 | var me = this;
663 | var args = arguments;
664 |
665 | var canHandlePromise =
666 | this.children.indexOf('completed') >= 0 &&
667 | this.children.indexOf('failed') >= 0;
668 |
669 | var promise = _.createPromise(function(resolve, reject) {
670 | // If `listenAndPromise` is listening
671 | // patch `promise` w/ context-loaded resolve/reject
672 | if (me.willCallPromise) {
673 | _.nextTick(function() {
674 | var old_promise_method = me.promise;
675 | me.promise = function (promise) {
676 | promise.then(resolve, reject);
677 | // Back to your regularly schedule programming.
678 | me.promise = old_promise_method;
679 | return me.promise.apply(me, arguments);
680 | };
681 | me.trigger.apply(me, args);
682 | });
683 | return;
684 | }
685 |
686 | if (canHandlePromise) {
687 | var removeSuccess = me.completed.listen(function(args) {
688 | removeSuccess();
689 | removeFailed();
690 | resolve(args);
691 | });
692 |
693 | var removeFailed = me.failed.listen(function(args) {
694 | removeSuccess();
695 | removeFailed();
696 | reject(args);
697 | });
698 | }
699 |
700 | me.triggerAsync.apply(me, args);
701 |
702 | if (!canHandlePromise) {
703 | resolve();
704 | }
705 | });
706 |
707 | return promise;
708 | }
709 | };
710 |
711 | },{"./utils":18}],7:[function(require,module,exports){
712 | /**
713 | * A module of methods that you want to include in all stores.
714 | * This module is consumed by `createStore`.
715 | */
716 | module.exports = {
717 | };
718 |
719 | },{}],8:[function(require,module,exports){
720 | module.exports = function(store, definition) {
721 | for (var name in definition) {
722 | if (Object.getOwnPropertyDescriptor && Object.defineProperty) {
723 | var propertyDescriptor = Object.getOwnPropertyDescriptor(definition, name);
724 |
725 | if (!propertyDescriptor.value || typeof propertyDescriptor.value !== 'function' || !definition.hasOwnProperty(name)) {
726 | continue;
727 | }
728 |
729 | store[name] = definition[name].bind(store);
730 | } else {
731 | var property = definition[name];
732 |
733 | if (typeof property !== 'function' || !definition.hasOwnProperty(name)) {
734 | continue;
735 | }
736 |
737 | store[name] = property.bind(store);
738 | }
739 | }
740 |
741 | return store;
742 | };
743 |
744 | },{}],9:[function(require,module,exports){
745 | var ListenerMethods = require('./ListenerMethods'),
746 | ListenerMixin = require('./ListenerMixin'),
747 | _ = require('./utils');
748 |
749 | module.exports = function(listenable,key){
750 | return {
751 | getInitialState: function(){
752 | if (!_.isFunction(listenable.getInitialState)) {
753 | return {};
754 | } else if (key === undefined) {
755 | return listenable.getInitialState();
756 | } else {
757 | return _.object([key],[listenable.getInitialState()]);
758 | }
759 | },
760 | componentDidMount: function(){
761 | _.extend(this,ListenerMethods);
762 | var me = this, cb = (key === undefined ? this.setState : function(v){
763 | if (typeof me.isMounted === "undefined" || me.isMounted() === true) {
764 | me.setState(_.object([key],[v]));
765 | }
766 | });
767 | this.listenTo(listenable,cb);
768 | },
769 | componentWillUnmount: ListenerMixin.componentWillUnmount
770 | };
771 | };
772 |
773 | },{"./ListenerMethods":4,"./ListenerMixin":5,"./utils":18}],10:[function(require,module,exports){
774 | var ListenerMethods = require('./ListenerMethods'),
775 | ListenerMixin = require('./ListenerMixin'),
776 | _ = require('./utils');
777 |
778 | module.exports = function(listenable, key, filterFunc) {
779 | filterFunc = _.isFunction(key) ? key : filterFunc;
780 | return {
781 | getInitialState: function() {
782 | if (!_.isFunction(listenable.getInitialState)) {
783 | return {};
784 | } else if (_.isFunction(key)) {
785 | return filterFunc.call(this, listenable.getInitialState());
786 | } else {
787 | // Filter initial payload from store.
788 | var result = filterFunc.call(this, listenable.getInitialState());
789 | if (typeof(result) !== "undefined") {
790 | return _.object([key], [result]);
791 | } else {
792 | return {};
793 | }
794 | }
795 | },
796 | componentDidMount: function() {
797 | _.extend(this, ListenerMethods);
798 | var me = this;
799 | var cb = function(value) {
800 | if (_.isFunction(key)) {
801 | me.setState(filterFunc.call(me, value));
802 | } else {
803 | var result = filterFunc.call(me, value);
804 | me.setState(_.object([key], [result]));
805 | }
806 | };
807 |
808 | this.listenTo(listenable, cb);
809 | },
810 | componentWillUnmount: ListenerMixin.componentWillUnmount
811 | };
812 | };
813 |
814 |
815 | },{"./ListenerMethods":4,"./ListenerMixin":5,"./utils":18}],11:[function(require,module,exports){
816 | var _ = require('./utils'),
817 | ActionMethods = require('./ActionMethods'),
818 | PublisherMethods = require('./PublisherMethods'),
819 | Keep = require('./Keep'),
820 | allowed = {preEmit:1,shouldEmit:1};
821 |
822 | /**
823 | * Creates an action functor object. It is mixed in with functions
824 | * from the `PublisherMethods` mixin. `preEmit` and `shouldEmit` may
825 | * be overridden in the definition object.
826 | *
827 | * @param {Object} definition The action object definition
828 | */
829 | var createAction = function(definition) {
830 |
831 | definition = definition || {};
832 | if (!_.isObject(definition)){
833 | definition = {actionName: definition};
834 | }
835 |
836 | for(var a in ActionMethods){
837 | if (!allowed[a] && PublisherMethods[a]) {
838 | throw new Error("Cannot override API method " + a +
839 | " in Reflux.ActionMethods. Use another method name or override it on Reflux.PublisherMethods instead."
840 | );
841 | }
842 | }
843 |
844 | for(var d in definition){
845 | if (!allowed[d] && PublisherMethods[d]) {
846 | throw new Error("Cannot override API method " + d +
847 | " in action creation. Use another method name or override it on Reflux.PublisherMethods instead."
848 | );
849 | }
850 | }
851 |
852 | definition.children = definition.children || [];
853 | if (definition.asyncResult){
854 | definition.children = definition.children.concat(["completed","failed"]);
855 | }
856 |
857 | var i = 0, childActions = {};
858 | for (; i < definition.children.length; i++) {
859 | var name = definition.children[i];
860 | childActions[name] = createAction(name);
861 | }
862 |
863 | var context = _.extend({
864 | eventLabel: "action",
865 | emitter: new _.EventEmitter(),
866 | _isAction: true
867 | }, PublisherMethods, ActionMethods, definition);
868 |
869 | var functor = function() {
870 | var triggerType = functor.sync ? "trigger" :
871 | ( _.environment.hasPromises ? "triggerPromise" : "triggerAsync" );
872 | return functor[triggerType].apply(functor, arguments);
873 | };
874 |
875 | _.extend(functor,childActions,context);
876 |
877 | Keep.createdActions.push(functor);
878 |
879 | return functor;
880 |
881 | };
882 |
883 | module.exports = createAction;
884 |
885 | },{"./ActionMethods":2,"./Keep":3,"./PublisherMethods":6,"./utils":18}],12:[function(require,module,exports){
886 | var _ = require('./utils'),
887 | Keep = require('./Keep'),
888 | mixer = require('./mixer'),
889 | allowed = {preEmit:1,shouldEmit:1},
890 | bindMethods = require('./bindMethods');
891 |
892 | /**
893 | * Creates an event emitting Data Store. It is mixed in with functions
894 | * from the `ListenerMethods` and `PublisherMethods` mixins. `preEmit`
895 | * and `shouldEmit` may be overridden in the definition object.
896 | *
897 | * @param {Object} definition The data store object definition
898 | * @returns {Store} A data store instance
899 | */
900 | module.exports = function(definition) {
901 |
902 | var StoreMethods = require('./StoreMethods'),
903 | PublisherMethods = require('./PublisherMethods'),
904 | ListenerMethods = require('./ListenerMethods');
905 |
906 | definition = definition || {};
907 |
908 | for(var a in StoreMethods){
909 | if (!allowed[a] && (PublisherMethods[a] || ListenerMethods[a])){
910 | throw new Error("Cannot override API method " + a +
911 | " in Reflux.StoreMethods. Use another method name or override it on Reflux.PublisherMethods / Reflux.ListenerMethods instead."
912 | );
913 | }
914 | }
915 |
916 | for(var d in definition){
917 | if (!allowed[d] && (PublisherMethods[d] || ListenerMethods[d])){
918 | throw new Error("Cannot override API method " + d +
919 | " in store creation. Use another method name or override it on Reflux.PublisherMethods / Reflux.ListenerMethods instead."
920 | );
921 | }
922 | }
923 |
924 | definition = mixer(definition);
925 |
926 | function Store() {
927 | var i=0, arr;
928 | this.subscriptions = [];
929 | this.emitter = new _.EventEmitter();
930 | this.eventLabel = "change";
931 | bindMethods(this, definition);
932 | if (this.init && _.isFunction(this.init)) {
933 | this.init();
934 | }
935 | if (this.listenables){
936 | arr = [].concat(this.listenables);
937 | for(;i < arr.length;i++){
938 | this.listenToMany(arr[i]);
939 | }
940 | }
941 | }
942 |
943 | _.extend(Store.prototype, ListenerMethods, PublisherMethods, StoreMethods, definition);
944 |
945 | var store = new Store();
946 | Keep.createdStores.push(store);
947 |
948 | return store;
949 | };
950 |
951 | },{"./Keep":3,"./ListenerMethods":4,"./PublisherMethods":6,"./StoreMethods":7,"./bindMethods":8,"./mixer":17,"./utils":18}],13:[function(require,module,exports){
952 | exports.ActionMethods = require('./ActionMethods');
953 |
954 | exports.ListenerMethods = require('./ListenerMethods');
955 |
956 | exports.PublisherMethods = require('./PublisherMethods');
957 |
958 | exports.StoreMethods = require('./StoreMethods');
959 |
960 | exports.createAction = require('./createAction');
961 |
962 | exports.createStore = require('./createStore');
963 |
964 | exports.connect = require('./connect');
965 |
966 | exports.connectFilter = require('./connectFilter');
967 |
968 | exports.ListenerMixin = require('./ListenerMixin');
969 |
970 | exports.listenTo = require('./listenTo');
971 |
972 | exports.listenToMany = require('./listenToMany');
973 |
974 |
975 | var maker = require('./joins').staticJoinCreator;
976 |
977 | exports.joinTrailing = exports.all = maker("last"); // Reflux.all alias for backward compatibility
978 |
979 | exports.joinLeading = maker("first");
980 |
981 | exports.joinStrict = maker("strict");
982 |
983 | exports.joinConcat = maker("all");
984 |
985 | var _ = exports.utils = require('./utils');
986 |
987 | exports.EventEmitter = _.EventEmitter;
988 |
989 | exports.Promise = _.Promise;
990 |
991 | /**
992 | * Convenience function for creating a set of actions
993 | *
994 | * @param definitions the definitions for the actions to be created
995 | * @returns an object with actions of corresponding action names
996 | */
997 | exports.createActions = function(definitions) {
998 | var actions = {};
999 | for (var k in definitions){
1000 | if (definitions.hasOwnProperty(k)) {
1001 | var val = definitions[k],
1002 | actionName = _.isObject(val) ? k : val;
1003 |
1004 | actions[actionName] = exports.createAction(val);
1005 | }
1006 | }
1007 | return actions;
1008 | };
1009 |
1010 | /**
1011 | * Sets the eventmitter that Reflux uses
1012 | */
1013 | exports.setEventEmitter = function(ctx) {
1014 | exports.EventEmitter = _.EventEmitter = ctx;
1015 | };
1016 |
1017 |
1018 | /**
1019 | * Sets the Promise library that Reflux uses
1020 | */
1021 | exports.setPromise = function(ctx) {
1022 | exports.Promise = _.Promise = ctx;
1023 | };
1024 |
1025 |
1026 | /**
1027 | * Sets the Promise factory that creates new promises
1028 | * @param {Function} factory has the signature `function(resolver) { return [new Promise]; }`
1029 | */
1030 | exports.setPromiseFactory = function(factory) {
1031 | _.createPromise = factory;
1032 | };
1033 |
1034 |
1035 | /**
1036 | * Sets the method used for deferring actions and stores
1037 | */
1038 | exports.nextTick = function(nextTick) {
1039 | _.nextTick = nextTick;
1040 | };
1041 |
1042 | /**
1043 | * Provides the set of created actions and stores for introspection
1044 | */
1045 | exports.__keep = require('./Keep');
1046 |
1047 | /**
1048 | * Warn if Function.prototype.bind not available
1049 | */
1050 | if (!Function.prototype.bind) {
1051 | console.error(
1052 | 'Function.prototype.bind not available. ' +
1053 | 'ES5 shim required. ' +
1054 | 'https://github.com/spoike/refluxjs#es5'
1055 | );
1056 | }
1057 |
1058 | },{"./ActionMethods":2,"./Keep":3,"./ListenerMethods":4,"./ListenerMixin":5,"./PublisherMethods":6,"./StoreMethods":7,"./connect":9,"./connectFilter":10,"./createAction":11,"./createStore":12,"./joins":14,"./listenTo":15,"./listenToMany":16,"./utils":18}],14:[function(require,module,exports){
1059 | /**
1060 | * Internal module used to create static and instance join methods
1061 | */
1062 |
1063 | var slice = Array.prototype.slice,
1064 | _ = require("./utils"),
1065 | createStore = require("./createStore"),
1066 | strategyMethodNames = {
1067 | strict: "joinStrict",
1068 | first: "joinLeading",
1069 | last: "joinTrailing",
1070 | all: "joinConcat"
1071 | };
1072 |
1073 | /**
1074 | * Used in `index.js` to create the static join methods
1075 | * @param {String} strategy Which strategy to use when tracking listenable trigger arguments
1076 | * @returns {Function} A static function which returns a store with a join listen on the given listenables using the given strategy
1077 | */
1078 | exports.staticJoinCreator = function(strategy){
1079 | return function(/* listenables... */) {
1080 | var listenables = slice.call(arguments);
1081 | return createStore({
1082 | init: function(){
1083 | this[strategyMethodNames[strategy]].apply(this,listenables.concat("triggerAsync"));
1084 | }
1085 | });
1086 | };
1087 | };
1088 |
1089 | /**
1090 | * Used in `ListenerMethods.js` to create the instance join methods
1091 | * @param {String} strategy Which strategy to use when tracking listenable trigger arguments
1092 | * @returns {Function} An instance method which sets up a join listen on the given listenables using the given strategy
1093 | */
1094 | exports.instanceJoinCreator = function(strategy){
1095 | return function(/* listenables..., callback*/){
1096 | _.throwIf(arguments.length < 2,'Cannot create a join with less than 2 listenables!');
1097 | var listenables = slice.call(arguments),
1098 | callback = listenables.pop(),
1099 | numberOfListenables = listenables.length,
1100 | join = {
1101 | numberOfListenables: numberOfListenables,
1102 | callback: this[callback]||callback,
1103 | listener: this,
1104 | strategy: strategy
1105 | }, i, cancels = [], subobj;
1106 | for (i = 0; i < numberOfListenables; i++) {
1107 | _.throwIf(this.validateListening(listenables[i]));
1108 | }
1109 | for (i = 0; i < numberOfListenables; i++) {
1110 | cancels.push(listenables[i].listen(newListener(i,join),this));
1111 | }
1112 | reset(join);
1113 | subobj = {listenable: listenables};
1114 | subobj.stop = makeStopper(subobj,cancels,this);
1115 | this.subscriptions = (this.subscriptions || []).concat(subobj);
1116 | return subobj;
1117 | };
1118 | };
1119 |
1120 | // ---- internal join functions ----
1121 |
1122 | function makeStopper(subobj,cancels,context){
1123 | return function() {
1124 | var i, subs = context.subscriptions,
1125 | index = (subs ? subs.indexOf(subobj) : -1);
1126 | _.throwIf(index === -1,'Tried to remove join already gone from subscriptions list!');
1127 | for(i=0;i < cancels.length; i++){
1128 | cancels[i]();
1129 | }
1130 | subs.splice(index, 1);
1131 | };
1132 | }
1133 |
1134 | function reset(join) {
1135 | join.listenablesEmitted = new Array(join.numberOfListenables);
1136 | join.args = new Array(join.numberOfListenables);
1137 | }
1138 |
1139 | function newListener(i,join) {
1140 | return function() {
1141 | var callargs = slice.call(arguments);
1142 | if (join.listenablesEmitted[i]){
1143 | switch(join.strategy){
1144 | case "strict": throw new Error("Strict join failed because listener triggered twice.");
1145 | case "last": join.args[i] = callargs; break;
1146 | case "all": join.args[i].push(callargs);
1147 | }
1148 | } else {
1149 | join.listenablesEmitted[i] = true;
1150 | join.args[i] = (join.strategy==="all"?[callargs]:callargs);
1151 | }
1152 | emitIfAllListenablesEmitted(join);
1153 | };
1154 | }
1155 |
1156 | function emitIfAllListenablesEmitted(join) {
1157 | for (var i = 0; i < join.numberOfListenables; i++) {
1158 | if (!join.listenablesEmitted[i]) {
1159 | return;
1160 | }
1161 | }
1162 | join.callback.apply(join.listener,join.args);
1163 | reset(join);
1164 | }
1165 |
1166 | },{"./createStore":12,"./utils":18}],15:[function(require,module,exports){
1167 | var ListenerMethods = require('./ListenerMethods');
1168 |
1169 | /**
1170 | * A mixin factory for a React component. Meant as a more convenient way of using the `ListenerMixin`,
1171 | * without having to manually set listeners in the `componentDidMount` method.
1172 | *
1173 | * @param {Action|Store} listenable An Action or Store that should be
1174 | * listened to.
1175 | * @param {Function|String} callback The callback to register as event handler
1176 | * @param {Function|String} defaultCallback The callback to register as default handler
1177 | * @returns {Object} An object to be used as a mixin, which sets up the listener for the given listenable.
1178 | */
1179 | module.exports = function(listenable,callback,initial){
1180 | return {
1181 | /**
1182 | * Set up the mixin before the initial rendering occurs. Import methods from `ListenerMethods`
1183 | * and then make the call to `listenTo` with the arguments provided to the factory function
1184 | */
1185 | componentDidMount: function() {
1186 | for(var m in ListenerMethods){
1187 | if (this[m] !== ListenerMethods[m]){
1188 | if (this[m]){
1189 | throw "Can't have other property '"+m+"' when using Reflux.listenTo!";
1190 | }
1191 | this[m] = ListenerMethods[m];
1192 | }
1193 | }
1194 | this.listenTo(listenable,callback,initial);
1195 | },
1196 | /**
1197 | * Cleans up all listener previously registered.
1198 | */
1199 | componentWillUnmount: ListenerMethods.stopListeningToAll
1200 | };
1201 | };
1202 |
1203 | },{"./ListenerMethods":4}],16:[function(require,module,exports){
1204 | var ListenerMethods = require('./ListenerMethods');
1205 |
1206 | /**
1207 | * A mixin factory for a React component. Meant as a more convenient way of using the `listenerMixin`,
1208 | * without having to manually set listeners in the `componentDidMount` method. This version is used
1209 | * to automatically set up a `listenToMany` call.
1210 | *
1211 | * @param {Object} listenables An object of listenables
1212 | * @returns {Object} An object to be used as a mixin, which sets up the listeners for the given listenables.
1213 | */
1214 | module.exports = function(listenables){
1215 | return {
1216 | /**
1217 | * Set up the mixin before the initial rendering occurs. Import methods from `ListenerMethods`
1218 | * and then make the call to `listenTo` with the arguments provided to the factory function
1219 | */
1220 | componentDidMount: function() {
1221 | for(var m in ListenerMethods){
1222 | if (this[m] !== ListenerMethods[m]){
1223 | if (this[m]){
1224 | throw "Can't have other property '"+m+"' when using Reflux.listenToMany!";
1225 | }
1226 | this[m] = ListenerMethods[m];
1227 | }
1228 | }
1229 | this.listenToMany(listenables);
1230 | },
1231 | /**
1232 | * Cleans up all listener previously registered.
1233 | */
1234 | componentWillUnmount: ListenerMethods.stopListeningToAll
1235 | };
1236 | };
1237 |
1238 | },{"./ListenerMethods":4}],17:[function(require,module,exports){
1239 | var _ = require('./utils');
1240 |
1241 | module.exports = function mix(def) {
1242 | var composed = {
1243 | init: [],
1244 | preEmit: [],
1245 | shouldEmit: []
1246 | };
1247 |
1248 | var updated = (function mixDef(mixin) {
1249 | var mixed = {};
1250 | if (mixin.mixins) {
1251 | mixin.mixins.forEach(function (subMixin) {
1252 | _.extend(mixed, mixDef(subMixin));
1253 | });
1254 | }
1255 | _.extend(mixed, mixin);
1256 | Object.keys(composed).forEach(function (composable) {
1257 | if (mixin.hasOwnProperty(composable)) {
1258 | composed[composable].push(mixin[composable]);
1259 | }
1260 | });
1261 | return mixed;
1262 | }(def));
1263 |
1264 | if (composed.init.length > 1) {
1265 | updated.init = function () {
1266 | var args = arguments;
1267 | composed.init.forEach(function (init) {
1268 | init.apply(this, args);
1269 | }, this);
1270 | };
1271 | }
1272 | if (composed.preEmit.length > 1) {
1273 | updated.preEmit = function () {
1274 | return composed.preEmit.reduce(function (args, preEmit) {
1275 | var newValue = preEmit.apply(this, args);
1276 | return newValue === undefined ? args : [newValue];
1277 | }.bind(this), arguments);
1278 | };
1279 | }
1280 | if (composed.shouldEmit.length > 1) {
1281 | updated.shouldEmit = function () {
1282 | var args = arguments;
1283 | return !composed.shouldEmit.some(function (shouldEmit) {
1284 | return !shouldEmit.apply(this, args);
1285 | }, this);
1286 | };
1287 | }
1288 | Object.keys(composed).forEach(function (composable) {
1289 | if (composed[composable].length === 1) {
1290 | updated[composable] = composed[composable][0];
1291 | }
1292 | });
1293 |
1294 | return updated;
1295 | };
1296 |
1297 | },{"./utils":18}],18:[function(require,module,exports){
1298 | exports.environment = {};
1299 |
1300 | /*
1301 | * isObject, extend, isFunction, isArguments are taken from undescore/lodash in
1302 | * order to remove the dependency
1303 | */
1304 | var isObject = exports.isObject = function(obj) {
1305 | var type = typeof obj;
1306 | return type === 'function' || type === 'object' && !!obj;
1307 | };
1308 |
1309 | exports.extend = function(obj) {
1310 | if (!isObject(obj)) {
1311 | return obj;
1312 | }
1313 | var source, prop;
1314 | for (var i = 1, length = arguments.length; i < length; i++) {
1315 | source = arguments[i];
1316 | for (prop in source) {
1317 | if (Object.getOwnPropertyDescriptor && Object.defineProperty) {
1318 | var propertyDescriptor = Object.getOwnPropertyDescriptor(source, prop);
1319 | Object.defineProperty(obj, prop, propertyDescriptor);
1320 | } else {
1321 | obj[prop] = source[prop];
1322 | }
1323 | }
1324 | }
1325 | return obj;
1326 | };
1327 |
1328 | exports.isFunction = function(value) {
1329 | return typeof value === 'function';
1330 | };
1331 |
1332 | exports.EventEmitter = require('eventemitter3');
1333 |
1334 | exports.nextTick = function(callback) {
1335 | setTimeout(callback, 0);
1336 | };
1337 |
1338 | exports.capitalize = function(string){
1339 | return string.charAt(0).toUpperCase()+string.slice(1);
1340 | };
1341 |
1342 | exports.callbackName = function(string){
1343 | return "on"+exports.capitalize(string);
1344 | };
1345 |
1346 | exports.object = function(keys,vals){
1347 | var o={}, i=0;
1348 | for(;i < keys.length; i++){
1349 | o[keys[i]] = vals[i];
1350 | }
1351 | return o;
1352 | };
1353 |
1354 | try {
1355 | exports.Promise = Promise;
1356 | exports.createPromise = function(resolver) {
1357 | return new exports.Promise(resolver);
1358 | };
1359 | } catch (err) {
1360 | // ReferenceError, Promise is not defined
1361 | exports.Promise = null;
1362 | exports.createPromise = function() {};
1363 | }
1364 | exports.environment.hasPromises = !!exports.Promise;
1365 |
1366 | exports.isArguments = function(value) {
1367 | return typeof value === 'object' && ('callee' in value) && typeof value.length === 'number';
1368 | };
1369 |
1370 | exports.throwIf = function(val,msg){
1371 | if (val){
1372 | throw Error(msg||val);
1373 | }
1374 | };
1375 |
1376 | },{"eventemitter3":1}]},{},[13])(13)
1377 | });
1378 |
--------------------------------------------------------------------------------
/public/fonts/glyphicons-halflings-regular.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------