diff --git a/.bowerrc b/.bowerrc
new file mode 100644
index 00000000..1f984984
--- /dev/null
+++ b/.bowerrc
@@ -0,0 +1,5 @@
+{
+ "directory": "vendor",
+ "json": "bower.json"
+}
+
diff --git a/.sass-cache/b82c160dcca64ba0bc7b96e353ba5844f81867d2/application.css.scssc b/.sass-cache/b82c160dcca64ba0bc7b96e353ba5844f81867d2/application.css.scssc
new file mode 100644
index 00000000..705c88b5
Binary files /dev/null and b/.sass-cache/b82c160dcca64ba0bc7b96e353ba5844f81867d2/application.css.scssc differ
diff --git a/Gruntfile.js b/Gruntfile.js
new file mode 100644
index 00000000..94fe4ad6
--- /dev/null
+++ b/Gruntfile.js
@@ -0,0 +1,672 @@
+module.exports = function ( grunt ) {
+
+ /**
+ * Load required Grunt tasks. These are installed based on the versions listed
+ * in `package.json` when you do `npm install` in this directory.
+ */
+ grunt.loadNpmTasks('grunt-contrib-clean');
+ grunt.loadNpmTasks('grunt-contrib-copy');
+ grunt.loadNpmTasks('grunt-contrib-jshint');
+ grunt.loadNpmTasks('grunt-contrib-concat');
+ grunt.loadNpmTasks('grunt-contrib-watch');
+ grunt.loadNpmTasks('grunt-contrib-uglify');
+ grunt.loadNpmTasks('grunt-contrib-coffee');
+ grunt.loadNpmTasks('grunt-conventional-changelog');
+ grunt.loadNpmTasks('grunt-bump');
+ grunt.loadNpmTasks('grunt-coffeelint');
+ grunt.loadNpmTasks('grunt-recess');
+ grunt.loadNpmTasks('grunt-contrib-compass');
+ grunt.loadNpmTasks('grunt-karma');
+ grunt.loadNpmTasks('grunt-ngmin');
+ grunt.loadNpmTasks('grunt-html2js');
+
+ /**
+ * Load in our build configuration file.
+ */
+ var userConfig = require( './build.config.js' );
+
+ /**
+ * This is the configuration object Grunt uses to give each plugin its
+ * instructions.
+ */
+ var taskConfig = {
+ /**
+ * We read in our `package.json` file so we can access the package name and
+ * version. It's already there, so we don't repeat ourselves here.
+ */
+ pkg: grunt.file.readJSON("package.json"),
+
+ /**
+ * The banner is the comment that is placed at the top of our compiled
+ * source files. It is first processed as a Grunt template, where the `<%=`
+ * pairs are evaluated based on this very configuration object.
+ */
+ meta: {
+ banner:
+ '/**\n' +
+ ' * <%= pkg.name %> - v<%= pkg.version %> - <%= grunt.template.today("yyyy-mm-dd") %>\n' +
+ ' * <%= pkg.homepage %>\n' +
+ ' *\n' +
+ ' * Copyright (c) <%= grunt.template.today("yyyy") %> <%= pkg.author %>\n' +
+ ' * Licensed <%= pkg.licenses.type %> <<%= pkg.licenses.url %>>\n' +
+ ' */\n'
+ },
+
+ /**
+ * Creates a changelog on a new version.
+ */
+ changelog: {
+ options: {
+ dest: 'CHANGELOG.md',
+ template: 'changelog.tpl'
+ }
+ },
+
+ /**
+ * Increments the version number, etc.
+ */
+ bump: {
+ options: {
+ files: [
+ "package.json",
+ "bower.json"
+ ],
+ commit: false,
+ commitMessage: 'chore(release): v%VERSION%',
+ commitFiles: [
+ "package.json",
+ "client/bower.json"
+ ],
+ createTag: false,
+ tagName: 'v%VERSION%',
+ tagMessage: 'Version %VERSION%',
+ push: false,
+ pushTo: 'origin'
+ }
+ },
+
+ /**
+ * The directories to delete when `grunt clean` is executed.
+ */
+ clean: [
+ '<%= build_dir %>',
+ '<%= compile_dir %>'
+ ],
+
+ /**
+ * The `copy` task just copies files from A to B. We use it here to copy
+ * our project assets (images, fonts, etc.) and javascripts into
+ * `build_dir`, and then to copy the assets to `compile_dir`.
+ */
+ copy: {
+ build_app_assets: {
+ files: [
+ {
+ src: [ '**' ],
+ dest: '<%= build_dir %>/assets/',
+ cwd: 'src/assets',
+ expand: true
+ }
+ ]
+ },
+ build_vendor_assets: {
+ files: [
+ {
+ src: [ '<%= vendor_files.assets %>' ],
+ dest: '<%= build_dir %>/assets/',
+ cwd: '.',
+ expand: true,
+ flatten: true
+ }
+ ]
+ },
+ build_appjs: {
+ files: [
+ {
+ src: [ '<%= app_files.js %>' ],
+ dest: '<%= build_dir %>/',
+ cwd: '.',
+ expand: true
+ }
+ ]
+ },
+ build_vendorjs: {
+ files: [
+ {
+ src: [ '<%= vendor_files.js %>' ],
+ dest: '<%= build_dir %>/',
+ cwd: '.',
+ expand: true
+ }
+ ]
+ },
+ compile_assets: {
+ files: [
+ {
+ src: [ '**' ],
+ dest: '<%= compile_dir %>/assets',
+ cwd: '<%= build_dir %>/assets',
+ expand: true
+ }
+ ]
+ }
+ },
+
+ /**
+ * `grunt concat` concatenates multiple source files into a single file.
+ */
+ concat: {
+ /**
+ * The `build_css` target concatenates compiled CSS and vendor CSS
+ * together.
+ */
+ build_css: {
+ src: [
+ '<%= vendor_files.css %>',
+ '<%= recess.build.dest %>',
+ '<%= compass.build.dest %>'
+ ],
+ dest: '<%= compass.build.dest %>'
+ },
+ /**
+ * The `compile_js` target is the concatenation of our application source
+ * code and all specified vendor source code into a single file.
+ */
+ compile_js: {
+ options: {
+ banner: '<%= meta.banner %>'
+ },
+ src: [
+ '<%= vendor_files.js %>',
+ 'module.prefix',
+ '<%= build_dir %>/src/**/*.js',
+ '<%= html2js.app.dest %>',
+ '<%= html2js.common.dest %>',
+ 'module.suffix'
+ ],
+ dest: '<%= compile_dir %>/assets/<%= pkg.name %>-<%= pkg.version %>.js'
+ }
+ },
+
+ /**
+ * `grunt coffee` compiles the CoffeeScript sources. To work well with the
+ * rest of the build, we have a separate compilation task for sources and
+ * specs so they can go to different places. For example, we need the
+ * sources to live with the rest of the copied JavaScript so we can include
+ * it in the final build, but we don't want to include our specs there.
+ */
+ coffee: {
+ source: {
+ options: {
+ bare: true
+ },
+ expand: true,
+ cwd: '.',
+ src: [ '<%= app_files.coffee %>' ],
+ dest: '<%= build_dir %>',
+ ext: '.js'
+ }
+ },
+
+ /**
+ * `ng-min` annotates the sources before minifying. That is, it allows us
+ * to code without the array syntax.
+ */
+ ngmin: {
+ compile: {
+ files: [
+ {
+ src: [ '<%= app_files.js %>' ],
+ cwd: '<%= build_dir %>',
+ dest: '<%= build_dir %>',
+ expand: true
+ }
+ ]
+ }
+ },
+
+ /**
+ * Minify the sources!
+ */
+ uglify: {
+ compile: {
+ options: {
+ banner: '<%= meta.banner %>'
+ },
+ files: {
+ '<%= concat.compile_js.dest %>': '<%= concat.compile_js.dest %>'
+ }
+ }
+ },
+
+ /**
+ * `recess` handles our LESS compilation and uglification automatically.
+ * Only our `main.less` file is included in compilation; all other files
+ * must be imported from this file.
+ */
+ recess: {
+ build: {
+ src: [ '<%= app_files.less %>' ],
+ dest: '<%= build_dir %>/assets/<%= pkg.name %>-<%= pkg.version %>.css',
+ options: {
+ compile: true,
+ compress: false,
+ noUnderscores: false,
+ noIDs: false,
+ zeroUnits: false
+ }
+ },
+ compile: {
+ src: [ '<%= recess.build.dest %>' ],
+ dest: '<%= recess.build.dest %>',
+ options: {
+ compile: true,
+ compress: true,
+ noUnderscores: false,
+ noIDs: false,
+ zeroUnits: false
+ }
+ }
+ },
+
+ compass: {
+ compile: {
+ options: {
+ sassDir: 'src/sass',
+ cssDir: '<%= build_dir %>/assets/styles/<%= pkg.name %>-<%= pkg.version %>.css',
+ environment: 'production',
+ raw: "preferred_syntax = :scss\n"
+ }
+ },
+
+ build: {
+ options: {
+ outputStyle: 'compact',
+ sassDir: 'src/sass',
+ cssDir: '<%= build_dir %>/assets/styles/<%= pkg.name %>-<%= pkg.version %>.css',
+ environment: 'development',
+ raw: "preferred_syntax = :scss\n"
+ }
+ }
+ },
+
+ /**
+ * `jshint` defines the rules of our linter as well as which files we
+ * should check. This file, all javascript sources, and all our unit tests
+ * are linted based on the policies listed in `options`. But we can also
+ * specify exclusionary patterns by prefixing them with an exclamation
+ * point (!); this is useful when code comes from a third party but is
+ * nonetheless inside `src/`.
+ */
+ jshint: {
+ src: [
+ '<%= app_files.js %>'
+ ],
+ test: [
+ '<%= app_files.jsunit %>'
+ ],
+ gruntfile: [
+ 'Gruntfile.js'
+ ],
+ options: {
+ curly: true,
+ immed: true,
+ newcap: true,
+ noarg: true,
+ sub: true,
+ boss: true,
+ eqnull: true
+ },
+ globals: {}
+ },
+
+ /**
+ * `coffeelint` does the same as `jshint`, but for CoffeeScript.
+ * CoffeeScript is not the default in ngBoilerplate, so we're just using
+ * the defaults here.
+ */
+ coffeelint: {
+ src: {
+ files: {
+ src: [ '<%= app_files.coffee %>' ]
+ }
+ },
+ test: {
+ files: {
+ src: [ '<%= app_files.coffeeunit %>' ]
+ }
+ }
+ },
+
+ /**
+ * HTML2JS is a Grunt plugin that takes all of your template files and
+ * places them into JavaScript files as strings that are added to
+ * AngularJS's template cache. This means that the templates too become
+ * part of the initial payload as one JavaScript file. Neat!
+ */
+ html2js: {
+ /**
+ * These are the templates from `src/app`.
+ */
+ app: {
+ options: {
+ base: 'src/app'
+ },
+ src: [ '<%= app_files.atpl %>' ],
+ dest: '<%= build_dir %>/templates-app.js'
+ },
+
+ /**
+ * These are the templates from `src/common`.
+ */
+ common: {
+ options: {
+ base: 'src/common'
+ },
+ src: [ '<%= app_files.ctpl %>' ],
+ dest: '<%= build_dir %>/templates-common.js'
+ }
+ },
+
+ /**
+ * The Karma configurations.
+ */
+ karma: {
+ options: {
+ configFile: '<%= build_dir %>/karma-unit.js'
+ },
+ unit: {
+ runnerPort: 9101,
+ background: true
+ },
+ continuous: {
+ singleRun: true
+ }
+ },
+
+ /**
+ * The `index` task compiles the `index.html` file as a Grunt template. CSS
+ * and JS files co-exist here but they get split apart later.
+ */
+ index: {
+
+ /**
+ * During development, we don't want to have wait for compilation,
+ * concatenation, minification, etc. So to avoid these steps, we simply
+ * add all script files directly to the `
` of `index.html`. The
+ * `src` property contains the list of included files.
+ */
+ build: {
+ dir: '<%= build_dir %>',
+ src: [
+ '<%= vendor_files.js %>',
+ '<%= build_dir %>/src/**/*.js',
+ '<%= html2js.common.dest %>',
+ '<%= html2js.app.dest %>',
+ '<%= vendor_files.css %>',
+ '<%= recess.build.dest %>',
+ '<%= compass.build.dest %>'
+ ]
+ },
+
+ /**
+ * When it is time to have a completely compiled application, we can
+ * alter the above to include only a single JavaScript and a single CSS
+ * file. Now we're back!
+ */
+ compile: {
+ dir: '<%= compile_dir %>',
+ src: [
+ '<%= concat.compile_js.dest %>',
+ '<%= vendor_files.css %>',
+ '<%= recess.compile.dest %>',
+ '<%= compass.build.dest %>'
+ ]
+ }
+ },
+
+ /**
+ * This task compiles the karma template so that changes to its file array
+ * don't have to be managed manually.
+ */
+ karmaconfig: {
+ unit: {
+ dir: '<%= build_dir %>',
+ src: [
+ '<%= vendor_files.js %>',
+ '<%= html2js.app.dest %>',
+ '<%= html2js.common.dest %>',
+ '<%= test_files.js %>'
+ ]
+ }
+ },
+
+ /**
+ * And for rapid development, we have a watch set up that checks to see if
+ * any of the files listed below change, and then to execute the listed
+ * tasks when they do. This just saves us from having to type "grunt" into
+ * the command-line every time we want to see what we're working on; we can
+ * instead just leave "grunt watch" running in a background terminal. Set it
+ * and forget it, as Ron Popeil used to tell us.
+ *
+ * But we don't need the same thing to happen for all the files.
+ */
+ delta: {
+ /**
+ * By default, we want the Live Reload to work for all tasks; this is
+ * overridden in some tasks (like this file) where browser resources are
+ * unaffected. It runs by default on port 35729, which your browser
+ * plugin should auto-detect.
+ */
+ options: {
+ livereload: true
+ },
+
+ /**
+ * When the Gruntfile changes, we just want to lint it. In fact, when
+ * your Gruntfile changes, it will automatically be reloaded!
+ */
+ gruntfile: {
+ files: 'Gruntfile.js',
+ tasks: [ 'jshint:gruntfile' ],
+ options: {
+ livereload: false
+ }
+ },
+
+ /**
+ * When our JavaScript source files change, we want to run lint them and
+ * run our unit tests.
+ */
+ jssrc: {
+ files: [
+ '<%= app_files.js %>'
+ ],
+ tasks: [ 'jshint:src', 'karma:unit:run', 'copy:build_appjs' ]
+ },
+
+ /**
+ * When our CoffeeScript source files change, we want to run lint them and
+ * run our unit tests.
+ */
+ coffeesrc: {
+ files: [
+ '<%= app_files.coffee %>'
+ ],
+ tasks: [ 'coffeelint:src', 'coffee:source', 'karma:unit:run', 'copy:build_appjs' ]
+ },
+
+ /**
+ * When assets are changed, copy them. Note that this will *not* copy new
+ * files, so this is probably not very useful.
+ */
+ assets: {
+ files: [
+ 'src/assets/**/*'
+ ],
+ tasks: [ 'copy:build_assets' ]
+ },
+
+ /**
+ * When index.html changes, we need to compile it.
+ */
+ html: {
+ files: [ '<%= app_files.html %>' ],
+ tasks: [ 'index:build' ]
+ },
+
+ /**
+ * When our templates change, we only rewrite the template cache.
+ */
+ tpls: {
+ files: [
+ '<%= app_files.atpl %>',
+ '<%= app_files.ctpl %>'
+ ],
+ tasks: [ 'html2js' ]
+ },
+
+ /**
+ * When the CSS files change, we need to compile and minify them.
+ */
+// less: {
+// files: [ 'src/**/*.less' ],
+// tasks: [ 'recess:build' ]
+// },
+
+ sass: {
+ files: [ 'src/**/*.scss' ],
+ tasks: 'compassCompile'
+ },
+
+ /**
+ * When a JavaScript unit test file changes, we only want to lint it and
+ * run the unit tests. We don't want to do any live reloading.
+ */
+ jsunit: {
+ files: [
+ '<%= app_files.jsunit %>'
+ ],
+ tasks: [ 'jshint:test', 'karma:unit:run' ],
+ options: {
+ livereload: false
+ }
+ },
+
+ /**
+ * When a CoffeeScript unit test file changes, we only want to lint it and
+ * run the unit tests. We don't want to do any live reloading.
+ */
+ coffeeunit: {
+ files: [
+ '<%= app_files.coffeeunit %>'
+ ],
+ tasks: [ 'coffeelint:test', 'karma:unit:run' ],
+ options: {
+ livereload: false
+ }
+ }
+ }
+ };
+
+ grunt.initConfig( grunt.util._.extend( taskConfig, userConfig ) );
+
+ /**
+ * In order to make it safe to just compile or copy *only* what was changed,
+ * we need to ensure we are starting from a clean, fresh build. So we rename
+ * the `watch` task to `delta` (that's why the configuration var above is
+ * `delta`) and then add a new task called `watch` that does a clean build
+ * before watching for changes.
+ */
+ grunt.renameTask( 'watch', 'delta' );
+ grunt.registerTask( 'watch', [ 'build', 'karma:unit', 'delta' ] );
+
+ /**
+ * The default task is to build and compile.
+ */
+ grunt.registerTask( 'default', [ 'build', 'compile' ] );
+
+ /**
+ * The `build` task gets your app ready to run for development and testing.
+ */
+ grunt.registerTask( 'build', [
+ 'clean', 'html2js', 'jshint', 'coffeelint', 'coffee', /*'recess:build',*/ 'compass:build',
+ 'concat:build_css', 'copy:build_app_assets', 'copy:build_vendor_assets',
+ 'copy:build_appjs', 'copy:build_vendorjs', 'index:build', 'karmaconfig',
+ 'karma:continuous'
+ ]);
+
+ /**
+ * The `compile` task gets your app ready for deployment by concatenating and
+ * minifying your code.
+ */
+ grunt.registerTask( 'compile', [
+ /*'recess:compile',*/ 'compass:compile', 'copy:compile_assets', 'ngmin', 'concat:compile_js', 'uglify', 'index:compile'
+ ]);
+
+ /**
+ * A utility function to get all app JavaScript sources.
+ */
+ function filterForJS ( files ) {
+ return files.filter( function ( file ) {
+ return file.match( /\.js$/ );
+ });
+ }
+
+ /**
+ * A utility function to get all app CSS sources.
+ */
+ function filterForCSS ( files ) {
+ return files.filter( function ( file ) {
+ return file.match( /\.css$/ );
+ });
+ }
+
+ /**
+ * The index.html template includes the stylesheet and javascript sources
+ * based on dynamic names calculated in this Gruntfile. This task assembles
+ * the list into variables for the template to use and then runs the
+ * compilation.
+ */
+ grunt.registerMultiTask( 'index', 'Process index.html template', function () {
+ var dirRE = new RegExp( '^('+grunt.config('build_dir')+'|'+grunt.config('compile_dir')+')\/', 'g' );
+ var jsFiles = filterForJS( this.filesSrc ).map( function ( file ) {
+ return file.replace( dirRE, '' );
+ });
+ var cssFiles = filterForCSS( this.filesSrc ).map( function ( file ) {
+ return file.replace( dirRE, '' );
+ });
+
+ grunt.file.copy('src/index.html', this.data.dir + '/index.html', {
+ process: function ( contents, path ) {
+ return grunt.template.process( contents, {
+ data: {
+ scripts: jsFiles,
+ styles: cssFiles,
+ version: grunt.config( 'pkg.version' )
+ }
+ });
+ }
+ });
+ });
+
+ /**
+ * In order to avoid having to specify manually the files needed for karma to
+ * run, we use grunt to manage the list for us. The `karma/*` files are
+ * compiled as grunt templates for use by Karma. Yay!
+ */
+ grunt.registerMultiTask( 'karmaconfig', 'Process karma config templates', function () {
+ var jsFiles = filterForJS( this.filesSrc );
+
+ grunt.file.copy( 'karma/karma-unit.tpl.js', grunt.config( 'build_dir' ) + '/karma-unit.js', {
+ process: function ( contents, path ) {
+ return grunt.template.process( contents, {
+ data: {
+ scripts: jsFiles
+ }
+ });
+ }
+ });
+ });
+
+};
diff --git a/bower.json b/bower.json
new file mode 100644
index 00000000..7a030938
--- /dev/null
+++ b/bower.json
@@ -0,0 +1,13 @@
+{
+ "name": "ng-boilerplate",
+ "version": "0.3.1",
+ "devDependencies": {
+ "angular": "~1.0.7",
+ "angular-mocks": "~1.0.7",
+ "bootstrap": "~2.3.2",
+ "angular-bootstrap": "~0.3.0",
+ "angular-ui-router": "~0.0.1",
+ "angular-ui-utils": "~0.0.3"
+ },
+ "dependencies": {}
+}
diff --git a/build.config.js b/build.config.js
new file mode 100644
index 00000000..70275f0a
--- /dev/null
+++ b/build.config.js
@@ -0,0 +1,76 @@
+/**
+ * This file/module contains all configuration for the build process.
+ */
+module.exports = {
+ /**
+ * The `build_dir` folder is where our projects are compiled during
+ * development and the `compile_dir` folder is where our app resides once it's
+ * completely built.
+ */
+ build_dir: 'build',
+ compile_dir: 'bin',
+
+ /**
+ * This is a collection of file patterns that refer to our app code (the
+ * stuff in `src/`). These file paths are used in the configuration of
+ * build tasks. `js` is all project javascript, less tests. `ctpl` contains
+ * our reusable components' (`src/common`) template HTML files, while
+ * `atpl` contains the same, but for our app's code. `html` is just our
+ * main HTML file, `less` is our main stylesheet, and `unit` contains our
+ * app's unit tests.
+ */
+ app_files: {
+ js: [ 'src/**/*.js', '!src/**/*.spec.js', '!src/assets/**/*.js' ],
+ jsunit: [ 'src/**/*.spec.js' ],
+
+ coffee: [ 'src/**/*.coffee', '!src/**/*.spec.coffee' ],
+ coffeeunit: [ 'src/**/*.spec.coffee' ],
+
+ atpl: [ 'src/app/**/*.tpl.html' ],
+ ctpl: [ 'src/common/**/*.tpl.html' ],
+
+ html: [ 'src/index.html' ],
+ less: 'src/less/main.less'
+ },
+
+ /**
+ * This is a collection of files used during testing only.
+ */
+ test_files: {
+ js: [
+ 'vendor/angular-mocks/angular-mocks.js'
+ ]
+ },
+
+ /**
+ * This is the same as `app_files`, except it contains patterns that
+ * reference vendor code (`vendor/`) that we need to place into the build
+ * process somewhere. While the `app_files` property ensures all
+ * standardized files are collected for compilation, it is the user's job
+ * to ensure non-standardized (i.e. vendor-related) files are handled
+ * appropriately in `vendor_files.js`.
+ *
+ * The `vendor_files.js` property holds files to be automatically
+ * concatenated and minified with our project source files.
+ *
+ * The `vendor_files.css` property holds any CSS files to be automatically
+ * included in our app.
+ *
+ * The `vendor_files.assets` property holds any assets to be copied along
+ * with our app's assets. This structure is flattened, so it is not
+ * recommended that you use wildcards.
+ */
+ vendor_files: {
+ js: [
+ 'vendor/angular/angular.js',
+ 'vendor/angular-bootstrap/ui-bootstrap-tpls.min.js',
+ 'vendor/placeholders/angular-placeholders-0.0.1-SNAPSHOT.min.js',
+ 'vendor/angular-ui-router/release/angular-ui-router.js',
+ 'vendor/angular-ui-utils/modules/route/route.js'
+ ],
+ css: [
+ ],
+ assets: [
+ ]
+ },
+};
diff --git a/changelog.tpl b/changelog.tpl
new file mode 100644
index 00000000..c0274e4a
--- /dev/null
+++ b/changelog.tpl
@@ -0,0 +1,23 @@
+
+# <%= version%> (<%= today%>)
+
+<% if (_(changelog.feat).size() > 0) { %> ## Features
+<% _(changelog.feat).forEach(function(changes, scope) { %>
+- **<%= scope%>:**
+ <% changes.forEach(function(change) { %> - <%= change.msg%> (<%= helpers.commitLink(change.sha1) %>)
+ <% }); %>
+<% }); %> <% } %>
+
+<% if (_(changelog.fix).size() > 0) { %> ## Fixes
+<% _(changelog.fix).forEach(function(changes, scope) { %>
+- **<%= scope%>:**
+ <% changes.forEach(function(change) { %> - <%= change.msg%> (<%= helpers.commitLink(change.sha1) %>)
+ <% }); %>
+<% }); %> <% } %>
+
+<% if (_(changelog.breaking).size() > 0) { %> ## Breaking Changes
+<% _(changelog.breaking).forEach(function(changes, scope) { %>
+- **<%= scope%>:**
+ <% changes.forEach(function(change) { %> <%= change.msg%>
+ <% }); %>
+<% }); %> <% } %>
diff --git a/karma/karma-unit.tpl.js b/karma/karma-unit.tpl.js
new file mode 100644
index 00000000..f4212690
--- /dev/null
+++ b/karma/karma-unit.tpl.js
@@ -0,0 +1,61 @@
+module.exports = function ( config ) {
+ config.set({
+ /**
+ * From where to look for files, starting with the location of this file.
+ */
+ basePath: '../',
+
+ /**
+ * This is the list of file patterns to load into the browser during testing.
+ */
+ files: [
+ <% scripts.forEach( function ( file ) { %>'<%= file %>',
+ <% }); %>
+ 'src/**/*.js',
+ 'src/**/*.coffee',
+ ],
+ exclude: [
+ 'src/assets/**/*.js'
+ ],
+ frameworks: [ 'jasmine' ],
+ plugins: [ 'karma-jasmine', 'karma-firefox-launcher', 'karma-chrome-launcher', 'karma-phantomjs-launcher', 'karma-coffee-preprocessor' ],
+ preprocessors: {
+ '**/*.coffee': 'coffee',
+ },
+
+ /**
+ * How to report, by default.
+ */
+ reporters: 'dots',
+
+ /**
+ * On which port should the browser connect, on which port is the test runner
+ * operating, and what is the URL path for the browser to use.
+ */
+ port: 9018,
+ runnerPort: 9100,
+ urlRoot: '/',
+
+ /**
+ * Disable file watching by default.
+ */
+ autoWatch: false,
+
+ /**
+ * The list of browsers to launch to test on. This includes only "Firefox" by
+ * default, but other browser names include:
+ * Chrome, ChromeCanary, Firefox, Opera, Safari, PhantomJS
+ *
+ * Note that you can also use the executable name of the browser, like "chromium"
+ * or "firefox", but that these vary based on your operating system.
+ *
+ * You may also leave this blank and manually navigate your browser to
+ * http://localhost:9018/ when you're running tests. The window/tab can be left
+ * open and the tests will automatically occur there during the build. This has
+ * the aesthetic advantage of not launching a browser every time you save.
+ */
+ /* browsers: [
+ 'Chrome'
+ ]*/
+ });
+};
diff --git a/module.prefix b/module.prefix
new file mode 100644
index 00000000..c52d9b72
--- /dev/null
+++ b/module.prefix
@@ -0,0 +1 @@
+(function ( window, angular, undefined ) {
diff --git a/module.suffix b/module.suffix
new file mode 100644
index 00000000..f6354bac
--- /dev/null
+++ b/module.suffix
@@ -0,0 +1 @@
+})( window, window.angular );
diff --git a/package.json b/package.json
index 812de454..1da0b2e1 100644
--- a/package.json
+++ b/package.json
@@ -1,33 +1,33 @@
{
- "author": "Anthony Truskinger",
- "name": "baw-client",
- "version": "",
- "description": "The AngularJS client for the QUT Bioacoustics server",
- "licenses": {
- "type": "Apache",
- "url": "https://github.com/QutBioacoustics/baw-client/blob/master/LICENSE"
- },
- "bugs": "https://github.com/QutBioacoustics/baw-client/issues",
- "repository": {
- "type": "git",
- "url": "https://github.com/QutBioacoustics/baw-client.git"
- },
- "devDependencies": {
- "grunt": "~0.4.1",
- "grunt-recess": "~0.3.0",
- "grunt-contrib-clean": "~0.4.1",
- "grunt-contrib-copy": "~0.4.1",
- "grunt-contrib-jshint": "~0.4.3",
- "grunt-contrib-concat": "~0.3.0",
- "grunt-contrib-watch": "~0.4.0",
- "grunt-contrib-uglify": "~0.2.0",
- "grunt-karma": "~0.5.0",
- "grunt-ngmin": "0.0.2",
- "grunt-html2js": "~0.1.3",
- "grunt-contrib-coffee": "~0.7.0",
- "grunt-coffeelint": "0.0.6",
- "grunt-conventional-changelog": "~0.1.1",
- "grunt-bump": "0.0.6"
- },
- "private": true
-}
\ No newline at end of file
+ "author": "Anthony Truskinger",
+ "name": "baw-client",
+ "version": "",
+ "description": "The AngularJS client for the QUT Bioacoustics server",
+ "licenses": {
+ "type": "Apache",
+ "url": "https://github.com/QutBioacoustics/baw-client/blob/master/LICENSE"
+ },
+ "bugs": "https://github.com/QutBioacoustics/baw-client/issues",
+ "repository": {
+ "type": "git",
+ "url": "https://github.com/QutBioacoustics/baw-client.git"
+ },
+ "devDependencies": {
+ "grunt": "~0.4.1",
+ "grunt-contrib-compass": "~0.5.0",
+ "grunt-contrib-clean": "~0.4.1",
+ "grunt-contrib-copy": "~0.4.1",
+ "grunt-contrib-jshint": "~0.4.3",
+ "grunt-contrib-concat": "~0.3.0",
+ "grunt-contrib-watch": "~0.4.0",
+ "grunt-contrib-uglify": "~0.2.0",
+ "grunt-karma": "~0.5.0",
+ "grunt-ngmin": "0.0.2",
+ "grunt-html2js": "~0.1.3",
+ "grunt-contrib-coffee": "~0.7.0",
+ "grunt-coffeelint": "0.0.6",
+ "grunt-conventional-changelog": "~0.1.1",
+ "grunt-bump": "0.0.6"
+ },
+ "private": true
+}
diff --git a/src/README.md b/src/README.md
new file mode 100644
index 00000000..80c247f9
--- /dev/null
+++ b/src/README.md
@@ -0,0 +1,48 @@
+# The `src` Directory
+
+## Overview
+
+The `src/` directory contains all code used in the application along with all
+tests of such code.
+
+```
+src/
+ |- app/
+ | |- about/
+ | |- home/
+ | |- app.js
+ | |- app.spec.js
+ |- assets/
+ |- common/
+ | |- plusOne/
+ |- less/
+ | |- main.less
+ | |- variables.less
+ |- index.html
+```
+
+- `src/app/` - application-specific code, i.e. code not likely to be reused in
+ another application. [Read more »](app/README.md)
+- `src/assets/` - static files like fonts and images.
+ [Read more »](assets/README.md)
+- `src/common/` - third-party libraries or components likely to be reused in
+ another application. [Read more »](common/README.md)
+- `src/less/` - LESS CSS files. [Read more »](less/README.md)
+- `src/index.html` - this is the HTML document of the single-page application.
+ See below.
+
+See each directory for a detailed explanation.
+
+## `index.html`
+
+The `index.html` file is the HTML document of the single-page application (SPA)
+that should contain all markup that applies to everything in the app, such as
+the header and footer. It declares with `ngApp` that this is `ngBoilerplate`,
+specifies the main `AppCtrl` controller, and contains the `ngView` directive
+into which route templates are placed.
+
+Unlike any other HTML document (e.g. the templates), `index.html` is compiled as
+a Grunt template, so variables from `Gruntfile.js` and `package.json` can be
+referenced from within it. Changing `name` in `package.json` from
+"ng-boilerplate" will rename the resultant CSS and JavaScript placed in `build/`,
+so this HTML references them by variable for convenience.
diff --git a/src/app/README.md b/src/app/README.md
new file mode 100644
index 00000000..7c05fdae
--- /dev/null
+++ b/src/app/README.md
@@ -0,0 +1,94 @@
+# The `src/app` Directory
+
+## Overview
+
+```
+src/
+ |- app/
+ | |- home/
+ | |- about/
+ | |- app.js
+ | |- app.spec.js
+```
+
+The `src/app` directory contains all code specific to this application. Apart
+from `app.js` and its accompanying tests (discussed below), this directory is
+filled with subdirectories corresponding to high-level sections of the
+application, often corresponding to top-level routes. Each directory can have as
+many subdirectories as it needs, and the build system will understand what to
+do. For example, a top-level route might be "products", which would be a folder
+within the `src/app` directory that conceptually corresponds to the top-level
+route `/products`, though this is in no way enforced. Products may then have
+subdirectories for "create", "view", "search", etc. The "view" submodule may
+then define a route of `/products/:id`, ad infinitum.
+
+As `ngBoilerplate` is quite minimal, take a look at the two provided submodules
+to gain a better understanding of how these are used as well as to get a
+glimpse of how powerful this simple construct can be.
+
+## `app.js`
+
+This is our main app configuration file. It kickstarts the whole process by
+requiring all the modules from `src/app` that we need. We must load these now to
+ensure the routes are loaded. If as in our "products" example there are
+subroutes, we only require the top-level module, and allow the submodules to
+require their own submodules.
+
+As a matter of course, we also require the template modules that are generated
+during the build.
+
+However, the modules from `src/common` should be required by the app
+submodules that need them to ensure proper dependency handling. These are
+app-wide dependencies that are required to assemble your app.
+
+```js
+angular.module( 'ngBoilerplate', [
+ 'templates-app',
+ 'templates-common',
+ 'ngBoilerplate.home',
+ 'ngBoilerplate.about'
+ 'ui.state',
+ 'ui.route'
+])
+```
+
+With app modules broken down in this way, all routing is performed by the
+submodules we include, as that is where our app's functionality is really
+defined. So all we need to do in `app.js` is specify a default route to follow,
+which route of course is defined in a submodule. In this case, our `home` module
+is where we want to start, which has a defined route for `/home` in
+`src/app/home/home.js`.
+
+```js
+.config( function myAppConfig ( $stateProvider, $urlRouterProvider ) {
+ $urlRouterProvider.otherwise( '/home' );
+})
+```
+
+Use the main applications run method to execute any code after services
+have been instantiated.
+
+```js
+.run( function run () {
+})
+```
+
+And then we define our main application controller. This is a good place for logic
+not specific to the template or route, such as menu logic or page title wiring.
+
+```js
+.controller( 'AppCtrl', function AppCtrl ( $scope, $location ) {
+ $scope.$on('$stateChangeSuccess', function(event, toState, toParams, fromState, fromParams){
+ if ( angular.isDefined( toState.data.pageTitle ) ) {
+ $scope.pageTitle = toState.data.pageTitle + ' | ngBoilerplate' ;
+ }
+ });
+})
+```
+
+### Testing
+
+One of the design philosophies of `ngBoilerplate` is that tests should exist
+alongside the code they test and that the build system should be smart enough to
+know the difference and react accordingly. As such, the unit test for `app.js`
+is `app.spec.js`, though it is quite minimal.
diff --git a/src/app/js/controllers/accounts.js b/src/app/accounts/accounts.js
similarity index 100%
rename from src/app/js/controllers/accounts.js
rename to src/app/accounts/accounts.js
diff --git a/src/app/partials/accounts_sign_in.html b/src/app/accounts/accounts_sign_in.tpl.html
similarity index 95%
rename from src/app/partials/accounts_sign_in.html
rename to src/app/accounts/accounts_sign_in.tpl.html
index f39cb4fe..a36684b6 100644
--- a/src/app/partials/accounts_sign_in.html
+++ b/src/app/accounts/accounts_sign_in.tpl.html
@@ -1,10 +1,10 @@
-
\ No newline at end of file
diff --git a/src/app/partials/experiment_base.html b/src/app/experiments/experiment_base.tpl.html
similarity index 100%
rename from src/app/partials/experiment_base.html
rename to src/app/experiments/experiment_base.tpl.html
diff --git a/src/app/js/controllers/experiments.js b/src/app/experiments/experiments.js
similarity index 100%
rename from src/app/js/controllers/experiments.js
rename to src/app/experiments/experiments.js
diff --git a/src/app/partials/rapid_scanning_experiment.html b/src/app/experiments/rapid_scanning_experiment.tpl.html
similarity index 100%
rename from src/app/partials/rapid_scanning_experiment.html
rename to src/app/experiments/rapid_scanning_experiment.tpl.html
diff --git a/src/app/partials/tour_experiment.html b/src/app/experiments/tour_experiment.tpl.html
similarity index 97%
rename from src/app/partials/tour_experiment.html
rename to src/app/experiments/tour_experiment.tpl.html
index e441b9fa..99320f22 100644
--- a/src/app/partials/tour_experiment.html
+++ b/src/app/experiments/tour_experiment.tpl.html
@@ -1,658 +1,658 @@
-
-
-
-
-
-
- Welcome to this virtual bird walk!
- On to the next waypoint!
-
-
-
-
- Hello! Welcome to this virtual bird tour. The tour consists of
- {{results.locationSpeciesOrder.locations.length}} waypoints.
- The first waypoint is {{results.steps[step - 1].toLocation.name}}.
- The map below shows your movement from one waypoint to the next.
- The order we'll be moving in is shown by the lines on the map.
- There are arrows on the lines that show the direction of movement.
-
-
-
- At each waypoint, we'll pause and look around. We'll learn about two
- birds at each waypoint. There will be information about the bird,
- and you'll be able to demonstrate what you know. For each bird, we
- have some audio recordings that may or may not contain the call of the bird.
-
-
-
- Click "Move to Waypoint" to continue.
- Read about {{results.steps[step - 1].toLocation.name}}, then click "Continue the Virtual Bird Tour"!
-
-
-
-
- On to the next waypoint! We're going to {{results.steps[step - 1].toLocation.name}} next.
- Click "Move to Waypoint" to continue.
- Read about {{results.steps[step - 1].toLocation.name}}, then click "Continue the Virtual Bird Tour"!
-
Are there {{currentSpecies.commonName}}
- calls in these audio recordings?
-
-
- Play the audio, and look at the spectrograms.
- Then indicate your opinion by responding
- 'Yes' if the audio recording contains any {{currentSpecies.commonName}} calls;
- 'No' if there are no {{currentSpecies.commonName}} calls in the audio recording;
- 'Unsure' if you can't tell either way.
- You need to record an answer for each audio recording.
- Click "Done" when you are satisfied with your answers to see what other people's opinions were. Then click "Next" to move on.
-
-
-
-
-
-
-
-
-
-
A total of {{currentAnnotation.otherPeopleTotal}} other people have also given their
- opinion on whether this annotation is a {{currentSpecies.commonName}}. Of those,
+ Welcome to this virtual bird walk!
+ On to the next waypoint!
+
+
+
+
+ Hello! Welcome to this virtual bird tour. The tour consists of
+ {{results.locationSpeciesOrder.locations.length}} waypoints.
+ The first waypoint is {{results.steps[step - 1].toLocation.name}}.
+ The map below shows your movement from one waypoint to the next.
+ The order we'll be moving in is shown by the lines on the map.
+ There are arrows on the lines that show the direction of movement.
+
+
+
+ At each waypoint, we'll pause and look around. We'll learn about two
+ birds at each waypoint. There will be information about the bird,
+ and you'll be able to demonstrate what you know. For each bird, we
+ have some audio recordings that may or may not contain the call of the bird.
+
+
+
+ Click "Move to Waypoint" to continue.
+ Read about {{results.steps[step - 1].toLocation.name}}, then click "Continue the Virtual Bird Tour"!
+
+
+
+
+ On to the next waypoint! We're going to {{results.steps[step - 1].toLocation.name}} next.
+ Click "Move to Waypoint" to continue.
+ Read about {{results.steps[step - 1].toLocation.name}}, then click "Continue the Virtual Bird Tour"!
+
Are there {{currentSpecies.commonName}}
+ calls in these audio recordings?
+
+
+ Play the audio, and look at the spectrograms.
+ Then indicate your opinion by responding
+ 'Yes' if the audio recording contains any {{currentSpecies.commonName}} calls;
+ 'No' if there are no {{currentSpecies.commonName}} calls in the audio recording;
+ 'Unsure' if you can't tell either way.
+ You need to record an answer for each audio recording.
+ Click "Done" when you are satisfied with your answers to see what other people's opinions were. Then click "Next" to move on.
+
+
+
+
+
+
+
+
+
+
A total of {{currentAnnotation.otherPeopleTotal}} other people have also given their
+ opinion on whether this annotation is a {{currentSpecies.commonName}}. Of those,
\ No newline at end of file
diff --git a/src/app/css/partials/_home.css.scss b/src/app/home/_home.css.scss
similarity index 100%
rename from src/app/css/partials/_home.css.scss
rename to src/app/home/_home.css.scss
diff --git a/src/app/js/controllers/home.js b/src/app/home/home.js
similarity index 100%
rename from src/app/js/controllers/home.js
rename to src/app/home/home.js
diff --git a/src/app/partials/home.html b/src/app/home/home.tpl.html
similarity index 100%
rename from src/app/partials/home.html
rename to src/app/home/home.tpl.html
diff --git a/src/app/img/bootstrap/glyphicons-halflings-white.png b/src/app/img/bootstrap/glyphicons-halflings-white.png
deleted file mode 100644
index 3bf6484a..00000000
Binary files a/src/app/img/bootstrap/glyphicons-halflings-white.png and /dev/null differ
diff --git a/src/app/img/bootstrap/glyphicons-halflings.png b/src/app/img/bootstrap/glyphicons-halflings.png
deleted file mode 100644
index a9969993..00000000
Binary files a/src/app/img/bootstrap/glyphicons-halflings.png and /dev/null differ
diff --git a/src/app/img/rails.png b/src/app/img/rails.png
deleted file mode 100644
index d5edc04e..00000000
Binary files a/src/app/img/rails.png and /dev/null differ
diff --git a/src/app/js/application.js b/src/app/js/application.js
deleted file mode 100644
index a71cf64a..00000000
--- a/src/app/js/application.js
+++ /dev/null
@@ -1,28 +0,0 @@
-// This is a manifest file that'll be compiled into application.js, which will include all the files
-// listed below.
-//
-// Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
-// or vendor/assets/javascripts of plugins, if any, can be referenced here using a relative path.
-//
-// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
-// the compiled file.
-//
-// WARNING: THE FIRST BLANK LINE MARKS THE END OF WHAT'S TO BE PROCESSED, ANY BLANK LINE SHOULD
-// GO AFTER THE REQUIRES BELOW.
-//
-//= require jquery
-//= require jquery_ujs
-// require jquery.ui.all // disabled because slow
-// require jquery.ui.datepicker // disabled because slow
-//= require moment
-//= require select2
-//= require angular.js
-//= require angular-resource.js
-//= require angular-ui.js
-//= require angular-ui-ieshiv.js
-//= require angular/controllers/controller_module.js
-//= require_tree .
-//= require lib
-//= require_tree ../../../vendor/assets/javascripts/.
-//= require app
-
diff --git a/src/app/js/controllers.js.erb b/src/app/js/controllers.js.erb
deleted file mode 100644
index e39b3b6b..00000000
--- a/src/app/js/controllers.js.erb
+++ /dev/null
@@ -1,23 +0,0 @@
-///* App Controllers */
-//
-//function PhotoGalleryCtrl($route, $http) {
-// $http.defaults.headers.post['Content-Type'] = 'application/json'
-// $http.defaults.headers.put['Content-Type'] = 'application/json'
-//
-// // assumes the presence of jQuery
-// var token = $("meta[name='csrf-token']").attr("content");
-// $http.defaults.headers.post['X-CSRF-Token'] = token;
-// $http.defaults.headers.put['X-CSRF-Token'] = token;
-// $http.defaults.headers['delete']['X-CSRF-Token'] = token;
-//
-//
-// $route.when('/photographers',
-// {template: '<%= asset_path("photographers.html") %>', controller: PhotographersCtrl});
-//
-// $route.when('/photographers/:photographer_id/galleries',
-// {template: '<%= asset_path("galleries.html") %>', controller: GalleriesCtrl});
-//
-// $route.when('/photographers/:photographer_id/galleries/:gallery_id/photos',
-// {template: '<%= asset_path("photos.html") %>', controller: PhotosCtrl});
-//
-// $route.otherwise({redirectTo: '/photographers'});
diff --git a/src/app/css/partials/_listen.css.scss b/src/app/listen/_listen.css.scss
similarity index 100%
rename from src/app/css/partials/_listen.css.scss
rename to src/app/listen/_listen.css.scss
diff --git a/src/app/js/controllers/listen.js b/src/app/listen/listen.js
similarity index 100%
rename from src/app/js/controllers/listen.js
rename to src/app/listen/listen.js
diff --git a/src/app/partials/listen.html b/src/app/listen/listen.tpl.html
similarity index 100%
rename from src/app/partials/listen.html
rename to src/app/listen/listen.tpl.html
diff --git a/src/app/css/partials/_login_control.css.scss b/src/app/login/_login_control.css.scss
similarity index 100%
rename from src/app/css/partials/_login_control.css.scss
rename to src/app/login/_login_control.css.scss
diff --git a/src/app/js/controllers/login.js b/src/app/login/login.js
similarity index 100%
rename from src/app/js/controllers/login.js
rename to src/app/login/login.js
diff --git a/src/app/js/controllers/navigation.js b/src/app/navigation/navigation.js
similarity index 100%
rename from src/app/js/controllers/navigation.js
rename to src/app/navigation/navigation.js
diff --git a/src/app/partials/tags_list.html b/src/app/partials/tags_list.html
deleted file mode 100644
index e69de29b..00000000
diff --git a/src/app/css/partials/_photos.css.scss b/src/app/photos/_photos.css.scss
similarity index 100%
rename from src/app/css/partials/_photos.css.scss
rename to src/app/photos/_photos.css.scss
diff --git a/src/app/partials/photo_details.html b/src/app/photos/photo_details.tpl.html
similarity index 97%
rename from src/app/partials/photo_details.html
rename to src/app/photos/photo_details.tpl.html
index df53f555..c2026065 100644
--- a/src/app/partials/photo_details.html
+++ b/src/app/photos/photo_details.tpl.html
@@ -1,13 +1,13 @@
-
\ No newline at end of file
diff --git a/src/app/js/controllers/photos.js b/src/app/photos/photos.js
similarity index 100%
rename from src/app/js/controllers/photos.js
rename to src/app/photos/photos.js
diff --git a/src/app/partials/photos_list.html b/src/app/photos/photos_list.tpl.html
similarity index 97%
rename from src/app/partials/photos_list.html
rename to src/app/photos/photos_list.tpl.html
index f3bc963f..64330b1e 100644
--- a/src/app/partials/photos_list.html
+++ b/src/app/photos/photos_list.tpl.html
@@ -1,20 +1,20 @@
-
\ No newline at end of file
diff --git a/src/app/partials/bookmark_details.html b/src/app/projects/_projects.css.scss
similarity index 100%
rename from src/app/partials/bookmark_details.html
rename to src/app/projects/_projects.css.scss
diff --git a/src/app/partials/project_details.html b/src/app/projects/project_details.tpl.html
similarity index 100%
rename from src/app/partials/project_details.html
rename to src/app/projects/project_details.tpl.html
diff --git a/src/app/js/controllers/projects.js b/src/app/projects/projects.js
similarity index 100%
rename from src/app/js/controllers/projects.js
rename to src/app/projects/projects.js
diff --git a/src/app/partials/projects_list.html b/src/app/projects/projects_list.tpl.html
similarity index 100%
rename from src/app/partials/projects_list.html
rename to src/app/projects/projects_list.tpl.html
diff --git a/src/app/css/partials/_record_information.css.scss b/src/app/recordInformation/_record_information.css.scss
similarity index 100%
rename from src/app/css/partials/_record_information.css.scss
rename to src/app/recordInformation/_record_information.css.scss
diff --git a/src/app/js/controllers/record_information.js b/src/app/recordInformation/recordInformation.js
similarity index 100%
rename from src/app/js/controllers/record_information.js
rename to src/app/recordInformation/recordInformation.js
diff --git a/src/app/partials/record_information.html b/src/app/recordInformation/record_information.tpl.html
similarity index 100%
rename from src/app/partials/record_information.html
rename to src/app/recordInformation/record_information.tpl.html
diff --git a/src/app/css/partials/_audio_recordings.css.scss b/src/app/recordings/_audio_recordings.css.scss
similarity index 100%
rename from src/app/css/partials/_audio_recordings.css.scss
rename to src/app/recordings/_audio_recordings.css.scss
diff --git a/src/app/partials/recording.html b/src/app/recordings/recording.tpl.html
similarity index 97%
rename from src/app/partials/recording.html
rename to src/app/recordings/recording.tpl.html
index d51afa5b..af267129 100644
--- a/src/app/partials/recording.html
+++ b/src/app/recordings/recording.tpl.html
@@ -1,11 +1,11 @@
-
\ No newline at end of file
diff --git a/src/app/js/controllers/recordings.js b/src/app/recordings/recordings.js
similarity index 100%
rename from src/app/js/controllers/recordings.js
rename to src/app/recordings/recordings.js
diff --git a/src/app/partials/recordings.html b/src/app/recordings/recordings.tpl.html
similarity index 97%
rename from src/app/partials/recordings.html
rename to src/app/recordings/recordings.tpl.html
index aa0a4b33..54241129 100644
--- a/src/app/partials/recordings.html
+++ b/src/app/recordings/recordings.tpl.html
@@ -1,15 +1,15 @@
-
\ No newline at end of file
diff --git a/src/app/css/partials/_saved_searches.css.scss b/src/app/search/_saved_searches.css.scss
similarity index 100%
rename from src/app/css/partials/_saved_searches.css.scss
rename to src/app/search/_saved_searches.css.scss
diff --git a/src/app/js/controllers/search.js b/src/app/search/search.js
similarity index 100%
rename from src/app/js/controllers/search.js
rename to src/app/search/search.js
diff --git a/src/app/partials/bookmarks_list.html b/src/app/search/search_details.tpl.html
similarity index 100%
rename from src/app/partials/bookmarks_list.html
rename to src/app/search/search_details.tpl.html
diff --git a/src/app/partials/search_edit.html b/src/app/search/search_edit.tpl.html
similarity index 100%
rename from src/app/partials/search_edit.html
rename to src/app/search/search_edit.tpl.html
diff --git a/src/app/partials/searches_list.html b/src/app/search/searches_list.tpl.html
similarity index 100%
rename from src/app/partials/searches_list.html
rename to src/app/search/searches_list.tpl.html
diff --git a/src/app/css/partials/_sites.css.scss b/src/app/sites/_sites.css.scss
similarity index 100%
rename from src/app/css/partials/_sites.css.scss
rename to src/app/sites/_sites.css.scss
diff --git a/src/app/partials/site_details.html b/src/app/sites/site_details.tpl.html
similarity index 97%
rename from src/app/partials/site_details.html
rename to src/app/sites/site_details.tpl.html
index 8d4a563d..ae9db537 100644
--- a/src/app/partials/site_details.html
+++ b/src/app/sites/site_details.tpl.html
@@ -1,73 +1,73 @@
-
-
Site
-
-
{{editing | boolToWords:'Editing site.':'The details for a site.'}}
diff --git a/src/app/js/controllers/sites.js b/src/app/sites/sites.js
similarity index 100%
rename from src/app/js/controllers/sites.js
rename to src/app/sites/sites.js
diff --git a/src/app/partials/sites_list.html b/src/app/sites/sites_list.tpl.html
similarity index 100%
rename from src/app/partials/sites_list.html
rename to src/app/sites/sites_list.tpl.html
diff --git a/src/app/css/partials/_tags.css.scss b/src/app/tags/_tags.css.scss
similarity index 100%
rename from src/app/css/partials/_tags.css.scss
rename to src/app/tags/_tags.css.scss
diff --git a/src/app/partials/search_details.html b/src/app/tags/tag_details.tpl.html
similarity index 100%
rename from src/app/partials/search_details.html
rename to src/app/tags/tag_details.tpl.html
diff --git a/src/app/js/controllers/tags.js b/src/app/tags/tags.js
similarity index 100%
rename from src/app/js/controllers/tags.js
rename to src/app/tags/tags.js
diff --git a/src/app/partials/tag_details.html b/src/app/tags/tags_list.tpl.html
similarity index 100%
rename from src/app/partials/tag_details.html
rename to src/app/tags/tags_list.tpl.html
diff --git a/src/app/partials/user_details.html b/src/app/users/user_details.tpl.html
similarity index 97%
rename from src/app/partials/user_details.html
rename to src/app/users/user_details.tpl.html
index a62f038b..37445782 100644
--- a/src/app/partials/user_details.html
+++ b/src/app/users/user_details.tpl.html
@@ -1,9 +1,9 @@
-
-
{{user.displayName}}
-
-
Display Name: {{user.displayName}}
-
User Name: {{user.userName}}
-
Last updated: {{lastModifiedDisplay}}
-
If we need to contact you, we'll email you on {{user.email}}.
-
We do not have your email address stored.
-
+
+
{{user.displayName}}
+
+
Display Name: {{user.displayName}}
+
User Name: {{user.userName}}
+
Last updated: {{lastModifiedDisplay}}
+
If we need to contact you, we'll email you on {{user.email}}.
+
We do not have your email address stored.
+
diff --git a/src/app/js/controllers/users.js b/src/app/users/users.js
similarity index 100%
rename from src/app/js/controllers/users.js
rename to src/app/users/users.js
diff --git a/src/app/partials/users_list.html b/src/app/users/users_list.tpl.html
similarity index 100%
rename from src/app/partials/users_list.html
rename to src/app/users/users_list.tpl.html
diff --git a/src/app/img/angular-auth/content_repeat.jpg b/src/assets/img/angular-auth/content_repeat.jpg
similarity index 100%
rename from src/app/img/angular-auth/content_repeat.jpg
rename to src/assets/img/angular-auth/content_repeat.jpg
diff --git a/src/app/img/angular-auth/loading.gif b/src/assets/img/angular-auth/loading.gif
similarity index 100%
rename from src/app/img/angular-auth/loading.gif
rename to src/assets/img/angular-auth/loading.gif
diff --git a/src/app/img/provider/auth-buttons.css.scss b/src/assets/img/provider/auth-buttons.css.scss
similarity index 100%
rename from src/app/img/provider/auth-buttons.css.scss
rename to src/assets/img/provider/auth-buttons.css.scss
diff --git a/src/app/img/provider/auth-icons.png b/src/assets/img/provider/auth-icons.png
similarity index 100%
rename from src/app/img/provider/auth-icons.png
rename to src/assets/img/provider/auth-icons.png
diff --git a/src/app/img/provider/facebook_48.png b/src/assets/img/provider/facebook_48.png
similarity index 100%
rename from src/app/img/provider/facebook_48.png
rename to src/assets/img/provider/facebook_48.png
diff --git a/src/app/img/provider/google_48.png b/src/assets/img/provider/google_48.png
similarity index 100%
rename from src/app/img/provider/google_48.png
rename to src/assets/img/provider/google_48.png
diff --git a/src/app/img/provider/openid_48.png b/src/assets/img/provider/openid_48.png
similarity index 100%
rename from src/app/img/provider/openid_48.png
rename to src/assets/img/provider/openid_48.png
diff --git a/src/app/img/provider/persona-buttons.css.scss b/src/assets/img/provider/persona-buttons.css.scss
similarity index 100%
rename from src/app/img/provider/persona-buttons.css.scss
rename to src/assets/img/provider/persona-buttons.css.scss
diff --git a/src/app/img/provider/persona_sign_in_blue.png b/src/assets/img/provider/persona_sign_in_blue.png
similarity index 100%
rename from src/app/img/provider/persona_sign_in_blue.png
rename to src/assets/img/provider/persona_sign_in_blue.png
diff --git a/src/app/img/provider/twitter_48.png b/src/assets/img/provider/twitter_48.png
similarity index 100%
rename from src/app/img/provider/twitter_48.png
rename to src/assets/img/provider/twitter_48.png
diff --git a/src/app/img/provider/windows_live_48.png b/src/assets/img/provider/windows_live_48.png
similarity index 100%
rename from src/app/img/provider/windows_live_48.png
rename to src/assets/img/provider/windows_live_48.png
diff --git a/src/app/img/provider/yahoo_48.png b/src/assets/img/provider/yahoo_48.png
similarity index 100%
rename from src/app/img/provider/yahoo_48.png
rename to src/assets/img/provider/yahoo_48.png
diff --git a/src/common/README.md b/src/common/README.md
new file mode 100644
index 00000000..2c68a757
--- /dev/null
+++ b/src/common/README.md
@@ -0,0 +1,24 @@
+# The `src/common/` Directory
+
+The `src/common/` directory houses internal and third-party re-usable
+components. Essentially, this folder is for everything that isn't completely
+specific to this application.
+
+Each component resides in its own directory that may then be structured any way
+the developer desires. The build system will read all `*.js` files that do not
+end in `.spec.js` as source files to be included in the final build, all
+`*.spec.js` files as unit tests to be executed, and all `*.tpl.html` files as
+templates to compiled into the `$templateCache`. There is currently no way to
+handle components that do not meet this pattern.
+
+```
+src/
+ |- common/
+ | |- plusOne/
+```
+
+- `plusOne` - a simple directive to load a Google +1 Button on an element.
+
+Every component contained here should be drag-and-drop reusable in any other
+project; they should depend on no other components that aren't similarly
+drag-and-drop reusable.
diff --git a/src/app/js/directives/auth.js b/src/components/directives/auth.js
similarity index 100%
rename from src/app/js/directives/auth.js
rename to src/components/directives/auth.js
diff --git a/src/app/js/directives/directives.js b/src/components/directives/directives.js
similarity index 100%
rename from src/app/js/directives/directives.js
rename to src/components/directives/directives.js
diff --git a/src/app/js/filters/filters.js b/src/components/filters/filters.js
similarity index 100%
rename from src/app/js/filters/filters.js
rename to src/components/filters/filters.js
diff --git a/src/app/js/models/annotation.js b/src/components/models/annotation.js
similarity index 100%
rename from src/app/js/models/annotation.js
rename to src/components/models/annotation.js
diff --git a/src/app/js/models/audio_event_tag.js b/src/components/models/audio_event_tag.js
similarity index 100%
rename from src/app/js/models/audio_event_tag.js
rename to src/components/models/audio_event_tag.js
diff --git a/src/app/js/services/angularjs-rails-resource.js b/src/components/services/angularjs-rails-resource.js
similarity index 100%
rename from src/app/js/services/angularjs-rails-resource.js
rename to src/components/services/angularjs-rails-resource.js
diff --git a/src/app/js/services/services.js b/src/components/services/services.js
similarity index 100%
rename from src/app/js/services/services.js
rename to src/components/services/services.js
diff --git a/src/app/css/_base.css.scss b/src/sass/_base.css.scss
similarity index 100%
rename from src/app/css/_base.css.scss
rename to src/sass/_base.css.scss
diff --git a/src/app/css/_dynamic.css.scss.erb b/src/sass/_dynamic.css.scss.erb
similarity index 100%
rename from src/app/css/_dynamic.css.scss.erb
rename to src/sass/_dynamic.css.scss.erb
diff --git a/src/app/css/_layout.css.scss b/src/sass/_layout.css.scss
similarity index 100%
rename from src/app/css/_layout.css.scss
rename to src/sass/_layout.css.scss
diff --git a/src/app/css/partials/_time_formats.css.scss b/src/sass/_time_formats.css.scss
similarity index 100%
rename from src/app/css/partials/_time_formats.css.scss
rename to src/sass/_time_formats.css.scss
diff --git a/src/app/css/application.css.scss b/src/sass/application.css.scss
similarity index 100%
rename from src/app/css/application.css.scss
rename to src/sass/application.css.scss