diff --git a/node_modules/material-design-lite/gulpfile.babel.js b/node_modules/material-design-lite/gulpfile.babel.js
new file mode 100644
index 0000000..d5b70d8
--- /dev/null
+++ b/node_modules/material-design-lite/gulpfile.babel.js
@@ -0,0 +1,807 @@
+/**
+ *
+ *  Material Design Lite
+ *  Copyright 2015 Google Inc. All rights reserved.
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      https://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License
+ *
+ */
+
+// jscs:disable jsDoc
+
+'use strict';
+
+// Include Gulp & Tools We'll Use
+import fs from 'fs';
+import path from 'path';
+import mergeStream from 'merge-stream';
+import del from 'del';
+import vinylPaths from 'vinyl-paths';
+import runSequence from 'run-sequence';
+import browserSync from 'browser-sync';
+import through from 'through2';
+import swig from 'swig';
+import gulp from 'gulp';
+import closureCompiler from 'gulp-closure-compiler';
+import gulpLoadPlugins from 'gulp-load-plugins';
+import uniffe from './utils/uniffe.js';
+import pkg from './package.json';
+
+const $ = gulpLoadPlugins();
+const reload = browserSync.reload;
+const hostedLibsUrlPrefix = 'https://code.getmdl.io';
+const templateArchivePrefix = 'mdl-template-';
+const bucketProd = 'gs://www.getmdl.io';
+const bucketStaging = 'gs://mdl-staging';
+const bucketCode = 'gs://code.getmdl.io';
+const banner = ['/**',
+  ' * <%= pkg.name %> - <%= pkg.description %>',
+  ' * @version v<%= pkg.version %>',
+  ' * @license <%= pkg.license %>',
+  ' * @copyright 2015 Google, Inc.',
+  ' * @link https://github.com/google/material-design-lite',
+  ' */',
+  ''].join('\n');
+
+let codeFiles = '';
+
+const AUTOPREFIXER_BROWSERS = [
+  'ie >= 10',
+  'ie_mob >= 10',
+  'ff >= 30',
+  'chrome >= 34',
+  'safari >= 7',
+  'opera >= 23',
+  'ios >= 7',
+  'android >= 4.4',
+  'bb >= 10'
+];
+
+const SOURCES = [
+  // Component handler
+  'src/mdlComponentHandler.js',
+  // Polyfills/dependencies
+  'src/third_party/**/*.js',
+  // Base components
+  'src/button/button.js',
+  'src/checkbox/checkbox.js',
+  'src/icon-toggle/icon-toggle.js',
+  'src/menu/menu.js',
+  'src/progress/progress.js',
+  'src/radio/radio.js',
+  'src/slider/slider.js',
+  'src/snackbar/snackbar.js',
+  'src/spinner/spinner.js',
+  'src/switch/switch.js',
+  'src/tabs/tabs.js',
+  'src/textfield/textfield.js',
+  'src/tooltip/tooltip.js',
+  // Complex components (which reuse base components)
+  'src/layout/layout.js',
+  'src/data-table/data-table.js',
+  // And finally, the ripples
+  'src/ripple/ripple.js'
+];
+
+// ***** Development tasks ****** //
+
+// Lint JavaScript
+gulp.task('lint', () => {
+  return gulp.src([
+      'src/**/*.js',
+      'gulpfile.babel.js'
+    ])
+    .pipe(reload({stream: true, once: true}))
+    .pipe($.jshint())
+    .pipe($.jscs())
+    .pipe($.jshint.reporter('jshint-stylish'))
+    .pipe($.jscs.reporter())
+    .pipe($.if(!browserSync.active, $.jshint.reporter('fail')))
+    .pipe($.if(!browserSync.active, $.jscs.reporter('fail')));
+});
+
+// ***** Production build tasks ****** //
+
+// Optimize Images
+// TODO: Update image paths in final CSS to match root/images
+gulp.task('images', () => {
+  return gulp.src('src/**/*.{svg,png,jpg}')
+    .pipe($.flatten())
+    .pipe($.cache($.imagemin({
+      progressive: true,
+      interlaced: true
+    })))
+    .pipe(gulp.dest('dist/images'))
+    .pipe($.size({title: 'images'}));
+});
+
+// Compile and Automatically Prefix Stylesheets (dev)
+gulp.task('styles:dev', () => {
+  return gulp.src('src/**/*.scss')
+    .pipe($.sass({
+      precision: 10,
+      onError: console.error.bind(console, 'Sass error:')
+    }))
+    .pipe($.cssInlineImages({
+      webRoot: 'src'
+    }))
+    .pipe($.autoprefixer(AUTOPREFIXER_BROWSERS))
+    .pipe(gulp.dest('.tmp/styles'))
+    .pipe($.size({title: 'styles'}));
+});
+
+// Compile and Automatically Prefix Stylesheet Templates (production)
+gulp.task('styletemplates', () => {
+  // For best performance, don't add Sass partials to `gulp.src`
+  return gulp.src('src/template.scss')
+    // Generate Source Maps
+    .pipe($.sourcemaps.init())
+    .pipe($.sass({
+      precision: 10,
+      onError: console.error.bind(console, 'Sass error:')
+    }))
+    .pipe($.cssInlineImages({webRoot: 'src'}))
+    .pipe($.autoprefixer(AUTOPREFIXER_BROWSERS))
+    .pipe(gulp.dest('.tmp'))
+    // Concatenate Styles
+    .pipe($.concat('material.css.template'))
+    .pipe(gulp.dest('dist'))
+    // Minify Styles
+    .pipe($.if('*.css.template', $.csso()))
+    .pipe($.concat('material.min.css.template'))
+    .pipe($.header(banner, {pkg}))
+    .pipe($.sourcemaps.write('.'))
+    .pipe(gulp.dest('dist'))
+    .pipe($.size({title: 'styles'}));
+});
+
+// Compile and Automatically Prefix Stylesheets (production)
+gulp.task('styles', () => {
+  // For best performance, don't add Sass partials to `gulp.src`
+  return gulp.src('src/material-design-lite.scss')
+    // Generate Source Maps
+    .pipe($.sourcemaps.init())
+    .pipe($.sass({
+      precision: 10,
+      onError: console.error.bind(console, 'Sass error:')
+    }))
+    .pipe($.cssInlineImages({webRoot: 'src'}))
+    .pipe($.autoprefixer(AUTOPREFIXER_BROWSERS))
+    .pipe(gulp.dest('.tmp'))
+    // Concatenate Styles
+    .pipe($.concat('material.css'))
+    .pipe($.header(banner, {pkg}))
+    .pipe(gulp.dest('dist'))
+    // Minify Styles
+    .pipe($.if('*.css', $.csso()))
+    .pipe($.concat('material.min.css'))
+    .pipe($.header(banner, {pkg}))
+    .pipe($.sourcemaps.write('.'))
+    .pipe(gulp.dest('dist'))
+    .pipe($.size({title: 'styles'}));
+});
+
+// Only generate CSS styles for the MDL grid
+gulp.task('styles-grid', () => {
+  return gulp.src('src/material-design-lite-grid.scss')
+    .pipe($.sass({
+      precision: 10,
+      onError: console.error.bind(console, 'Sass error:')
+    }))
+    .pipe($.autoprefixer(AUTOPREFIXER_BROWSERS))
+    .pipe(gulp.dest('.tmp'))
+    // Concatenate Styles
+    .pipe($.concat('material-grid.css'))
+    .pipe($.header(banner, {pkg}))
+    .pipe(gulp.dest('dist'))
+    // Minify Styles
+    .pipe($.if('*.css', $.csso()))
+    .pipe($.concat('material-grid.min.css'))
+    .pipe($.header(banner, {pkg}))
+    .pipe(gulp.dest('dist'))
+    .pipe($.size({title: 'styles-grid'}));
+});
+
+// Build with Google's Closure Compiler, requires Java 1.7+ installed.
+gulp.task('closure', () => {
+  return gulp.src(SOURCES)
+    .pipe(closureCompiler({
+      compilerPath: 'node_modules/google-closure-compiler/compiler.jar',
+      fileName: 'material.closure.min.js',
+      compilerFlags: {
+        // jscs:disable requireCamelCaseOrUpperCaseIdentifiers
+        compilation_level: 'ADVANCED_OPTIMIZATIONS',
+        language_in: 'ECMASCRIPT6_STRICT',
+        language_out: 'ECMASCRIPT5_STRICT',
+        warning_level: 'VERBOSE'
+        // jscs:enable requireCamelCaseOrUpperCaseIdentifiers
+      }
+    }))
+    .pipe(gulp.dest('./dist'));
+});
+
+// Concatenate And Minify JavaScript
+gulp.task('scripts', ['lint'], () => {
+  return gulp.src(SOURCES)
+    .pipe($.if(/mdlComponentHandler\.js/, $.util.noop(), uniffe()))
+    .pipe($.sourcemaps.init())
+    // Concatenate Scripts
+    .pipe($.concat('material.js'))
+    .pipe($.iife({useStrict: true}))
+    .pipe(gulp.dest('dist'))
+    // Minify Scripts
+    .pipe($.uglify({
+      sourceRoot: '.',
+      sourceMapIncludeSources: true
+    }))
+    .pipe($.header(banner, {pkg}))
+    .pipe($.concat('material.min.js'))
+    // Write Source Maps
+    .pipe($.sourcemaps.write('.'))
+    .pipe(gulp.dest('dist'))
+    .pipe($.size({title: 'scripts'}));
+});
+
+// Clean Output Directory
+gulp.task('clean', () => del(['dist', '.publish']));
+
+// Copy package manger and LICENSE files to dist
+gulp.task('metadata', () => {
+  return gulp.src([
+      'package.json',
+      'bower.json',
+      'LICENSE'
+    ])
+    .pipe(gulp.dest('dist'));
+});
+
+// Build Production Files, the Default Task
+gulp.task('default', ['clean'], cb => {
+  runSequence(
+    ['styles', 'styles-grid'],
+    ['scripts'],
+    ['mocha'],
+    cb);
+});
+
+// Build production files and microsite
+gulp.task('all', ['clean'], cb => {
+  runSequence(
+    ['styletemplates'],
+    ['styles-grid', 'styles:gen'],
+    ['scripts'],
+    ['mocha'],
+    ['assets', 'pages',
+     'templates', 'images', 'metadata'],
+    ['zip'],
+    cb);
+});
+
+// ***** Testing tasks ***** //
+
+gulp.task('mocha', ['styles'], () => {
+  return gulp.src('test/index.html')
+    .pipe($.mochaPhantomjs({reporter: 'tap'}));
+});
+
+gulp.task('mocha:closure', ['closure'], () => {
+  return gulp.src('test/index.html')
+    .pipe($.replace('src="../dist/material.js"',
+        'src="../dist/material.closure.min.js"'))
+    .pipe($.rename('temp.html'))
+    .pipe(gulp.dest('test'))
+    .pipe($.mochaPhantomjs({reporter: 'tap'}))
+    .on('finish', () => del.sync('test/temp.html'))
+    .on('error', () => del.sync('test/temp.html'));
+});
+
+gulp.task('test', [
+  'lint',
+  'mocha',
+  'mocha:closure'
+]);
+
+gulp.task('test:visual', () => {
+  browserSync({
+    notify: false,
+    server: '.',
+    startPath: 'test/visual/index.html'
+  });
+
+  gulp.watch('test/visual/**', reload);
+});
+
+// ***** Landing page tasks ***** //
+
+/**
+ * Site metadata for use with templates.
+ * @type {Object}
+ */
+const site = {};
+
+/**
+ * Generates an HTML file based on a template and file metadata.
+ */
+function applyTemplate() {
+  return through.obj((file, enc, cb) => {
+    const data = {
+      site,
+      page: file.page,
+      content: file.contents.toString()
+    };
+
+    const templateFile = path.join(
+        __dirname, 'docs', '_templates', `${file.page.layout}.html`);
+    const tpl = swig.compileFile(templateFile, {cache: false});
+
+    file.contents = new Buffer(tpl(data));
+    cb(null, file);
+  });
+}
+
+/**
+ * Generates an index.html file for each README in MDL/src directory.
+ */
+gulp.task('components', ['demos'], () => {
+  return gulp.src('src/**/README.md', {base: 'src'})
+    // Add basic front matter.
+    .pipe($.header('---\nlayout: component\nbodyclass: component\ninclude_prefix: ../../\n---\n\n'))
+    .pipe($.frontMatter({
+      property: 'page',
+      remove: true
+    }))
+    .pipe($.marked())
+    .pipe((() => {
+      return through.obj((file, enc, cb) => {
+        file.page.component = file.relative.split('/')[0];
+        cb(null, file);
+      });
+    })())
+    .pipe(applyTemplate())
+    .pipe($.rename(path => path.basename = 'index'))
+    .pipe(gulp.dest('dist/components'));
+});
+
+/**
+ * Copies demo files from MDL/src directory.
+ */
+gulp.task('demoresources', () => {
+  return gulp.src([
+      'src/**/demos.css',
+      'src/**/demo.css',
+      'src/**/demo.js'
+    ], {base: 'src'})
+    .pipe($.if('*.scss', $.sass({
+      precision: 10,
+      onError: console.error.bind(console, 'Sass error:')
+    })))
+    .pipe($.cssInlineImages({webRoot: 'src'}))
+    .pipe($.if('*.css', $.autoprefixer(AUTOPREFIXER_BROWSERS)))
+    .pipe(gulp.dest('dist/components'));
+});
+
+/**
+ * Generates demo files for testing made of all the snippets and the demo file
+ * put together.
+ */
+gulp.task('demos', ['demoresources'], () => {
+  /**
+   * Retrieves the list of component folders.
+   */
+  function getComponentFolders() {
+    return fs.readdirSync('src')
+      .filter(file => fs.statSync(path.join('src', file)).isDirectory());
+  }
+
+  const tasks = getComponentFolders().map(component => {
+    return gulp.src([
+        path.join('src', component, 'snippets', '*.html'),
+        path.join('src', component, 'demo.html')
+      ])
+      .pipe($.concat('/demo.html'))
+      // Add basic front matter.
+      .pipe($.header('---\nlayout: demo\nbodyclass: demo\ninclude_prefix: ../../\n---\n\n'))
+      .pipe($.frontMatter({
+        property: 'page',
+        remove: true
+      }))
+      .pipe($.marked())
+      .pipe((() => {
+        return through.obj((file, enc, cb) => {
+          file.page.component = component;
+          cb(null, file);
+        });
+      })())
+      .pipe(applyTemplate())
+      .pipe(gulp.dest(path.join('dist', 'components', component)));
+  });
+
+  return mergeStream(tasks);
+});
+
+/**
+ * Generates an HTML file for each md file in _pages directory.
+ */
+gulp.task('pages', ['components'], () => {
+  return gulp.src('docs/_pages/*.md')
+    .pipe($.frontMatter({
+      property: 'page',
+      remove: true
+    }))
+    .pipe($.marked())
+    .pipe(applyTemplate())
+    .pipe($.replace('$$version$$', pkg.version))
+    .pipe($.replace('$$hosted_libs_prefix$$', hostedLibsUrlPrefix))
+    .pipe($.replace('$$template_archive_prefix$$', templateArchivePrefix))
+    /* Replacing code blocks class name to match Prism's. */
+    .pipe($.replace('class="lang-', 'class="language-'))
+    /* Translate html code blocks to "markup" because that's what Prism uses. */
+    .pipe($.replace('class="language-html', 'class="language-markup'))
+    .pipe($.rename(path => {
+      if (path.basename !== 'index') {
+        path.dirname = path.basename;
+        path.basename = 'index';
+      }
+    }))
+    .pipe(gulp.dest('dist'));
+});
+
+/**
+ * Copies assets from MDL and _assets directory.
+ */
+gulp.task('assets', () => {
+  return gulp.src([
+      'docs/_assets/**/*',
+      'node_modules/clippy/build/clippy.swf',
+      'node_modules/swfobject-npm/swfobject/src/swfobject.js',
+      'node_modules/prismjs/prism.js',
+      'node_modules/prismjs/components/prism-markup.min.js',
+      'node_modules/prismjs/components/prism-javascript.min.js',
+      'node_modules/prismjs/components/prism-css.min.js',
+      'node_modules/prismjs/components/prism-bash.min.js',
+      'node_modules/prismjs/dist/prism-default/prism-default.css'
+    ])
+    .pipe($.if(/\.js/i, $.replace('$$version$$', pkg.version)))
+    .pipe($.if(/\.js/i, $.replace('$$hosted_libs_prefix$$', hostedLibsUrlPrefix)))
+    .pipe($.if(/\.(svg|jpg|png)$/i, $.imagemin({
+      progressive: true,
+      interlaced: true
+    })))
+    .pipe($.if(/\.css/i, $.autoprefixer(AUTOPREFIXER_BROWSERS)))
+    .pipe($.if(/\.css/i, $.csso()))
+    .pipe($.if(/\.js/i, $.uglify({
+      preserveComments: 'some',
+      sourceRoot: '.',
+      sourceMapIncludeSources: true
+    })))
+    .pipe(gulp.dest('dist/assets'));
+});
+
+/**
+ * Defines the list of resources to watch for changes.
+ */
+function watch() {
+  gulp.watch(['src/**/*.js', '!src/**/README.md'],
+    ['scripts', 'demos', 'components', reload]);
+  gulp.watch(['src/**/*.{scss,css}'],
+    ['styles', 'styles-grid', 'styletemplates', reload]);
+  gulp.watch(['src/**/*.html'], ['pages', reload]);
+  gulp.watch(['src/**/*.{svg,png,jpg}'], ['images', reload]);
+  gulp.watch(['src/**/README.md'], ['pages', reload]);
+  gulp.watch(['templates/**/*'], ['templates', reload]);
+  gulp.watch(['docs/**/*'], ['pages', 'assets', reload]);
+  gulp.watch(['package.json', 'bower.json', 'LICENSE'], ['metadata']);
+}
+
+/**
+ * Serves the landing page from "out" directory.
+ */
+gulp.task('serve:browsersync', () => {
+  browserSync({
+    notify: false,
+    server: {
+      baseDir: ['dist']
+    }
+  });
+
+  watch();
+});
+
+gulp.task('serve', () => {
+  $.connect.server({
+    root: 'dist',
+    port: 5000,
+    livereload: true
+  });
+
+  watch();
+
+  gulp.src('dist/index.html')
+    .pipe($.open({uri: 'http://localhost:5000'}));
+});
+
+// Generate release archive containing just JS, CSS, Source Map deps
+gulp.task('zip:mdl', () => {
+  return gulp.src([
+      'dist/material?(.min)@(.js|.css)?(.map)',
+      'LICENSE',
+      'bower.json',
+      'package.json'
+    ])
+    .pipe($.zip('mdl.zip'))
+    .pipe(gulp.dest('dist'));
+});
+
+/**
+ * Returns the list of children directories inside the given directory.
+ * @param {string} dir the parent directory
+ * @return {Array<string>} list of child directories
+ */
+function getSubDirectories(dir) {
+  return fs.readdirSync(dir)
+    .filter(file => fs.statSync(path.join(dir, file)).isDirectory());
+}
+
+// Generate release archives containing the templates and assets for templates.
+gulp.task('zip:templates', () => {
+  const templates = getSubDirectories('dist/templates');
+
+  // Generate a zip file for each template.
+  const generateZips = templates.map(template => {
+    return gulp.src([
+        `dist/templates/${template}/**/*.*`,
+        'LICENSE'
+      ])
+      .pipe($.rename(path => {
+        path.dirname = path.dirname.replace(`dist/templates/${template}`, '');
+      }))
+      .pipe($.zip(`${templateArchivePrefix}${template}.zip`))
+      .pipe(gulp.dest('dist'));
+  });
+
+  return mergeStream(generateZips);
+});
+
+gulp.task('zip', [
+  'zip:templates',
+  'zip:mdl'
+]);
+
+gulp.task('genCodeFiles', () => {
+  return gulp.src([
+      'dist/material.*@(js|css)?(.map)',
+      'dist/mdl.zip',
+      `dist/${templateArchivePrefix}*.zip`
+    ], {read: false})
+    .pipe($.tap(file => {
+      codeFiles += ` dist/${path.basename(file.path)}`;
+    }));
+});
+
+// Push the latest version of code resources (CSS+JS) to Google Cloud Storage.
+// Public-read objects in GCS are served by a Google provided and supported
+// global, high performance caching/content delivery network (CDN) service.
+// This task requires gsutil to be installed and configured.
+// For info on gsutil: https://cloud.google.com/storage/docs/gsutil.
+gulp.task('pushCodeFiles', () => {
+  const dest = bucketCode;
+  console.log(`Publishing ${pkg.version} to CDN (${dest})`);
+
+  // Build cache control and gsutil cmd to copy
+  // each object into a GCS bucket. The dest is a version specific path.
+  // The gsutil -m option requests parallel copies.
+  // The gsutil -h option is used to set metadata headers
+  // (cache control, in this case).
+  // Code files should NEVER be touched after uploading, therefore
+  // 30 days caching is a safe value.
+  const cacheControl = '-h "Cache-Control:public,max-age=2592000"';
+  const gsutilCpCmd = 'gsutil -m cp -z js,css,map ';
+  const gsutilCacheCmd = `gsutil -m setmeta -R ${cacheControl}`;
+
+  // Upload the goodies to a separate GCS bucket with versioning.
+  // Using a sep bucket avoids the risk of accidentally blowing away
+  // old versions in the microsite bucket.
+  return gulp.src('')
+    .pipe($.shell([
+      `${gsutilCpCmd}${codeFiles} ${dest}/${pkg.version}`,
+      `${gsutilCacheCmd} ${dest}/${pkg.version}`
+    ]));
+});
+
+gulp.task('publish:code', cb => {
+  runSequence(
+    ['zip:mdl', 'zip:templates'],
+    'genCodeFiles',
+    'pushCodeFiles',
+    cb);
+});
+
+/**
+ * Function to publish staging or prod version from local tree,
+ * or to promote staging to prod, per passed arg.
+ * @param {string} pubScope the scope to publish to.
+ */
+function mdlPublish(pubScope) {
+  let cacheTtl = null;
+  let src = null;
+  let dest = null;
+
+  if (pubScope === 'staging') {
+    // Set staging specific vars here.
+    cacheTtl = 0;
+    src = 'dist/*';
+    dest = bucketStaging;
+  } else if (pubScope === 'prod') {
+    // Set prod specific vars here.
+    cacheTtl = 60;
+    src = 'dist/*';
+    dest = bucketProd;
+  } else if (pubScope === 'promote') {
+    // Set promote (essentially prod) specific vars here.
+    cacheTtl = 60;
+    src = `${bucketStaging}/*`;
+    dest = bucketProd;
+  }
+
+  let infoMsg = `Publishing ${pubScope}/${pkg.version} to GCS (${dest})`;
+  if (src) {
+    infoMsg += ` from ${src}`;
+  }
+  console.log(infoMsg);
+
+  // Build gsutil commands:
+  // The gsutil -h option is used to set metadata headers.
+  // The gsutil -m option requests parallel copies.
+  // The gsutil -R option is used for recursive file copy.
+  const cacheControl = `-h "Cache-Control:public,max-age=${cacheTtl}"`;
+  const gsutilCacheCmd = `gsutil -m setmeta ${cacheControl} ${dest}/**`;
+  const gsutilCpCmd = `gsutil -m cp -r -z html,css,js,svg ${src} ${dest}`;
+
+  gulp.src('').pipe($.shell([gsutilCpCmd, gsutilCacheCmd]));
+}
+
+// Push the local build of the MDL microsite and release artifacts to the
+// production Google Cloud Storage bucket for general serving to the web.
+// Public-read objects in GCS are served by a Google provided and supported
+// global, high performance caching/content delivery network (CDN) service.
+// This task requires gsutil to be installed and configured.
+// For info on gsutil: https://cloud.google.com/storage/docs/gsutil.
+//
+gulp.task('publish:prod', () => {
+  mdlPublish('prod');
+});
+
+// Promote the staging version of the MDL microsite and release artifacts
+// to the production Google Cloud Storage bucket for general serving.
+// Public-read objects in GCS are served by a Google provided and supported
+// global, high performance caching/content delivery network (CDN) service.
+// This task requires gsutil to be installed and configured.
+// For info on gsutil: https://cloud.google.com/storage/docs/gsutil.
+//
+gulp.task('publish:promote', () => {
+  mdlPublish('promote');
+});
+
+// Push the staged version of the MDL microsite and release artifacts
+// to a production Google Cloud Storage bucket for staging and pre-production testing.
+//
+// This task requires gsutil to be installed and configured.
+// For info on gsutil: https://cloud.google.com/storage/docs/gsutil.
+//
+gulp.task('publish:staging', () => {
+  mdlPublish('staging');
+});
+
+gulp.task('_release', () => {
+  return gulp.src([
+      'dist/material?(.min)@(.js|.css)?(.map)',
+      'LICENSE',
+      'README.md',
+      'bower.json',
+      'package.json',
+      '.jscsrc',
+      '.jshintrc',
+      './sr?/**/*',
+      'gulpfile.babel.js',
+      './util?/**/*'
+    ])
+    .pipe(gulp.dest('_release'));
+});
+
+gulp.task('publish:release', ['_release'], () => {
+  return gulp.src('_release')
+    .pipe($.subtree({
+      remote: 'origin',
+      branch: 'release'
+    }))
+    .pipe(vinylPaths(del));
+});
+
+gulp.task('templates:styles', () => {
+  return gulp.src('templates/**/*.css')
+    .pipe($.autoprefixer(AUTOPREFIXER_BROWSERS))
+    // FIXME: This crashes. It's a bug in gulp-csso,
+    // not csso itself.
+    //.pipe($.csso())
+    .pipe(gulp.dest('dist/templates'));
+});
+
+gulp.task('templates:static', () => {
+  return gulp.src('templates/**/*.html')
+  .pipe($.replace('$$version$$', pkg.version))
+  .pipe($.replace('$$hosted_libs_prefix$$', hostedLibsUrlPrefix))
+  .pipe(gulp.dest('dist/templates'));
+});
+
+// This task can be used if you want to test the templates against locally
+// built version of the MDL libraries.
+gulp.task('templates:localtestingoverride', () => {
+  return gulp.src('templates/**/*.html')
+    .pipe($.replace('$$version$$', '.'))
+    .pipe($.replace('$$hosted_libs_prefix$$', ''))
+    .pipe(gulp.dest('dist/templates'));
+});
+
+gulp.task('templates:images', () => {
+  return gulp.src('templates/*/images/**/*')
+    .pipe($.imagemin({
+      progressive: true,
+      interlaced: true
+    }))
+    .pipe(gulp.dest('dist/templates'));
+});
+
+gulp.task('templates:fonts', () => {
+  return gulp.src('templates/*/fonts/**/*')
+    .pipe(gulp.dest('dist/templates/'));
+});
+
+gulp.task('templates', [
+  'templates:static',
+  'templates:images',
+  'templates:fonts',
+  'templates:styles'
+]);
+
+gulp.task('styles:gen', ['styles'], () => {
+  const MaterialCustomizer = require('./docs/_assets/customizer.js');
+  const templatePath = path.join(__dirname, 'dist', 'material.min.css.template');
+  // TODO: This task needs refactoring once we turn MaterialCustomizer
+  // into a proper Node module.
+  const mc = new MaterialCustomizer();
+  mc.template = fs.readFileSync(templatePath).toString();
+
+  let stream = gulp.src('');
+
+  mc.paletteIndices.forEach(primary => {
+    mc.paletteIndices.forEach(accent => {
+      if (primary === accent) {
+        return;
+      }
+
+      if (mc.forbiddenAccents.indexOf(accent) !== -1) {
+        return;
+      }
+
+      const primaryName = primary.toLowerCase().replace(' ', '_');
+      const accentName = accent.toLowerCase().replace(' ', '_');
+
+      stream = stream.pipe($.file(
+        `material.${primaryName}-${accentName}.min.css`,
+        mc.processTemplate(primary, accent)
+      ));
+    });
+  });
+
+  stream.pipe(gulp.dest('dist'));
+});
