├── css ├── partials │ ├── _colors.scss │ ├── _fonts.scss │ ├── _reset.scss │ └── _global.scss ├── bourbon │ ├── settings │ │ ├── _px-to-em.scss │ │ ├── _asset-pipeline.scss │ │ └── _prefixer.scss │ ├── css3 │ │ ├── _appearance.scss │ │ ├── _user-select.scss │ │ ├── _calc.scss │ │ ├── _hyphens.scss │ │ ├── _box-sizing.scss │ │ ├── _filter.scss │ │ ├── _placeholder.scss │ │ ├── _perspective.scss │ │ ├── _backface-visibility.scss │ │ ├── _image-rendering.scss │ │ ├── _font-feature-settings.scss │ │ ├── _hidpi-media-query.scss │ │ ├── _transform.scss │ │ ├── _border-radius.scss │ │ ├── _font-face.scss │ │ ├── _keyframes.scss │ │ ├── _columns.scss │ │ ├── _linear-gradient.scss │ │ ├── _background-image.scss │ │ ├── _radial-gradient.scss │ │ ├── _animation.scss │ │ ├── _background.scss │ │ ├── _border-image.scss │ │ ├── _transition.scss │ │ └── _flex-box.scss │ ├── functions │ │ ├── _golden-ratio.scss │ │ ├── _strip-units.scss │ │ ├── _tint-shade.scss │ │ ├── _assign.scss │ │ ├── _px-to-rem.scss │ │ ├── _px-to-em.scss │ │ ├── _grid-width.scss │ │ ├── _color-lightness.scss │ │ ├── _unpack.scss │ │ ├── _transition-property-name.scss │ │ ├── _flex-grid.scss │ │ └── _modular-scale.scss │ ├── addons │ │ ├── _ellipsis.scss │ │ ├── _hide-text.scss │ │ ├── _word-wrap.scss │ │ ├── _font-family.scss │ │ ├── _size.scss │ │ ├── _clearfix.scss │ │ ├── _position.scss │ │ ├── _retina-image.scss │ │ ├── _prefixer.scss │ │ ├── _timing-functions.scss │ │ ├── _triangle.scss │ │ ├── _directional-values.scss │ │ ├── _html5-input-types.scss │ │ └── _button.scss │ ├── helpers │ │ ├── _shape-size-stripper.scss │ │ ├── _is-num.scss │ │ ├── _gradient-positions-parser.scss │ │ ├── _radial-positions-parser.scss │ │ ├── _convert-units.scss │ │ ├── _linear-angle-parser.scss │ │ ├── _render-gradients.scss │ │ ├── _linear-side-corner-parser.scss │ │ ├── _linear-gradient-parser.scss │ │ ├── _str-to-num.scss │ │ ├── _radial-gradient-parser.scss │ │ ├── _radial-arg-parser.scss │ │ └── _linear-positions-parser.scss │ ├── _bourbon-deprecated-upcoming.scss │ └── _bourbon.scss ├── fonts │ └── icomoon │ │ ├── fonts │ │ ├── icomoon.eot │ │ ├── icomoon.ttf │ │ ├── icomoon.woff │ │ └── icomoon.svg │ │ ├── Read Me.txt │ │ ├── demo-files │ │ ├── demo.js │ │ └── demo.css │ │ ├── style.css │ │ └── demo.html ├── main.scss └── main.css ├── assets ├── blackmirror.jpg └── favicons │ ├── favicon.ico │ ├── favicon-16x16.png │ ├── favicon-32x32.png │ ├── favicon-96x96.png │ ├── mstile-144x144.png │ ├── mstile-150x150.png │ ├── mstile-310x150.png │ ├── mstile-310x310.png │ ├── mstile-70x70.png │ ├── apple-touch-icon.png │ ├── android-chrome-36x36.png │ ├── android-chrome-48x48.png │ ├── android-chrome-72x72.png │ ├── android-chrome-96x96.png │ ├── android-chrome-144x144.png │ ├── android-chrome-192x192.png │ ├── apple-touch-icon-114x114.png │ ├── apple-touch-icon-120x120.png │ ├── apple-touch-icon-144x144.png │ ├── apple-touch-icon-152x152.png │ ├── apple-touch-icon-180x180.png │ ├── apple-touch-icon-57x57.png │ ├── apple-touch-icon-60x60.png │ ├── apple-touch-icon-72x72.png │ ├── apple-touch-icon-76x76.png │ ├── apple-touch-icon-precomposed.png │ ├── browserconfig.xml │ └── manifest.json ├── .gitignore ├── js ├── app │ ├── templates │ │ └── ticker.html │ ├── app.js │ └── views │ │ ├── weather.js │ │ ├── clock.js │ │ ├── news.js │ │ ├── stocks.js │ │ └── subway.js ├── main.js └── lib │ ├── require.js │ ├── almond.js │ └── text.js ├── package.json ├── README.md ├── Gruntfile.js ├── server.js └── index.html /css/partials/_colors.scss: -------------------------------------------------------------------------------- 1 | $red: #f34146; 2 | $green: #81c14f; -------------------------------------------------------------------------------- /css/bourbon/settings/_px-to-em.scss: -------------------------------------------------------------------------------- 1 | $em-base: 16px !default; 2 | -------------------------------------------------------------------------------- /css/bourbon/settings/_asset-pipeline.scss: -------------------------------------------------------------------------------- 1 | $asset-pipeline: false !default; 2 | -------------------------------------------------------------------------------- /assets/blackmirror.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/plondon/BlackMirror/HEAD/assets/blackmirror.jpg -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | .DS_Store? 3 | 4 | *main.css.map* 5 | *style.css.map* 6 | node_modules 7 | npm-debug.log -------------------------------------------------------------------------------- /assets/favicons/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/plondon/BlackMirror/HEAD/assets/favicons/favicon.ico -------------------------------------------------------------------------------- /assets/favicons/favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/plondon/BlackMirror/HEAD/assets/favicons/favicon-16x16.png -------------------------------------------------------------------------------- /assets/favicons/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/plondon/BlackMirror/HEAD/assets/favicons/favicon-32x32.png -------------------------------------------------------------------------------- /assets/favicons/favicon-96x96.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/plondon/BlackMirror/HEAD/assets/favicons/favicon-96x96.png -------------------------------------------------------------------------------- /assets/favicons/mstile-144x144.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/plondon/BlackMirror/HEAD/assets/favicons/mstile-144x144.png -------------------------------------------------------------------------------- /assets/favicons/mstile-150x150.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/plondon/BlackMirror/HEAD/assets/favicons/mstile-150x150.png -------------------------------------------------------------------------------- /assets/favicons/mstile-310x150.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/plondon/BlackMirror/HEAD/assets/favicons/mstile-310x150.png -------------------------------------------------------------------------------- /assets/favicons/mstile-310x310.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/plondon/BlackMirror/HEAD/assets/favicons/mstile-310x310.png -------------------------------------------------------------------------------- /assets/favicons/mstile-70x70.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/plondon/BlackMirror/HEAD/assets/favicons/mstile-70x70.png -------------------------------------------------------------------------------- /assets/favicons/apple-touch-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/plondon/BlackMirror/HEAD/assets/favicons/apple-touch-icon.png -------------------------------------------------------------------------------- /css/fonts/icomoon/fonts/icomoon.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/plondon/BlackMirror/HEAD/css/fonts/icomoon/fonts/icomoon.eot -------------------------------------------------------------------------------- /css/fonts/icomoon/fonts/icomoon.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/plondon/BlackMirror/HEAD/css/fonts/icomoon/fonts/icomoon.ttf -------------------------------------------------------------------------------- /css/fonts/icomoon/fonts/icomoon.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/plondon/BlackMirror/HEAD/css/fonts/icomoon/fonts/icomoon.woff -------------------------------------------------------------------------------- /assets/favicons/android-chrome-36x36.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/plondon/BlackMirror/HEAD/assets/favicons/android-chrome-36x36.png -------------------------------------------------------------------------------- /assets/favicons/android-chrome-48x48.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/plondon/BlackMirror/HEAD/assets/favicons/android-chrome-48x48.png -------------------------------------------------------------------------------- /assets/favicons/android-chrome-72x72.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/plondon/BlackMirror/HEAD/assets/favicons/android-chrome-72x72.png -------------------------------------------------------------------------------- /assets/favicons/android-chrome-96x96.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/plondon/BlackMirror/HEAD/assets/favicons/android-chrome-96x96.png -------------------------------------------------------------------------------- /assets/favicons/android-chrome-144x144.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/plondon/BlackMirror/HEAD/assets/favicons/android-chrome-144x144.png -------------------------------------------------------------------------------- /assets/favicons/android-chrome-192x192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/plondon/BlackMirror/HEAD/assets/favicons/android-chrome-192x192.png -------------------------------------------------------------------------------- /assets/favicons/apple-touch-icon-114x114.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/plondon/BlackMirror/HEAD/assets/favicons/apple-touch-icon-114x114.png -------------------------------------------------------------------------------- /assets/favicons/apple-touch-icon-120x120.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/plondon/BlackMirror/HEAD/assets/favicons/apple-touch-icon-120x120.png -------------------------------------------------------------------------------- /assets/favicons/apple-touch-icon-144x144.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/plondon/BlackMirror/HEAD/assets/favicons/apple-touch-icon-144x144.png -------------------------------------------------------------------------------- /assets/favicons/apple-touch-icon-152x152.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/plondon/BlackMirror/HEAD/assets/favicons/apple-touch-icon-152x152.png -------------------------------------------------------------------------------- /assets/favicons/apple-touch-icon-180x180.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/plondon/BlackMirror/HEAD/assets/favicons/apple-touch-icon-180x180.png -------------------------------------------------------------------------------- /assets/favicons/apple-touch-icon-57x57.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/plondon/BlackMirror/HEAD/assets/favicons/apple-touch-icon-57x57.png -------------------------------------------------------------------------------- /assets/favicons/apple-touch-icon-60x60.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/plondon/BlackMirror/HEAD/assets/favicons/apple-touch-icon-60x60.png -------------------------------------------------------------------------------- /assets/favicons/apple-touch-icon-72x72.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/plondon/BlackMirror/HEAD/assets/favicons/apple-touch-icon-72x72.png -------------------------------------------------------------------------------- /assets/favicons/apple-touch-icon-76x76.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/plondon/BlackMirror/HEAD/assets/favicons/apple-touch-icon-76x76.png -------------------------------------------------------------------------------- /css/bourbon/css3/_appearance.scss: -------------------------------------------------------------------------------- 1 | @mixin appearance ($value) { 2 | @include prefixer(appearance, $value, webkit moz ms o spec); 3 | } 4 | -------------------------------------------------------------------------------- /css/bourbon/css3/_user-select.scss: -------------------------------------------------------------------------------- 1 | @mixin user-select($arg: none) { 2 | @include prefixer(user-select, $arg, webkit moz ms spec); 3 | } 4 | -------------------------------------------------------------------------------- /assets/favicons/apple-touch-icon-precomposed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/plondon/BlackMirror/HEAD/assets/favicons/apple-touch-icon-precomposed.png -------------------------------------------------------------------------------- /css/bourbon/functions/_golden-ratio.scss: -------------------------------------------------------------------------------- 1 | @function golden-ratio($value, $increment) { 2 | @return modular-scale($value, $increment, $golden) 3 | } 4 | -------------------------------------------------------------------------------- /css/bourbon/css3/_calc.scss: -------------------------------------------------------------------------------- 1 | @mixin calc($property, $value) { 2 | #{$property}: -webkit-calc(#{$value}); 3 | #{$property}: calc(#{$value}); 4 | } 5 | -------------------------------------------------------------------------------- /css/bourbon/css3/_hyphens.scss: -------------------------------------------------------------------------------- 1 | @mixin hyphens($hyphenation: none) { 2 | // none | manual | auto 3 | @include prefixer(hyphens, $hyphenation, webkit moz ms spec); 4 | } -------------------------------------------------------------------------------- /css/bourbon/css3/_box-sizing.scss: -------------------------------------------------------------------------------- 1 | @mixin box-sizing ($box) { 2 | // content-box | border-box | inherit 3 | @include prefixer(box-sizing, $box, webkit moz spec); 4 | } 5 | -------------------------------------------------------------------------------- /css/bourbon/functions/_strip-units.scss: -------------------------------------------------------------------------------- 1 | // Srtips the units from a value. e.g. 12px -> 12 2 | 3 | @function strip-units($val) { 4 | @return ($val / ($val * 0 + 1)); 5 | } 6 | -------------------------------------------------------------------------------- /css/main.scss: -------------------------------------------------------------------------------- 1 | @import "bourbon/bourbon"; 2 | @import "partials/colors"; 3 | 4 | @import "partials/reset"; 5 | 6 | @import "partials/fonts"; 7 | 8 | @import "partials/global"; -------------------------------------------------------------------------------- /css/bourbon/css3/_filter.scss: -------------------------------------------------------------------------------- 1 | @mixin filter($function: none) { 2 | // [ 3 | @include prefixer(perspective, $depth, webkit moz spec); 4 | } 5 | 6 | @mixin perspective-origin($value: 50% 50%) { 7 | @include prefixer(perspective-origin, $value, webkit moz spec); 8 | } 9 | -------------------------------------------------------------------------------- /css/bourbon/functions/_tint-shade.scss: -------------------------------------------------------------------------------- 1 | // Add percentage of white to a color 2 | @function tint($color, $percent){ 3 | @return mix(white, $color, $percent); 4 | } 5 | 6 | // Add percentage of black to a color 7 | @function shade($color, $percent){ 8 | @return mix(black, $color, $percent); 9 | } 10 | -------------------------------------------------------------------------------- /css/bourbon/functions/_assign.scss: -------------------------------------------------------------------------------- 1 | @function assign-inputs($inputs, $pseudo: null) { 2 | $list : (); 3 | 4 | @each $input in $inputs { 5 | $input: unquote($input); 6 | $input: if($pseudo, $input + ":" + $pseudo, $input); 7 | $list: append($list, $input, comma); 8 | } 9 | 10 | @return $list; 11 | } -------------------------------------------------------------------------------- /css/bourbon/settings/_prefixer.scss: -------------------------------------------------------------------------------- 1 | // Variable settings for /addons/prefixer.scss 2 | $prefix-for-webkit: true !default; 3 | $prefix-for-mozilla: true !default; 4 | $prefix-for-microsoft: true !default; 5 | $prefix-for-opera: true !default; 6 | $prefix-for-spec: true !default; // required for keyframe mixin 7 | -------------------------------------------------------------------------------- /css/bourbon/addons/_font-family.scss: -------------------------------------------------------------------------------- 1 | $georgia: Georgia, Cambria, "Times New Roman", Times, serif; 2 | $helvetica: "Helvetica Neue", Helvetica, Roboto, Arial, sans-serif; 3 | $lucida-grande: "Lucida Grande", Tahoma, Verdana, Arial, sans-serif; 4 | $monospace: "Bitstream Vera Sans Mono", Consolas, Courier, monospace; 5 | $verdana: Verdana, Geneva, sans-serif; 6 | -------------------------------------------------------------------------------- /css/bourbon/css3/_backface-visibility.scss: -------------------------------------------------------------------------------- 1 | //************************************************************************// 2 | // Backface-visibility mixin 3 | //************************************************************************// 4 | @mixin backface-visibility($visibility) { 5 | @include prefixer(backface-visibility, $visibility, webkit spec); 6 | } 7 | -------------------------------------------------------------------------------- /css/bourbon/helpers/_shape-size-stripper.scss: -------------------------------------------------------------------------------- 1 | @function _shape-size-stripper($shape-size) { 2 | $shape-size-spec: null; 3 | @each $value in $shape-size { 4 | @if ($value == "cover") or ($value == "contain") { 5 | $value: null; 6 | } 7 | $shape-size-spec: "#{$shape-size-spec} #{$value}"; 8 | } 9 | @return $shape-size-spec; 10 | } 11 | -------------------------------------------------------------------------------- /css/bourbon/helpers/_is-num.scss: -------------------------------------------------------------------------------- 1 | //************************************************************************// 2 | // Helper for linear-gradient-parser 3 | //************************************************************************// 4 | @function _is-num($char) { 5 | $values: '0' '1' '2' '3' '4' '5' '6' '7' '8' '9' 0 1 2 3 4 5 6 7 8 9; 6 | $index: index($values, $char); 7 | @return if($index, true, false); 8 | } 9 | -------------------------------------------------------------------------------- /js/app/templates/ticker.html: -------------------------------------------------------------------------------- 1 | <% var stocks = data.d %> 2 | 3 |
4 |
    5 | <% for (var i=0; i 6 | <% var stock = stocks[i] %> 7 | <% var isUp = stock.c >= 0 %> 8 |
  • " > 9 | <%= stock.t %> 10 | 11 | <%= stock.c %> 12 |
  • 13 | <% } %> 14 |
15 |
-------------------------------------------------------------------------------- /css/bourbon/addons/_size.scss: -------------------------------------------------------------------------------- 1 | @mixin size($size) { 2 | $height: nth($size, 1); 3 | $width: $height; 4 | 5 | @if length($size) > 1 { 6 | $height: nth($size, 2); 7 | } 8 | 9 | @if $height == auto or (type-of($height) == number and not unitless($height)) { 10 | height: $height; 11 | } 12 | 13 | @if $width == auto or (type-of($width) == number and not unitless($width)) { 14 | width: $width; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /css/bourbon/css3/_image-rendering.scss: -------------------------------------------------------------------------------- 1 | @mixin image-rendering ($mode:auto) { 2 | 3 | @if ($mode == crisp-edges) { 4 | -ms-interpolation-mode: nearest-neighbor; // IE8+ 5 | image-rendering: -moz-crisp-edges; 6 | image-rendering: -o-crisp-edges; 7 | image-rendering: -webkit-optimize-contrast; 8 | image-rendering: crisp-edges; 9 | } 10 | 11 | @else { 12 | image-rendering: $mode; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /css/bourbon/functions/_px-to-rem.scss: -------------------------------------------------------------------------------- 1 | // Convert pixels to rems 2 | // eg. for a relational value of 12px write rem(12) 3 | // Assumes $em-base is the font-size of 4 | 5 | @function rem($pxval) { 6 | @if not unitless($pxval) { 7 | $pxval: strip-units($pxval); 8 | } 9 | 10 | $base: $em-base; 11 | @if not unitless($base) { 12 | $base: strip-units($base); 13 | } 14 | @return ($pxval / $base) * 1rem; 15 | } 16 | -------------------------------------------------------------------------------- /css/bourbon/functions/_px-to-em.scss: -------------------------------------------------------------------------------- 1 | // Convert pixels to ems 2 | // eg. for a relational value of 12px write em(12) when the parent is 16px 3 | // if the parent is another value say 24px write em(12, 24) 4 | 5 | @function em($pxval, $base: $em-base) { 6 | @if not unitless($pxval) { 7 | $pxval: strip-units($pxval); 8 | } 9 | @if not unitless($base) { 10 | $base: strip-units($base); 11 | } 12 | @return ($pxval / $base) * 1em; 13 | } 14 | -------------------------------------------------------------------------------- /css/bourbon/_bourbon-deprecated-upcoming.scss: -------------------------------------------------------------------------------- 1 | //************************************************************************// 2 | // These mixins/functions are deprecated 3 | // They will be removed in the next MAJOR version release 4 | //************************************************************************// 5 | @mixin inline-block { 6 | display: inline-block; 7 | @warn "inline-block mixin is deprecated and will be removed in the next major version release"; 8 | } 9 | -------------------------------------------------------------------------------- /assets/favicons/browserconfig.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | #da532c 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /css/bourbon/functions/_grid-width.scss: -------------------------------------------------------------------------------- 1 | @function grid-width($n) { 2 | @return $n * $gw-column + ($n - 1) * $gw-gutter; 3 | } 4 | 5 | // The $gw-column and $gw-gutter variables must be defined in your base stylesheet to properly use the grid-width function. 6 | // 7 | // $gw-column: 100px; // Column Width 8 | // $gw-gutter: 40px; // Gutter Width 9 | // 10 | // div { 11 | // width: grid-width(4); // returns 520px; 12 | // margin-left: $gw-gutter; // returns 40px; 13 | // } 14 | -------------------------------------------------------------------------------- /css/bourbon/css3/_font-feature-settings.scss: -------------------------------------------------------------------------------- 1 | // Font feature settings mixin and property default. 2 | // Examples: @include font-feature-settings("liga"); 3 | // @include font-feature-settings("lnum" false); 4 | // @include font-feature-settings("pnum" 1, "kern" 0); 5 | // @include font-feature-settings("ss01", "ss02"); 6 | 7 | @mixin font-feature-settings($settings...) { 8 | @if length($settings) == 0 { $settings: none; } 9 | @include prefixer(font-feature-settings, $settings, webkit moz ms spec); 10 | } -------------------------------------------------------------------------------- /css/bourbon/css3/_hidpi-media-query.scss: -------------------------------------------------------------------------------- 1 | // HiDPI mixin. Default value set to 1.3 to target Google Nexus 7 (http://bjango.com/articles/min-device-pixel-ratio/) 2 | @mixin hidpi($ratio: 1.3) { 3 | @media only screen and (-webkit-min-device-pixel-ratio: $ratio), 4 | only screen and (min--moz-device-pixel-ratio: $ratio), 5 | only screen and (-o-min-device-pixel-ratio: #{$ratio}/1), 6 | only screen and (min-resolution: #{round($ratio*96)}dpi), 7 | only screen and (min-resolution: #{$ratio}dppx) { 8 | @content; 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "BlackMirror", 3 | "version": "0.1.0", 4 | "devDependencies": { 5 | "grunt": "^0.4.5", 6 | "grunt-autoprefixer": "^3.0.3", 7 | "grunt-contrib-requirejs": "^0.4.4", 8 | "grunt-contrib-watch": "^0.6.1", 9 | "grunt-sass": "^1.0.0", 10 | "grunt-shell-spawn": "^0.3.2" 11 | }, 12 | "main": "server.js", 13 | "scripts": { 14 | "start": "node server.js" 15 | }, 16 | "dependencies": { 17 | "ejs": "~1.0.0", 18 | "express": "~4.9.8", 19 | "request": "^2.63.0" 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /css/bourbon/functions/_color-lightness.scss: -------------------------------------------------------------------------------- 1 | // Programatically determines whether a color is light or dark 2 | // Returns a boolean 3 | // More details here http://robots.thoughtbot.com/closer-look-color-lightness 4 | 5 | @function is-light($hex-color) { 6 | $-local-red: red(rgba($hex-color, 1.0)); 7 | $-local-green: green(rgba($hex-color, 1.0)); 8 | $-local-blue: blue(rgba($hex-color, 1.0)); 9 | 10 | $-local-lightness: ($-local-red * 0.2126 + $-local-green * 0.7152 + $-local-blue * 0.0722) / 255; 11 | 12 | @return $-local-lightness > .6; 13 | } 14 | -------------------------------------------------------------------------------- /css/bourbon/helpers/_gradient-positions-parser.scss: -------------------------------------------------------------------------------- 1 | @function _gradient-positions-parser($gradient-type, $gradient-positions) { 2 | @if $gradient-positions 3 | and ($gradient-type == linear) 4 | and (type-of($gradient-positions) != color) { 5 | $gradient-positions: _linear-positions-parser($gradient-positions); 6 | } 7 | @else if $gradient-positions 8 | and ($gradient-type == radial) 9 | and (type-of($gradient-positions) != color) { 10 | $gradient-positions: _radial-positions-parser($gradient-positions); 11 | } 12 | @return $gradient-positions; 13 | } 14 | -------------------------------------------------------------------------------- /css/bourbon/css3/_transform.scss: -------------------------------------------------------------------------------- 1 | @mixin transform($property: none) { 2 | // none | 3 | @include prefixer(transform, $property, webkit moz ms o spec); 4 | } 5 | 6 | @mixin transform-origin($axes: 50%) { 7 | // x-axis - left | center | right | length | % 8 | // y-axis - top | center | bottom | length | % 9 | // z-axis - length 10 | @include prefixer(transform-origin, $axes, webkit moz ms o spec); 11 | } 12 | 13 | @mixin transform-style ($style: flat) { 14 | @include prefixer(transform-style, $style, webkit moz ms o spec); 15 | } 16 | -------------------------------------------------------------------------------- /css/bourbon/functions/_unpack.scss: -------------------------------------------------------------------------------- 1 | // Convert shorthand to the 4-value syntax 2 | 3 | @function unpack($shorthand) { 4 | @if length($shorthand) == 1 { 5 | @return nth($shorthand, 1) nth($shorthand, 1) nth($shorthand, 1) nth($shorthand, 1); 6 | } 7 | @else if length($shorthand) == 2 { 8 | @return nth($shorthand, 1) nth($shorthand, 2) nth($shorthand, 1) nth($shorthand, 2); 9 | } 10 | @else if length($shorthand) == 3 { 11 | @return nth($shorthand, 1) nth($shorthand, 2) nth($shorthand, 3) nth($shorthand, 2); 12 | } 13 | @else { 14 | @return $shorthand; 15 | } 16 | } 17 | 18 | -------------------------------------------------------------------------------- /css/bourbon/helpers/_radial-positions-parser.scss: -------------------------------------------------------------------------------- 1 | @function _radial-positions-parser($gradient-pos) { 2 | $shape-size: nth($gradient-pos, 1); 3 | $pos: nth($gradient-pos, 2); 4 | $shape-size-spec: _shape-size-stripper($shape-size); 5 | 6 | $pre-spec: unquote(if($pos, "#{$pos}, ", null)) 7 | unquote(if($shape-size, "#{$shape-size},", null)); 8 | $pos-spec: if($pos, "at #{$pos}", null); 9 | 10 | $spec: "#{$shape-size-spec} #{$pos-spec}"; 11 | 12 | // Add comma 13 | @if ($spec != ' ') { 14 | $spec: "#{$spec}," 15 | } 16 | 17 | @return $pre-spec $spec; 18 | } 19 | -------------------------------------------------------------------------------- /css/bourbon/addons/_clearfix.scss: -------------------------------------------------------------------------------- 1 | // Modern micro clearfix provides an easy way to contain floats without adding additional markup. 2 | // 3 | // Example usage: 4 | // 5 | // // Contain all floats within .wrapper 6 | // .wrapper { 7 | // @include clearfix; 8 | // .content, 9 | // .sidebar { 10 | // float : left; 11 | // } 12 | // } 13 | 14 | @mixin clearfix { 15 | &:after { 16 | content:""; 17 | display:table; 18 | clear:both; 19 | } 20 | } 21 | 22 | // Acknowledgements 23 | // Beat *that* clearfix: [Thierry Koblentz](http://www.css-101.org/articles/clearfix/latest-new-clearfix-so-far.php) 24 | -------------------------------------------------------------------------------- /js/app/app.js: -------------------------------------------------------------------------------- 1 | define([ 2 | 'jquery', 3 | 'views/news', 4 | 'views/clock', 5 | 'views/subway', 6 | 'views/stocks', 7 | 'views/weather', 8 | ], function($, NewsView, ClockView, SubwayView, StocksView, WeatherView) { 9 | 10 | "use strict"; 11 | 12 | $(document).ready(function() { 13 | 14 | // new NewsView({ el: $('.news') }); 15 | new ClockView({ el: $('.clock') }); 16 | new SubwayView({ el: $('.subway') }); 17 | new WeatherView({ el: $('.weather') }); 18 | new StocksView({ el: $('.stocks') }); 19 | 20 | $(document).ajaxStop(function() { 21 | 22 | $('body').addClass('active'); 23 | 24 | }); 25 | 26 | }); 27 | 28 | }); 29 | -------------------------------------------------------------------------------- /js/main.js: -------------------------------------------------------------------------------- 1 | require.config({ 2 | baseUrl: "/js/app", 3 | paths: { 4 | "jquery": "../lib/jquery.min", 5 | "underscore": "../lib/underscore", 6 | "backbone": "../lib/backbone", 7 | "text": "../lib/text" 8 | }, 9 | shim: { 10 | jquery: { 11 | exports: "$" 12 | }, 13 | underscore: { 14 | deps: ["jquery"], 15 | exports: "_" 16 | }, 17 | backbone: { 18 | deps: ["jquery", "underscore"], 19 | exports: "Backbone" 20 | } 21 | }, 22 | urlArgs: "bust=" + (new Date()).getTime(), 23 | waitSeconds: 0 24 | }); 25 | 26 | require([ 27 | "jquery", 28 | "underscore", 29 | "backbone", 30 | "text" 31 | ], function($, _, Backbone) { 32 | 33 | require(['app'], function() {}); 34 | 35 | }); -------------------------------------------------------------------------------- /css/fonts/icomoon/Read Me.txt: -------------------------------------------------------------------------------- 1 | Open *demo.html* to see a list of all the glyphs in your font along with their codes/ligatures. 2 | 3 | To use the generated font in desktop programs, you can install the TTF font. In order to copy the character associated with each icon, refer to the text box at the bottom right corner of each glyph in demo.html. The character inside this text box may be invisible; but it can still be copied. See this guide for more info: https://icomoon.io/#docs/local-fonts 4 | 5 | You won't need any of the files located under the *demo-files* directory when including the generated font in your own projects. 6 | 7 | You can import *selection.json* back to the IcoMoon app using the *Import Icons* button (or via Main Menu → Manage Projects) to retrieve your icon selection. 8 | -------------------------------------------------------------------------------- /css/bourbon/helpers/_convert-units.scss: -------------------------------------------------------------------------------- 1 | //************************************************************************// 2 | // Helper function for str-to-num fn. 3 | // Source: http://sassmeister.com/gist/9647408 4 | //************************************************************************// 5 | @function _convert-units($number, $unit) { 6 | $strings: 'px' 'cm' 'mm' '%' 'ch' 'pica' 'in' 'em' 'rem' 'pt' 'pc' 'ex' 'vw' 'vh' 'vmin' 'vmax', 'deg', 'rad', 'grad', 'turn'; 7 | $units: 1px 1cm 1mm 1% 1ch 1pica 1in 1em 1rem 1pt 1pc 1ex 1vw 1vh 1vmin 1vmax, 1deg, 1rad, 1grad, 1turn; 8 | $index: index($strings, $unit); 9 | 10 | @if not $index { 11 | @warn "Unknown unit `#{$unit}`."; 12 | @return false; 13 | } 14 | @return $number * nth($units, $index); 15 | } 16 | -------------------------------------------------------------------------------- /css/bourbon/functions/_transition-property-name.scss: -------------------------------------------------------------------------------- 1 | // Return vendor-prefixed property names if appropriate 2 | // Example: transition-property-names((transform, color, background), moz) -> -moz-transform, color, background 3 | //************************************************************************// 4 | @function transition-property-names($props, $vendor: false) { 5 | $new-props: (); 6 | 7 | @each $prop in $props { 8 | $new-props: append($new-props, transition-property-name($prop, $vendor), comma); 9 | } 10 | 11 | @return $new-props; 12 | } 13 | 14 | @function transition-property-name($prop, $vendor: false) { 15 | // put other properties that need to be prefixed here aswell 16 | @if $vendor and $prop == transform { 17 | @return unquote('-'+$vendor+'-'+$prop); 18 | } 19 | @else { 20 | @return $prop; 21 | } 22 | } -------------------------------------------------------------------------------- /js/app/views/weather.js: -------------------------------------------------------------------------------- 1 | define([ 2 | 'jquery', 3 | 'underscore', 4 | 'backbone' 5 | ], function($, _, Backbone) { 6 | 7 | "use strict"; 8 | 9 | var WeatherView = Backbone.View.extend({ 10 | initialize: function() { 11 | var self = this; 12 | var req = $.get('/weather'); 13 | 14 | req.done(function(d) { self.render(d); }); 15 | 16 | /* Update every 5 minutes */ 17 | setInterval(function() { 18 | var req = $.get('/weather'); 19 | req.done(function(d) { self.render(d); }); 20 | }, 1000*60*5); 21 | }, 22 | render: function(d) { 23 | d = JSON.parse(d.body); 24 | var icon = d.currently.icon; 25 | var temp = this.formatTemp(d.currently.temperature); 26 | 27 | this.$el.html(temp + '° F').addClass(icon); 28 | }, 29 | formatTemp: function(i) { 30 | return i.toString().split('.')[0]; 31 | } 32 | }); 33 | 34 | return WeatherView; 35 | 36 | }); -------------------------------------------------------------------------------- /css/bourbon/addons/_position.scss: -------------------------------------------------------------------------------- 1 | @mixin position ($position: relative, $coordinates: null null null null) { 2 | 3 | @if type-of($position) == list { 4 | $coordinates: $position; 5 | $position: relative; 6 | } 7 | 8 | $coordinates: unpack($coordinates); 9 | 10 | $top: nth($coordinates, 1); 11 | $right: nth($coordinates, 2); 12 | $bottom: nth($coordinates, 3); 13 | $left: nth($coordinates, 4); 14 | 15 | position: $position; 16 | 17 | @if ($top and $top == auto) or (type-of($top) == number) { 18 | top: $top; 19 | } 20 | 21 | @if ($right and $right == auto) or (type-of($right) == number) { 22 | right: $right; 23 | } 24 | 25 | @if ($bottom and $bottom == auto) or (type-of($bottom) == number) { 26 | bottom: $bottom; 27 | } 28 | 29 | @if ($left and $left == auto) or (type-of($left) == number) { 30 | left: $left; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /css/bourbon/helpers/_linear-angle-parser.scss: -------------------------------------------------------------------------------- 1 | // Private function for linear-gradient-parser 2 | @function _linear-angle-parser($image, $first-val, $prefix, $suffix) { 3 | $offset: null; 4 | $unit-short: str-slice($first-val, str-length($first-val) - 2, str-length($first-val)); 5 | $unit-long: str-slice($first-val, str-length($first-val) - 3, str-length($first-val)); 6 | 7 | @if ($unit-long == "grad") or 8 | ($unit-long == "turn") { 9 | $offset: if($unit-long == "grad", -100grad * 3, -0.75turn); 10 | } 11 | 12 | @else if ($unit-short == "deg") or 13 | ($unit-short == "rad") { 14 | $offset: if($unit-short == "deg", -90 * 3, 1.6rad); 15 | } 16 | 17 | @if $offset { 18 | $num: _str-to-num($first-val); 19 | 20 | @return ( 21 | webkit-image: -webkit- + $prefix + ($offset - $num) + $suffix, 22 | spec-image: $image 23 | ); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /assets/favicons/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "BlackMirror", 3 | "icons": [ 4 | { 5 | "src": "\/android-chrome-36x36.png", 6 | "sizes": "36x36", 7 | "type": "image\/png", 8 | "density": "0.75" 9 | }, 10 | { 11 | "src": "\/android-chrome-48x48.png", 12 | "sizes": "48x48", 13 | "type": "image\/png", 14 | "density": "1.0" 15 | }, 16 | { 17 | "src": "\/android-chrome-72x72.png", 18 | "sizes": "72x72", 19 | "type": "image\/png", 20 | "density": "1.5" 21 | }, 22 | { 23 | "src": "\/android-chrome-96x96.png", 24 | "sizes": "96x96", 25 | "type": "image\/png", 26 | "density": "2.0" 27 | }, 28 | { 29 | "src": "\/android-chrome-144x144.png", 30 | "sizes": "144x144", 31 | "type": "image\/png", 32 | "density": "3.0" 33 | }, 34 | { 35 | "src": "\/android-chrome-192x192.png", 36 | "sizes": "192x192", 37 | "type": "image\/png", 38 | "density": "4.0" 39 | } 40 | ] 41 | } 42 | -------------------------------------------------------------------------------- /css/bourbon/css3/_border-radius.scss: -------------------------------------------------------------------------------- 1 | //************************************************************************// 2 | // Shorthand Border-radius mixins 3 | //************************************************************************// 4 | @mixin border-top-radius($radii) { 5 | @include prefixer(border-top-left-radius, $radii, spec); 6 | @include prefixer(border-top-right-radius, $radii, spec); 7 | } 8 | 9 | @mixin border-bottom-radius($radii) { 10 | @include prefixer(border-bottom-left-radius, $radii, spec); 11 | @include prefixer(border-bottom-right-radius, $radii, spec); 12 | } 13 | 14 | @mixin border-left-radius($radii) { 15 | @include prefixer(border-top-left-radius, $radii, spec); 16 | @include prefixer(border-bottom-left-radius, $radii, spec); 17 | } 18 | 19 | @mixin border-right-radius($radii) { 20 | @include prefixer(border-top-right-radius, $radii, spec); 21 | @include prefixer(border-bottom-right-radius, $radii, spec); 22 | } 23 | -------------------------------------------------------------------------------- /css/bourbon/helpers/_render-gradients.scss: -------------------------------------------------------------------------------- 1 | // User for linear and radial gradients within background-image or border-image properties 2 | 3 | @function _render-gradients($gradient-positions, $gradients, $gradient-type, $vendor: false) { 4 | $pre-spec: null; 5 | $spec: null; 6 | $vendor-gradients: null; 7 | @if $gradient-type == linear { 8 | @if $gradient-positions { 9 | $pre-spec: nth($gradient-positions, 1); 10 | $spec: nth($gradient-positions, 2); 11 | } 12 | } 13 | @else if $gradient-type == radial { 14 | $pre-spec: nth($gradient-positions, 1); 15 | $spec: nth($gradient-positions, 2); 16 | } 17 | 18 | @if $vendor { 19 | $vendor-gradients: -#{$vendor}-#{$gradient-type}-gradient(#{$pre-spec} $gradients); 20 | } 21 | @else if $vendor == false { 22 | $vendor-gradients: "#{$gradient-type}-gradient(#{$spec} #{$gradients})"; 23 | $vendor-gradients: unquote($vendor-gradients); 24 | } 25 | @return $vendor-gradients; 26 | } 27 | -------------------------------------------------------------------------------- /css/bourbon/addons/_retina-image.scss: -------------------------------------------------------------------------------- 1 | @mixin retina-image($filename, $background-size, $extension: png, $retina-filename: null, $retina-suffix: _2x, $asset-pipeline: $asset-pipeline) { 2 | @if $asset-pipeline { 3 | background-image: image-url("#{$filename}.#{$extension}"); 4 | } 5 | @else { 6 | background-image: url("#{$filename}.#{$extension}"); 7 | } 8 | 9 | @include hidpi { 10 | @if $asset-pipeline { 11 | @if $retina-filename { 12 | background-image: image-url("#{$retina-filename}.#{$extension}"); 13 | } 14 | @else { 15 | background-image: image-url("#{$filename}#{$retina-suffix}.#{$extension}"); 16 | } 17 | } 18 | 19 | @else { 20 | @if $retina-filename { 21 | background-image: url("#{$retina-filename}.#{$extension}"); 22 | } 23 | @else { 24 | background-image: url("#{$filename}#{$retina-suffix}.#{$extension}"); 25 | } 26 | } 27 | 28 | background-size: $background-size; 29 | 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /css/bourbon/helpers/_linear-side-corner-parser.scss: -------------------------------------------------------------------------------- 1 | // Private function for linear-gradient-parser 2 | @function _linear-side-corner-parser($image, $first-val, $prefix, $suffix, $has-multiple-vals) { 3 | $val-1: str-slice($first-val, 0, $has-multiple-vals - 1 ); 4 | $val-2: str-slice($first-val, $has-multiple-vals + 1, str-length($first-val)); 5 | $val-3: null; 6 | $has-val-3: str-index($val-2, " "); 7 | 8 | @if $has-val-3 { 9 | $val-3: str-slice($val-2, $has-val-3 + 1, str-length($val-2)); 10 | $val-2: str-slice($val-2, 0, $has-val-3 - 1); 11 | } 12 | 13 | $pos: _position-flipper($val-1) _position-flipper($val-2) _position-flipper($val-3); 14 | $pos: unquote($pos + ""); 15 | 16 | // Use old spec for webkit 17 | @if $val-1 == "to" { 18 | @return ( 19 | webkit-image: -webkit- + $prefix + $pos + $suffix, 20 | spec-image: $image 21 | ); 22 | } 23 | 24 | // Bring the code up to spec 25 | @else { 26 | @return ( 27 | webkit-image: -webkit- + $image, 28 | spec-image: $prefix + "to " + $pos + $suffix 29 | ); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /js/app/views/clock.js: -------------------------------------------------------------------------------- 1 | define([ 2 | 'jquery', 3 | 'underscore', 4 | 'backbone' 5 | ], function($, _, Backbone) { 6 | 7 | "use strict"; 8 | 9 | var ClockView = Backbone.View.extend({ 10 | initialize: function() { 11 | this.today(); 12 | this.ticktock(); 13 | setInterval( this.ticktock.bind(this), 1000 ); 14 | }, 15 | today: function() { 16 | var time = new Date(); 17 | time = time.toDateString(); 18 | 19 | this.$el.find('.date').html(time); 20 | }, 21 | ticktock: function() { 22 | var time = new Date(); 23 | var hour = time.getHours() % 12; 24 | hour = time.getHours() === 12 ? 12 : hour; 25 | var ampm = time.getHours() < 12 ? 'AM' : 'PM'; 26 | var minute = this.addZero(time.getMinutes()); 27 | var seconds = this.addZero(time.getSeconds()); 28 | 29 | var timeString = hour + ':' + minute + ':' + seconds; 30 | var $ampm = $('').html(ampm); 31 | 32 | this.$el.find('.time').html(timeString) 33 | .append($ampm); 34 | }, 35 | addZero: function(i) { 36 | if (i < 10) { 37 | i = "0" + i; 38 | } 39 | return i; 40 | } 41 | }); 42 | 43 | return ClockView; 44 | 45 | }); -------------------------------------------------------------------------------- /css/fonts/icomoon/demo-files/demo.js: -------------------------------------------------------------------------------- 1 | if (!('boxShadow' in document.body.style)) { 2 | document.body.setAttribute('class', 'noBoxShadow'); 3 | } 4 | 5 | document.body.addEventListener("click", function(e) { 6 | var target = e.target; 7 | if (target.tagName === "INPUT" && 8 | target.getAttribute('class').indexOf('liga') === -1) { 9 | target.select(); 10 | } 11 | }); 12 | 13 | (function() { 14 | var fontSize = document.getElementById('fontSize'), 15 | testDrive = document.getElementById('testDrive'), 16 | testText = document.getElementById('testText'); 17 | function updateTest() { 18 | testDrive.innerHTML = testText.value || String.fromCharCode(160); 19 | if (window.icomoonLiga) { 20 | window.icomoonLiga(testDrive); 21 | } 22 | } 23 | function updateSize() { 24 | testDrive.style.fontSize = fontSize.value + 'px'; 25 | } 26 | fontSize.addEventListener('change', updateSize, false); 27 | testText.addEventListener('input', updateTest, false); 28 | testText.addEventListener('change', updateTest, false); 29 | updateSize(); 30 | }()); 31 | -------------------------------------------------------------------------------- /css/bourbon/css3/_font-face.scss: -------------------------------------------------------------------------------- 1 | // Order of the includes matters, and it is: normal, bold, italic, bold+italic. 2 | 3 | @mixin font-face($font-family, $file-path, $weight: normal, $style: normal, $asset-pipeline: $asset-pipeline) { 4 | @font-face { 5 | font-family: $font-family; 6 | font-weight: $weight; 7 | font-style: $style; 8 | 9 | @if $asset-pipeline == true { 10 | src: font-url('#{$file-path}.eot'); 11 | src: font-url('#{$file-path}.eot?#iefix') format('embedded-opentype'), 12 | font-url('#{$file-path}.woff') format('woff'), 13 | font-url('#{$file-path}.ttf') format('truetype'), 14 | font-url('#{$file-path}.svg##{$font-family}') format('svg'); 15 | } @else { 16 | src: url('#{$file-path}.eot'); 17 | src: url('#{$file-path}.eot?#iefix') format('embedded-opentype'), 18 | url('#{$file-path}.woff') format('woff'), 19 | url('#{$file-path}.ttf') format('truetype'), 20 | url('#{$file-path}.svg##{$font-family}') format('svg'); 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /css/partials/_fonts.scss: -------------------------------------------------------------------------------- 1 | @font-face { 2 | font-family: 'icomoon'; 3 | src:url('./fonts/icomoon/fonts/icomoon.eot?9d6p5j'); 4 | src:url('./fonts/icomoon/fonts/icomoon.eot?#iefix9d6p5j') format('embedded-opentype'), 5 | url('./fonts/icomoon/fonts/icomoon.ttf?9d6p5j') format('truetype'), 6 | url('./fonts/icomoon/fonts/icomoon.woff?9d6p5j') format('woff'), 7 | url('./fonts/icomoon/fonts/icomoon.svg?9d6p5j#icomoon') format('svg'); 8 | font-weight: normal; 9 | font-style: normal; 10 | } 11 | 12 | [class^=""], [class*=" "] { 13 | /* Better Font Rendering =========== */ 14 | -webkit-font-smoothing: antialiased; 15 | -moz-osx-font-smoothing: grayscale; 16 | } 17 | 18 | .clear-day:before { 19 | content: "\e600"; 20 | } 21 | .clear-night:before { 22 | content: "\e601"; 23 | } 24 | .cloudy:before { 25 | content: "\e602"; 26 | } 27 | .fog:before { 28 | content: "\e603"; 29 | } 30 | .partly-cloudy-day:before { 31 | content: "\e604"; 32 | } 33 | .partly-cloudy-night:before { 34 | content: "\e605"; 35 | } 36 | .rain:before { 37 | content: "\e606"; 38 | } 39 | .sleet:before { 40 | content: "\e607"; 41 | } 42 | .snow:before { 43 | content: "\e608"; 44 | } 45 | .wind:before { 46 | content: "\e609"; 47 | } 48 | -------------------------------------------------------------------------------- /js/app/views/news.js: -------------------------------------------------------------------------------- 1 | define([ 2 | 'jquery', 3 | 'underscore', 4 | 'backbone' 5 | ], function($, _, Backbone) { 6 | 7 | "use strict"; 8 | 9 | var NewsView = Backbone.View.extend({ 10 | initialize: function() { 11 | this.idx = 0; 12 | this.max = 8; 13 | var self = this; 14 | var req = $.get('/news'); 15 | 16 | req.done(function(d) { self.render(d); }); 17 | 18 | /* Update every hour */ 19 | setInterval(function() { 20 | var req = $.get('/news'); 21 | req.done(function(d) { self.render(d); }); 22 | }, 1000*60*60 + 4); 23 | }, 24 | render: function(d) { 25 | var $ul = this.$el.find('> ul'); 26 | d = JSON.parse(d.body); 27 | 28 | d.responseData.results.forEach(function(article) { 29 | var $li = $('
  • '); 30 | $li.html(article.title); 31 | 32 | $ul.append($li); 33 | }); 34 | 35 | this.cycle(); 36 | if (this.interval) { clearInterval(interval); } 37 | this.interval = setInterval( this.cycle.bind(this), 4000 ); 38 | }, 39 | cycle: function() { 40 | var idx = this.idx; 41 | var $list = this.$el.find('> ul > li'); 42 | 43 | $list.removeClass('active'); 44 | $($list[idx]).addClass('active'); 45 | 46 | this.idx = idx+1; 47 | if ( this.idx >= 8 ) { 48 | this.idx = 0; 49 | } 50 | } 51 | }); 52 | 53 | return NewsView; 54 | 55 | }); 56 | -------------------------------------------------------------------------------- /css/bourbon/helpers/_linear-gradient-parser.scss: -------------------------------------------------------------------------------- 1 | @function _linear-gradient-parser($image) { 2 | $image: unquote($image); 3 | $gradients: (); 4 | $start: str-index($image, "("); 5 | $end: str-index($image, ","); 6 | $first-val: str-slice($image, $start + 1, $end - 1); 7 | 8 | $prefix: str-slice($image, 0, $start); 9 | $suffix: str-slice($image, $end, str-length($image)); 10 | 11 | $has-multiple-vals: str-index($first-val, " "); 12 | $has-single-position: unquote(_position-flipper($first-val) + ""); 13 | $has-angle: _is-num(str-slice($first-val, 0, 0)); 14 | 15 | @if $has-multiple-vals { 16 | $gradients: _linear-side-corner-parser($image, $first-val, $prefix, $suffix, $has-multiple-vals); 17 | } 18 | 19 | @else if $has-single-position != "" { 20 | $pos: unquote($has-single-position + ""); 21 | 22 | $gradients: ( 23 | webkit-image: -webkit- + $image, 24 | spec-image: $prefix + "to " + $pos + $suffix 25 | ); 26 | } 27 | 28 | @else if $has-angle { 29 | // Rotate degree for webkit 30 | $gradients: _linear-angle-parser($image, $first-val, $prefix, $suffix); 31 | } 32 | 33 | @else { 34 | $gradients: ( 35 | webkit-image: -webkit- + $image, 36 | spec-image: $image 37 | ); 38 | } 39 | 40 | @return $gradients; 41 | } 42 | -------------------------------------------------------------------------------- /css/bourbon/css3/_keyframes.scss: -------------------------------------------------------------------------------- 1 | // Adds keyframes blocks for supported prefixes, removing redundant prefixes in the block's content 2 | @mixin keyframes($name) { 3 | $original-prefix-for-webkit: $prefix-for-webkit; 4 | $original-prefix-for-mozilla: $prefix-for-mozilla; 5 | $original-prefix-for-microsoft: $prefix-for-microsoft; 6 | $original-prefix-for-opera: $prefix-for-opera; 7 | $original-prefix-for-spec: $prefix-for-spec; 8 | 9 | @if $original-prefix-for-webkit { 10 | @include disable-prefix-for-all(); 11 | $prefix-for-webkit: true !global; 12 | @-webkit-keyframes #{$name} { 13 | @content; 14 | } 15 | } 16 | @if $original-prefix-for-mozilla { 17 | @include disable-prefix-for-all(); 18 | $prefix-for-mozilla: true !global; 19 | @-moz-keyframes #{$name} { 20 | @content; 21 | } 22 | } 23 | 24 | $prefix-for-webkit: $original-prefix-for-webkit !global; 25 | $prefix-for-mozilla: $original-prefix-for-mozilla !global; 26 | $prefix-for-microsoft: $original-prefix-for-microsoft !global; 27 | $prefix-for-opera: $original-prefix-for-opera !global; 28 | $prefix-for-spec: $original-prefix-for-spec !global; 29 | 30 | @if $original-prefix-for-spec { 31 | @keyframes #{$name} { 32 | @content; 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # BlackMirror 2 | 3 | ![alt tag](./assets/blackmirror.jpg) 4 | 5 | BlackMirror is a side project inspired by Hannah Mitt's [HomeMirror](https://github.com/HannahMitt/HomeMirror). 6 | 7 | ### Features 8 | 9 | - [x] Date and Time 10 | - [x] News and Events 11 | - [x] Weather (pull from forecast.io) 12 | - [ ] Weather Forecast 13 | - [x] Weather Icons (pull from noun project) 14 | - [x] Subway (pull from [Google Maps](https://developers.google.com/maps/documentation/directions/intro#TravelModes)) 15 | - [ ] Exercise (pull from [nike+](https://developer.nike.com/content/nike-developer-cq/us/en_us/index/documentation/api-docs.html)) (Can't get an api key) 16 | - [ ] Stock Ticker (pull from [markit](http://dev.markitondemand.com/)) 17 | 18 | ### Stack 19 | 20 | - Node and Express 21 | - Backbone 22 | - Sass 23 | - Grunt 24 | 25 | ### Tools 26 | 27 | - [x] Mirror 24x16 1/8" 28 | - [x] Android Device [Amazon](http://www.amazon.com/gp/offer-listing/B009X3UW2G/ref=olp_tab_refurbished?ie=UTF8&condition=refurbished&qid=1441327955&sr=8-1) 29 | - [x] Black Backing 30 | - [x] Velcro [Amazon](http://www.amazon.com/VELCRO-Industrial-Strength-Wide-Black/dp/B00006RSP1/ref=sr_1_2?ie=UTF8&qid=1442924711&sr=8-2&keywords=strong+velcro+strips) 31 | - [x] Adhesive Spray [Home Depot](http://www.homedepot.com/p/3M-Super-77-16-75-fl-oz-Multi-Purpose-Spray-Adhesive-77-CC/100067550) -------------------------------------------------------------------------------- /css/bourbon/addons/_prefixer.scss: -------------------------------------------------------------------------------- 1 | //************************************************************************// 2 | // Example: @include prefixer(border-radius, $radii, webkit ms spec); 3 | //************************************************************************// 4 | // Variables located in /settings/_prefixer.scss 5 | 6 | @mixin prefixer ($property, $value, $prefixes) { 7 | @each $prefix in $prefixes { 8 | @if $prefix == webkit { 9 | @if $prefix-for-webkit { 10 | -webkit-#{$property}: $value; 11 | } 12 | } 13 | @else if $prefix == moz { 14 | @if $prefix-for-mozilla { 15 | -moz-#{$property}: $value; 16 | } 17 | } 18 | @else if $prefix == ms { 19 | @if $prefix-for-microsoft { 20 | -ms-#{$property}: $value; 21 | } 22 | } 23 | @else if $prefix == o { 24 | @if $prefix-for-opera { 25 | -o-#{$property}: $value; 26 | } 27 | } 28 | @else if $prefix == spec { 29 | @if $prefix-for-spec { 30 | #{$property}: $value; 31 | } 32 | } 33 | @else { 34 | @warn "Unrecognized prefix: #{$prefix}"; 35 | } 36 | } 37 | } 38 | 39 | @mixin disable-prefix-for-all() { 40 | $prefix-for-webkit: false !global; 41 | $prefix-for-mozilla: false !global; 42 | $prefix-for-microsoft: false !global; 43 | $prefix-for-opera: false !global; 44 | $prefix-for-spec: false !global; 45 | } 46 | -------------------------------------------------------------------------------- /css/bourbon/css3/_columns.scss: -------------------------------------------------------------------------------- 1 | @mixin columns($arg: auto) { 2 | // || 3 | @include prefixer(columns, $arg, webkit moz spec); 4 | } 5 | 6 | @mixin column-count($int: auto) { 7 | // auto || integer 8 | @include prefixer(column-count, $int, webkit moz spec); 9 | } 10 | 11 | @mixin column-gap($length: normal) { 12 | // normal || length 13 | @include prefixer(column-gap, $length, webkit moz spec); 14 | } 15 | 16 | @mixin column-fill($arg: auto) { 17 | // auto || length 18 | @include prefixer(column-fill, $arg, webkit moz spec); 19 | } 20 | 21 | @mixin column-rule($arg) { 22 | // || || 23 | @include prefixer(column-rule, $arg, webkit moz spec); 24 | } 25 | 26 | @mixin column-rule-color($color) { 27 | @include prefixer(column-rule-color, $color, webkit moz spec); 28 | } 29 | 30 | @mixin column-rule-style($style: none) { 31 | // none | hidden | dashed | dotted | double | groove | inset | inset | outset | ridge | solid 32 | @include prefixer(column-rule-style, $style, webkit moz spec); 33 | } 34 | 35 | @mixin column-rule-width ($width: none) { 36 | @include prefixer(column-rule-width, $width, webkit moz spec); 37 | } 38 | 39 | @mixin column-span($arg: none) { 40 | // none || all 41 | @include prefixer(column-span, $arg, webkit moz spec); 42 | } 43 | 44 | @mixin column-width($length: auto) { 45 | // auto || length 46 | @include prefixer(column-width, $length, webkit moz spec); 47 | } 48 | -------------------------------------------------------------------------------- /css/bourbon/helpers/_str-to-num.scss: -------------------------------------------------------------------------------- 1 | //************************************************************************// 2 | // Helper function for linear/radial-gradient-parsers. 3 | // Source: http://sassmeister.com/gist/9647408 4 | //************************************************************************// 5 | @function _str-to-num($string) { 6 | // Matrices 7 | $strings: '0' '1' '2' '3' '4' '5' '6' '7' '8' '9'; 8 | $numbers: 0 1 2 3 4 5 6 7 8 9; 9 | 10 | // Result 11 | $result: 0; 12 | $divider: 0; 13 | $minus: false; 14 | 15 | // Looping through all characters 16 | @for $i from 1 through str-length($string) { 17 | $character: str-slice($string, $i, $i); 18 | $index: index($strings, $character); 19 | 20 | @if $character == '-' { 21 | $minus: true; 22 | } 23 | 24 | @else if $character == '.' { 25 | $divider: 1; 26 | } 27 | 28 | @else { 29 | @if not $index { 30 | $result: if($minus, $result * -1, $result); 31 | @return _convert-units($result, str-slice($string, $i)); 32 | } 33 | 34 | $number: nth($numbers, $index); 35 | 36 | @if $divider == 0 { 37 | $result: $result * 10; 38 | } 39 | 40 | @else { 41 | // Move the decimal dot to the left 42 | $divider: $divider * 10; 43 | $number: $number / $divider; 44 | } 45 | 46 | $result: $result + $number; 47 | } 48 | } 49 | @return if($minus, $result * -1, $result); 50 | } 51 | -------------------------------------------------------------------------------- /css/bourbon/css3/_linear-gradient.scss: -------------------------------------------------------------------------------- 1 | @mixin linear-gradient($pos, $G1, $G2: null, 2 | $G3: null, $G4: null, 3 | $G5: null, $G6: null, 4 | $G7: null, $G8: null, 5 | $G9: null, $G10: null, 6 | $fallback: null) { 7 | // Detect what type of value exists in $pos 8 | $pos-type: type-of(nth($pos, 1)); 9 | $pos-spec: null; 10 | $pos-degree: null; 11 | 12 | // If $pos is missing from mixin, reassign vars and add default position 13 | @if ($pos-type == color) or (nth($pos, 1) == "transparent") { 14 | $G10: $G9; $G9: $G8; $G8: $G7; $G7: $G6; $G6: $G5; 15 | $G5: $G4; $G4: $G3; $G3: $G2; $G2: $G1; $G1: $pos; 16 | $pos: null; 17 | } 18 | 19 | @if $pos { 20 | $positions: _linear-positions-parser($pos); 21 | $pos-degree: nth($positions, 1); 22 | $pos-spec: nth($positions, 2); 23 | } 24 | 25 | $full: $G1, $G2, $G3, $G4, $G5, $G6, $G7, $G8, $G9, $G10; 26 | 27 | // Set $G1 as the default fallback color 28 | $fallback-color: nth($G1, 1); 29 | 30 | // If $fallback is a color use that color as the fallback color 31 | @if (type-of($fallback) == color) or ($fallback == "transparent") { 32 | $fallback-color: $fallback; 33 | } 34 | 35 | background-color: $fallback-color; 36 | background-image: -webkit-linear-gradient($pos-degree $full); // Safari 5.1+, Chrome 37 | background-image: unquote("linear-gradient(#{$pos-spec}#{$full})"); 38 | } 39 | -------------------------------------------------------------------------------- /css/bourbon/helpers/_radial-gradient-parser.scss: -------------------------------------------------------------------------------- 1 | @function _radial-gradient-parser($image) { 2 | $image: unquote($image); 3 | $gradients: (); 4 | $start: str-index($image, "("); 5 | $end: str-index($image, ","); 6 | $first-val: str-slice($image, $start + 1, $end - 1); 7 | 8 | $prefix: str-slice($image, 0, $start); 9 | $suffix: str-slice($image, $end, str-length($image)); 10 | 11 | $is-spec-syntax: str-index($first-val, "at"); 12 | 13 | @if $is-spec-syntax and $is-spec-syntax > 1 { 14 | $keyword: str-slice($first-val, 1, $is-spec-syntax - 2); 15 | $pos: str-slice($first-val, $is-spec-syntax + 3, str-length($first-val)); 16 | $pos: append($pos, $keyword, comma); 17 | 18 | $gradients: ( 19 | webkit-image: -webkit- + $prefix + $pos + $suffix, 20 | spec-image: $image 21 | ) 22 | } 23 | 24 | @else if $is-spec-syntax == 1 { 25 | $pos: str-slice($first-val, $is-spec-syntax + 3, str-length($first-val)); 26 | 27 | $gradients: ( 28 | webkit-image: -webkit- + $prefix + $pos + $suffix, 29 | spec-image: $image 30 | ) 31 | } 32 | 33 | @else if str-index($image, "cover") or str-index($image, "contain") { 34 | @warn "Radial-gradient needs to be updated to conform to latest spec."; 35 | 36 | $gradients: ( 37 | webkit-image: null, 38 | spec-image: $image 39 | ) 40 | } 41 | 42 | @else { 43 | $gradients: ( 44 | webkit-image: -webkit- + $image, 45 | spec-image: $image 46 | ) 47 | } 48 | 49 | @return $gradients; 50 | } 51 | -------------------------------------------------------------------------------- /css/bourbon/css3/_background-image.scss: -------------------------------------------------------------------------------- 1 | //************************************************************************// 2 | // Background-image property for adding multiple background images with 3 | // gradients, or for stringing multiple gradients together. 4 | //************************************************************************// 5 | 6 | @mixin background-image($images...) { 7 | $webkit-images: (); 8 | $spec-images: (); 9 | 10 | @each $image in $images { 11 | $webkit-image: (); 12 | $spec-image: (); 13 | 14 | @if (type-of($image) == string) { 15 | $url-str: str-slice($image, 0, 3); 16 | $gradient-type: str-slice($image, 0, 6); 17 | 18 | @if $url-str == "url" { 19 | $webkit-image: $image; 20 | $spec-image: $image; 21 | } 22 | 23 | @else if $gradient-type == "linear" { 24 | $gradients: _linear-gradient-parser($image); 25 | $webkit-image: map-get($gradients, webkit-image); 26 | $spec-image: map-get($gradients, spec-image); 27 | } 28 | 29 | @else if $gradient-type == "radial" { 30 | $gradients: _radial-gradient-parser($image); 31 | $webkit-image: map-get($gradients, webkit-image); 32 | $spec-image: map-get($gradients, spec-image); 33 | } 34 | } 35 | 36 | $webkit-images: append($webkit-images, $webkit-image, comma); 37 | $spec-images: append($spec-images, $spec-image, comma); 38 | } 39 | 40 | background-image: $webkit-images; 41 | background-image: $spec-images; 42 | } 43 | -------------------------------------------------------------------------------- /css/bourbon/css3/_radial-gradient.scss: -------------------------------------------------------------------------------- 1 | // Requires Sass 3.1+ 2 | @mixin radial-gradient($G1, $G2, 3 | $G3: null, $G4: null, 4 | $G5: null, $G6: null, 5 | $G7: null, $G8: null, 6 | $G9: null, $G10: null, 7 | $pos: null, 8 | $shape-size: null, 9 | $fallback: null) { 10 | 11 | $data: _radial-arg-parser($G1, $G2, $pos, $shape-size); 12 | $G1: nth($data, 1); 13 | $G2: nth($data, 2); 14 | $pos: nth($data, 3); 15 | $shape-size: nth($data, 4); 16 | 17 | $full: $G1, $G2, $G3, $G4, $G5, $G6, $G7, $G8, $G9, $G10; 18 | 19 | // Strip deprecated cover/contain for spec 20 | $shape-size-spec: _shape-size-stripper($shape-size); 21 | 22 | // Set $G1 as the default fallback color 23 | $first-color: nth($full, 1); 24 | $fallback-color: nth($first-color, 1); 25 | 26 | @if (type-of($fallback) == color) or ($fallback == "transparent") { 27 | $fallback-color: $fallback; 28 | } 29 | 30 | // Add Commas and spaces 31 | $shape-size: if($shape-size, '#{$shape-size}, ', null); 32 | $pos: if($pos, '#{$pos}, ', null); 33 | $pos-spec: if($pos, 'at #{$pos}', null); 34 | $shape-size-spec: if(($shape-size-spec != ' ') and ($pos == null), '#{$shape-size-spec}, ', '#{$shape-size-spec} '); 35 | 36 | background-color: $fallback-color; 37 | background-image: -webkit-radial-gradient(unquote(#{$pos}#{$shape-size}#{$full})); 38 | background-image: unquote("radial-gradient(#{$shape-size-spec}#{$pos-spec}#{$full})"); 39 | } 40 | -------------------------------------------------------------------------------- /css/fonts/icomoon/style.css: -------------------------------------------------------------------------------- 1 | @font-face { 2 | font-family: 'icomoon'; 3 | src: url('fonts/icomoon.eot?p5nt58'); 4 | src: url('fonts/icomoon.eot?p5nt58#iefix') format('embedded-opentype'), 5 | url('fonts/icomoon.ttf?p5nt58') format('truetype'), 6 | url('fonts/icomoon.woff?p5nt58') format('woff'), 7 | url('fonts/icomoon.svg?p5nt58#icomoon') format('svg'); 8 | font-weight: normal; 9 | font-style: normal; 10 | } 11 | 12 | [class^="icon-"], [class*=" icon-"] { 13 | /* use !important to prevent issues with browser extensions that change fonts */ 14 | font-family: 'icomoon' !important; 15 | speak: none; 16 | font-style: normal; 17 | font-weight: normal; 18 | font-variant: normal; 19 | text-transform: none; 20 | line-height: 1; 21 | 22 | /* Better Font Rendering =========== */ 23 | -webkit-font-smoothing: antialiased; 24 | -moz-osx-font-smoothing: grayscale; 25 | } 26 | 27 | .icon-stock-graph:before { 28 | content: "\e900"; 29 | } 30 | .icon-clear-day:before { 31 | content: "\e600"; 32 | } 33 | .icon-clear-night:before { 34 | content: "\e601"; 35 | } 36 | .icon-cloudy:before { 37 | content: "\e602"; 38 | } 39 | .icon-fog:before { 40 | content: "\e603"; 41 | } 42 | .icon-partly-cloudy-day:before { 43 | content: "\e604"; 44 | } 45 | .icon-partly-cloudy-night:before { 46 | content: "\e605"; 47 | } 48 | .icon-rain:before { 49 | content: "\e606"; 50 | } 51 | .icon-sleet:before { 52 | content: "\e607"; 53 | } 54 | .icon-snow:before { 55 | content: "\e608"; 56 | } 57 | .icon-wind:before { 58 | content: "\e609"; 59 | } 60 | 61 | -------------------------------------------------------------------------------- /css/partials/_reset.scss: -------------------------------------------------------------------------------- 1 | /* http://meyerweb.com/eric/tools/css/reset/ 2 | v2.0 | 20110126 3 | License: none (public domain) 4 | */ 5 | 6 | html, body, div, span, applet, object, iframe, 7 | h1, h2, h3, h4, h5, h6, p, blockquote, pre, 8 | a, abbr, acronym, address, big, cite, code, 9 | del, dfn, em, img, ins, kbd, q, s, samp, 10 | small, strike, strong, sub, sup, tt, var, 11 | b, u, i, center, 12 | dl, dt, dd, ol, ul, li, 13 | fieldset, form, label, legend, 14 | table, caption, tbody, tfoot, thead, tr, th, td, 15 | article, aside, canvas, details, embed, 16 | figure, figcaption, footer, header, hgroup, 17 | menu, nav, output, ruby, section, summary, 18 | time, mark, audio, video { 19 | margin: 0; 20 | padding: 0; 21 | border: 0; 22 | font-size: 100%; 23 | font: inherit; 24 | vertical-align: baseline; 25 | } 26 | /* HTML5 display-role reset for older browsers */ 27 | article, aside, details, figcaption, figure, 28 | footer, header, hgroup, menu, nav, section { 29 | display: block; 30 | } 31 | body { 32 | line-height: 1; 33 | } 34 | ol, ul { 35 | list-style: none; 36 | } 37 | blockquote, q { 38 | quotes: none; 39 | } 40 | blockquote:before, blockquote:after, 41 | q:before, q:after { 42 | content: ''; 43 | content: none; 44 | } 45 | table { 46 | border-collapse: collapse; 47 | border-spacing: 0; 48 | } 49 | 50 | // ADDED 51 | * { 52 | outline: none; 53 | -webkit-font-smoothing: antialiased; 54 | -moz-osx-font-smoothing: grayscale; 55 | box-sizing: border-box; 56 | -webkit-box-sizing: border-box; 57 | -moz-box-sizing: border-box; 58 | -webkit-tap-highlight-color: rgba(0,0,0,0); 59 | letter-spacing: 0px; 60 | } -------------------------------------------------------------------------------- /js/app/views/stocks.js: -------------------------------------------------------------------------------- 1 | define([ 2 | 'jquery', 3 | 'underscore', 4 | 'backbone', 5 | 'text!templates/ticker.html' 6 | ], function($, _, Backbone, TickerTemplate) { 7 | 8 | var StocksView = Backbone.View.extend({ 9 | initialize: function() { 10 | var self = this; 11 | var req = $.get('/stocks', {stocks: ['.INX', 12 | '.DJI', 13 | '.ICIX', 14 | 'JNJ', 15 | 'FDN', 16 | 'PJP']}) 17 | 18 | req.done(function(d) { 19 | var d = JSON.parse(d.body.replace(/\//g, '')); 20 | var temp = _.template(TickerTemplate, {variable: 'data'})({'d': d}); 21 | 22 | self.$el.append(temp); 23 | self.buildTicker(); 24 | }); 25 | }, 26 | buildTicker: function() { 27 | this.$ticker = this.$el.find('.slider'); 28 | this.$overflow = this.$ticker.find('ul'); 29 | var $clones = this.$ticker.find('li').clone(); 30 | 31 | // get max width 32 | this.w = this.$ticker.width(); 33 | 34 | // set max width on slider 35 | this.$ticker.css('max-width', this.w); 36 | // and overflow 37 | this.$overflow.css('width', this.w*2 + 21); 38 | 39 | this.$overflow.append($clones); 40 | 41 | this.initSlider(); 42 | }, 43 | initSlider: function() { 44 | clearInterval(this.int); 45 | var self = this; 46 | var i = 0; 47 | 48 | this.int = setInterval(function() { 49 | if ( i < -self.w ) { self.initSlider() } 50 | self.$overflow.css('left', i--); 51 | }, 20); 52 | } 53 | }); 54 | 55 | return StocksView; 56 | 57 | }); -------------------------------------------------------------------------------- /css/bourbon/functions/_flex-grid.scss: -------------------------------------------------------------------------------- 1 | // Flexible grid 2 | @function flex-grid($columns, $container-columns: $fg-max-columns) { 3 | $width: $columns * $fg-column + ($columns - 1) * $fg-gutter; 4 | $container-width: $container-columns * $fg-column + ($container-columns - 1) * $fg-gutter; 5 | @return percentage($width / $container-width); 6 | } 7 | 8 | // Flexible gutter 9 | @function flex-gutter($container-columns: $fg-max-columns, $gutter: $fg-gutter) { 10 | $container-width: $container-columns * $fg-column + ($container-columns - 1) * $fg-gutter; 11 | @return percentage($gutter / $container-width); 12 | } 13 | 14 | // The $fg-column, $fg-gutter and $fg-max-columns variables must be defined in your base stylesheet to properly use the flex-grid function. 15 | // This function takes the fluid grid equation (target / context = result) and uses columns to help define each. 16 | // 17 | // The calculation presumes that your column structure will be missing the last gutter: 18 | // 19 | // -- column -- gutter -- column -- gutter -- column 20 | // 21 | // $fg-column: 60px; // Column Width 22 | // $fg-gutter: 25px; // Gutter Width 23 | // $fg-max-columns: 12; // Total Columns For Main Container 24 | // 25 | // div { 26 | // width: flex-grid(4); // returns (315px / 995px) = 31.65829%; 27 | // margin-left: flex-gutter(); // returns (25px / 995px) = 2.51256%; 28 | // 29 | // p { 30 | // width: flex-grid(2, 4); // returns (145px / 315px) = 46.031746%; 31 | // float: left; 32 | // margin: flex-gutter(4); // returns (25px / 315px) = 7.936508%; 33 | // } 34 | // 35 | // blockquote { 36 | // float: left; 37 | // width: flex-grid(2, 4); // returns (145px / 315px) = 46.031746%; 38 | // } 39 | // } -------------------------------------------------------------------------------- /css/bourbon/functions/_modular-scale.scss: -------------------------------------------------------------------------------- 1 | // Scaling Variables 2 | $golden: 1.618; 3 | $minor-second: 1.067; 4 | $major-second: 1.125; 5 | $minor-third: 1.2; 6 | $major-third: 1.25; 7 | $perfect-fourth: 1.333; 8 | $augmented-fourth: 1.414; 9 | $perfect-fifth: 1.5; 10 | $minor-sixth: 1.6; 11 | $major-sixth: 1.667; 12 | $minor-seventh: 1.778; 13 | $major-seventh: 1.875; 14 | $octave: 2; 15 | $major-tenth: 2.5; 16 | $major-eleventh: 2.667; 17 | $major-twelfth: 3; 18 | $double-octave: 4; 19 | 20 | @function modular-scale($value, $increment, $ratio) { 21 | $v1: nth($value, 1); 22 | $v2: nth($value, length($value)); 23 | $value: $v1; 24 | 25 | // scale $v2 to just above $v1 26 | @while $v2 > $v1 { 27 | $v2: ($v2 / $ratio); // will be off-by-1 28 | } 29 | @while $v2 < $v1 { 30 | $v2: ($v2 * $ratio); // will fix off-by-1 31 | } 32 | 33 | // check AFTER scaling $v2 to prevent double-counting corner-case 34 | $double-stranded: $v2 > $v1; 35 | 36 | @if $increment > 0 { 37 | @for $i from 1 through $increment { 38 | @if $double-stranded and ($v1 * $ratio) > $v2 { 39 | $value: $v2; 40 | $v2: ($v2 * $ratio); 41 | } @else { 42 | $v1: ($v1 * $ratio); 43 | $value: $v1; 44 | } 45 | } 46 | } 47 | 48 | @if $increment < 0 { 49 | // adjust $v2 to just below $v1 50 | @if $double-stranded { 51 | $v2: ($v2 / $ratio); 52 | } 53 | 54 | @for $i from $increment through -1 { 55 | @if $double-stranded and ($v1 / $ratio) < $v2 { 56 | $value: $v2; 57 | $v2: ($v2 / $ratio); 58 | } @else { 59 | $v1: ($v1 / $ratio); 60 | $value: $v1; 61 | } 62 | } 63 | } 64 | 65 | @return $value; 66 | } 67 | -------------------------------------------------------------------------------- /Gruntfile.js: -------------------------------------------------------------------------------- 1 | module.exports = function(grunt) { 2 | var ip = grunt.option('ip') || 'localhost'; 3 | 4 | grunt.initConfig({ 5 | sass: { 6 | dev: { 7 | options: { 8 | outputStyle: 'expanded' 9 | }, 10 | files: { 11 | 'css/main.css': 'css/main.scss' 12 | } 13 | } 14 | }, 15 | 16 | watch: { 17 | sass: { 18 | files: ['css/*.scss', 'css/partials/*.scss'], 19 | tasks: ['sass:dev'] 20 | } 21 | }, 22 | 23 | requirejs: { 24 | compile: { 25 | options: { 26 | baseUrl: "js", 27 | name: "lib/almond", 28 | mainConfigFile: "js/main.js", 29 | out: "js/build/main.js", 30 | done: function(done, output) { 31 | var duplicates = require('rjs-build-analysis').duplicates(output); 32 | 33 | if (Object.keys(duplicates).length > 0) { 34 | grunt.log.subhead('Duplicates found in requirejs build:'); 35 | for (var key in duplicates) { 36 | grunt.log.error(duplicates[key] + ": " + key); 37 | } 38 | return done(new Error('r.js built duplicate modules, please check the excludes option.')); 39 | } else { 40 | grunt.log.success("No duplicates found!"); 41 | } 42 | 43 | done(); 44 | } 45 | } 46 | } 47 | }, 48 | 49 | shell: { 50 | server: { 51 | command: 'killall node; node server.js', 52 | options: { 53 | async: true 54 | } 55 | } 56 | } 57 | }); 58 | 59 | grunt.loadNpmTasks('grunt-sass'); 60 | grunt.loadNpmTasks('grunt-shell-spawn'); 61 | grunt.loadNpmTasks('grunt-contrib-watch'); 62 | grunt.loadNpmTasks('grunt-contrib-requirejs'); 63 | 64 | 65 | grunt.registerTask('build', ['requirejs']); 66 | grunt.registerTask('default', ['shell:server', 'watch']); 67 | }; -------------------------------------------------------------------------------- /css/bourbon/css3/_animation.scss: -------------------------------------------------------------------------------- 1 | // http://www.w3.org/TR/css3-animations/#the-animation-name-property- 2 | // Each of these mixins support comma separated lists of values, which allows different transitions for individual properties to be described in a single style rule. Each value in the list corresponds to the value at that same position in the other properties. 3 | 4 | // Official animation shorthand property. 5 | @mixin animation ($animations...) { 6 | @include prefixer(animation, $animations, webkit moz spec); 7 | } 8 | 9 | // Individual Animation Properties 10 | @mixin animation-name ($names...) { 11 | @include prefixer(animation-name, $names, webkit moz spec); 12 | } 13 | 14 | 15 | @mixin animation-duration ($times...) { 16 | @include prefixer(animation-duration, $times, webkit moz spec); 17 | } 18 | 19 | 20 | @mixin animation-timing-function ($motions...) { 21 | // ease | linear | ease-in | ease-out | ease-in-out 22 | @include prefixer(animation-timing-function, $motions, webkit moz spec); 23 | } 24 | 25 | 26 | @mixin animation-iteration-count ($values...) { 27 | // infinite | 28 | @include prefixer(animation-iteration-count, $values, webkit moz spec); 29 | } 30 | 31 | 32 | @mixin animation-direction ($directions...) { 33 | // normal | alternate 34 | @include prefixer(animation-direction, $directions, webkit moz spec); 35 | } 36 | 37 | 38 | @mixin animation-play-state ($states...) { 39 | // running | paused 40 | @include prefixer(animation-play-state, $states, webkit moz spec); 41 | } 42 | 43 | 44 | @mixin animation-delay ($times...) { 45 | @include prefixer(animation-delay, $times, webkit moz spec); 46 | } 47 | 48 | 49 | @mixin animation-fill-mode ($modes...) { 50 | // none | forwards | backwards | both 51 | @include prefixer(animation-fill-mode, $modes, webkit moz spec); 52 | } 53 | -------------------------------------------------------------------------------- /css/bourbon/addons/_timing-functions.scss: -------------------------------------------------------------------------------- 1 | // CSS cubic-bezier timing functions. Timing functions courtesy of jquery.easie (github.com/jaukia/easie) 2 | // Timing functions are the same as demo'ed here: http://jqueryui.com/resources/demos/effect/easing.html 3 | 4 | // EASE IN 5 | $ease-in-quad: cubic-bezier(0.550, 0.085, 0.680, 0.530); 6 | $ease-in-cubic: cubic-bezier(0.550, 0.055, 0.675, 0.190); 7 | $ease-in-quart: cubic-bezier(0.895, 0.030, 0.685, 0.220); 8 | $ease-in-quint: cubic-bezier(0.755, 0.050, 0.855, 0.060); 9 | $ease-in-sine: cubic-bezier(0.470, 0.000, 0.745, 0.715); 10 | $ease-in-expo: cubic-bezier(0.950, 0.050, 0.795, 0.035); 11 | $ease-in-circ: cubic-bezier(0.600, 0.040, 0.980, 0.335); 12 | $ease-in-back: cubic-bezier(0.600, -0.280, 0.735, 0.045); 13 | 14 | // EASE OUT 15 | $ease-out-quad: cubic-bezier(0.250, 0.460, 0.450, 0.940); 16 | $ease-out-cubic: cubic-bezier(0.215, 0.610, 0.355, 1.000); 17 | $ease-out-quart: cubic-bezier(0.165, 0.840, 0.440, 1.000); 18 | $ease-out-quint: cubic-bezier(0.230, 1.000, 0.320, 1.000); 19 | $ease-out-sine: cubic-bezier(0.390, 0.575, 0.565, 1.000); 20 | $ease-out-expo: cubic-bezier(0.190, 1.000, 0.220, 1.000); 21 | $ease-out-circ: cubic-bezier(0.075, 0.820, 0.165, 1.000); 22 | $ease-out-back: cubic-bezier(0.175, 0.885, 0.320, 1.275); 23 | 24 | // EASE IN OUT 25 | $ease-in-out-quad: cubic-bezier(0.455, 0.030, 0.515, 0.955); 26 | $ease-in-out-cubic: cubic-bezier(0.645, 0.045, 0.355, 1.000); 27 | $ease-in-out-quart: cubic-bezier(0.770, 0.000, 0.175, 1.000); 28 | $ease-in-out-quint: cubic-bezier(0.860, 0.000, 0.070, 1.000); 29 | $ease-in-out-sine: cubic-bezier(0.445, 0.050, 0.550, 0.950); 30 | $ease-in-out-expo: cubic-bezier(1.000, 0.000, 0.000, 1.000); 31 | $ease-in-out-circ: cubic-bezier(0.785, 0.135, 0.150, 0.860); 32 | $ease-in-out-back: cubic-bezier(0.680, -0.550, 0.265, 1.550); 33 | -------------------------------------------------------------------------------- /js/app/views/subway.js: -------------------------------------------------------------------------------- 1 | define([ 2 | 'jquery', 3 | 'underscore', 4 | 'backbone' 5 | ], function($, _, Backbone) { 6 | 7 | "use strict"; 8 | 9 | var SubwayView = Backbone.View.extend({ 10 | initialize: function() { 11 | var self = this; 12 | var req = $.get('/subway'); 13 | 14 | req.done(function(d) { self.render(d); }); 15 | 16 | /* Update every minute */ 17 | setInterval(function() { 18 | var req = $.get('/subway'); 19 | req.done(function(d) { self.render(d); }); 20 | }, 1000*60); 21 | }, 22 | render: function(d) { 23 | d = JSON.parse(d.body); 24 | 25 | var departure = d.routes[0].legs[0]; 26 | var firstStep = this.getFirstStep(departure); 27 | 28 | var $subwayIcon = this.getSubwayIcon(firstStep); 29 | var subwayString = this.getSubwayString(firstStep); 30 | 31 | this.$el.html(subwayString); 32 | this.$el.prepend($subwayIcon); 33 | }, 34 | getFirstStep: function(departure) { 35 | var steps = departure.steps; 36 | var l = steps.length; 37 | 38 | for ( var i = 0; i < l; i++ ) { 39 | if ( steps[i].travel_mode === 'TRANSIT' ) { 40 | return steps[i]; 41 | } 42 | } 43 | }, 44 | getSubwayString: function(step) { 45 | var time; 46 | 47 | var departure_time = step.transit_details.departure_time; 48 | 49 | var nextTrain = new Date(departure_time.value*1000).getMinutes(); 50 | var currentTime = new Date().getMinutes(); 51 | var minutesAway = nextTrain - currentTime; 52 | 53 | minutesAway = minutesAway <= -1 ? 60 % minutesAway : minutesAway; 54 | 55 | if ( minutesAway === 1 ) { 56 | time = 'minute'; 57 | } else { 58 | time = 'minutes'; 59 | } 60 | 61 | var s = 'Train is ' + minutesAway + ' ' + time + ' away'; 62 | return s; 63 | }, 64 | getSubwayIcon: function(departure) { 65 | var src = departure.transit_details.line.icon; 66 | 67 | return $('').attr('src', src); 68 | } 69 | }); 70 | 71 | return SubwayView; 72 | 73 | }); -------------------------------------------------------------------------------- /css/bourbon/css3/_background.scss: -------------------------------------------------------------------------------- 1 | //************************************************************************// 2 | // Background property for adding multiple backgrounds using shorthand 3 | // notation. 4 | //************************************************************************// 5 | 6 | @mixin background($backgrounds...) { 7 | $webkit-backgrounds: (); 8 | $spec-backgrounds: (); 9 | 10 | @each $background in $backgrounds { 11 | $webkit-background: (); 12 | $spec-background: (); 13 | $background-type: type-of($background); 14 | 15 | @if $background-type == string or list { 16 | $background-str: if($background-type == list, nth($background, 1), $background); 17 | 18 | $url-str: str-slice($background-str, 0, 3); 19 | $gradient-type: str-slice($background-str, 0, 6); 20 | 21 | @if $url-str == "url" { 22 | $webkit-background: $background; 23 | $spec-background: $background; 24 | } 25 | 26 | @else if $gradient-type == "linear" { 27 | $gradients: _linear-gradient-parser("#{$background}"); 28 | $webkit-background: map-get($gradients, webkit-image); 29 | $spec-background: map-get($gradients, spec-image); 30 | } 31 | 32 | @else if $gradient-type == "radial" { 33 | $gradients: _radial-gradient-parser("#{$background}"); 34 | $webkit-background: map-get($gradients, webkit-image); 35 | $spec-background: map-get($gradients, spec-image); 36 | } 37 | 38 | @else { 39 | $webkit-background: $background; 40 | $spec-background: $background; 41 | } 42 | } 43 | 44 | @else { 45 | $webkit-background: $background; 46 | $spec-background: $background; 47 | } 48 | 49 | $webkit-backgrounds: append($webkit-backgrounds, $webkit-background, comma); 50 | $spec-backgrounds: append($spec-backgrounds, $spec-background, comma); 51 | } 52 | 53 | background: $webkit-backgrounds; 54 | background: $spec-backgrounds; 55 | } 56 | -------------------------------------------------------------------------------- /css/bourbon/css3/_border-image.scss: -------------------------------------------------------------------------------- 1 | @mixin border-image($borders...) { 2 | $webkit-borders: (); 3 | $spec-borders: (); 4 | 5 | @each $border in $borders { 6 | $webkit-border: (); 7 | $spec-border: (); 8 | $border-type: type-of($border); 9 | 10 | @if $border-type == string or list { 11 | $border-str: if($border-type == list, nth($border, 1), $border); 12 | 13 | $url-str: str-slice($border-str, 0, 3); 14 | $gradient-type: str-slice($border-str, 0, 6); 15 | 16 | @if $url-str == "url" { 17 | $webkit-border: $border; 18 | $spec-border: $border; 19 | } 20 | 21 | @else if $gradient-type == "linear" { 22 | $gradients: _linear-gradient-parser("#{$border}"); 23 | $webkit-border: map-get($gradients, webkit-image); 24 | $spec-border: map-get($gradients, spec-image); 25 | } 26 | 27 | @else if $gradient-type == "radial" { 28 | $gradients: _radial-gradient-parser("#{$border}"); 29 | $webkit-border: map-get($gradients, webkit-image); 30 | $spec-border: map-get($gradients, spec-image); 31 | } 32 | 33 | @else { 34 | $webkit-border: $border; 35 | $spec-border: $border; 36 | } 37 | } 38 | 39 | @else { 40 | $webkit-border: $border; 41 | $spec-border: $border; 42 | } 43 | 44 | $webkit-borders: append($webkit-borders, $webkit-border, comma); 45 | $spec-borders: append($spec-borders, $spec-border, comma); 46 | } 47 | 48 | -webkit-border-image: $webkit-borders; 49 | border-image: $spec-borders; 50 | border-style: solid; 51 | } 52 | 53 | //Examples: 54 | // @include border-image(url("image.png")); 55 | // @include border-image(url("image.png") 20 stretch); 56 | // @include border-image(linear-gradient(45deg, orange, yellow)); 57 | // @include border-image(linear-gradient(45deg, orange, yellow) stretch); 58 | // @include border-image(linear-gradient(45deg, orange, yellow) 20 30 40 50 stretch round); 59 | // @include border-image(radial-gradient(top, cover, orange, yellow, orange)); 60 | -------------------------------------------------------------------------------- /css/bourbon/helpers/_radial-arg-parser.scss: -------------------------------------------------------------------------------- 1 | @function _radial-arg-parser($G1, $G2, $pos, $shape-size) { 2 | @each $value in $G1, $G2 { 3 | $first-val: nth($value, 1); 4 | $pos-type: type-of($first-val); 5 | $spec-at-index: null; 6 | 7 | // Determine if spec was passed to mixin 8 | @if type-of($value) == list { 9 | $spec-at-index: if(index($value, at), index($value, at), false); 10 | } 11 | @if $spec-at-index { 12 | @if $spec-at-index > 1 { 13 | @for $i from 1 through ($spec-at-index - 1) { 14 | $shape-size: $shape-size nth($value, $i); 15 | } 16 | @for $i from ($spec-at-index + 1) through length($value) { 17 | $pos: $pos nth($value, $i); 18 | } 19 | } 20 | @else if $spec-at-index == 1 { 21 | @for $i from ($spec-at-index + 1) through length($value) { 22 | $pos: $pos nth($value, $i); 23 | } 24 | } 25 | $G1: null; 26 | } 27 | 28 | // If not spec calculate correct values 29 | @else { 30 | @if ($pos-type != color) or ($first-val != "transparent") { 31 | @if ($pos-type == number) 32 | or ($first-val == "center") 33 | or ($first-val == "top") 34 | or ($first-val == "right") 35 | or ($first-val == "bottom") 36 | or ($first-val == "left") { 37 | 38 | $pos: $value; 39 | 40 | @if $pos == $G1 { 41 | $G1: null; 42 | } 43 | } 44 | 45 | @else if 46 | ($first-val == "ellipse") 47 | or ($first-val == "circle") 48 | or ($first-val == "closest-side") 49 | or ($first-val == "closest-corner") 50 | or ($first-val == "farthest-side") 51 | or ($first-val == "farthest-corner") 52 | or ($first-val == "contain") 53 | or ($first-val == "cover") { 54 | 55 | $shape-size: $value; 56 | 57 | @if $value == $G1 { 58 | $G1: null; 59 | } 60 | 61 | @else if $value == $G2 { 62 | $G2: null; 63 | } 64 | } 65 | } 66 | } 67 | } 68 | @return $G1, $G2, $pos, $shape-size; 69 | } 70 | -------------------------------------------------------------------------------- /css/bourbon/helpers/_linear-positions-parser.scss: -------------------------------------------------------------------------------- 1 | @function _linear-positions-parser($pos) { 2 | $type: type-of(nth($pos, 1)); 3 | $spec: null; 4 | $degree: null; 5 | $side: null; 6 | $corner: null; 7 | $length: length($pos); 8 | // Parse Side and corner positions 9 | @if ($length > 1) { 10 | @if nth($pos, 1) == "to" { // Newer syntax 11 | $side: nth($pos, 2); 12 | 13 | @if $length == 2 { // eg. to top 14 | // Swap for backwards compatability 15 | $degree: _position-flipper(nth($pos, 2)); 16 | } 17 | @else if $length == 3 { // eg. to top left 18 | $corner: nth($pos, 3); 19 | } 20 | } 21 | @else if $length == 2 { // Older syntax ("top left") 22 | $side: _position-flipper(nth($pos, 1)); 23 | $corner: _position-flipper(nth($pos, 2)); 24 | } 25 | 26 | @if ("#{$side} #{$corner}" == "left top") or ("#{$side} #{$corner}" == "top left") { 27 | $degree: _position-flipper(#{$side}) _position-flipper(#{$corner}); 28 | } 29 | @else if ("#{$side} #{$corner}" == "right top") or ("#{$side} #{$corner}" == "top right") { 30 | $degree: _position-flipper(#{$side}) _position-flipper(#{$corner}); 31 | } 32 | @else if ("#{$side} #{$corner}" == "right bottom") or ("#{$side} #{$corner}" == "bottom right") { 33 | $degree: _position-flipper(#{$side}) _position-flipper(#{$corner}); 34 | } 35 | @else if ("#{$side} #{$corner}" == "left bottom") or ("#{$side} #{$corner}" == "bottom left") { 36 | $degree: _position-flipper(#{$side}) _position-flipper(#{$corner}); 37 | } 38 | $spec: to $side $corner; 39 | } 40 | @else if $length == 1 { 41 | // Swap for backwards compatability 42 | @if $type == string { 43 | $degree: $pos; 44 | $spec: to _position-flipper($pos); 45 | } 46 | @else { 47 | $degree: -270 - $pos; //rotate the gradient opposite from spec 48 | $spec: $pos; 49 | } 50 | } 51 | $degree: unquote($degree + ","); 52 | $spec: unquote($spec + ","); 53 | @return $degree $spec; 54 | } 55 | 56 | @function _position-flipper($pos) { 57 | @return if($pos == left, right, null) 58 | if($pos == right, left, null) 59 | if($pos == top, bottom, null) 60 | if($pos == bottom, top, null); 61 | } 62 | -------------------------------------------------------------------------------- /css/partials/_global.scss: -------------------------------------------------------------------------------- 1 | html, body { 2 | font-family: 'Roboto Condensed', sans-serif; 3 | background: black; 4 | text-align: right; 5 | color: white; 6 | padding: 20px; 7 | padding-top: 40px; 8 | padding-right: 40px; 9 | } 10 | 11 | body { 12 | opacity: 0; 13 | &.active { 14 | opacity: 1; 15 | @include transition(opacity 0.2s); 16 | } 17 | } 18 | 19 | .weather, .subway { 20 | margin-bottom: 40px; 21 | } 22 | 23 | // clock 24 | .clock .date { 25 | font-size: 52px; 26 | margin-bottom: 20px; 27 | } 28 | 29 | .clock .time { 30 | font-size: 128px; 31 | font-weight: bold; 32 | margin-bottom: 15px; 33 | > span { 34 | font-size: 24px; 35 | margin-left: 5px; 36 | font-weight: normal; 37 | } 38 | } 39 | 40 | // weather 41 | .weather { 42 | font-size: 100px; 43 | &:before { 44 | margin-right: 20px; 45 | font-family: 'icomoon'; 46 | } 47 | } 48 | 49 | // subway 50 | .subway { 51 | font-size: 52px; 52 | img { 53 | margin-right: 20px; 54 | } 55 | } 56 | 57 | // news 58 | .news { 59 | h3 { 60 | font-size: 48px; 61 | text-decoration: underline; 62 | } 63 | ul { 64 | position: relative; 65 | min-height: 100px; 66 | li { 67 | right: 0; 68 | top: 20px; 69 | opacity: 0; 70 | font-size: 36px; 71 | position: absolute; 72 | @include transition(opacity 0.5s); 73 | &.active { 74 | opacity: 1; 75 | @include transition(opacity 1s); 76 | } 77 | } 78 | } 79 | } 80 | 81 | // stocks 82 | .stocks { 83 | &:before { 84 | font-size: 52px; 85 | content: '\e900'; 86 | margin-top: -16px; 87 | margin-right: 10px; 88 | display: inline-block; 89 | font-family: 'icomoon'; 90 | } 91 | .slider { 92 | float: right; 93 | overflow: hidden; 94 | display: inline-block; 95 | } 96 | ul { 97 | left: 0px; 98 | @include clearfix; 99 | position: relative; 100 | @include transform(translateZ(0)); 101 | li.stock { 102 | float: left; 103 | font-size: 24px; 104 | padding-left: 20px; 105 | &:first-child { 106 | margin-left: 0px; 107 | } 108 | &:before { 109 | content: ''; 110 | display: inline-block; 111 | @include triangle(10px, $red, down) 112 | } 113 | &.up { 114 | color: $green; 115 | &:before { 116 | @include triangle(0px, $red, down) 117 | @include triangle(10px, $green, up) 118 | } 119 | } 120 | &.down { 121 | color: $red; 122 | } 123 | } 124 | } 125 | } -------------------------------------------------------------------------------- /server.js: -------------------------------------------------------------------------------- 1 | var express = require('express'); 2 | var request = require('request'); 3 | var app = express(); 4 | 5 | // set the port of our application 6 | // process.env.PORT lets the port be set by third party 7 | var port = process.env.PORT || 8080; 8 | 9 | // set the view engine to ejs but use html 10 | app.engine('html', require('ejs').renderFile); 11 | app.set('views', __dirname); 12 | 13 | // make express look in the root directory for assets (css/js/img) 14 | app.use(express.static(__dirname + '/')); 15 | 16 | app.get('/', function(req, res) { 17 | res.render('index.html'); 18 | }); 19 | 20 | app.get('/weather', function(req, res) { 21 | // hard code for now 22 | var lng = '-73.984511'; 23 | var lat = '40.7694445'; 24 | var key = 'edfb819a19e630697ed7519902c209ee'; 25 | var url = 'https://api.forecast.io/forecast/'; 26 | 27 | url += key; 28 | url += '/'; 29 | url += lat; 30 | url += ','; 31 | url += lng; 32 | 33 | request(url, function(err, d) { 34 | res.writeHead(200, {"Content-Type": "application/json"}); 35 | res.write(JSON.stringify(d)); 36 | res.end(); 37 | }); 38 | }); 39 | 40 | app.get('/subway', function(req, res) { 41 | // hard code for now 42 | var mode = 'transit'; 43 | var origin = 'Columbus_Circle'; 44 | var dest = '159_West_25th_NewYork'; 45 | var key = 'AIzaSyAJFm6N6BEzYHLsdKwapx_43Ez1sD1Igmk'; 46 | var url = 'https://maps.googleapis.com/maps/api/directions/json'; 47 | 48 | url += '?origin='+origin; 49 | url += '&destination='+dest; 50 | url += '&mode='+mode; 51 | url += '&key='+key; 52 | 53 | request(url, function(err, d) { 54 | res.writeHead(200, {"Content-Type": "application/json"}); 55 | res.write(JSON.stringify(d)); 56 | res.end(); 57 | }); 58 | 59 | }); 60 | 61 | app.get('/news', function(req, res) { 62 | var url = 'https://ajax.googleapis.com/ajax/services/search/news?v=1.0&q=news&rsz=8'; 63 | 64 | request(url, function(err, d) { 65 | res.writeHead(200, {"Content-Type": "application/json"}); 66 | res.write(JSON.stringify(d)); 67 | res.end(); 68 | }); 69 | }); 70 | 71 | app.get('/stocks', function(req, res) { 72 | var url = 'https://www.google.com/finance/info?infotype=infoquoteall&q='; 73 | var stocks = req.query.stocks.join(); 74 | 75 | url += stocks; 76 | 77 | request(url, function(err, d) { 78 | res.writeHead(200, {"Content-Type": "application/json"}); 79 | res.write(JSON.stringify(d)); 80 | res.end(); 81 | }); 82 | }); 83 | 84 | app.listen(port, function() { 85 | console.log('BlackMirror is running on http://localhost:' + port); 86 | }); 87 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | BlackMirror 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 |
    34 |
    35 | 36 |
    37 |
    38 |
    39 |
    40 |
    41 |
    42 |
    43 | 44 |
    45 |
    46 | 47 | 48 | 49 | 50 | 51 | -------------------------------------------------------------------------------- /css/bourbon/_bourbon.scss: -------------------------------------------------------------------------------- 1 | // Settings 2 | @import "settings/prefixer"; 3 | @import "settings/px-to-em"; 4 | @import "settings/asset-pipeline"; 5 | 6 | // Custom Helpers 7 | @import "helpers/convert-units"; 8 | @import "helpers/gradient-positions-parser"; 9 | @import "helpers/is-num"; 10 | @import "helpers/linear-angle-parser"; 11 | @import "helpers/linear-gradient-parser"; 12 | @import "helpers/linear-positions-parser"; 13 | @import "helpers/linear-side-corner-parser"; 14 | @import "helpers/radial-arg-parser"; 15 | @import "helpers/radial-positions-parser"; 16 | @import "helpers/radial-gradient-parser"; 17 | @import "helpers/render-gradients"; 18 | @import "helpers/shape-size-stripper"; 19 | @import "helpers/str-to-num"; 20 | 21 | // Custom Functions 22 | @import "functions/assign"; 23 | @import "functions/color-lightness"; 24 | @import "functions/flex-grid"; 25 | @import "functions/golden-ratio"; 26 | @import "functions/grid-width"; 27 | @import "functions/modular-scale"; 28 | @import "functions/px-to-em"; 29 | @import "functions/px-to-rem"; 30 | @import "functions/strip-units"; 31 | @import "functions/tint-shade"; 32 | @import "functions/transition-property-name"; 33 | @import "functions/unpack"; 34 | 35 | // CSS3 Mixins 36 | @import "css3/animation"; 37 | @import "css3/appearance"; 38 | @import "css3/backface-visibility"; 39 | @import "css3/background"; 40 | @import "css3/background-image"; 41 | @import "css3/border-image"; 42 | @import "css3/border-radius"; 43 | @import "css3/box-sizing"; 44 | @import "css3/calc"; 45 | @import "css3/columns"; 46 | @import "css3/filter"; 47 | @import "css3/flex-box"; 48 | @import "css3/font-face"; 49 | @import "css3/font-feature-settings"; 50 | @import "css3/hyphens"; 51 | @import "css3/hidpi-media-query"; 52 | @import "css3/image-rendering"; 53 | @import "css3/keyframes"; 54 | @import "css3/linear-gradient"; 55 | @import "css3/perspective"; 56 | @import "css3/radial-gradient"; 57 | @import "css3/transform"; 58 | @import "css3/transition"; 59 | @import "css3/user-select"; 60 | @import "css3/placeholder"; 61 | 62 | // Addons & other mixins 63 | @import "addons/button"; 64 | @import "addons/clearfix"; 65 | @import "addons/directional-values"; 66 | @import "addons/ellipsis"; 67 | @import "addons/font-family"; 68 | @import "addons/hide-text"; 69 | @import "addons/html5-input-types"; 70 | @import "addons/position"; 71 | @import "addons/prefixer"; 72 | @import "addons/retina-image"; 73 | @import "addons/size"; 74 | @import "addons/timing-functions"; 75 | @import "addons/triangle"; 76 | @import "addons/word-wrap"; 77 | 78 | // Soon to be deprecated Mixins 79 | @import "bourbon-deprecated-upcoming"; 80 | -------------------------------------------------------------------------------- /css/bourbon/css3/_transition.scss: -------------------------------------------------------------------------------- 1 | // Shorthand mixin. Supports multiple parentheses-deliminated values for each variable. 2 | // Example: @include transition (all 2s ease-in-out); 3 | // @include transition (opacity 1s ease-in 2s, width 2s ease-out); 4 | // @include transition-property (transform, opacity); 5 | 6 | @mixin transition ($properties...) { 7 | // Fix for vendor-prefix transform property 8 | $needs-prefixes: false; 9 | $webkit: (); 10 | $moz: (); 11 | $spec: (); 12 | 13 | // Create lists for vendor-prefixed transform 14 | @each $list in $properties { 15 | @if nth($list, 1) == "transform" { 16 | $needs-prefixes: true; 17 | $list1: -webkit-transform; 18 | $list2: -moz-transform; 19 | $list3: (); 20 | 21 | @each $var in $list { 22 | $list3: join($list3, $var); 23 | 24 | @if $var != "transform" { 25 | $list1: join($list1, $var); 26 | $list2: join($list2, $var); 27 | } 28 | } 29 | 30 | $webkit: append($webkit, $list1); 31 | $moz: append($moz, $list2); 32 | $spec: append($spec, $list3); 33 | } 34 | 35 | // Create lists for non-prefixed transition properties 36 | @else { 37 | $webkit: append($webkit, $list, comma); 38 | $moz: append($moz, $list, comma); 39 | $spec: append($spec, $list, comma); 40 | } 41 | } 42 | 43 | @if $needs-prefixes { 44 | -webkit-transition: $webkit; 45 | -moz-transition: $moz; 46 | transition: $spec; 47 | } 48 | @else { 49 | @if length($properties) >= 1 { 50 | @include prefixer(transition, $properties, webkit moz spec); 51 | } 52 | 53 | @else { 54 | $properties: all 0.15s ease-out 0s; 55 | @include prefixer(transition, $properties, webkit moz spec); 56 | } 57 | } 58 | } 59 | 60 | @mixin transition-property ($properties...) { 61 | -webkit-transition-property: transition-property-names($properties, 'webkit'); 62 | -moz-transition-property: transition-property-names($properties, 'moz'); 63 | transition-property: transition-property-names($properties, false); 64 | } 65 | 66 | @mixin transition-duration ($times...) { 67 | @include prefixer(transition-duration, $times, webkit moz spec); 68 | } 69 | 70 | @mixin transition-timing-function ($motions...) { 71 | // ease | linear | ease-in | ease-out | ease-in-out | cubic-bezier() 72 | @include prefixer(transition-timing-function, $motions, webkit moz spec); 73 | } 74 | 75 | @mixin transition-delay ($times...) { 76 | @include prefixer(transition-delay, $times, webkit moz spec); 77 | } 78 | -------------------------------------------------------------------------------- /css/bourbon/addons/_triangle.scss: -------------------------------------------------------------------------------- 1 | @mixin triangle ($size, $color, $direction) { 2 | height: 0; 3 | width: 0; 4 | 5 | $width: nth($size, 1); 6 | $height: nth($size, length($size)); 7 | 8 | $foreground-color: nth($color, 1); 9 | $background-color: if(length($color) == 2, nth($color, 2), transparent); 10 | 11 | @if ($direction == up) or ($direction == down) or ($direction == right) or ($direction == left) { 12 | 13 | $width: $width / 2; 14 | $height: if(length($size) > 1, $height, $height/2); 15 | 16 | @if $direction == up { 17 | border-left: $width solid $background-color; 18 | border-right: $width solid $background-color; 19 | border-bottom: $height solid $foreground-color; 20 | 21 | } @else if $direction == right { 22 | border-top: $width solid $background-color; 23 | border-bottom: $width solid $background-color; 24 | border-left: $height solid $foreground-color; 25 | 26 | } @else if $direction == down { 27 | border-left: $width solid $background-color; 28 | border-right: $width solid $background-color; 29 | border-top: $height solid $foreground-color; 30 | 31 | } @else if $direction == left { 32 | border-top: $width solid $background-color; 33 | border-bottom: $width solid $background-color; 34 | border-right: $height solid $foreground-color; 35 | } 36 | } 37 | 38 | @else if ($direction == up-right) or ($direction == up-left) { 39 | border-top: $height solid $foreground-color; 40 | 41 | @if $direction == up-right { 42 | border-left: $width solid $background-color; 43 | 44 | } @else if $direction == up-left { 45 | border-right: $width solid $background-color; 46 | } 47 | } 48 | 49 | @else if ($direction == down-right) or ($direction == down-left) { 50 | border-bottom: $height solid $foreground-color; 51 | 52 | @if $direction == down-right { 53 | border-left: $width solid $background-color; 54 | 55 | } @else if $direction == down-left { 56 | border-right: $width solid $background-color; 57 | } 58 | } 59 | 60 | @else if ($direction == inset-up) { 61 | border-width: $height $width; 62 | border-style: solid; 63 | border-color: $background-color $background-color $foreground-color; 64 | } 65 | 66 | @else if ($direction == inset-down) { 67 | border-width: $height $width; 68 | border-style: solid; 69 | border-color: $foreground-color $background-color $background-color; 70 | } 71 | 72 | @else if ($direction == inset-right) { 73 | border-width: $width $height; 74 | border-style: solid; 75 | border-color: $background-color $background-color $background-color $foreground-color; 76 | } 77 | 78 | @else if ($direction == inset-left) { 79 | border-width: $width $height; 80 | border-style: solid; 81 | border-color: $background-color $foreground-color $background-color $background-color; 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /css/fonts/icomoon/demo-files/demo.css: -------------------------------------------------------------------------------- 1 | body { 2 | padding: 0; 3 | margin: 0; 4 | font-family: sans-serif; 5 | font-size: 1em; 6 | line-height: 1.5; 7 | color: #555; 8 | background: #fff; 9 | } 10 | h1 { 11 | font-size: 1.5em; 12 | font-weight: normal; 13 | } 14 | small { 15 | font-size: .66666667em; 16 | } 17 | a { 18 | color: #e74c3c; 19 | text-decoration: none; 20 | } 21 | a:hover, a:focus { 22 | box-shadow: 0 1px #e74c3c; 23 | } 24 | .bshadow0, input { 25 | box-shadow: inset 0 -2px #e7e7e7; 26 | } 27 | input:hover { 28 | box-shadow: inset 0 -2px #ccc; 29 | } 30 | input, fieldset { 31 | font-family: sans-serif; 32 | font-size: 1em; 33 | margin: 0; 34 | padding: 0; 35 | border: 0; 36 | } 37 | input { 38 | color: inherit; 39 | line-height: 1.5; 40 | height: 1.5em; 41 | padding: .25em 0; 42 | } 43 | input:focus { 44 | outline: none; 45 | box-shadow: inset 0 -2px #449fdb; 46 | } 47 | .glyph { 48 | font-size: 16px; 49 | width: 15em; 50 | padding-bottom: 1em; 51 | margin-right: 4em; 52 | margin-bottom: 1em; 53 | float: left; 54 | overflow: hidden; 55 | } 56 | .liga { 57 | width: 80%; 58 | width: calc(100% - 2.5em); 59 | } 60 | .talign-right { 61 | text-align: right; 62 | } 63 | .talign-center { 64 | text-align: center; 65 | } 66 | .bgc1 { 67 | background: #f1f1f1; 68 | } 69 | .fgc1 { 70 | color: #999; 71 | } 72 | .fgc0 { 73 | color: #000; 74 | } 75 | p { 76 | margin-top: 1em; 77 | margin-bottom: 1em; 78 | } 79 | .mvm { 80 | margin-top: .75em; 81 | margin-bottom: .75em; 82 | } 83 | .mtn { 84 | margin-top: 0; 85 | } 86 | .mtl, .mal { 87 | margin-top: 1.5em; 88 | } 89 | .mbl, .mal { 90 | margin-bottom: 1.5em; 91 | } 92 | .mal, .mhl { 93 | margin-left: 1.5em; 94 | margin-right: 1.5em; 95 | } 96 | .mhmm { 97 | margin-left: 1em; 98 | margin-right: 1em; 99 | } 100 | .mls { 101 | margin-left: .25em; 102 | } 103 | .ptl { 104 | padding-top: 1.5em; 105 | } 106 | .pbs, .pvs { 107 | padding-bottom: .25em; 108 | } 109 | .pvs, .pts { 110 | padding-top: .25em; 111 | } 112 | .unit { 113 | float: left; 114 | } 115 | .unitRight { 116 | float: right; 117 | } 118 | .size1of2 { 119 | width: 50%; 120 | } 121 | .size1of1 { 122 | width: 100%; 123 | } 124 | .clearfix:before, .clearfix:after { 125 | content: " "; 126 | display: table; 127 | } 128 | .clearfix:after { 129 | clear: both; 130 | } 131 | .hidden-true { 132 | display: none; 133 | } 134 | .textbox0 { 135 | width: 3em; 136 | background: #f1f1f1; 137 | padding: .25em .5em; 138 | line-height: 1.5; 139 | height: 1.5em; 140 | } 141 | #testDrive { 142 | display: block; 143 | padding-top: 24px; 144 | line-height: 1.5; 145 | } 146 | .fs0 { 147 | font-size: 16px; 148 | } 149 | .fs1 { 150 | font-size: 32px; 151 | } 152 | 153 | -------------------------------------------------------------------------------- /css/bourbon/addons/_directional-values.scss: -------------------------------------------------------------------------------- 1 | // directional-property mixins are shorthands 2 | // for writing properties like the following 3 | // 4 | // @include margin(null 0 10px); 5 | // ------ 6 | // margin-right: 0; 7 | // margin-bottom: 10px; 8 | // margin-left: 0; 9 | // 10 | // - or - 11 | // 12 | // @include border-style(dotted null); 13 | // ------ 14 | // border-top-style: dotted; 15 | // border-bottom-style: dotted; 16 | // 17 | // ------ 18 | // 19 | // Note: You can also use false instead of null 20 | 21 | @function collapse-directionals($vals) { 22 | $output: null; 23 | 24 | $A: nth( $vals, 1 ); 25 | $B: if( length($vals) < 2, $A, nth($vals, 2)); 26 | $C: if( length($vals) < 3, $A, nth($vals, 3)); 27 | $D: if( length($vals) < 2, $A, nth($vals, if( length($vals) < 4, 2, 4) )); 28 | 29 | @if $A == 0 { $A: 0 } 30 | @if $B == 0 { $B: 0 } 31 | @if $C == 0 { $C: 0 } 32 | @if $D == 0 { $D: 0 } 33 | 34 | @if $A == $B and $A == $C and $A == $D { $output: $A } 35 | @else if $A == $C and $B == $D { $output: $A $B } 36 | @else if $B == $D { $output: $A $B $C } 37 | @else { $output: $A $B $C $D } 38 | 39 | @return $output; 40 | } 41 | 42 | @function contains-falsy($list) { 43 | @each $item in $list { 44 | @if not $item { 45 | @return true; 46 | } 47 | } 48 | 49 | @return false; 50 | } 51 | 52 | @mixin directional-property($pre, $suf, $vals) { 53 | // Property Names 54 | $top: $pre + "-top" + if($suf, "-#{$suf}", ""); 55 | $bottom: $pre + "-bottom" + if($suf, "-#{$suf}", ""); 56 | $left: $pre + "-left" + if($suf, "-#{$suf}", ""); 57 | $right: $pre + "-right" + if($suf, "-#{$suf}", ""); 58 | $all: $pre + if($suf, "-#{$suf}", ""); 59 | 60 | $vals: collapse-directionals($vals); 61 | 62 | @if contains-falsy($vals) { 63 | @if nth($vals, 1) { #{$top}: nth($vals, 1); } 64 | 65 | @if length($vals) == 1 { 66 | @if nth($vals, 1) { #{$right}: nth($vals, 1); } 67 | } @else { 68 | @if nth($vals, 2) { #{$right}: nth($vals, 2); } 69 | } 70 | 71 | // prop: top/bottom right/left 72 | @if length($vals) == 2 { 73 | @if nth($vals, 1) { #{$bottom}: nth($vals, 1); } 74 | @if nth($vals, 2) { #{$left}: nth($vals, 2); } 75 | 76 | // prop: top right/left bottom 77 | } @else if length($vals) == 3 { 78 | @if nth($vals, 3) { #{$bottom}: nth($vals, 3); } 79 | @if nth($vals, 2) { #{$left}: nth($vals, 2); } 80 | 81 | // prop: top right bottom left 82 | } @else if length($vals) == 4 { 83 | @if nth($vals, 3) { #{$bottom}: nth($vals, 3); } 84 | @if nth($vals, 4) { #{$left}: nth($vals, 4); } 85 | } 86 | 87 | // prop: top/right/bottom/left 88 | } @else { 89 | #{$all}: $vals; 90 | } 91 | } 92 | 93 | @mixin margin($vals...) { 94 | @include directional-property(margin, false, $vals...); 95 | } 96 | 97 | @mixin padding($vals...) { 98 | @include directional-property(padding, false, $vals...); 99 | } 100 | 101 | @mixin border-style($vals...) { 102 | @include directional-property(border, style, $vals...); 103 | } 104 | 105 | @mixin border-color($vals...) { 106 | @include directional-property(border, color, $vals...); 107 | } 108 | 109 | @mixin border-width($vals...) { 110 | @include directional-property(border, width, $vals...); 111 | } 112 | -------------------------------------------------------------------------------- /css/bourbon/addons/_html5-input-types.scss: -------------------------------------------------------------------------------- 1 | //************************************************************************// 2 | // Generate a variable ($all-text-inputs) with a list of all html5 3 | // input types that have a text-based input, excluding textarea. 4 | // http://diveintohtml5.org/forms.html 5 | //************************************************************************// 6 | $inputs-list: 'input[type="email"]', 7 | 'input[type="number"]', 8 | 'input[type="password"]', 9 | 'input[type="search"]', 10 | 'input[type="tel"]', 11 | 'input[type="text"]', 12 | 'input[type="url"]', 13 | 14 | // Webkit & Gecko may change the display of these in the future 15 | 'input[type="color"]', 16 | 'input[type="date"]', 17 | 'input[type="datetime"]', 18 | 'input[type="datetime-local"]', 19 | 'input[type="month"]', 20 | 'input[type="time"]', 21 | 'input[type="week"]'; 22 | 23 | // Bare inputs 24 | //************************************************************************// 25 | $all-text-inputs: assign-inputs($inputs-list); 26 | 27 | // Hover Pseudo-class 28 | //************************************************************************// 29 | $all-text-inputs-hover: assign-inputs($inputs-list, hover); 30 | 31 | // Focus Pseudo-class 32 | //************************************************************************// 33 | $all-text-inputs-focus: assign-inputs($inputs-list, focus); 34 | 35 | 36 | 37 | // You must use interpolation on the variable: 38 | // #{$all-text-inputs} 39 | // #{$all-text-inputs-hover} 40 | // #{$all-text-inputs-focus} 41 | 42 | // Example 43 | //************************************************************************// 44 | // #{$all-text-inputs}, textarea { 45 | // border: 1px solid red; 46 | // } 47 | 48 | 49 | 50 | //************************************************************************// 51 | // Generate a variable ($all-button-inputs) with a list of all html5 52 | // input types that have a button-based input, excluding button. 53 | //************************************************************************// 54 | $inputs-button-list: 'input[type="button"]', 55 | 'input[type="reset"]', 56 | 'input[type="submit"]'; 57 | 58 | // Bare inputs 59 | //************************************************************************// 60 | $all-button-inputs: assign-inputs($inputs-button-list); 61 | 62 | // Hover Pseudo-class 63 | //************************************************************************// 64 | $all-button-inputs-hover: assign-inputs($inputs-button-list, hover); 65 | 66 | // Focus Pseudo-class 67 | //************************************************************************// 68 | $all-button-inputs-focus: assign-inputs($inputs-button-list, focus); 69 | 70 | // Active Pseudo-class 71 | //************************************************************************// 72 | $all-button-inputs-active: assign-inputs($inputs-button-list, active); 73 | 74 | 75 | 76 | // You must use interpolation on the variable: 77 | // #{$all-button-inputs} 78 | // #{$all-button-inputs-hover} 79 | // #{$all-button-inputs-focus} 80 | // #{$all-button-inputs-active} 81 | 82 | // Example 83 | //************************************************************************// 84 | // #{$all-button-inputs}, button { 85 | // border: 1px solid red; 86 | // } 87 | -------------------------------------------------------------------------------- /css/main.css: -------------------------------------------------------------------------------- 1 | /* http://meyerweb.com/eric/tools/css/reset/ 2 | v2.0 | 20110126 3 | License: none (public domain) 4 | */ 5 | html, body, div, span, applet, object, iframe, 6 | h1, h2, h3, h4, h5, h6, p, blockquote, pre, 7 | a, abbr, acronym, address, big, cite, code, 8 | del, dfn, em, img, ins, kbd, q, s, samp, 9 | small, strike, strong, sub, sup, tt, var, 10 | b, u, i, center, 11 | dl, dt, dd, ol, ul, li, 12 | fieldset, form, label, legend, 13 | table, caption, tbody, tfoot, thead, tr, th, td, 14 | article, aside, canvas, details, embed, 15 | figure, figcaption, footer, header, hgroup, 16 | menu, nav, output, ruby, section, summary, 17 | time, mark, audio, video { 18 | margin: 0; 19 | padding: 0; 20 | border: 0; 21 | font-size: 100%; 22 | font: inherit; 23 | vertical-align: baseline; 24 | } 25 | 26 | /* HTML5 display-role reset for older browsers */ 27 | article, aside, details, figcaption, figure, 28 | footer, header, hgroup, menu, nav, section { 29 | display: block; 30 | } 31 | 32 | body { 33 | line-height: 1; 34 | } 35 | 36 | ol, ul { 37 | list-style: none; 38 | } 39 | 40 | blockquote, q { 41 | quotes: none; 42 | } 43 | 44 | blockquote:before, blockquote:after, 45 | q:before, q:after { 46 | content: ''; 47 | content: none; 48 | } 49 | 50 | table { 51 | border-collapse: collapse; 52 | border-spacing: 0; 53 | } 54 | 55 | * { 56 | outline: none; 57 | -webkit-font-smoothing: antialiased; 58 | -moz-osx-font-smoothing: grayscale; 59 | box-sizing: border-box; 60 | -webkit-box-sizing: border-box; 61 | -moz-box-sizing: border-box; 62 | -webkit-tap-highlight-color: transparent; 63 | letter-spacing: 0px; 64 | } 65 | 66 | @font-face { 67 | font-family: 'icomoon'; 68 | src: url("./fonts/icomoon/fonts/icomoon.eot?9d6p5j"); 69 | src: url("./fonts/icomoon/fonts/icomoon.eot?#iefix9d6p5j") format("embedded-opentype"), url("./fonts/icomoon/fonts/icomoon.ttf?9d6p5j") format("truetype"), url("./fonts/icomoon/fonts/icomoon.woff?9d6p5j") format("woff"), url("./fonts/icomoon/fonts/icomoon.svg?9d6p5j#icomoon") format("svg"); 70 | font-weight: normal; 71 | font-style: normal; 72 | } 73 | 74 | [class^=""], [class*=" "] { 75 | /* Better Font Rendering =========== */ 76 | -webkit-font-smoothing: antialiased; 77 | -moz-osx-font-smoothing: grayscale; 78 | } 79 | 80 | .clear-day:before { 81 | content: "\e600"; 82 | } 83 | 84 | .clear-night:before { 85 | content: "\e601"; 86 | } 87 | 88 | .cloudy:before { 89 | content: "\e602"; 90 | } 91 | 92 | .fog:before { 93 | content: "\e603"; 94 | } 95 | 96 | .partly-cloudy-day:before { 97 | content: "\e604"; 98 | } 99 | 100 | .partly-cloudy-night:before { 101 | content: "\e605"; 102 | } 103 | 104 | .rain:before { 105 | content: "\e606"; 106 | } 107 | 108 | .sleet:before { 109 | content: "\e607"; 110 | } 111 | 112 | .snow:before { 113 | content: "\e608"; 114 | } 115 | 116 | .wind:before { 117 | content: "\e609"; 118 | } 119 | 120 | html, body { 121 | font-family: 'Roboto Condensed', sans-serif; 122 | background: black; 123 | text-align: right; 124 | color: white; 125 | padding: 20px; 126 | padding-top: 40px; 127 | padding-right: 40px; 128 | } 129 | 130 | body { 131 | opacity: 0; 132 | } 133 | 134 | body.active { 135 | opacity: 1; 136 | -webkit-transition: opacity 0.2s; 137 | -moz-transition: opacity 0.2s; 138 | transition: opacity 0.2s; 139 | } 140 | 141 | .weather, .subway { 142 | margin-bottom: 40px; 143 | } 144 | 145 | .clock .date { 146 | font-size: 52px; 147 | margin-bottom: 20px; 148 | } 149 | 150 | .clock .time { 151 | font-size: 128px; 152 | font-weight: bold; 153 | margin-bottom: 15px; 154 | } 155 | 156 | .clock .time > span { 157 | font-size: 24px; 158 | margin-left: 5px; 159 | font-weight: normal; 160 | } 161 | 162 | .weather { 163 | font-size: 100px; 164 | } 165 | 166 | .weather:before { 167 | margin-right: 20px; 168 | font-family: 'icomoon'; 169 | } 170 | 171 | .subway { 172 | font-size: 52px; 173 | } 174 | 175 | .subway img { 176 | margin-right: 20px; 177 | } 178 | 179 | .news h3 { 180 | font-size: 48px; 181 | text-decoration: underline; 182 | } 183 | 184 | .news ul { 185 | position: relative; 186 | min-height: 100px; 187 | } 188 | 189 | .news ul li { 190 | right: 0; 191 | top: 20px; 192 | opacity: 0; 193 | font-size: 36px; 194 | position: absolute; 195 | -webkit-transition: opacity 0.5s; 196 | -moz-transition: opacity 0.5s; 197 | transition: opacity 0.5s; 198 | } 199 | 200 | .news ul li.active { 201 | opacity: 1; 202 | -webkit-transition: opacity 1s; 203 | -moz-transition: opacity 1s; 204 | transition: opacity 1s; 205 | } 206 | 207 | .stocks:before { 208 | font-size: 52px; 209 | content: '\e900'; 210 | margin-top: -16px; 211 | margin-right: 10px; 212 | display: inline-block; 213 | font-family: 'icomoon'; 214 | } 215 | 216 | .stocks .slider { 217 | float: right; 218 | overflow: hidden; 219 | display: inline-block; 220 | } 221 | 222 | .stocks ul { 223 | left: 0px; 224 | position: relative; 225 | -webkit-transform: translateZ(0); 226 | -moz-transform: translateZ(0); 227 | -ms-transform: translateZ(0); 228 | -o-transform: translateZ(0); 229 | transform: translateZ(0); 230 | } 231 | 232 | .stocks ul:after { 233 | content: ""; 234 | display: table; 235 | clear: both; 236 | } 237 | 238 | .stocks ul li.stock { 239 | float: left; 240 | font-size: 24px; 241 | padding-left: 20px; 242 | } 243 | 244 | .stocks ul li.stock:first-child { 245 | margin-left: 0px; 246 | } 247 | 248 | .stocks ul li.stock:before { 249 | content: ''; 250 | display: inline-block; 251 | height: 0; 252 | width: 0; 253 | border-left: 5px solid transparent; 254 | border-right: 5px solid transparent; 255 | border-top: 5px solid #f34146; 256 | } 257 | 258 | .stocks ul li.stock.up { 259 | color: #81c14f; 260 | } 261 | 262 | .stocks ul li.stock.up:before { 263 | height: 0; 264 | width: 0; 265 | border-left: 0px solid transparent; 266 | border-right: 0px solid transparent; 267 | border-top: 0px solid #f34146; 268 | height: 0; 269 | width: 0; 270 | border-left: 5px solid transparent; 271 | border-right: 5px solid transparent; 272 | border-bottom: 5px solid #81c14f; 273 | } 274 | 275 | .stocks ul li.stock.down { 276 | color: #f34146; 277 | } 278 | -------------------------------------------------------------------------------- /css/bourbon/css3/_flex-box.scss: -------------------------------------------------------------------------------- 1 | // CSS3 Flexible Box Model and property defaults 2 | 3 | // Custom shorthand notation for flexbox 4 | @mixin box($orient: inline-axis, $pack: start, $align: stretch) { 5 | @include display-box; 6 | @include box-orient($orient); 7 | @include box-pack($pack); 8 | @include box-align($align); 9 | } 10 | 11 | @mixin display-box { 12 | display: -webkit-box; 13 | display: -moz-box; 14 | display: -ms-flexbox; // IE 10 15 | display: box; 16 | } 17 | 18 | @mixin box-orient($orient: inline-axis) { 19 | // horizontal|vertical|inline-axis|block-axis|inherit 20 | @include prefixer(box-orient, $orient, webkit moz spec); 21 | } 22 | 23 | @mixin box-pack($pack: start) { 24 | // start|end|center|justify 25 | @include prefixer(box-pack, $pack, webkit moz spec); 26 | -ms-flex-pack: $pack; // IE 10 27 | } 28 | 29 | @mixin box-align($align: stretch) { 30 | // start|end|center|baseline|stretch 31 | @include prefixer(box-align, $align, webkit moz spec); 32 | -ms-flex-align: $align; // IE 10 33 | } 34 | 35 | @mixin box-direction($direction: normal) { 36 | // normal|reverse|inherit 37 | @include prefixer(box-direction, $direction, webkit moz spec); 38 | -ms-flex-direction: $direction; // IE 10 39 | } 40 | 41 | @mixin box-lines($lines: single) { 42 | // single|multiple 43 | @include prefixer(box-lines, $lines, webkit moz spec); 44 | } 45 | 46 | @mixin box-ordinal-group($int: 1) { 47 | @include prefixer(box-ordinal-group, $int, webkit moz spec); 48 | -ms-flex-order: $int; // IE 10 49 | } 50 | 51 | @mixin box-flex($value: 0.0) { 52 | @include prefixer(box-flex, $value, webkit moz spec); 53 | -ms-flex: $value; // IE 10 54 | } 55 | 56 | @mixin box-flex-group($int: 1) { 57 | @include prefixer(box-flex-group, $int, webkit moz spec); 58 | } 59 | 60 | // CSS3 Flexible Box Model and property defaults 61 | // Unified attributes for 2009, 2011, and 2012 flavours. 62 | 63 | // 2009 - display (box | inline-box) 64 | // 2011 - display (flexbox | inline-flexbox) 65 | // 2012 - display (flex | inline-flex) 66 | @mixin display($value) { 67 | // flex | inline-flex 68 | @if $value == "flex" { 69 | // 2009 70 | display: -webkit-box; 71 | display: -moz-box; 72 | display: box; 73 | 74 | // 2012 75 | display: -webkit-flex; 76 | display: -moz-flex; 77 | display: -ms-flexbox; // 2011 (IE 10) 78 | display: flex; 79 | } 80 | 81 | @elseif $value == "inline-flex" { 82 | display: -webkit-inline-box; 83 | display: -moz-inline-box; 84 | display: inline-box; 85 | 86 | display: -webkit-inline-flex; 87 | display: -moz-inline-flex; 88 | display: -ms-inline-flexbox; 89 | display: inline-flex; 90 | } 91 | 92 | @else { 93 | display: $value; 94 | } 95 | } 96 | 97 | // 2009 - box-flex (integer) 98 | // 2011 - flex (decimal | width decimal) 99 | // 2012 - flex (integer integer width) 100 | @mixin flex($value) { 101 | 102 | // Grab flex-grow for older browsers. 103 | $flex-grow: nth($value, 1); 104 | 105 | // 2009 106 | @include prefixer(box-flex, $flex-grow, webkit moz spec); 107 | 108 | // 2011 (IE 10), 2012 109 | @include prefixer(flex, $value, webkit moz ms spec); 110 | } 111 | 112 | // 2009 - box-orient ( horizontal | vertical | inline-axis | block-axis) 113 | // - box-direction (normal | reverse) 114 | // 2011 - flex-direction (row | row-reverse | column | column-reverse) 115 | // 2012 - flex-direction (row | row-reverse | column | column-reverse) 116 | @mixin flex-direction($value: row) { 117 | 118 | // Alt values. 119 | $value-2009: $value; 120 | $value-2011: $value; 121 | $direction: "normal"; 122 | 123 | @if $value == row { 124 | $value-2009: horizontal; 125 | } 126 | 127 | @elseif $value == "row-reverse" { 128 | $value-2009: horizontal; 129 | $direction: reverse; 130 | } 131 | 132 | @elseif $value == column { 133 | $value-2009: vertical; 134 | } 135 | 136 | @elseif $value == "column-reverse" { 137 | $value-2009: vertical; 138 | $direction: reverse; 139 | } 140 | 141 | // 2009 142 | @include prefixer(box-orient, $value-2009, webkit moz spec); 143 | @if $direction == "reverse" { 144 | @include prefixer(box-direction, $direction, webkit moz spec); 145 | } 146 | 147 | // 2012 148 | @include prefixer(flex-direction, $value, webkit moz spec); 149 | 150 | // 2011 (IE 10) 151 | -ms-flex-direction: $value; 152 | } 153 | 154 | // 2009 - box-lines (single | multiple) 155 | // 2011 - flex-wrap (nowrap | wrap | wrap-reverse) 156 | // 2012 - flex-wrap (nowrap | wrap | wrap-reverse) 157 | @mixin flex-wrap($value: nowrap) { 158 | 159 | // Alt values. 160 | $alt-value: $value; 161 | @if $value == nowrap { 162 | $alt-value: single; 163 | } 164 | 165 | @elseif $value == wrap { 166 | $alt-value: multiple; 167 | } 168 | 169 | @elseif $value == "wrap-reverse" { 170 | $alt-value: multiple; 171 | } 172 | 173 | @include prefixer(box-lines, $alt-value, webkit moz spec); 174 | @include prefixer(flex-wrap, $value, webkit moz ms spec); 175 | } 176 | 177 | // 2009 - TODO: parse values into flex-direction/flex-wrap 178 | // 2011 - TODO: parse values into flex-direction/flex-wrap 179 | // 2012 - flex-flow (flex-direction || flex-wrap) 180 | @mixin flex-flow($value) { 181 | @include prefixer(flex-flow, $value, webkit moz spec); 182 | } 183 | 184 | // 2009 - box-ordinal-group (integer) 185 | // 2011 - flex-order (integer) 186 | // 2012 - order (integer) 187 | @mixin order($int: 0) { 188 | // 2009 189 | @include prefixer(box-ordinal-group, $int, webkit moz spec); 190 | 191 | // 2012 192 | @include prefixer(order, $int, webkit moz spec); 193 | 194 | // 2011 (IE 10) 195 | -ms-flex-order: $int; 196 | } 197 | 198 | // 2012 - flex-grow (number) 199 | @mixin flex-grow($number: 0) { 200 | @include prefixer(flex-grow, $number, webkit moz spec); 201 | -ms-flex-positive: $number; 202 | } 203 | 204 | // 2012 - flex-shrink (number) 205 | @mixin flex-shrink($number: 1) { 206 | @include prefixer(flex-shrink, $number, webkit moz spec); 207 | -ms-flex-negative: $number; 208 | } 209 | 210 | // 2012 - flex-basis (number) 211 | @mixin flex-basis($width: auto) { 212 | @include prefixer(flex-basis, $width, webkit moz spec); 213 | -ms-flex-preferred-size: $width; 214 | } 215 | 216 | // 2009 - box-pack (start | end | center | justify) 217 | // 2011 - flex-pack (start | end | center | justify) 218 | // 2012 - justify-content (flex-start | flex-end | center | space-between | space-around) 219 | @mixin justify-content ($value: flex-start) { 220 | 221 | // Alt values. 222 | $alt-value: $value; 223 | @if $value == "flex-start" { 224 | $alt-value: start; 225 | } 226 | 227 | @elseif $value == "flex-end" { 228 | $alt-value: end; 229 | } 230 | 231 | @elseif $value == "space-between" { 232 | $alt-value: justify; 233 | } 234 | 235 | @elseif $value == "space-around" { 236 | $alt-value: center; 237 | } 238 | 239 | // 2009 240 | @include prefixer(box-pack, $alt-value, webkit moz spec); 241 | 242 | // 2012 243 | @include prefixer(justify-content, $value, webkit moz ms o spec); 244 | 245 | // 2011 (IE 10) 246 | -ms-flex-pack: $alt-value; 247 | } 248 | 249 | // 2009 - box-align (start | end | center | baseline | stretch) 250 | // 2011 - flex-align (start | end | center | baseline | stretch) 251 | // 2012 - align-items (flex-start | flex-end | center | baseline | stretch) 252 | @mixin align-items($value: stretch) { 253 | 254 | $alt-value: $value; 255 | 256 | @if $value == "flex-start" { 257 | $alt-value: start; 258 | } 259 | 260 | @elseif $value == "flex-end" { 261 | $alt-value: end; 262 | } 263 | 264 | // 2009 265 | @include prefixer(box-align, $alt-value, webkit moz spec); 266 | 267 | // 2012 268 | @include prefixer(align-items, $value, webkit moz ms o spec); 269 | 270 | // 2011 (IE 10) 271 | -ms-flex-align: $alt-value; 272 | } 273 | 274 | // 2011 - flex-item-align (auto | start | end | center | baseline | stretch) 275 | // 2012 - align-self (auto | flex-start | flex-end | center | baseline | stretch) 276 | @mixin align-self($value: auto) { 277 | 278 | $value-2011: $value; 279 | @if $value == "flex-start" { 280 | $value-2011: start; 281 | } 282 | 283 | @elseif $value == "flex-end" { 284 | $value-2011: end; 285 | } 286 | 287 | // 2012 288 | @include prefixer(align-self, $value, webkit moz spec); 289 | 290 | // 2011 (IE 10) 291 | -ms-flex-item-align: $value-2011; 292 | } 293 | 294 | // 2011 - flex-line-pack (start | end | center | justify | distribute | stretch) 295 | // 2012 - align-content (flex-start | flex-end | center | space-between | space-around | stretch) 296 | @mixin align-content($value: stretch) { 297 | 298 | $value-2011: $value; 299 | @if $value == "flex-start" { 300 | $value-2011: start; 301 | } 302 | 303 | @elseif $value == "flex-end" { 304 | $value-2011: end; 305 | } 306 | 307 | @elseif $value == "space-between" { 308 | $value-2011: justify; 309 | } 310 | 311 | @elseif $value == "space-around" { 312 | $value-2011: distribute; 313 | } 314 | 315 | // 2012 316 | @include prefixer(align-content, $value, webkit moz spec); 317 | 318 | // 2011 (IE 10) 319 | -ms-flex-line-pack: $value-2011; 320 | } 321 | 322 | -------------------------------------------------------------------------------- /css/fonts/icomoon/demo.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IcoMoon Demo 6 | 7 | 8 | 9 | 10 | 11 |
    12 |

    Font Name: icomoon (Glyphs: 11)

    13 |
    14 |
    15 |

    Grid Size: Unknown

    16 |
    17 |
    18 | 19 | 20 | 21 | icon-stock-graph 22 |
    23 |
    24 | 25 | 26 |
    27 |
    28 | liga: 29 | 30 |
    31 |
    32 |
    33 |
    34 | 35 | 36 | 37 | icon-clear-day 38 |
    39 |
    40 | 41 | 42 |
    43 |
    44 | liga: 45 | 46 |
    47 |
    48 |
    49 |
    50 | 51 | 52 | 53 | icon-clear-night 54 |
    55 |
    56 | 57 | 58 |
    59 |
    60 | liga: 61 | 62 |
    63 |
    64 |
    65 |
    66 | 67 | 68 | 69 | icon-cloudy 70 |
    71 |
    72 | 73 | 74 |
    75 |
    76 | liga: 77 | 78 |
    79 |
    80 |
    81 |
    82 | 83 | 84 | 85 | icon-fog 86 |
    87 |
    88 | 89 | 90 |
    91 |
    92 | liga: 93 | 94 |
    95 |
    96 |
    97 |
    98 | 99 | 100 | 101 | icon-partly-cloudy-day 102 |
    103 |
    104 | 105 | 106 |
    107 |
    108 | liga: 109 | 110 |
    111 |
    112 |
    113 |
    114 | 115 | 116 | 117 | icon-partly-cloudy-night 118 |
    119 |
    120 | 121 | 122 |
    123 |
    124 | liga: 125 | 126 |
    127 |
    128 |
    129 |
    130 | 131 | 132 | 133 | icon-rain 134 |
    135 |
    136 | 137 | 138 |
    139 |
    140 | liga: 141 | 142 |
    143 |
    144 |
    145 |
    146 | 147 | 148 | 149 | icon-sleet 150 |
    151 |
    152 | 153 | 154 |
    155 |
    156 | liga: 157 | 158 |
    159 |
    160 |
    161 |
    162 | 163 | 164 | 165 | icon-snow 166 |
    167 |
    168 | 169 | 170 |
    171 |
    172 | liga: 173 | 174 |
    175 |
    176 |
    177 |
    178 | 179 | 180 | 181 | icon-wind 182 |
    183 |
    184 | 185 | 186 |
    187 |
    188 | liga: 189 | 190 |
    191 |
    192 |
    193 | 194 | 195 |
    196 |

    Font Test Drive

    197 | 202 | 204 | 205 |
      206 |
    207 |
    208 | 209 |
    210 |

    Generated by IcoMoon

    211 |
    212 | 213 | 214 | 215 | 216 | -------------------------------------------------------------------------------- /css/bourbon/addons/_button.scss: -------------------------------------------------------------------------------- 1 | @mixin button ($style: simple, $base-color: #4294f0, $text-size: inherit, $padding: 7px 18px) { 2 | 3 | @if type-of($style) == string and type-of($base-color) == color { 4 | @include buttonstyle($style, $base-color, $text-size, $padding); 5 | } 6 | 7 | @if type-of($style) == string and type-of($base-color) == number { 8 | $padding: $text-size; 9 | $text-size: $base-color; 10 | $base-color: #4294f0; 11 | 12 | @if $padding == inherit { 13 | $padding: 7px 18px; 14 | } 15 | 16 | @include buttonstyle($style, $base-color, $text-size, $padding); 17 | } 18 | 19 | @if type-of($style) == color and type-of($base-color) == color { 20 | $base-color: $style; 21 | $style: simple; 22 | @include buttonstyle($style, $base-color, $text-size, $padding); 23 | } 24 | 25 | @if type-of($style) == color and type-of($base-color) == number { 26 | $padding: $text-size; 27 | $text-size: $base-color; 28 | $base-color: $style; 29 | $style: simple; 30 | 31 | @if $padding == inherit { 32 | $padding: 7px 18px; 33 | } 34 | 35 | @include buttonstyle($style, $base-color, $text-size, $padding); 36 | } 37 | 38 | @if type-of($style) == number { 39 | $padding: $base-color; 40 | $text-size: $style; 41 | $base-color: #4294f0; 42 | $style: simple; 43 | 44 | @if $padding == #4294f0 { 45 | $padding: 7px 18px; 46 | } 47 | 48 | @include buttonstyle($style, $base-color, $text-size, $padding); 49 | } 50 | 51 | &:disabled { 52 | opacity: 0.5; 53 | cursor: not-allowed; 54 | } 55 | } 56 | 57 | 58 | // Selector Style Button 59 | //************************************************************************// 60 | @mixin buttonstyle($type, $b-color, $t-size, $pad) { 61 | // Grayscale button 62 | @if $type == simple and $b-color == grayscale($b-color) { 63 | @include simple($b-color, true, $t-size, $pad); 64 | } 65 | 66 | @if $type == shiny and $b-color == grayscale($b-color) { 67 | @include shiny($b-color, true, $t-size, $pad); 68 | } 69 | 70 | @if $type == pill and $b-color == grayscale($b-color) { 71 | @include pill($b-color, true, $t-size, $pad); 72 | } 73 | 74 | @if $type == flat and $b-color == grayscale($b-color) { 75 | @include flat($b-color, true, $t-size, $pad); 76 | } 77 | 78 | // Colored button 79 | @if $type == simple { 80 | @include simple($b-color, false, $t-size, $pad); 81 | } 82 | 83 | @else if $type == shiny { 84 | @include shiny($b-color, false, $t-size, $pad); 85 | } 86 | 87 | @else if $type == pill { 88 | @include pill($b-color, false, $t-size, $pad); 89 | } 90 | 91 | @else if $type == flat { 92 | @include flat($b-color, false, $t-size, $pad); 93 | } 94 | } 95 | 96 | 97 | // Simple Button 98 | //************************************************************************// 99 | @mixin simple($base-color, $grayscale: false, $textsize: inherit, $padding: 7px 18px) { 100 | $color: hsl(0, 0, 100%); 101 | $border: adjust-color($base-color, $saturation: 9%, $lightness: -14%); 102 | $inset-shadow: adjust-color($base-color, $saturation: -8%, $lightness: 15%); 103 | $stop-gradient: adjust-color($base-color, $saturation: 9%, $lightness: -11%); 104 | $text-shadow: adjust-color($base-color, $saturation: 15%, $lightness: -18%); 105 | 106 | @if is-light($base-color) { 107 | $color: hsl(0, 0, 20%); 108 | $text-shadow: adjust-color($base-color, $saturation: 10%, $lightness: 4%); 109 | } 110 | 111 | @if $grayscale == true { 112 | $border: grayscale($border); 113 | $inset-shadow: grayscale($inset-shadow); 114 | $stop-gradient: grayscale($stop-gradient); 115 | $text-shadow: grayscale($text-shadow); 116 | } 117 | 118 | border: 1px solid $border; 119 | border-radius: 3px; 120 | box-shadow: inset 0 1px 0 0 $inset-shadow; 121 | color: $color; 122 | display: inline-block; 123 | font-size: $textsize; 124 | font-weight: bold; 125 | @include linear-gradient ($base-color, $stop-gradient); 126 | padding: $padding; 127 | text-decoration: none; 128 | text-shadow: 0 1px 0 $text-shadow; 129 | background-clip: padding-box; 130 | 131 | &:hover:not(:disabled) { 132 | $base-color-hover: adjust-color($base-color, $saturation: -4%, $lightness: -5%); 133 | $inset-shadow-hover: adjust-color($base-color, $saturation: -7%, $lightness: 5%); 134 | $stop-gradient-hover: adjust-color($base-color, $saturation: 8%, $lightness: -14%); 135 | 136 | @if $grayscale == true { 137 | $base-color-hover: grayscale($base-color-hover); 138 | $inset-shadow-hover: grayscale($inset-shadow-hover); 139 | $stop-gradient-hover: grayscale($stop-gradient-hover); 140 | } 141 | 142 | box-shadow: inset 0 1px 0 0 $inset-shadow-hover; 143 | cursor: pointer; 144 | @include linear-gradient ($base-color-hover, $stop-gradient-hover); 145 | } 146 | 147 | &:active:not(:disabled), 148 | &:focus:not(:disabled) { 149 | $border-active: adjust-color($base-color, $saturation: 9%, $lightness: -14%); 150 | $inset-shadow-active: adjust-color($base-color, $saturation: 7%, $lightness: -17%); 151 | 152 | @if $grayscale == true { 153 | $border-active: grayscale($border-active); 154 | $inset-shadow-active: grayscale($inset-shadow-active); 155 | } 156 | 157 | border: 1px solid $border-active; 158 | box-shadow: inset 0 0 8px 4px $inset-shadow-active, inset 0 0 8px 4px $inset-shadow-active; 159 | } 160 | } 161 | 162 | 163 | // Shiny Button 164 | //************************************************************************// 165 | @mixin shiny($base-color, $grayscale: false, $textsize: inherit, $padding: 7px 18px) { 166 | $color: hsl(0, 0, 100%); 167 | $border: adjust-color($base-color, $red: -117, $green: -111, $blue: -81); 168 | $border-bottom: adjust-color($base-color, $red: -126, $green: -127, $blue: -122); 169 | $fourth-stop: adjust-color($base-color, $red: -79, $green: -70, $blue: -46); 170 | $inset-shadow: adjust-color($base-color, $red: 37, $green: 29, $blue: 12); 171 | $second-stop: adjust-color($base-color, $red: -56, $green: -50, $blue: -33); 172 | $text-shadow: adjust-color($base-color, $red: -140, $green: -141, $blue: -114); 173 | $third-stop: adjust-color($base-color, $red: -86, $green: -75, $blue: -48); 174 | 175 | @if is-light($base-color) { 176 | $color: hsl(0, 0, 20%); 177 | $text-shadow: adjust-color($base-color, $saturation: 10%, $lightness: 4%); 178 | } 179 | 180 | @if $grayscale == true { 181 | $border: grayscale($border); 182 | $border-bottom: grayscale($border-bottom); 183 | $fourth-stop: grayscale($fourth-stop); 184 | $inset-shadow: grayscale($inset-shadow); 185 | $second-stop: grayscale($second-stop); 186 | $text-shadow: grayscale($text-shadow); 187 | $third-stop: grayscale($third-stop); 188 | } 189 | 190 | border: 1px solid $border; 191 | border-bottom: 1px solid $border-bottom; 192 | border-radius: 5px; 193 | box-shadow: inset 0 1px 0 0 $inset-shadow; 194 | color: $color; 195 | display: inline-block; 196 | font-size: $textsize; 197 | font-weight: bold; 198 | @include linear-gradient(top, $base-color 0%, $second-stop 50%, $third-stop 50%, $fourth-stop 100%); 199 | padding: $padding; 200 | text-align: center; 201 | text-decoration: none; 202 | text-shadow: 0 -1px 1px $text-shadow; 203 | 204 | &:hover:not(:disabled) { 205 | $first-stop-hover: adjust-color($base-color, $red: -13, $green: -15, $blue: -18); 206 | $second-stop-hover: adjust-color($base-color, $red: -66, $green: -62, $blue: -51); 207 | $third-stop-hover: adjust-color($base-color, $red: -93, $green: -85, $blue: -66); 208 | $fourth-stop-hover: adjust-color($base-color, $red: -86, $green: -80, $blue: -63); 209 | 210 | @if $grayscale == true { 211 | $first-stop-hover: grayscale($first-stop-hover); 212 | $second-stop-hover: grayscale($second-stop-hover); 213 | $third-stop-hover: grayscale($third-stop-hover); 214 | $fourth-stop-hover: grayscale($fourth-stop-hover); 215 | } 216 | 217 | cursor: pointer; 218 | @include linear-gradient(top, $first-stop-hover 0%, 219 | $second-stop-hover 50%, 220 | $third-stop-hover 50%, 221 | $fourth-stop-hover 100%); 222 | } 223 | 224 | &:active:not(:disabled), 225 | &:focus:not(:disabled) { 226 | $inset-shadow-active: adjust-color($base-color, $red: -111, $green: -116, $blue: -122); 227 | 228 | @if $grayscale == true { 229 | $inset-shadow-active: grayscale($inset-shadow-active); 230 | } 231 | 232 | box-shadow: inset 0 0 20px 0 $inset-shadow-active; 233 | } 234 | } 235 | 236 | 237 | // Pill Button 238 | //************************************************************************// 239 | @mixin pill($base-color, $grayscale: false, $textsize: inherit, $padding: 7px 18px) { 240 | $color: hsl(0, 0, 100%); 241 | $border-bottom: adjust-color($base-color, $hue: 8, $saturation: -11%, $lightness: -26%); 242 | $border-sides: adjust-color($base-color, $hue: 4, $saturation: -21%, $lightness: -21%); 243 | $border-top: adjust-color($base-color, $hue: -1, $saturation: -30%, $lightness: -15%); 244 | $inset-shadow: adjust-color($base-color, $hue: -1, $saturation: -1%, $lightness: 7%); 245 | $stop-gradient: adjust-color($base-color, $hue: 8, $saturation: 14%, $lightness: -10%); 246 | $text-shadow: adjust-color($base-color, $hue: 5, $saturation: -19%, $lightness: -15%); 247 | 248 | @if is-light($base-color) { 249 | $color: hsl(0, 0, 20%); 250 | $text-shadow: adjust-color($base-color, $saturation: 10%, $lightness: 4%); 251 | } 252 | 253 | @if $grayscale == true { 254 | $border-bottom: grayscale($border-bottom); 255 | $border-sides: grayscale($border-sides); 256 | $border-top: grayscale($border-top); 257 | $inset-shadow: grayscale($inset-shadow); 258 | $stop-gradient: grayscale($stop-gradient); 259 | $text-shadow: grayscale($text-shadow); 260 | } 261 | 262 | border: 1px solid $border-top; 263 | border-color: $border-top $border-sides $border-bottom; 264 | border-radius: 16px; 265 | box-shadow: inset 0 1px 0 0 $inset-shadow; 266 | color: $color; 267 | display: inline-block; 268 | font-size: $textsize; 269 | font-weight: normal; 270 | line-height: 1; 271 | @include linear-gradient ($base-color, $stop-gradient); 272 | padding: $padding; 273 | text-align: center; 274 | text-decoration: none; 275 | text-shadow: 0 -1px 1px $text-shadow; 276 | background-clip: padding-box; 277 | 278 | &:hover:not(:disabled) { 279 | $base-color-hover: adjust-color($base-color, $lightness: -4.5%); 280 | $border-bottom: adjust-color($base-color, $hue: 8, $saturation: 13.5%, $lightness: -32%); 281 | $border-sides: adjust-color($base-color, $hue: 4, $saturation: -2%, $lightness: -27%); 282 | $border-top: adjust-color($base-color, $hue: -1, $saturation: -17%, $lightness: -21%); 283 | $inset-shadow-hover: adjust-color($base-color, $saturation: -1%, $lightness: 3%); 284 | $stop-gradient-hover: adjust-color($base-color, $hue: 8, $saturation: -4%, $lightness: -15.5%); 285 | $text-shadow-hover: adjust-color($base-color, $hue: 5, $saturation: -5%, $lightness: -22%); 286 | 287 | @if $grayscale == true { 288 | $base-color-hover: grayscale($base-color-hover); 289 | $border-bottom: grayscale($border-bottom); 290 | $border-sides: grayscale($border-sides); 291 | $border-top: grayscale($border-top); 292 | $inset-shadow-hover: grayscale($inset-shadow-hover); 293 | $stop-gradient-hover: grayscale($stop-gradient-hover); 294 | $text-shadow-hover: grayscale($text-shadow-hover); 295 | } 296 | 297 | border: 1px solid $border-top; 298 | border-color: $border-top $border-sides $border-bottom; 299 | box-shadow: inset 0 1px 0 0 $inset-shadow-hover; 300 | cursor: pointer; 301 | @include linear-gradient ($base-color-hover, $stop-gradient-hover); 302 | text-shadow: 0 -1px 1px $text-shadow-hover; 303 | background-clip: padding-box; 304 | } 305 | 306 | &:active:not(:disabled), 307 | &:focus:not(:disabled) { 308 | $active-color: adjust-color($base-color, $hue: 4, $saturation: -12%, $lightness: -10%); 309 | $border-active: adjust-color($base-color, $hue: 6, $saturation: -2.5%, $lightness: -30%); 310 | $border-bottom-active: adjust-color($base-color, $hue: 11, $saturation: 6%, $lightness: -31%); 311 | $inset-shadow-active: adjust-color($base-color, $hue: 9, $saturation: 2%, $lightness: -21.5%); 312 | $text-shadow-active: adjust-color($base-color, $hue: 5, $saturation: -12%, $lightness: -21.5%); 313 | 314 | @if $grayscale == true { 315 | $active-color: grayscale($active-color); 316 | $border-active: grayscale($border-active); 317 | $border-bottom-active: grayscale($border-bottom-active); 318 | $inset-shadow-active: grayscale($inset-shadow-active); 319 | $text-shadow-active: grayscale($text-shadow-active); 320 | } 321 | 322 | background: $active-color; 323 | border: 1px solid $border-active; 324 | border-bottom: 1px solid $border-bottom-active; 325 | box-shadow: inset 0 0 6px 3px $inset-shadow-active; 326 | text-shadow: 0 -1px 1px $text-shadow-active; 327 | } 328 | } 329 | 330 | 331 | 332 | // Flat Button 333 | //************************************************************************// 334 | @mixin flat($base-color, $grayscale: false, $textsize: inherit, $padding: 7px 18px) { 335 | $color: hsl(0, 0, 100%); 336 | 337 | @if is-light($base-color) { 338 | $color: hsl(0, 0, 20%); 339 | } 340 | 341 | background-color: $base-color; 342 | border-radius: 3px; 343 | border: none; 344 | color: $color; 345 | display: inline-block; 346 | font-size: inherit; 347 | font-weight: bold; 348 | padding: 7px 18px; 349 | text-decoration: none; 350 | background-clip: padding-box; 351 | 352 | &:hover:not(:disabled){ 353 | $base-color-hover: adjust-color($base-color, $saturation: 4%, $lightness: 5%); 354 | 355 | @if $grayscale == true { 356 | $base-color-hover: grayscale($base-color-hover); 357 | } 358 | 359 | background-color: $base-color-hover; 360 | cursor: pointer; 361 | } 362 | 363 | &:active:not(:disabled), 364 | &:focus:not(:disabled) { 365 | $base-color-active: adjust-color($base-color, $saturation: -4%, $lightness: -5%); 366 | 367 | @if $grayscale == true { 368 | $base-color-active: grayscale($base-color-active); 369 | } 370 | 371 | background-color: $base-color-active; 372 | cursor: pointer; 373 | } 374 | } 375 | -------------------------------------------------------------------------------- /js/lib/require.js: -------------------------------------------------------------------------------- 1 | /* 2 | RequireJS 2.1.11 Copyright (c) 2010-2014, The Dojo Foundation All Rights Reserved. 3 | Available via the MIT or new BSD license. 4 | see: http://github.com/jrburke/requirejs for details 5 | */ 6 | var requirejs,require,define; 7 | (function(ca){function G(b){return"[object Function]"===M.call(b)}function H(b){return"[object Array]"===M.call(b)}function v(b,c){if(b){var d;for(d=0;dthis.depCount&&!this.defined){if(G(c)){if(this.events.error&&this.map.isDefine||h.onError!==da)try{f=i.execCb(b,c,e,f)}catch(d){a=d}else f=i.execCb(b,c,e,f);this.map.isDefine&&void 0===f&&((e=this.module)?f=e.exports:this.usingExports&& 19 | (f=this.exports));if(a)return a.requireMap=this.map,a.requireModules=this.map.isDefine?[this.map.id]:null,a.requireType=this.map.isDefine?"define":"require",w(this.error=a)}else f=c;this.exports=f;if(this.map.isDefine&&!this.ignore&&(p[b]=f,h.onResourceLoad))h.onResourceLoad(i,this.map,this.depMaps);y(b);this.defined=!0}this.defining=!1;this.defined&&!this.defineEmitted&&(this.defineEmitted=!0,this.emit("defined",this.exports),this.defineEmitComplete=!0)}}else this.fetch()}},callPlugin:function(){var a= 20 | this.map,b=a.id,d=m(a.prefix);this.depMaps.push(d);r(d,"defined",t(this,function(f){var d,g;g=j(ba,this.map.id);var J=this.map.name,u=this.map.parentMap?this.map.parentMap.name:null,p=i.makeRequire(a.parentMap,{enableBuildCallback:!0});if(this.map.unnormalized){if(f.normalize&&(J=f.normalize(J,function(a){return c(a,u,!0)})||""),f=m(a.prefix+"!"+J,this.map.parentMap),r(f,"defined",t(this,function(a){this.init([],function(){return a},null,{enabled:!0,ignore:!0})})),g=j(k,f.id)){this.depMaps.push(f); 21 | if(this.events.error)g.on("error",t(this,function(a){this.emit("error",a)}));g.enable()}}else g?(this.map.url=i.nameToUrl(g),this.load()):(d=t(this,function(a){this.init([],function(){return a},null,{enabled:!0})}),d.error=t(this,function(a){this.inited=!0;this.error=a;a.requireModules=[b];B(k,function(a){0===a.map.id.indexOf(b+"_unnormalized")&&y(a.map.id)});w(a)}),d.fromText=t(this,function(f,c){var g=a.name,J=m(g),k=O;c&&(f=c);k&&(O=!1);q(J);s(l.config,b)&&(l.config[g]=l.config[b]);try{h.exec(f)}catch(j){return w(C("fromtexteval", 22 | "fromText eval for "+b+" failed: "+j,j,[b]))}k&&(O=!0);this.depMaps.push(J);i.completeLoad(g);p([g],d)}),f.load(a.name,p,d,l))}));i.enable(d,this);this.pluginMaps[d.id]=d},enable:function(){W[this.map.id]=this;this.enabling=this.enabled=!0;v(this.depMaps,t(this,function(a,b){var c,f;if("string"===typeof a){a=m(a,this.map.isDefine?this.map:this.map.parentMap,!1,!this.skipMap);this.depMaps[b]=a;if(c=j(N,a.id)){this.depExports[b]=c(this);return}this.depCount+=1;r(a,"defined",t(this,function(a){this.defineDep(b, 23 | a);this.check()}));this.errback&&r(a,"error",t(this,this.errback))}c=a.id;f=k[c];!s(N,c)&&(f&&!f.enabled)&&i.enable(a,this)}));B(this.pluginMaps,t(this,function(a){var b=j(k,a.id);b&&!b.enabled&&i.enable(a,this)}));this.enabling=!1;this.check()},on:function(a,b){var c=this.events[a];c||(c=this.events[a]=[]);c.push(b)},emit:function(a,b){v(this.events[a],function(a){a(b)});"error"===a&&delete this.events[a]}};i={config:l,contextName:b,registry:k,defined:p,urlFetched:T,defQueue:A,Module:$,makeModuleMap:m, 24 | nextTick:h.nextTick,onError:w,configure:function(a){a.baseUrl&&"/"!==a.baseUrl.charAt(a.baseUrl.length-1)&&(a.baseUrl+="/");var b=l.shim,c={paths:!0,bundles:!0,config:!0,map:!0};B(a,function(a,b){c[b]?(l[b]||(l[b]={}),V(l[b],a,!0,!0)):l[b]=a});a.bundles&&B(a.bundles,function(a,b){v(a,function(a){a!==b&&(ba[a]=b)})});a.shim&&(B(a.shim,function(a,c){H(a)&&(a={deps:a});if((a.exports||a.init)&&!a.exportsFn)a.exportsFn=i.makeShimExports(a);b[c]=a}),l.shim=b);a.packages&&v(a.packages,function(a){var b, 25 | a="string"===typeof a?{name:a}:a;b=a.name;a.location&&(l.paths[b]=a.location);l.pkgs[b]=a.name+"/"+(a.main||"main").replace(ja,"").replace(R,"")});B(k,function(a,b){!a.inited&&!a.map.unnormalized&&(a.map=m(b))});if(a.deps||a.callback)i.require(a.deps||[],a.callback)},makeShimExports:function(a){return function(){var b;a.init&&(b=a.init.apply(ca,arguments));return b||a.exports&&ea(a.exports)}},makeRequire:function(a,e){function g(f,c,d){var j,l;e.enableBuildCallback&&(c&&G(c))&&(c.__requireJsBuild= 26 | !0);if("string"===typeof f){if(G(c))return w(C("requireargs","Invalid require call"),d);if(a&&s(N,f))return N[f](k[a.id]);if(h.get)return h.get(i,f,a,g);j=m(f,a,!1,!0);j=j.id;return!s(p,j)?w(C("notloaded",'Module name "'+j+'" has not been loaded yet for context: '+b+(a?"":". Use require([])"))):p[j]}L();i.nextTick(function(){L();l=q(m(null,a));l.skipMap=e.skipMap;l.init(f,c,d,{enabled:!0});D()});return g}e=e||{};V(g,{isBrowser:z,toUrl:function(b){var e,d=b.lastIndexOf("."),g=b.split("/")[0];if(-1!== 27 | d&&(!("."===g||".."===g)||1g.attachEvent.toString().indexOf("[native code"))&&!Z?(O=!0,g.attachEvent("onreadystatechange",b.onScriptLoad)): 34 | (g.addEventListener("load",b.onScriptLoad,!1),g.addEventListener("error",b.onScriptError,!1)),g.src=d,L=g,D?y.insertBefore(g,D):y.appendChild(g),L=null,g;if(fa)try{importScripts(d),b.completeLoad(c)}catch(j){b.onError(C("importscripts","importScripts failed for "+c+" at "+d,j,[c]))}};z&&!r.skipDataMain&&U(document.getElementsByTagName("script"),function(b){y||(y=b.parentNode);if(K=b.getAttribute("data-main"))return q=K,r.baseUrl||(E=q.split("/"),q=E.pop(),Q=E.length?E.join("/")+"/":"./",r.baseUrl= 35 | Q),q=q.replace(R,""),h.jsExtRegExp.test(q)&&(q=K),r.deps=r.deps?r.deps.concat(q):[q],!0});define=function(b,c,d){var g,h;"string"!==typeof b&&(d=c,c=b,b=null);H(c)||(d=c,c=null);!c&&G(d)&&(c=[],d.length&&(d.toString().replace(la,"").replace(ma,function(b,d){c.push(d)}),c=(1===d.length?["require"]:["require","exports","module"]).concat(c)));if(O){if(!(g=L))P&&"interactive"===P.readyState||U(document.getElementsByTagName("script"),function(b){if("interactive"===b.readyState)return P=b}),g=P;g&&(b|| 36 | (b=g.getAttribute("data-requiremodule")),h=F[g.getAttribute("data-requirecontext")])}(h?h.defQueue:S).push([b,c,d])};define.amd={jQuery:!0};h.exec=function(b){return eval(b)};h(r)}})(this); -------------------------------------------------------------------------------- /js/lib/almond.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @license almond 0.3.1 Copyright (c) 2011-2014, The Dojo Foundation All Rights Reserved. 3 | * Available via the MIT or new BSD license. 4 | * see: http://github.com/jrburke/almond for details 5 | */ 6 | //Going sloppy to avoid 'use strict' string cost, but strict practices should 7 | //be followed. 8 | /*jslint sloppy: true */ 9 | /*global setTimeout: false */ 10 | 11 | var requirejs, require, define; 12 | (function (undef) { 13 | var main, req, makeMap, handlers, 14 | defined = {}, 15 | waiting = {}, 16 | config = {}, 17 | defining = {}, 18 | hasOwn = Object.prototype.hasOwnProperty, 19 | aps = [].slice, 20 | jsSuffixRegExp = /\.js$/; 21 | 22 | function hasProp(obj, prop) { 23 | return hasOwn.call(obj, prop); 24 | } 25 | 26 | /** 27 | * Given a relative module name, like ./something, normalize it to 28 | * a real name that can be mapped to a path. 29 | * @param {String} name the relative name 30 | * @param {String} baseName a real name that the name arg is relative 31 | * to. 32 | * @returns {String} normalized name 33 | */ 34 | function normalize(name, baseName) { 35 | var nameParts, nameSegment, mapValue, foundMap, lastIndex, 36 | foundI, foundStarMap, starI, i, j, part, 37 | baseParts = baseName && baseName.split("/"), 38 | map = config.map, 39 | starMap = (map && map['*']) || {}; 40 | 41 | //Adjust any relative paths. 42 | if (name && name.charAt(0) === ".") { 43 | //If have a base name, try to normalize against it, 44 | //otherwise, assume it is a top-level require that will 45 | //be relative to baseUrl in the end. 46 | if (baseName) { 47 | name = name.split('/'); 48 | lastIndex = name.length - 1; 49 | 50 | // Node .js allowance: 51 | if (config.nodeIdCompat && jsSuffixRegExp.test(name[lastIndex])) { 52 | name[lastIndex] = name[lastIndex].replace(jsSuffixRegExp, ''); 53 | } 54 | 55 | //Lop off the last part of baseParts, so that . matches the 56 | //"directory" and not name of the baseName's module. For instance, 57 | //baseName of "one/two/three", maps to "one/two/three.js", but we 58 | //want the directory, "one/two" for this normalization. 59 | name = baseParts.slice(0, baseParts.length - 1).concat(name); 60 | 61 | //start trimDots 62 | for (i = 0; i < name.length; i += 1) { 63 | part = name[i]; 64 | if (part === ".") { 65 | name.splice(i, 1); 66 | i -= 1; 67 | } else if (part === "..") { 68 | if (i === 1 && (name[2] === '..' || name[0] === '..')) { 69 | //End of the line. Keep at least one non-dot 70 | //path segment at the front so it can be mapped 71 | //correctly to disk. Otherwise, there is likely 72 | //no path mapping for a path starting with '..'. 73 | //This can still fail, but catches the most reasonable 74 | //uses of .. 75 | break; 76 | } else if (i > 0) { 77 | name.splice(i - 1, 2); 78 | i -= 2; 79 | } 80 | } 81 | } 82 | //end trimDots 83 | 84 | name = name.join("/"); 85 | } else if (name.indexOf('./') === 0) { 86 | // No baseName, so this is ID is resolved relative 87 | // to baseUrl, pull off the leading dot. 88 | name = name.substring(2); 89 | } 90 | } 91 | 92 | //Apply map config if available. 93 | if ((baseParts || starMap) && map) { 94 | nameParts = name.split('/'); 95 | 96 | for (i = nameParts.length; i > 0; i -= 1) { 97 | nameSegment = nameParts.slice(0, i).join("/"); 98 | 99 | if (baseParts) { 100 | //Find the longest baseName segment match in the config. 101 | //So, do joins on the biggest to smallest lengths of baseParts. 102 | for (j = baseParts.length; j > 0; j -= 1) { 103 | mapValue = map[baseParts.slice(0, j).join('/')]; 104 | 105 | //baseName segment has config, find if it has one for 106 | //this name. 107 | if (mapValue) { 108 | mapValue = mapValue[nameSegment]; 109 | if (mapValue) { 110 | //Match, update name to the new value. 111 | foundMap = mapValue; 112 | foundI = i; 113 | break; 114 | } 115 | } 116 | } 117 | } 118 | 119 | if (foundMap) { 120 | break; 121 | } 122 | 123 | //Check for a star map match, but just hold on to it, 124 | //if there is a shorter segment match later in a matching 125 | //config, then favor over this star map. 126 | if (!foundStarMap && starMap && starMap[nameSegment]) { 127 | foundStarMap = starMap[nameSegment]; 128 | starI = i; 129 | } 130 | } 131 | 132 | if (!foundMap && foundStarMap) { 133 | foundMap = foundStarMap; 134 | foundI = starI; 135 | } 136 | 137 | if (foundMap) { 138 | nameParts.splice(0, foundI, foundMap); 139 | name = nameParts.join('/'); 140 | } 141 | } 142 | 143 | return name; 144 | } 145 | 146 | function makeRequire(relName, forceSync) { 147 | return function () { 148 | //A version of a require function that passes a moduleName 149 | //value for items that may need to 150 | //look up paths relative to the moduleName 151 | var args = aps.call(arguments, 0); 152 | 153 | //If first arg is not require('string'), and there is only 154 | //one arg, it is the array form without a callback. Insert 155 | //a null so that the following concat is correct. 156 | if (typeof args[0] !== 'string' && args.length === 1) { 157 | args.push(null); 158 | } 159 | return req.apply(undef, args.concat([relName, forceSync])); 160 | }; 161 | } 162 | 163 | function makeNormalize(relName) { 164 | return function (name) { 165 | return normalize(name, relName); 166 | }; 167 | } 168 | 169 | function makeLoad(depName) { 170 | return function (value) { 171 | defined[depName] = value; 172 | }; 173 | } 174 | 175 | function callDep(name) { 176 | if (hasProp(waiting, name)) { 177 | var args = waiting[name]; 178 | delete waiting[name]; 179 | defining[name] = true; 180 | main.apply(undef, args); 181 | } 182 | 183 | if (!hasProp(defined, name) && !hasProp(defining, name)) { 184 | throw new Error('No ' + name); 185 | } 186 | return defined[name]; 187 | } 188 | 189 | //Turns a plugin!resource to [plugin, resource] 190 | //with the plugin being undefined if the name 191 | //did not have a plugin prefix. 192 | function splitPrefix(name) { 193 | var prefix, 194 | index = name ? name.indexOf('!') : -1; 195 | if (index > -1) { 196 | prefix = name.substring(0, index); 197 | name = name.substring(index + 1, name.length); 198 | } 199 | return [prefix, name]; 200 | } 201 | 202 | /** 203 | * Makes a name map, normalizing the name, and using a plugin 204 | * for normalization if necessary. Grabs a ref to plugin 205 | * too, as an optimization. 206 | */ 207 | makeMap = function (name, relName) { 208 | var plugin, 209 | parts = splitPrefix(name), 210 | prefix = parts[0]; 211 | 212 | name = parts[1]; 213 | 214 | if (prefix) { 215 | prefix = normalize(prefix, relName); 216 | plugin = callDep(prefix); 217 | } 218 | 219 | //Normalize according 220 | if (prefix) { 221 | if (plugin && plugin.normalize) { 222 | name = plugin.normalize(name, makeNormalize(relName)); 223 | } else { 224 | name = normalize(name, relName); 225 | } 226 | } else { 227 | name = normalize(name, relName); 228 | parts = splitPrefix(name); 229 | prefix = parts[0]; 230 | name = parts[1]; 231 | if (prefix) { 232 | plugin = callDep(prefix); 233 | } 234 | } 235 | 236 | //Using ridiculous property names for space reasons 237 | return { 238 | f: prefix ? prefix + '!' + name : name, //fullName 239 | n: name, 240 | pr: prefix, 241 | p: plugin 242 | }; 243 | }; 244 | 245 | function makeConfig(name) { 246 | return function () { 247 | return (config && config.config && config.config[name]) || {}; 248 | }; 249 | } 250 | 251 | handlers = { 252 | require: function (name) { 253 | return makeRequire(name); 254 | }, 255 | exports: function (name) { 256 | var e = defined[name]; 257 | if (typeof e !== 'undefined') { 258 | return e; 259 | } else { 260 | return (defined[name] = {}); 261 | } 262 | }, 263 | module: function (name) { 264 | return { 265 | id: name, 266 | uri: '', 267 | exports: defined[name], 268 | config: makeConfig(name) 269 | }; 270 | } 271 | }; 272 | 273 | main = function (name, deps, callback, relName) { 274 | var cjsModule, depName, ret, map, i, 275 | args = [], 276 | callbackType = typeof callback, 277 | usingExports; 278 | 279 | //Use name if no relName 280 | relName = relName || name; 281 | 282 | //Call the callback to define the module, if necessary. 283 | if (callbackType === 'undefined' || callbackType === 'function') { 284 | //Pull out the defined dependencies and pass the ordered 285 | //values to the callback. 286 | //Default to [require, exports, module] if no deps 287 | deps = !deps.length && callback.length ? ['require', 'exports', 'module'] : deps; 288 | for (i = 0; i < deps.length; i += 1) { 289 | map = makeMap(deps[i], relName); 290 | depName = map.f; 291 | 292 | //Fast path CommonJS standard dependencies. 293 | if (depName === "require") { 294 | args[i] = handlers.require(name); 295 | } else if (depName === "exports") { 296 | //CommonJS module spec 1.1 297 | args[i] = handlers.exports(name); 298 | usingExports = true; 299 | } else if (depName === "module") { 300 | //CommonJS module spec 1.1 301 | cjsModule = args[i] = handlers.module(name); 302 | } else if (hasProp(defined, depName) || 303 | hasProp(waiting, depName) || 304 | hasProp(defining, depName)) { 305 | args[i] = callDep(depName); 306 | } else if (map.p) { 307 | map.p.load(map.n, makeRequire(relName, true), makeLoad(depName), {}); 308 | args[i] = defined[depName]; 309 | } else { 310 | throw new Error(name + ' missing ' + depName); 311 | } 312 | } 313 | 314 | ret = callback ? callback.apply(defined[name], args) : undefined; 315 | 316 | if (name) { 317 | //If setting exports via "module" is in play, 318 | //favor that over return value and exports. After that, 319 | //favor a non-undefined return value over exports use. 320 | if (cjsModule && cjsModule.exports !== undef && 321 | cjsModule.exports !== defined[name]) { 322 | defined[name] = cjsModule.exports; 323 | } else if (ret !== undef || !usingExports) { 324 | //Use the return value from the function. 325 | defined[name] = ret; 326 | } 327 | } 328 | } else if (name) { 329 | //May just be an object definition for the module. Only 330 | //worry about defining if have a module name. 331 | defined[name] = callback; 332 | } 333 | }; 334 | 335 | requirejs = require = req = function (deps, callback, relName, forceSync, alt) { 336 | if (typeof deps === "string") { 337 | if (handlers[deps]) { 338 | //callback in this case is really relName 339 | return handlers[deps](callback); 340 | } 341 | //Just return the module wanted. In this scenario, the 342 | //deps arg is the module name, and second arg (if passed) 343 | //is just the relName. 344 | //Normalize module name, if it contains . or .. 345 | return callDep(makeMap(deps, callback).f); 346 | } else if (!deps.splice) { 347 | //deps is a config object, not an array. 348 | config = deps; 349 | if (config.deps) { 350 | req(config.deps, config.callback); 351 | } 352 | if (!callback) { 353 | return; 354 | } 355 | 356 | if (callback.splice) { 357 | //callback is an array, which means it is a dependency list. 358 | //Adjust args if there are dependencies 359 | deps = callback; 360 | callback = relName; 361 | relName = null; 362 | } else { 363 | deps = undef; 364 | } 365 | } 366 | 367 | //Support require(['a']) 368 | callback = callback || function () {}; 369 | 370 | //If relName is a function, it is an errback handler, 371 | //so remove it. 372 | if (typeof relName === 'function') { 373 | relName = forceSync; 374 | forceSync = alt; 375 | } 376 | 377 | //Simulate async callback; 378 | if (forceSync) { 379 | main(undef, deps, callback, relName); 380 | } else { 381 | //Using a non-zero value because of concern for what old browsers 382 | //do, and latest browsers "upgrade" to 4 if lower value is used: 383 | //http://www.whatwg.org/specs/web-apps/current-work/multipage/timers.html#dom-windowtimers-settimeout: 384 | //If want a value immediately, use require('id') instead -- something 385 | //that works in almond on the global level, but not guaranteed and 386 | //unlikely to work in other AMD implementations. 387 | setTimeout(function () { 388 | main(undef, deps, callback, relName); 389 | }, 4); 390 | } 391 | 392 | return req; 393 | }; 394 | 395 | /** 396 | * Just drops the config on the floor, but returns req in case 397 | * the config return value is used. 398 | */ 399 | req.config = function (cfg) { 400 | return req(cfg); 401 | }; 402 | 403 | /** 404 | * Expose module registry for debugging and tooling 405 | */ 406 | requirejs._defined = defined; 407 | 408 | define = function (name, deps, callback) { 409 | if (typeof name !== 'string') { 410 | throw new Error('See almond README: incorrect module build, no module name'); 411 | } 412 | 413 | //This module may not have dependencies 414 | if (!deps.splice) { 415 | //deps is not an array, so probably means 416 | //an object literal or factory function for 417 | //the value. Adjust args. 418 | callback = deps; 419 | deps = []; 420 | } 421 | 422 | if (!hasProp(defined, name) && !hasProp(waiting, name)) { 423 | waiting[name] = [name, deps, callback]; 424 | } 425 | }; 426 | 427 | define.amd = { 428 | jQuery: true 429 | }; 430 | }()); -------------------------------------------------------------------------------- /js/lib/text.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @license RequireJS text 2.0.14 Copyright (c) 2010-2014, The Dojo Foundation All Rights Reserved. 3 | * Available via the MIT or new BSD license. 4 | * see: http://github.com/requirejs/text for details 5 | */ 6 | /*jslint regexp: true */ 7 | /*global require, XMLHttpRequest, ActiveXObject, 8 | define, window, process, Packages, 9 | java, location, Components, FileUtils */ 10 | 11 | define(['module'], function (module) { 12 | 'use strict'; 13 | 14 | var text, fs, Cc, Ci, xpcIsWindows, 15 | progIds = ['Msxml2.XMLHTTP', 'Microsoft.XMLHTTP', 'Msxml2.XMLHTTP.4.0'], 16 | xmlRegExp = /^\s*<\?xml(\s)+version=[\'\"](\d)*.(\d)*[\'\"](\s)*\?>/im, 17 | bodyRegExp = /]*>\s*([\s\S]+)\s*<\/body>/im, 18 | hasLocation = typeof location !== 'undefined' && location.href, 19 | defaultProtocol = hasLocation && location.protocol && location.protocol.replace(/\:/, ''), 20 | defaultHostName = hasLocation && location.hostname, 21 | defaultPort = hasLocation && (location.port || undefined), 22 | buildMap = {}, 23 | masterConfig = (module.config && module.config()) || {}; 24 | 25 | text = { 26 | version: '2.0.14', 27 | 28 | strip: function (content) { 29 | //Strips declarations so that external SVG and XML 30 | //documents can be added to a document without worry. Also, if the string 31 | //is an HTML document, only the part inside the body tag is returned. 32 | if (content) { 33 | content = content.replace(xmlRegExp, ""); 34 | var matches = content.match(bodyRegExp); 35 | if (matches) { 36 | content = matches[1]; 37 | } 38 | } else { 39 | content = ""; 40 | } 41 | return content; 42 | }, 43 | 44 | jsEscape: function (content) { 45 | return content.replace(/(['\\])/g, '\\$1') 46 | .replace(/[\f]/g, "\\f") 47 | .replace(/[\b]/g, "\\b") 48 | .replace(/[\n]/g, "\\n") 49 | .replace(/[\t]/g, "\\t") 50 | .replace(/[\r]/g, "\\r") 51 | .replace(/[\u2028]/g, "\\u2028") 52 | .replace(/[\u2029]/g, "\\u2029"); 53 | }, 54 | 55 | createXhr: masterConfig.createXhr || function () { 56 | //Would love to dump the ActiveX crap in here. Need IE 6 to die first. 57 | var xhr, i, progId; 58 | if (typeof XMLHttpRequest !== "undefined") { 59 | return new XMLHttpRequest(); 60 | } else if (typeof ActiveXObject !== "undefined") { 61 | for (i = 0; i < 3; i += 1) { 62 | progId = progIds[i]; 63 | try { 64 | xhr = new ActiveXObject(progId); 65 | } catch (e) {} 66 | 67 | if (xhr) { 68 | progIds = [progId]; // so faster next time 69 | break; 70 | } 71 | } 72 | } 73 | 74 | return xhr; 75 | }, 76 | 77 | /** 78 | * Parses a resource name into its component parts. Resource names 79 | * look like: module/name.ext!strip, where the !strip part is 80 | * optional. 81 | * @param {String} name the resource name 82 | * @returns {Object} with properties "moduleName", "ext" and "strip" 83 | * where strip is a boolean. 84 | */ 85 | parseName: function (name) { 86 | var modName, ext, temp, 87 | strip = false, 88 | index = name.lastIndexOf("."), 89 | isRelative = name.indexOf('./') === 0 || 90 | name.indexOf('../') === 0; 91 | 92 | if (index !== -1 && (!isRelative || index > 1)) { 93 | modName = name.substring(0, index); 94 | ext = name.substring(index + 1); 95 | } else { 96 | modName = name; 97 | } 98 | 99 | temp = ext || modName; 100 | index = temp.indexOf("!"); 101 | if (index !== -1) { 102 | //Pull off the strip arg. 103 | strip = temp.substring(index + 1) === "strip"; 104 | temp = temp.substring(0, index); 105 | if (ext) { 106 | ext = temp; 107 | } else { 108 | modName = temp; 109 | } 110 | } 111 | 112 | return { 113 | moduleName: modName, 114 | ext: ext, 115 | strip: strip 116 | }; 117 | }, 118 | 119 | xdRegExp: /^((\w+)\:)?\/\/([^\/\\]+)/, 120 | 121 | /** 122 | * Is an URL on another domain. Only works for browser use, returns 123 | * false in non-browser environments. Only used to know if an 124 | * optimized .js version of a text resource should be loaded 125 | * instead. 126 | * @param {String} url 127 | * @returns Boolean 128 | */ 129 | useXhr: function (url, protocol, hostname, port) { 130 | var uProtocol, uHostName, uPort, 131 | match = text.xdRegExp.exec(url); 132 | if (!match) { 133 | return true; 134 | } 135 | uProtocol = match[2]; 136 | uHostName = match[3]; 137 | 138 | uHostName = uHostName.split(':'); 139 | uPort = uHostName[1]; 140 | uHostName = uHostName[0]; 141 | 142 | return (!uProtocol || uProtocol === protocol) && 143 | (!uHostName || uHostName.toLowerCase() === hostname.toLowerCase()) && 144 | ((!uPort && !uHostName) || uPort === port); 145 | }, 146 | 147 | finishLoad: function (name, strip, content, onLoad) { 148 | content = strip ? text.strip(content) : content; 149 | if (masterConfig.isBuild) { 150 | buildMap[name] = content; 151 | } 152 | onLoad(content); 153 | }, 154 | 155 | load: function (name, req, onLoad, config) { 156 | //Name has format: some.module.filext!strip 157 | //The strip part is optional. 158 | //if strip is present, then that means only get the string contents 159 | //inside a body tag in an HTML string. For XML/SVG content it means 160 | //removing the declarations so the content can be inserted 161 | //into the current doc without problems. 162 | 163 | // Do not bother with the work if a build and text will 164 | // not be inlined. 165 | if (config && config.isBuild && !config.inlineText) { 166 | onLoad(); 167 | return; 168 | } 169 | 170 | masterConfig.isBuild = config && config.isBuild; 171 | 172 | var parsed = text.parseName(name), 173 | nonStripName = parsed.moduleName + 174 | (parsed.ext ? '.' + parsed.ext : ''), 175 | url = req.toUrl(nonStripName), 176 | useXhr = (masterConfig.useXhr) || 177 | text.useXhr; 178 | 179 | // Do not load if it is an empty: url 180 | if (url.indexOf('empty:') === 0) { 181 | onLoad(); 182 | return; 183 | } 184 | 185 | //Load the text. Use XHR if possible and in a browser. 186 | if (!hasLocation || useXhr(url, defaultProtocol, defaultHostName, defaultPort)) { 187 | text.get(url, function (content) { 188 | text.finishLoad(name, parsed.strip, content, onLoad); 189 | }, function (err) { 190 | if (onLoad.error) { 191 | onLoad.error(err); 192 | } 193 | }); 194 | } else { 195 | //Need to fetch the resource across domains. Assume 196 | //the resource has been optimized into a JS module. Fetch 197 | //by the module name + extension, but do not include the 198 | //!strip part to avoid file system issues. 199 | req([nonStripName], function (content) { 200 | text.finishLoad(parsed.moduleName + '.' + parsed.ext, 201 | parsed.strip, content, onLoad); 202 | }); 203 | } 204 | }, 205 | 206 | write: function (pluginName, moduleName, write, config) { 207 | if (buildMap.hasOwnProperty(moduleName)) { 208 | var content = text.jsEscape(buildMap[moduleName]); 209 | write.asModule(pluginName + "!" + moduleName, 210 | "define(function () { return '" + 211 | content + 212 | "';});\n"); 213 | } 214 | }, 215 | 216 | writeFile: function (pluginName, moduleName, req, write, config) { 217 | var parsed = text.parseName(moduleName), 218 | extPart = parsed.ext ? '.' + parsed.ext : '', 219 | nonStripName = parsed.moduleName + extPart, 220 | //Use a '.js' file name so that it indicates it is a 221 | //script that can be loaded across domains. 222 | fileName = req.toUrl(parsed.moduleName + extPart) + '.js'; 223 | 224 | //Leverage own load() method to load plugin value, but only 225 | //write out values that do not have the strip argument, 226 | //to avoid any potential issues with ! in file names. 227 | text.load(nonStripName, req, function (value) { 228 | //Use own write() method to construct full module value. 229 | //But need to create shell that translates writeFile's 230 | //write() to the right interface. 231 | var textWrite = function (contents) { 232 | return write(fileName, contents); 233 | }; 234 | textWrite.asModule = function (moduleName, contents) { 235 | return write.asModule(moduleName, fileName, contents); 236 | }; 237 | 238 | text.write(pluginName, nonStripName, textWrite, config); 239 | }, config); 240 | } 241 | }; 242 | 243 | if (masterConfig.env === 'node' || (!masterConfig.env && 244 | typeof process !== "undefined" && 245 | process.versions && 246 | !!process.versions.node && 247 | !process.versions['node-webkit'] && 248 | !process.versions['atom-shell'])) { 249 | //Using special require.nodeRequire, something added by r.js. 250 | fs = require.nodeRequire('fs'); 251 | 252 | text.get = function (url, callback, errback) { 253 | try { 254 | var file = fs.readFileSync(url, 'utf8'); 255 | //Remove BOM (Byte Mark Order) from utf8 files if it is there. 256 | if (file[0] === '\uFEFF') { 257 | file = file.substring(1); 258 | } 259 | callback(file); 260 | } catch (e) { 261 | if (errback) { 262 | errback(e); 263 | } 264 | } 265 | }; 266 | } else if (masterConfig.env === 'xhr' || (!masterConfig.env && 267 | text.createXhr())) { 268 | text.get = function (url, callback, errback, headers) { 269 | var xhr = text.createXhr(), header; 270 | xhr.open('GET', url, true); 271 | 272 | //Allow plugins direct access to xhr headers 273 | if (headers) { 274 | for (header in headers) { 275 | if (headers.hasOwnProperty(header)) { 276 | xhr.setRequestHeader(header.toLowerCase(), headers[header]); 277 | } 278 | } 279 | } 280 | 281 | //Allow overrides specified in config 282 | if (masterConfig.onXhr) { 283 | masterConfig.onXhr(xhr, url); 284 | } 285 | 286 | xhr.onreadystatechange = function (evt) { 287 | var status, err; 288 | //Do not explicitly handle errors, those should be 289 | //visible via console output in the browser. 290 | if (xhr.readyState === 4) { 291 | status = xhr.status || 0; 292 | if (status > 399 && status < 600) { 293 | //An http 4xx or 5xx error. Signal an error. 294 | err = new Error(url + ' HTTP status: ' + status); 295 | err.xhr = xhr; 296 | if (errback) { 297 | errback(err); 298 | } 299 | } else { 300 | callback(xhr.responseText); 301 | } 302 | 303 | if (masterConfig.onXhrComplete) { 304 | masterConfig.onXhrComplete(xhr, url); 305 | } 306 | } 307 | }; 308 | xhr.send(null); 309 | }; 310 | } else if (masterConfig.env === 'rhino' || (!masterConfig.env && 311 | typeof Packages !== 'undefined' && typeof java !== 'undefined')) { 312 | //Why Java, why is this so awkward? 313 | text.get = function (url, callback) { 314 | var stringBuffer, line, 315 | encoding = "utf-8", 316 | file = new java.io.File(url), 317 | lineSeparator = java.lang.System.getProperty("line.separator"), 318 | input = new java.io.BufferedReader(new java.io.InputStreamReader(new java.io.FileInputStream(file), encoding)), 319 | content = ''; 320 | try { 321 | stringBuffer = new java.lang.StringBuffer(); 322 | line = input.readLine(); 323 | 324 | // Byte Order Mark (BOM) - The Unicode Standard, version 3.0, page 324 325 | // http://www.unicode.org/faq/utf_bom.html 326 | 327 | // Note that when we use utf-8, the BOM should appear as "EF BB BF", but it doesn't due to this bug in the JDK: 328 | // http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4508058 329 | if (line && line.length() && line.charAt(0) === 0xfeff) { 330 | // Eat the BOM, since we've already found the encoding on this file, 331 | // and we plan to concatenating this buffer with others; the BOM should 332 | // only appear at the top of a file. 333 | line = line.substring(1); 334 | } 335 | 336 | if (line !== null) { 337 | stringBuffer.append(line); 338 | } 339 | 340 | while ((line = input.readLine()) !== null) { 341 | stringBuffer.append(lineSeparator); 342 | stringBuffer.append(line); 343 | } 344 | //Make sure we return a JavaScript string and not a Java string. 345 | content = String(stringBuffer.toString()); //String 346 | } finally { 347 | input.close(); 348 | } 349 | callback(content); 350 | }; 351 | } else if (masterConfig.env === 'xpconnect' || (!masterConfig.env && 352 | typeof Components !== 'undefined' && Components.classes && 353 | Components.interfaces)) { 354 | //Avert your gaze! 355 | Cc = Components.classes; 356 | Ci = Components.interfaces; 357 | Components.utils['import']('resource://gre/modules/FileUtils.jsm'); 358 | xpcIsWindows = ('@mozilla.org/windows-registry-key;1' in Cc); 359 | 360 | text.get = function (url, callback) { 361 | var inStream, convertStream, fileObj, 362 | readData = {}; 363 | 364 | if (xpcIsWindows) { 365 | url = url.replace(/\//g, '\\'); 366 | } 367 | 368 | fileObj = new FileUtils.File(url); 369 | 370 | //XPCOM, you so crazy 371 | try { 372 | inStream = Cc['@mozilla.org/network/file-input-stream;1'] 373 | .createInstance(Ci.nsIFileInputStream); 374 | inStream.init(fileObj, 1, 0, false); 375 | 376 | convertStream = Cc['@mozilla.org/intl/converter-input-stream;1'] 377 | .createInstance(Ci.nsIConverterInputStream); 378 | convertStream.init(inStream, "utf-8", inStream.available(), 379 | Ci.nsIConverterInputStream.DEFAULT_REPLACEMENT_CHARACTER); 380 | 381 | convertStream.readString(inStream.available(), readData); 382 | convertStream.close(); 383 | inStream.close(); 384 | callback(readData.value); 385 | } catch (e) { 386 | throw new Error((fileObj && fileObj.path || '') + ': ' + e); 387 | } 388 | }; 389 | } 390 | return text; 391 | }); -------------------------------------------------------------------------------- /css/fonts/icomoon/fonts/icomoon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Generated by IcoMoon 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | --------------------------------------------------------------------------------