<commit_before>/*!
 * Bootstrap's Gruntfile
 * http://getbootstrap.com
 * Copyright 2013-2014 Twitter, Inc.
 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
 */

module.exports = function (grunt) {
  'use strict';

  // Force use of Unix newlines
  grunt.util.linefeed = '\n';

  RegExp.quote = function (string) {
    return string.replace(/[-\\^$*+?.()|[\]{}]/g, '\\$&');
  };

  var fs = require('fs');
  var path = require('path');
  var generateGlyphiconsData = require('./grunt/bs-glyphicons-data-generator.js');
  var BsLessdocParser = require('./grunt/bs-lessdoc-parser.js');
  var generateRawFilesJs = require('./grunt/bs-raw-files-generator.js');
  var updateShrinkwrap = require('./grunt/shrinkwrap.js');

  // Project configuration.
  grunt.initConfig({

    // Metadata.
    pkg: grunt.file.readJSON('package.json'),
    banner: '/*!\n' +
            ' * Bootstrap v<%= pkg.version %> (<%= pkg.homepage %>)\n' +
            ' * Copyright 2011-<%= grunt.template.today("yyyy") %> <%= pkg.author %>\n' +
            ' * Licensed under <%= pkg.license.type %> (<%= pkg.license.url %>)\n' +
            ' */\n',
    jqueryCheck: 'if (typeof jQuery === \'undefined\') { throw new Error(\'Bootstrap\\\'s JavaScript requires jQuery\') }\n\n',

    // Task configuration.
    clean: {
      dist: ['dist', 'docs/dist']
    },

    jshint: {
      options: {
        jshintrc: 'js/.jshintrc'
      },
      grunt: {
        options: {
          jshintrc: 'grunt/.jshintrc'
        },
        src: ['Gruntfile.js', 'grunt/*.js']
      },
      src: {
        src: 'js/*.js'
      },
      test: {
        src: 'js/tests/unit/*.js'
      },
      assets: {
        src: 'docs/assets/js/src/*.js'
      }
    },

    jscs: {
      options: {
        config: 'js/.jscsrc'
      },
      grunt: {
        options: {
          'requireCamelCaseOrUpperCaseIdentifiers': null,
          'requireParenthesesAroundIIFE': true
        },
        src: '<%= jshint.grunt.src %>'
      },
      src: {
        src: '<%= jshint.src.src %>'
      },
      test: {
        src: '<%= jshint.test.src %>'
      },
      assets: {
        src: '<%= jshint.assets.src %>'
      }
    },

    csslint: {
      options: {
        csslintrc: 'less/.csslintrc'
      },
      src: [
        'dist/css/bootstrap.css',
        'dist/css/bootstrap-theme.css'
      ],
      examples: [
        'docs/examples/**/*.css'
      ],
      docs: {
        options: {
          'ids': false,
          'overqualified-elements': false
        },
        src: 'docs/assets/css/src/docs.css'
      }
    },

    concat: {
      options: {
        banner: '<%= banner %>\n<%= jqueryCheck %>',
        stripBanners: false
      },
      bootstrap: {
        src: [
          'js/transition.js',
          'js/alert.js',
          'js/button.js',
          'js/carousel.js',
          'js/collapse.js',
          'js/dropdown.js',
          'js/modal.js',
          'js/tooltip.js',
          'js/popover.js',
          'js/scrollspy.js',
          'js/tab.js',
          'js/affix.js'
        ],
        dest: 'dist/js/<%= pkg.name %>.js'
      }
    },

    uglify: {
      options: {
        report: 'min'
      },
      bootstrap: {
        options: {
          banner: '<%= banner %>'
        },
        src: '<%= concat.bootstrap.dest %>',
        dest: 'dist/js/<%= pkg.name %>.min.js'
      },
      customize: {
        options: {
          preserveComments: 'some'
        },
        src: [
          'docs/assets/js/vendor/less.min.js',
          'docs/assets/js/vendor/jszip.min.js',
          'docs/assets/js/vendor/uglify.min.js',
          'docs/assets/js/vendor/blob.js',
          'docs/assets/js/vendor/filesaver.js',
          'docs/assets/js/raw-files.min.js',
          'docs/assets/js/src/customizer.js'
        ],
        dest: 'docs/assets/js/customize.min.js'
      },
      docsJs: {
        options: {
          preserveComments: 'some'
        },
        src: [
          'docs/assets/js/vendor/holder.js',
          'docs/assets/js/src/application.js'
        ],
        dest: 'docs/assets/js/docs.min.js'
      }
    },

    less: {
      compileCore: {
        options: {
          strictMath: true,
          sourceMap: true,
          outputSourceFiles: true,
          sourceMapURL: '<%= pkg.name %>.css.map',
          sourceMapFilename: 'dist/css/<%= pkg.name %>.css.map'
        },
        files: {
          'dist/css/<%= pkg.name %>.css': 'less/bootstrap.less'
        }
      },
      compileTheme: {
        options: {
          strictMath: true,
          sourceMap: true,
          outputSourceFiles: true,
          sourceMapURL: '<%= pkg.name %>-theme.css.map',
          sourceMapFilename: 'dist/css/<%= pkg.name %>-theme.css.map'
        },
        files: {
          'dist/css/<%= pkg.name %>-theme.css': 'less/theme.less'
        }
      },
      minify: {
        options: {
          cleancss: true,
          report: 'min'
        },
        files: {
          'dist/css/<%= pkg.name %>.min.css': 'dist/css/<%= pkg.name %>.css',
          'dist/css/<%= pkg.name %>-rtl.min.css': 'dist/css/<%= pkg.name %>-rtl.css',
          'dist/css/<%= pkg.name %>-theme.min.css': 'dist/css/<%= pkg.name %>-theme.css'
        }
      }
    },

    autoprefixer: {
      options: {
        browsers: ['last 2 versions', 'ie 8', 'ie 9', 'android 2.3', 'android 4', 'opera 12']
      },
      core: {
        options: {
          map: true
        },
        src: 'dist/css/<%= pkg.name %>.css'
      },
      theme: {
        options: {
          map: true
        },
        src: 'dist/css/<%= pkg.name %>-theme.css'
      },
      docs: {
        src: 'docs/assets/css/docs.css'
      },
      examples: {
        expand: true,
        cwd: 'docs/examples/',
        src: ['**/*.css'],
        dest: 'docs/examples/'
      }
    },

    css_flip: {
      rtl: {
        files: {
          'dist/css/<%= pkg.name %>-rtl.css': 'dist/css/<%= pkg.name %>.css'
        }
      }
    },

    cssmin: {
      compress: {
        options: {
          keepSpecialComments: '*',
          noAdvanced: true, // turn advanced optimizations off until the issue is fixed in clean-css
          report: 'min',
          compatibility: 'ie8'
        },
        src: [
          'docs/assets/css/src/docs.css',
          'docs/assets/css/src/pygments-manni.css'
        ],
        dest: 'docs/assets/css/docs.min.css'
      }
    },

    usebanner: {
      dist: {
        options: {
          position: 'top',
          banner: '<%= banner %>'
        },
        files: {
          src: [
            'dist/css/<%= pkg.name %>.css',
            'dist/css/<%= pkg.name %>-rtl.css',
            'dist/css/<%= pkg.name %>.min.css',
            'dist/css/<%= pkg.name %>-rtl.min.css',
            'dist/css/<%= pkg.name %>-theme.css',
            'dist/css/<%= pkg.name %>-theme.min.css'
          ]
        }
      }
    },

    csscomb: {
      options: {
        config: 'less/.csscomb.json'
      },
      dist: {
        files: {
          'dist/css/<%= pkg.name %>.css': 'dist/css/<%= pkg.name %>.css',
          'dist/css/<%= pkg.name %>-rtl.css': 'dist/css/<%= pkg.name %>-rtl.css',
          'dist/css/<%= pkg.name %>-theme.css': 'dist/css/<%= pkg.name %>-theme.css'
        }
      },
      examples: {
        expand: true,
        cwd: 'docs/examples/',
        src: '**/*.css',
        dest: 'docs/examples/'
      },
      docs: {
        files: {
          'docs/assets/css/src/docs.css': 'docs/assets/css/src/docs.css'
        }
      }
    },

    copy: {
      fonts: {
        expand: true,
        src: 'fonts/*',
        dest: 'dist/'
      },
      docs: {
        expand: true,
        cwd: './dist',
        src: [
          '{css,js}/*.min.*',
          'css/*.map',
          'fonts/*'
        ],
        dest: 'docs/dist'
      }
    },

    qunit: {
      options: {
        inject: 'js/tests/unit/phantom.js'
      },
      files: 'js/tests/index.html'
    },

    connect: {
      server: {
        options: {
          port: 3000,
          base: '.'
        }
      }
    },

    jekyll: {
      docs: {}
    },

    jade: {
      compile: {
        options: {
          pretty: true,
          data: function () {
            var filePath = path.join(__dirname, 'less/variables.less');
            var fileContent = fs.readFileSync(filePath, {encoding: 'utf8'});
            var parser = new BsLessdocParser(fileContent);
            return {sections: parser.parseFile()};
          }
        },
        files: {
          'docs/_includes/customizer-variables.html': 'docs/jade/customizer-variables.jade',
          'docs/_includes/nav-customize.html': 'docs/jade/customizer-nav.jade'
        }
      }
    },

    validation: {
      options: {
        charset: 'utf-8',
        doctype: 'HTML5',
        failHard: true,
        reset: true,
        relaxerror: [
          'Bad value X-UA-Compatible for attribute http-equiv on element meta.',
          'Element img is missing required attribute src.'
        ]
      },
      files: {
        src: '_gh_pages/**/*.html'
      }
    },

    watch: {
      src: {
        files: '<%= jshint.src.src %>',
        tasks: ['jshint:src', 'qunit']
      },
      test: {
        files: '<%= jshint.test.src %>',
        tasks: ['jshint:test', 'qunit']
      },
      less: {
        files: 'less/*.less',
        tasks: 'less'
      }
    },

    sed: {
      versionNumber: {
        pattern: (function () {
          var old = grunt.option('oldver');
          return old ? RegExp.quote(old) : old;
        })(),
        replacement: grunt.option('newver'),
        recursive: true
      }
    },

    'saucelabs-qunit': {
      all: {
        options: {
          build: process.env.TRAVIS_JOB_ID,
          concurrency: 10,
          urls: ['http://127.0.0.1:3000/js/tests/index.html'],
          browsers: grunt.file.readYAML('test-infra/sauce_browsers.yml')
        }
      }
    },

    exec: {
      npmUpdate: {
        command: 'npm update'
      },
      npmShrinkWrap: {
        command: 'npm shrinkwrap --dev'
      }
    }
  });

  // These plugins provide necessary tasks.
  require('load-grunt-tasks')(grunt, {scope: 'devDependencies'});
  require('time-grunt')(grunt);

  // Docs HTML validation task
  grunt.registerTask('validate-html', ['jekyll', 'validation']);

  // Test task.
  var testSubtasks = [];
  // Skip core tests if running a different subset of the test suite
  if (!process.env.TWBS_TEST || process.env.TWBS_TEST === 'core') {
    testSubtasks = testSubtasks.concat(['dist-css', 'csslint', 'jshint', 'jscs', 'qunit', 'build-customizer-html']);
  }
  // Skip HTML validation if running a different subset of the test suite
  if (!process.env.TWBS_TEST || process.env.TWBS_TEST === 'validate-html') {
    testSubtasks.push('validate-html');
  }
  // Only run Sauce Labs tests if there's a Sauce access key
  if (typeof process.env.SAUCE_ACCESS_KEY !== 'undefined' &&
      // Skip Sauce if running a different subset of the test suite
      (!process.env.TWBS_TEST || process.env.TWBS_TEST === 'sauce-js-unit')) {
    testSubtasks.push('connect');
    testSubtasks.push('saucelabs-qunit');
  }
  grunt.registerTask('test', testSubtasks);

  // JS distribution task.
  grunt.registerTask('dist-js', ['concat', 'uglify']);

  // CSS distribution task.
  grunt.registerTask('less-compile', ['less:compileCore', 'less:compileTheme']);
  grunt.registerTask('dist-css', ['less-compile', 'autoprefixer', 'css_flip', 'csscomb', 'less:minify', 'cssmin', 'usebanner']);

  // Docs distribution task.
  grunt.registerTask('dist-docs', 'copy:docs');

  // Full distribution task.
  grunt.registerTask('dist', ['clean', 'dist-css', 'copy:fonts', 'dist-js', 'dist-docs']);

  // Default task.
  grunt.registerTask('default', ['test', 'dist', 'build-glyphicons-data', 'build-customizer', 'update-shrinkwrap']);

  // Version numbering task.
  // grunt change-version-number --oldver=A.B.C --newver=X.Y.Z
  // This can be overzealous, so its changes should always be manually reviewed!
  grunt.registerTask('change-version-number', 'sed');

  grunt.registerTask('build-glyphicons-data', generateGlyphiconsData);

  // task for building customizer
  grunt.registerTask('build-customizer', ['build-customizer-html', 'build-raw-files']);
  grunt.registerTask('build-customizer-html', 'jade');
  grunt.registerTask('build-raw-files', 'Add scripts/less files to customizer.', function () {
    var banner = grunt.template.process('<%= banner %>');
    generateRawFilesJs(banner);
  });

  // Task for updating the npm packages used by the Travis build.
  grunt.registerTask('update-shrinkwrap', ['exec:npmUpdate', 'exec:npmShrinkWrap', '_update-shrinkwrap']);
  grunt.registerTask('_update-shrinkwrap', function () { updateShrinkwrap.call(this, grunt); });
};
<commit_msg>Rename generateRawFilesJs to generateRawFiles<commit_after>/*!
 * Bootstrap's Gruntfile
 * http://getbootstrap.com
 * Copyright 2013-2014 Twitter, Inc.
 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
 */

module.exports = function (grunt) {
  'use strict';

  // Force use of Unix newlines
  grunt.util.linefeed = '\n';

  RegExp.quote = function (string) {
    return string.replace(/[-\\^$*+?.()|[\]{}]/g, '\\$&');
  };

  var fs = require('fs');
  var path = require('path');
  var generateGlyphiconsData = require('./grunt/bs-glyphicons-data-generator.js');
  var BsLessdocParser = require('./grunt/bs-lessdoc-parser.js');
  var generateRawFiles = require('./grunt/bs-raw-files-generator.js');
  var updateShrinkwrap = require('./grunt/shrinkwrap.js');

  // Project configuration.
  grunt.initConfig({

    // Metadata.
    pkg: grunt.file.readJSON('package.json'),
    banner: '/*!\n' +
            ' * Bootstrap v<%= pkg.version %> (<%= pkg.homepage %>)\n' +
            ' * Copyright 2011-<%= grunt.template.today("yyyy") %> <%= pkg.author %>\n' +
            ' * Licensed under <%= pkg.license.type %> (<%= pkg.license.url %>)\n' +
            ' */\n',
    jqueryCheck: 'if (typeof jQuery === \'undefined\') { throw new Error(\'Bootstrap\\\'s JavaScript requires jQuery\') }\n\n',

    // Task configuration.
    clean: {
      dist: ['dist', 'docs/dist']
    },

    jshint: {
      options: {
        jshintrc: 'js/.jshintrc'
      },
      grunt: {
        options: {
          jshintrc: 'grunt/.jshintrc'
        },
        src: ['Gruntfile.js', 'grunt/*.js']
      },
      src: {
        src: 'js/*.js'
      },
      test: {
        src: 'js/tests/unit/*.js'
      },
      assets: {
        src: 'docs/assets/js/src/*.js'
      }
    },

    jscs: {
      options: {
        config: 'js/.jscsrc'
      },
      grunt: {
        options: {
          'requireCamelCaseOrUpperCaseIdentifiers': null,
          'requireParenthesesAroundIIFE': true
        },
        src: '<%= jshint.grunt.src %>'
      },
      src: {
        src: '<%= jshint.src.src %>'
      },
      test: {
        src: '<%= jshint.test.src %>'
      },
      assets: {
        src: '<%= jshint.assets.src %>'
      }
    },

    csslint: {
      options: {
        csslintrc: 'less/.csslintrc'
      },
      src: [
        'dist/css/bootstrap.css',
        'dist/css/bootstrap-theme.css'
      ],
      examples: [
        'docs/examples/**/*.css'
      ],
      docs: {
        options: {
          'ids': false,
          'overqualified-elements': false
        },
        src: 'docs/assets/css/src/docs.css'
      }
    },

    concat: {
      options: {
        banner: '<%= banner %>\n<%= jqueryCheck %>',
        stripBanners: false
      },
      bootstrap: {
        src: [
          'js/transition.js',
          'js/alert.js',
          'js/button.js',
          'js/carousel.js',
          'js/collapse.js',
          'js/dropdown.js',
          'js/modal.js',
          'js/tooltip.js',
          'js/popover.js',
          'js/scrollspy.js',
          'js/tab.js',
          'js/affix.js'
        ],
        dest: 'dist/js/<%= pkg.name %>.js'
      }
    },

    uglify: {
      options: {
        report: 'min'
      },
      bootstrap: {
        options: {
          banner: '<%= banner %>'
        },
        src: '<%= concat.bootstrap.dest %>',
        dest: 'dist/js/<%= pkg.name %>.min.js'
      },
      customize: {
        options: {
          preserveComments: 'some'
        },
        src: [
          'docs/assets/js/vendor/less.min.js',
          'docs/assets/js/vendor/jszip.min.js',
          'docs/assets/js/vendor/uglify.min.js',
          'docs/assets/js/vendor/blob.js',
          'docs/assets/js/vendor/filesaver.js',
          'docs/assets/js/raw-files.min.js',
          'docs/assets/js/src/customizer.js'
        ],
        dest: 'docs/assets/js/customize.min.js'
      },
      docsJs: {
        options: {
          preserveComments: 'some'
        },
        src: [
          'docs/assets/js/vendor/holder.js',
          'docs/assets/js/src/application.js'
        ],
        dest: 'docs/assets/js/docs.min.js'
      }
    },

    less: {
      compileCore: {
        options: {
          strictMath: true,
          sourceMap: true,
          outputSourceFiles: true,
          sourceMapURL: '<%= pkg.name %>.css.map',
          sourceMapFilename: 'dist/css/<%= pkg.name %>.css.map'
        },
        files: {
          'dist/css/<%= pkg.name %>.css': 'less/bootstrap.less'
        }
      },
      compileTheme: {
        options: {
          strictMath: true,
          sourceMap: true,
          outputSourceFiles: true,
          sourceMapURL: '<%= pkg.name %>-theme.css.map',
          sourceMapFilename: 'dist/css/<%= pkg.name %>-theme.css.map'
        },
        files: {
          'dist/css/<%= pkg.name %>-theme.css': 'less/theme.less'
        }
      },
      minify: {
        options: {
          cleancss: true,
          report: 'min'
        },
        files: {
          'dist/css/<%= pkg.name %>.min.css': 'dist/css/<%= pkg.name %>.css',
          'dist/css/<%= pkg.name %>-rtl.min.css': 'dist/css/<%= pkg.name %>-rtl.css',
          'dist/css/<%= pkg.name %>-theme.min.css': 'dist/css/<%= pkg.name %>-theme.css'
        }
      }
    },

    autoprefixer: {
      options: {
        browsers: ['last 2 versions', 'ie 8', 'ie 9', 'android 2.3', 'android 4', 'opera 12']
      },
      core: {
        options: {
          map: true
        },
        src: 'dist/css/<%= pkg.name %>.css'
      },
      theme: {
        options: {
          map: true
        },
        src: 'dist/css/<%= pkg.name %>-theme.css'
      },
      docs: {
        src: 'docs/assets/css/docs.css'
      },
      examples: {
        expand: true,
        cwd: 'docs/examples/',
        src: ['**/*.css'],
        dest: 'docs/examples/'
      }
    },

    css_flip: {
      rtl: {
        files: {
          'dist/css/<%= pkg.name %>-rtl.css': 'dist/css/<%= pkg.name %>.css'
        }
      }
    },

    cssmin: {
      compress: {
        options: {
          keepSpecialComments: '*',
          noAdvanced: true, // turn advanced optimizations off until the issue is fixed in clean-css
          report: 'min',
          compatibility: 'ie8'
        },
        src: [
          'docs/assets/css/src/docs.css',
          'docs/assets/css/src/pygments-manni.css'
        ],
        dest: 'docs/assets/css/docs.min.css'
      }
    },

    usebanner: {
      dist: {
        options: {
          position: 'top',
          banner: '<%= banner %>'
        },
        files: {
          src: [
            'dist/css/<%= pkg.name %>.css',
            'dist/css/<%= pkg.name %>-rtl.css',
            'dist/css/<%= pkg.name %>.min.css',
            'dist/css/<%= pkg.name %>-rtl.min.css',
            'dist/css/<%= pkg.name %>-theme.css',
            'dist/css/<%= pkg.name %>-theme.min.css'
          ]
        }
      }
    },

    csscomb: {
      options: {
        config: 'less/.csscomb.json'
      },
      dist: {
        files: {
          'dist/css/<%= pkg.name %>.css': 'dist/css/<%= pkg.name %>.css',
          'dist/css/<%= pkg.name %>-rtl.css': 'dist/css/<%= pkg.name %>-rtl.css',
          'dist/css/<%= pkg.name %>-theme.css': 'dist/css/<%= pkg.name %>-theme.css'
        }
      },
      examples: {
        expand: true,
        cwd: 'docs/examples/',
        src: '**/*.css',
        dest: 'docs/examples/'
      },
      docs: {
        files: {
          'docs/assets/css/src/docs.css': 'docs/assets/css/src/docs.css'
        }
      }
    },

    copy: {
      fonts: {
        expand: true,
        src: 'fonts/*',
        dest: 'dist/'
      },
      docs: {
        expand: true,
        cwd: './dist',
        src: [
          '{css,js}/*.min.*',
          'css/*.map',
          'fonts/*'
        ],
        dest: 'docs/dist'
      }
    },

    qunit: {
      options: {
        inject: 'js/tests/unit/phantom.js'
      },
      files: 'js/tests/index.html'
    },

    connect: {
      server: {
        options: {
          port: 3000,
          base: '.'
        }
      }
    },

    jekyll: {
      docs: {}
    },

    jade: {
      compile: {
        options: {
          pretty: true,
          data: function () {
            var filePath = path.join(__dirname, 'less/variables.less');
            var fileContent = fs.readFileSync(filePath, {encoding: 'utf8'});
            var parser = new BsLessdocParser(fileContent);
            return {sections: parser.parseFile()};
          }
        },
        files: {
          'docs/_includes/customizer-variables.html': 'docs/jade/customizer-variables.jade',
          'docs/_includes/nav-customize.html': 'docs/jade/customizer-nav.jade'
        }
      }
    },

    validation: {
      options: {
        charset: 'utf-8',
        doctype: 'HTML5',
        failHard: true,
        reset: true,
        relaxerror: [
          'Bad value X-UA-Compatible for attribute http-equiv on element meta.',
          'Element img is missing required attribute src.'
        ]
      },
      files: {
        src: '_gh_pages/**/*.html'
      }
    },

    watch: {
      src: {
        files: '<%= jshint.src.src %>',
        tasks: ['jshint:src', 'qunit']
      },
      test: {
        files: '<%= jshint.test.src %>',
        tasks: ['jshint:test', 'qunit']
      },
      less: {
        files: 'less/*.less',
        tasks: 'less'
      }
    },

    sed: {
      versionNumber: {
        pattern: (function () {
          var old = grunt.option('oldver');
          return old ? RegExp.quote(old) : old;
        })(),
        replacement: grunt.option('newver'),
        recursive: true
      }
    },

    'saucelabs-qunit': {
      all: {
        options: {
          build: process.env.TRAVIS_JOB_ID,
          concurrency: 10,
          urls: ['http://127.0.0.1:3000/js/tests/index.html'],
          browsers: grunt.file.readYAML('test-infra/sauce_browsers.yml')
        }
      }
    },

    exec: {
      npmUpdate: {
        command: 'npm update'
      },
      npmShrinkWrap: {
        command: 'npm shrinkwrap --dev'
      }
    }
  });

  // These plugins provide necessary tasks.
  require('load-grunt-tasks')(grunt, {scope: 'devDependencies'});
  require('time-grunt')(grunt);

  // Docs HTML validation task
  grunt.registerTask('validate-html', ['jekyll', 'validation']);

  // Test task.
  var testSubtasks = [];
  // Skip core tests if running a different subset of the test suite
  if (!process.env.TWBS_TEST || process.env.TWBS_TEST === 'core') {
    testSubtasks = testSubtasks.concat(['dist-css', 'csslint', 'jshint', 'jscs', 'qunit', 'build-customizer-html']);
  }
  // Skip HTML validation if running a different subset of the test suite
  if (!process.env.TWBS_TEST || process.env.TWBS_TEST === 'validate-html') {
    testSubtasks.push('validate-html');
  }
  // Only run Sauce Labs tests if there's a Sauce access key
  if (typeof process.env.SAUCE_ACCESS_KEY !== 'undefined' &&
      // Skip Sauce if running a different subset of the test suite
      (!process.env.TWBS_TEST || process.env.TWBS_TEST === 'sauce-js-unit')) {
    testSubtasks.push('connect');
    testSubtasks.push('saucelabs-qunit');
  }
  grunt.registerTask('test', testSubtasks);

  // JS distribution task.
  grunt.registerTask('dist-js', ['concat', 'uglify']);

  // CSS distribution task.
  grunt.registerTask('less-compile', ['less:compileCore', 'less:compileTheme']);
  grunt.registerTask('dist-css', ['less-compile', 'autoprefixer', 'css_flip', 'csscomb', 'less:minify', 'cssmin', 'usebanner']);

  // Docs distribution task.
  grunt.registerTask('dist-docs', 'copy:docs');

  // Full distribution task.
  grunt.registerTask('dist', ['clean', 'dist-css', 'copy:fonts', 'dist-js', 'dist-docs']);

  // Default task.
  grunt.registerTask('default', ['test', 'dist', 'build-glyphicons-data', 'build-customizer', 'update-shrinkwrap']);

  // Version numbering task.
  // grunt change-version-number --oldver=A.B.C --newver=X.Y.Z
  // This can be overzealous, so its changes should always be manually reviewed!
  grunt.registerTask('change-version-number', 'sed');

  grunt.registerTask('build-glyphicons-data', generateGlyphiconsData);

  // task for building customizer
  grunt.registerTask('build-customizer', ['build-customizer-html', 'build-raw-files']);
  grunt.registerTask('build-customizer-html', 'jade');
  grunt.registerTask('build-raw-files', 'Add scripts/less files to customizer.', function () {
    var banner = grunt.template.process('<%= banner %>');
    generateRawFiles(banner);
  });

  // Task for updating the npm packages used by the Travis build.
  grunt.registerTask('update-shrinkwrap', ['exec:npmUpdate', 'exec:npmShrinkWrap', '_update-shrinkwrap']);
  grunt.registerTask('_update-shrinkwrap', function () { updateShrinkwrap.call(this, grunt); });
};
<|endoftext|>


<commit_before>$(window).ready(function() {

// Safari compatibility
window.URL = window.URL || window.webkitURL

var files = {}
var rcvFile = {}
var fileMIME = new RegExp(
	'^(image\/(png|jpeg|gif))|(application\/((x-compressed)|' +
	'(x-zip-compressed)|(zip)))|(multipart/x-zip)$'
)

function cn(to) {
	return Cryptocat.conversationName + '@' + Cryptocat.conferenceServer + '/' + to
}

Cryptocat.beginSendFile = function(data) {
	if (!data.file.type.match(fileMIME)) {
		$('#fileInfoField').text(Cryptocat.language['chatWindow']['fileTypeError'])
		return
	}
	else if (data.file.size > (Cryptocat.fileSize * 1024)) {
		$('#fileInfoField').text(Cryptocat.language['chatWindow']['fileSizeError'])
		return
	}
	else {
		window.setTimeout(function() {
			$('#dialogBoxClose').click()
		}, 500)
	}
	sid = Cryptocat.connection.getUniqueId()
	files[sid] = {
		to: data.to,
		position: 0,
		file: data.file,
		key: data.key,
		total: Math.ceil(data.file.size / Cryptocat.chunkSize),
		ctr: -1
	}
	Cryptocat.connection.si_filetransfer.send(
		cn(data.to),
		sid,
		data.file.name,
		data.file.size,
		data.file.type,
		function(err) {
			if (err) {
				return console.log(err)
			}
			Cryptocat.connection.ibb.open(cn(data.to), sid, Cryptocat.chunkSize, function(err) {
				if (err) {
					return console.log(err)
				}
				Cryptocat.addToConversation(sid, Cryptocat.myNickname, data.to, true)
				Cryptocat.sendFileData({
					start: true,
					to: data.to,
					sid: sid
				})
			})
		}
	)
}

Cryptocat.sendFileData = function(data) {
	var sid = data.sid
	var seq = data.start ? 0 : parseInt(data.seq, 10) + 1
	if (seq > 65535) seq = 0
	if (files[sid].position > files[sid].file.size) {
		Cryptocat.connection.ibb.close(cn(data.to), sid, function(err) {
			if (err) {
				return console.log(err)
			}
		})
		Cryptocat.updateFileProgressBar(sid, files[sid].ctr + 1, files[sid].file.size, data.to)
		return
	}
	var end = files[sid].position + Cryptocat.chunkSize
	var chunk = files[sid].file.slice(files[sid].position, end)
	files[sid].position = end
	files[sid].ctr += 1
	var reader = new FileReader()
	reader.onload = function(event) {
		var msg = event.target.result
		// Remove dataURL header
		msg = msg.split(',')[1]
		// Encrypt
		// don't use seq as a counter
		// it repeats after 65535 above
		var opts = {
			mode: CryptoJS.mode.CTR,
			iv: CryptoJS.enc.Latin1.parse(OTR.HLP.packCtr(files[sid].ctr)),
			padding: CryptoJS.pad.NoPadding
		}
		var aesctr = CryptoJS.AES.encrypt (
			CryptoJS.enc.Base64.parse(msg),
			CryptoJS.enc.Latin1.parse(files[sid].key[0]),
			opts
		)
		msg = aesctr.toString()
		// Then mac
		var prefix = OTR.HLP.packBytes(files[sid].ctr, 8)
		prefix += OTR.HLP.packBytes(files[sid].total, 8)
		var mac = CryptoJS.HmacSHA512(
			CryptoJS.enc.Base64.parse(prefix + msg),
			CryptoJS.enc.Latin1.parse(files[sid].key[1])
		)
		// Combine ciphertext and mac, then transfer chunk
		msg += mac.toString(CryptoJS.enc.Base64)
		Cryptocat.connection.ibb.data(cn(data.to), sid, seq, msg, function(err) {
			if (err) {
				return console.log(err)
			}
			Cryptocat.sendFileData({
				seq: seq,
				to: data.to,
				sid: sid
			})
		})
		Cryptocat.updateFileProgressBar(sid, files[sid].ctr + 1, files[sid].file.size, data.to)
	}
	reader.readAsDataURL(chunk)
}

Cryptocat.ibbHandler = function(type, from, sid, data, seq) {
	var nick = from.split('/')[1]
	switch (type) {
		case 'open':
			var file = rcvFile[from][sid].filename
			rcvFile[from][sid].key = Cryptocat.fileKeys[nick][file]
			if (sid.match(/^\w{64}$/) && rcvFile[from][sid].mime.match(fileMIME)) {
				Cryptocat.addToConversation(sid, nick, nick, true)
			}
			delete Cryptocat.fileKeys[nick][file]
			break
		case 'data':
			if (rcvFile[from][sid].abort) return
			rcvFile[from][sid].seq = seq
			var key = rcvFile[from][sid].key
			var ss = data.length - 88
			var msg = data.substring(0, ss)
			var mac = data.substring(ss)
			var prefix = OTR.HLP.packBytes(rcvFile[from][sid].ctr, 8)
			prefix += OTR.HLP.packBytes(rcvFile[from][sid].total, 8)
			var cmac = CryptoJS.HmacSHA512(
				CryptoJS.enc.Base64.parse(prefix + msg),
				CryptoJS.enc.Latin1.parse(key[1])
			)
			if (mac !== cmac.toString(CryptoJS.enc.Base64)) {
				rcvFile[from][sid].abort = true
				console.log('OTR file transfer: MACs do not match.')
				return
			}
			var opts = {
				mode: CryptoJS.mode.CTR,
				iv: CryptoJS.enc.Latin1.parse(OTR.HLP.packCtr(rcvFile[from][sid].ctr)),
				padding: CryptoJS.pad.NoPadding
			}
			msg = CryptoJS.AES.decrypt(msg, CryptoJS.enc.Latin1.parse(key[0]), opts)
			rcvFile[from][sid].data += (msg.toString(CryptoJS.enc.Latin1))
			rcvFile[from][sid].ctr += 1
			Cryptocat.updateFileProgressBar(sid, rcvFile[from][sid].ctr, rcvFile[from][sid].size, nick)
			break
		case 'close':
			if (!rcvFile[from][sid].abort) {
				// Convert data to blob
				var ia = new Uint8Array(rcvFile[from][sid].data.length)
				for (var i = 0; i < rcvFile[from][sid].data.length; i++) {
					ia[i] = rcvFile[from][sid].data.charCodeAt(i)
				}
				var blob = new Blob([ia], { type: rcvFile[from][sid].mime })
				var url = URL.createObjectURL(blob)
				if (rcvFile[from][sid].filename.match(/^[\w-.]+$/) &&
						rcvFile[from][sid].mime.match(fileMIME)
				) {
					Cryptocat.addFile(url, sid, nick, rcvFile[from][sid].filename)
				} else {
					console.log('Received file of unallowed file type ' +
						rcvFile[from][sid].mime + ' from ' + nick)
				}
			}
			delete rcvFile[from][sid]
			break
	}
}

Cryptocat.fileHandler = function(from, sid, filename, size, mime) {
	if (!rcvFile[from]) rcvFile[from] = {}
	rcvFile[from][sid] = {
		filename: filename,
		size: size,
		mime: mime,
		seq: 0,
		ctr: 0,
		total: Math.ceil(size / Cryptocat.chunkSize),
		abort: false,
		data: ''
	}
}

})<commit_msg>More checks.<commit_after>$(window).ready(function() {

// Safari compatibility
window.URL = window.URL || window.webkitURL

var files = {}
var rcvFile = {}
var fileMIME = new RegExp(
	'^(image\/(png|jpeg|gif))|(application\/((x-compressed)|' +
	'(x-zip-compressed)|(zip)))|(multipart/x-zip)$'
)

function cn(to) {
	return Cryptocat.conversationName + '@' + Cryptocat.conferenceServer + '/' + to
}

Cryptocat.beginSendFile = function(data) {
	if (!data.file.type.match(fileMIME)) {
		$('#fileInfoField').text(Cryptocat.language['chatWindow']['fileTypeError'])
		return
	}
	else if (data.file.size > (Cryptocat.fileSize * 1024)) {
		$('#fileInfoField').text(Cryptocat.language['chatWindow']['fileSizeError'])
		return
	}
	else {
		window.setTimeout(function() {
			$('#dialogBoxClose').click()
		}, 500)
	}
	sid = Cryptocat.connection.getUniqueId()
	files[sid] = {
		to: data.to,
		position: 0,
		file: data.file,
		key: data.key,
		total: Math.ceil(data.file.size / Cryptocat.chunkSize),
		ctr: -1
	}
	Cryptocat.connection.si_filetransfer.send(
		cn(data.to),
		sid,
		data.file.name,
		data.file.size,
		data.file.type,
		function(err) {
			if (err) {
				return console.log(err)
			}
			Cryptocat.connection.ibb.open(cn(data.to), sid, Cryptocat.chunkSize, function(err) {
				if (err) {
					return console.log(err)
				}
				Cryptocat.addToConversation(sid, Cryptocat.myNickname, data.to, true)
				Cryptocat.sendFileData({
					start: true,
					to: data.to,
					sid: sid
				})
			})
		}
	)
}

Cryptocat.sendFileData = function(data) {
	var sid = data.sid
	var seq = data.start ? 0 : parseInt(data.seq, 10) + 1
	if (seq > 65535) seq = 0
	if (files[sid].position > files[sid].file.size) {
		Cryptocat.connection.ibb.close(cn(data.to), sid, function(err) {
			if (err) {
				return console.log(err)
			}
		})
		Cryptocat.updateFileProgressBar(sid, files[sid].ctr + 1, files[sid].file.size, data.to)
		return
	}
	var end = files[sid].position + Cryptocat.chunkSize
	var chunk = files[sid].file.slice(files[sid].position, end)
	files[sid].position = end
	files[sid].ctr += 1
	var reader = new FileReader()
	reader.onload = function(event) {
		var msg = event.target.result
		// Remove dataURL header
		msg = msg.split(',')[1]
		// Encrypt
		// don't use seq as a counter
		// it repeats after 65535 above
		var opts = {
			mode: CryptoJS.mode.CTR,
			iv: CryptoJS.enc.Latin1.parse(OTR.HLP.packCtr(files[sid].ctr)),
			padding: CryptoJS.pad.NoPadding
		}
		var aesctr = CryptoJS.AES.encrypt (
			CryptoJS.enc.Base64.parse(msg),
			CryptoJS.enc.Latin1.parse(files[sid].key[0]),
			opts
		)
		msg = aesctr.toString()
		// Then mac
		var prefix = OTR.HLP.packBytes(files[sid].ctr, 8)
		prefix += OTR.HLP.packBytes(files[sid].total, 8)
		var mac = CryptoJS.HmacSHA512(
			CryptoJS.enc.Base64.parse(prefix + msg),
			CryptoJS.enc.Latin1.parse(files[sid].key[1])
		)
		// Combine ciphertext and mac, then transfer chunk
		msg += mac.toString(CryptoJS.enc.Base64)
		Cryptocat.connection.ibb.data(cn(data.to), sid, seq, msg, function(err) {
			if (err) {
				return console.log(err)
			}
			Cryptocat.sendFileData({
				seq: seq,
				to: data.to,
				sid: sid
			})
		})
		Cryptocat.updateFileProgressBar(sid, files[sid].ctr + 1, files[sid].file.size, data.to)
	}
	reader.readAsDataURL(chunk)
}

Cryptocat.ibbHandler = function(type, from, sid, data, seq) {
	var nick = from.split('/')[1]
	switch (type) {
		case 'open':
			var file = rcvFile[from][sid].filename
			rcvFile[from][sid].key = Cryptocat.fileKeys[nick][file]
			if (sid.match(/^\w{64}$/) && rcvFile[from][sid].mime.match(fileMIME)) {
				Cryptocat.addToConversation(sid, nick, nick, true)
			}
			delete Cryptocat.fileKeys[nick][file]
			break
		case 'data':
			if (rcvFile[from][sid].abort) return
			if (rcvFile[from][sid].ctr > rcvFile[from][sid].total - 1) {
				rcvFile[from][sid].abort = true
				return
			}
			rcvFile[from][sid].seq = seq
			var key = rcvFile[from][sid].key
			var ss = data.length - 88
			var msg = data.substring(0, ss)
			var mac = data.substring(ss)
			var prefix = OTR.HLP.packBytes(rcvFile[from][sid].ctr, 8)
			prefix += OTR.HLP.packBytes(rcvFile[from][sid].total, 8)
			var cmac = CryptoJS.HmacSHA512(
				CryptoJS.enc.Base64.parse(prefix + msg),
				CryptoJS.enc.Latin1.parse(key[1])
			)
			if (mac !== cmac.toString(CryptoJS.enc.Base64)) {
				rcvFile[from][sid].abort = true
				console.log('OTR file transfer: MACs do not match.')
				return
			}
			var opts = {
				mode: CryptoJS.mode.CTR,
				iv: CryptoJS.enc.Latin1.parse(OTR.HLP.packCtr(rcvFile[from][sid].ctr)),
				padding: CryptoJS.pad.NoPadding
			}
			msg = CryptoJS.AES.decrypt(msg, CryptoJS.enc.Latin1.parse(key[0]), opts)
			rcvFile[from][sid].data += (msg.toString(CryptoJS.enc.Latin1))
			rcvFile[from][sid].ctr += 1
			Cryptocat.updateFileProgressBar(sid, rcvFile[from][sid].ctr, rcvFile[from][sid].size, nick)
			break
		case 'close':
			if (!rcvFile[from][sid].abort &&
				rcvFile[from][sid].total === (rcvFile[from][sid].ctr)
      ) {
				// Convert data to blob
				var ia = new Uint8Array(rcvFile[from][sid].data.length)
				for (var i = 0; i < rcvFile[from][sid].data.length; i++) {
					ia[i] = rcvFile[from][sid].data.charCodeAt(i)
				}
				var blob = new Blob([ia], { type: rcvFile[from][sid].mime })
				var url = URL.createObjectURL(blob)
				if (rcvFile[from][sid].filename.match(/^[\w-.]+$/) &&
						rcvFile[from][sid].mime.match(fileMIME)
				) {
					Cryptocat.addFile(url, sid, nick, rcvFile[from][sid].filename)
				} else {
					console.log('Received file of unallowed file type ' +
						rcvFile[from][sid].mime + ' from ' + nick)
				}
			}
			delete rcvFile[from][sid]
			break
	}
}

Cryptocat.fileHandler = function(from, sid, filename, size, mime) {
	if (!rcvFile[from]) rcvFile[from] = {}
	rcvFile[from][sid] = {
		filename: filename,
		size: size,
		mime: mime,
		seq: 0,
		ctr: 0,
		total: Math.ceil(size / Cryptocat.chunkSize),
		abort: false,
		data: ''
	}
}

})<|endoftext|>


<commit_before>module.exports = function(grunt) {

  // Project configuration.
  grunt.initConfig({
    pkg: grunt.file.readJSON('package.json'),
    jshint: {
      all: ['Grunfile.js', 'drupal-common/src/*']
    },
    watch: {
      humanise: {
        files: ['style/humanise/sass/**/*.scss'],
        tasks: ['compass:humanise'],
        options: {
          spawn: false,
        }
      },
      karenslyst: {
        files: ['style/karenslyst/sass/**/*.scss'],
        tasks: ['compass:karenslyst'],
        options: {
          spawn: false,
        }
      }
    },
    compass: {
      humanise: {
        options: {
          sassDir: "style/humanise/sass",
          cssDir: "style/humanise/css",
        }
      },
      karenslyst: {
        options: {
          sassDir: "style/karenslyst/sass",
          cssDir: "style/karenslyst/css",
        }
      }
    },
    clean: {
      transfer: ["transfer"],
    },
  });

  // Load plugins.
  grunt.loadNpmTasks('grunt-contrib-concat');
  grunt.loadNpmTasks('grunt-contrib-jshint');
  grunt.loadNpmTasks('grunt-contrib-symlink');
  grunt.loadNpmTasks('grunt-contrib-uglify');
  grunt.loadNpmTasks('grunt-shell');
  grunt.loadNpmTasks('grunt-contrib-watch');
  grunt.loadNpmTasks('grunt-contrib-compass');
  grunt.loadNpmTasks('grunt-contrib-copy');
  grunt.loadNpmTasks('grunt-contrib-clean');
  grunt.loadNpmTasks('grunt-jsdoc');

  // Default task(s).
  grunt.registerTask('default', 'Standard tasks', ['watch']);

};<commit_msg>No comments<commit_after>module.exports = function(grunt) {

  // Project configuration.
  grunt.initConfig({
    pkg: grunt.file.readJSON('package.json'),
    jshint: {
      all: ['Grunfile.js', 'drupal-common/src/*']
    },
    watch: {
      humanise: {
        files: ['style/humanise/sass/**/*.scss'],
        tasks: ['compass:humanise'],
        options: {
          spawn: false,
        }
      },
      karenslyst: {
        files: ['style/karenslyst/sass/**/*.scss'],
        tasks: ['compass:karenslyst'],
        options: {
          spawn: false,
        }
      }
    },
    compass: {
      humanise: {
        options: {
          sassDir: "style/humanise/sass",
          cssDir: "style/humanise/css",
			    noLineComments: true,
        }
      },
      karenslyst: {
        options: {
          sassDir: "style/karenslyst/sass",
          cssDir: "style/karenslyst/css",
			    noLineComments: true,
        }
      }
    },
    clean: {
      transfer: ["transfer"],
    },
  });

  // Load plugins.
  grunt.loadNpmTasks('grunt-contrib-concat');
  grunt.loadNpmTasks('grunt-contrib-jshint');
  grunt.loadNpmTasks('grunt-contrib-symlink');
  grunt.loadNpmTasks('grunt-contrib-uglify');
  grunt.loadNpmTasks('grunt-shell');
  grunt.loadNpmTasks('grunt-contrib-watch');
  grunt.loadNpmTasks('grunt-contrib-compass');
  grunt.loadNpmTasks('grunt-contrib-copy');
  grunt.loadNpmTasks('grunt-contrib-clean');
  grunt.loadNpmTasks('grunt-jsdoc');

  // Default task(s).
  grunt.registerTask('default', 'Standard tasks', ['watch']);

};<|endoftext|>


<commit_before>/*jslint es5:true, indent:2, maxlen:80, node:true*/
'use strict';

module.exports = function (grunt) {

  // Project configuration.
  grunt.initConfig({

    jslint: {
      all: {
        src: [
          '**/*.js',
          '**/*.json',
        ],
        exclude: [
//          'test/**/*',
          'node_modules/**/*'
        ],
        options: {
          errorsOnly: true,
          failOnError: true
        }
      }
    },

    mochacli: {
      options: {
        require: ['chai'],
        ui: 'tdd'
      },
      all: ['test/*.js']
    },

    mochacov: {
      html: {
        options: {
          reporter: 'html-cov',
          output: 'coverage.html'
        }
      },
      coveralls: {
        options: {
          coveralls: {
            serviceName: 'travis-ci'
          }
        }
      },
      options: {
        require: ['chai'],
        ui: 'tdd'
      },
      all: ['test/*.js']
    },

    watch: {
      scripts: {
        files: [
          '<%= jslint.all.src %>'
        ],
        tasks: ['test'],
        options: {
          interrupt: true
        }
      }
    }
  });

  grunt.loadNpmTasks('grunt-contrib-watch');
  grunt.loadNpmTasks('grunt-jslint');
  grunt.loadNpmTasks('grunt-mocha-cli');
  grunt.loadNpmTasks('grunt-mocha-cov');

  grunt.registerTask('travis', ['jslint', 'mochacli', 'mochacov:coveralls']);
  grunt.registerTask('test', ['jslint', 'mochacli', 'mochacov:html']);

  // Default task.
  grunt.registerTask('default', ['test']);

};
<commit_msg>fix Gruntfile.js watch and jslint tasks<commit_after>/*jslint es5:true, indent:2, maxlen:80, node:true*/
'use strict';

module.exports = function (grunt) {

  // Project configuration.
  grunt.initConfig({

    jslint: {
      all: {
        src: [
          '**/*.js',
          '**/*.json',
          '!node_modules/**/*'
        ],
        options: {
          errorsOnly: true,
          failOnError: true
        }
      }
    },

    mochacli: {
      options: {
        require: ['chai'],
        ui: 'tdd'
      },
      all: ['test/*.js']
    },

    mochacov: {
      html: {
        options: {
          reporter: 'html-cov',
          output: 'coverage.html'
        }
      },
      coveralls: {
        options: {
          coveralls: {
            serviceName: 'travis-ci'
          }
        }
      },
      options: {
        require: ['chai'],
        ui: 'tdd'
      },
      all: ['test/*.js']
    },

    watch: {
      scripts: {
        files: '<%= jslint.all.src %>',
        tasks: ['test'],
        options: {
          interrupt: true
        }
      }
    }
  });

  grunt.loadNpmTasks('grunt-contrib-watch');
  grunt.loadNpmTasks('grunt-jslint');
  grunt.loadNpmTasks('grunt-mocha-cli');
  grunt.loadNpmTasks('grunt-mocha-cov');

  grunt.registerTask('travis', ['jslint', 'mochacli', 'mochacov:coveralls']);
  grunt.registerTask('test', ['jslint', 'mochacli', 'mochacov:html']);

  // Default task.
  grunt.registerTask('default', ['test']);

};
<|endoftext|>


<commit_before>module.exports = function(grunt) {

  require('matchdep').filterDev('grunt-*').forEach(grunt.loadNpmTasks);

  grunt.initConfig({
    pkg: grunt.file.readJSON('package.json'),
    source: 'src',
    release: 'release',
    test: 'test',
    temp: '.tmp',

    bump: {
      options: {
        files: ['package.json', 'bower.json'],
        commit: true,
        commitMessage: 'Release v%VERSION%',
        commitFiles: ['-a'], // '-a' for all files
        createTag: true,
        tagName: 'v%VERSION%',
        tagMessage: 'Version %VERSION%',
        push: true,
        pushTo: 'origin',
        gitDescribeOptions: '--tags --always --abbrev=1 --dirty=-d' // options to use with '$ git describe'
      }
    },

    clean: {
      swf: '<%= release %>',
      temp: '<%= temp %>'
    },

    exec: {
      check_for_mxmlc: {
        cmd: 'mxmlc --version',
        callback: function(error) {
          if (error) {
            grunt.log.writeln("Couldn't find Flex SDK on your path!");
            grunt.log.writeln('You can download it here: http://sourceforge.net/adobe/flexsdk/wiki/Flex%20SDK/');
          }
        }
      },
      build_swf: {
        cmd: 'mxmlc <%= source %>/Player.as -o <%= temp %>/divine-player.swf -use-network=false -static-link-runtime-shared-libraries=true'
      }
    },

    copy: {
      swf: {
        files: [{expand: true, cwd: '<%= temp %>', src: '*', dest: '<%= release %>', filter: 'isFile'}]
      }
    }

  });

  grunt.registerTask('default', ['build']);

  grunt.registerTask('build', [
    'exec:check_for_mxmlc',
    'clean:swf',
    'exec:build_swf',
    'copy:swf',
    'clean:temp'
  ]);

  grunt.registerTask('release', [
    'build',
    'bump'
  ]);

  grunt.registerTask('release:patch', [
    'build',
    'bump:patch'
  ]);

  grunt.registerTask('release:minor', [
    'build',
    'bump:minor'
  ]);

  grunt.registerTask('release:major', [
    'build',
    'bump:major'
  ]);
};
<commit_msg>Remove grunt release tasks – they're just noise.<commit_after>module.exports = function(grunt) {

  require('matchdep').filterDev('grunt-*').forEach(grunt.loadNpmTasks);

  grunt.initConfig({
    pkg: grunt.file.readJSON('package.json'),
    source: 'src',
    release: 'release',
    test: 'test',
    temp: '.tmp',

    bump: {
      options: {
        files: ['package.json', 'bower.json'],
        commit: true,
        commitMessage: 'Release v%VERSION%',
        commitFiles: ['-a'], // '-a' for all files
        createTag: true,
        tagName: 'v%VERSION%',
        tagMessage: 'Version %VERSION%',
        push: true,
        pushTo: 'origin',
        gitDescribeOptions: '--tags --always --abbrev=1 --dirty=-d' // options to use with '$ git describe'
      }
    },

    clean: {
      swf: '<%= release %>',
      temp: '<%= temp %>'
    },

    exec: {
      check_for_mxmlc: {
        cmd: 'mxmlc --version',
        callback: function(error) {
          if (error) {
            grunt.log.writeln("Couldn't find Flex SDK on your path!");
            grunt.log.writeln('You can download it here: http://sourceforge.net/adobe/flexsdk/wiki/Flex%20SDK/');
          }
        }
      },
      build_swf: {
        cmd: 'mxmlc <%= source %>/Player.as -o <%= temp %>/divine-player.swf -use-network=false -static-link-runtime-shared-libraries=true'
      }
    },

    copy: {
      swf: {
        files: [{expand: true, cwd: '<%= temp %>', src: '*', dest: '<%= release %>', filter: 'isFile'}]
      }
    }

  });

  grunt.registerTask('default', ['build']);

  grunt.registerTask('build', [
    'exec:check_for_mxmlc',
    'clean:swf',
    'exec:build_swf',
    'copy:swf',
    'clean:temp'
  ]);
};
<|endoftext|>


<commit_before>module.exports = function (grunt) {

    /* Task configuration */

    grunt.initConfig({

        pkg: grunt.file.readJSON('package.json'),

        watch: {

            src: {

                files: [ 'Gruntfile.js', 'src/**/*.js', 'src/templates/**/*.template' ],
                tasks: [ 'jshint:src', 'build' ],

            },

            spec: {

                files: 'spec/**/*.js',
                tasks: 'jshint:spec',

            },

            sass: {

                files: 'src/css/*.scss',
                tasks: 'sass',
            }
        },

        handlebars: {

            template: {

                files: {

                    'dist/<%= pkg.name %>-templates.js': 'src/templates/**/*.template'

                },

                options: {

                    namespace: 'Handlebars.templates',

                    processName: function (path) {

                        // Use filename as the name of the template (View.template -> View)
                        var split = path.split('/');
                        var file = split[split.length - 1];
                        var filename = file.split('.')[0];

                        return filename;
                    }
                }
            }
        },

        concat: {

            dist: {

                src: [ 'src/<%= pkg.name %>.js', 'src/**/*.js' ],
                dest: 'dist/<%= pkg.name %>.js',
                options: {

                    separator: ';'

                }
            },

            handlebars: {

                src: ['dist/<%= pkg.name %>-templates.js',
                      'dist/<%= pkg.name %>.js'],
                dest: 'dist/<%= pkg.name %>.js',
                options: {

                    separator: ';'

                }
            }
        },

        uglify: {

            dist: {

                files: {

                    'dist/<%= pkg.name %>-min.js': 'dist/<%= pkg.name %>.js'

                },

                options: {

                    report: 'min'

                }
            }
        },

        jshint: {

            src: {

                src: [ 'Gruntfile.js', 'src/**/*.js' ],
                options: {

                    jshintrc: 'jshint.json'

                }
            },

            spec: {

                src: 'spec/**/*.js',
                options: {

                    jshintrc: 'spec/jshint.json'

                }
            }
        },

        sass: {

            dist: {

                files: {

                    'demo/assets/css/<%= pkg.name %>.css': 'src/css/<%= pkg.name %>.scss'

                },

                options: {

                    style: 'compressed'

                }
            }
        },

        copy: {

            assets: {

                expand: true,
                flatten: true,
                src: [ 'dist/<%= pkg.name %>.js', 'dist/<%= pkg.name %>-min.js' ],
                dest: 'demo/assets/js/',
                filter: 'isFile'

            }
        },

        clean: {

            build: [ 'dist/', 'coverage/', 'demo/assets/' ]

        },

        jasmine: {

            src: [ 'dist/<%= pkg.name %>-templates.js', 'src/<%= pkg.name %>.js', 'src/**/*.js' ],
            options: {

                vendor: [ 'http://cdnjs.cloudflare.com/ajax/libs/handlebars.js/1.3.0/handlebars.runtime.min.js' ],
                specs: 'spec/**/*-spec.js',
                template: require('grunt-template-jasmine-istanbul'),
                templateOptions: {

                    coverage: 'coverage/coverage.json',
                    report: {

                        type: 'lcov',
                        options: {

                            dir: 'coverage/'

                        }
                    }
                }
            }
        }
    });

    /* Load tasks */

    grunt.loadNpmTasks('grunt-contrib-watch');
    grunt.loadNpmTasks('grunt-contrib-handlebars');
    grunt.loadNpmTasks('grunt-contrib-concat');
    grunt.loadNpmTasks('grunt-contrib-uglify');
    grunt.loadNpmTasks('grunt-contrib-jshint');
    grunt.loadNpmTasks('grunt-contrib-sass');
    grunt.loadNpmTasks('grunt-contrib-copy');
    grunt.loadNpmTasks('grunt-contrib-clean');
    grunt.loadNpmTasks('grunt-contrib-jasmine');

    /* Register tasks */

    grunt.registerTask('test', [ 'jshint', 'jasmine' ]);
    grunt.registerTask('build', [ 'handlebars', 'concat:dist', 'concat:handlebars', 'uglify', 'sass', 'copy' ]);
    grunt.registerTask('default', [ 'test', 'build' ]);
}
<commit_msg>Fix clean and test tasks<commit_after>module.exports = function (grunt) {

    /* Task configuration */

    grunt.initConfig({

        pkg: grunt.file.readJSON('package.json'),

        watch: {

            src: {

                files: [ 'Gruntfile.js', 'src/**/*.js', 'src/templates/**/*.template' ],
                tasks: [ 'jshint:src', 'build' ],

            },

            spec: {

                files: 'spec/**/*.js',
                tasks: 'jshint:spec',

            },

            sass: {

                files: 'src/css/*.scss',
                tasks: 'sass',
            }
        },

        handlebars: {

            template: {

                files: {

                    'dist/<%= pkg.name %>-templates.js': 'src/templates/**/*.template'

                },

                options: {

                    namespace: 'Handlebars.templates',

                    processName: function (path) {

                        // Use filename as the name of the template (View.template -> View)
                        var split = path.split('/');
                        var file = split[split.length - 1];
                        var filename = file.split('.')[0];

                        return filename;
                    }
                }
            }
        },

        concat: {

            dist: {

                src: [ 'src/<%= pkg.name %>.js', 'src/**/*.js' ],
                dest: 'dist/<%= pkg.name %>.js',
                options: {

                    separator: ';'

                }
            },

            handlebars: {

                src: ['dist/<%= pkg.name %>-templates.js',
                      'dist/<%= pkg.name %>.js'],
                dest: 'dist/<%= pkg.name %>.js',
                options: {

                    separator: ';'

                }
            }
        },

        uglify: {

            dist: {

                files: {

                    'dist/<%= pkg.name %>-min.js': 'dist/<%= pkg.name %>.js'

                },

                options: {

                    report: 'min'

                }
            }
        },

        jshint: {

            src: {

                src: [ 'Gruntfile.js', 'src/**/*.js' ],
                options: {

                    jshintrc: 'jshint.json'

                }
            },

            spec: {

                src: 'spec/**/*.js',
                options: {

                    jshintrc: 'spec/jshint.json'

                }
            }
        },

        sass: {

            dist: {

                files: {

                    'demo/assets/css/<%= pkg.name %>.css': 'src/css/<%= pkg.name %>.scss'

                },

                options: {

                    style: 'compressed'

                }
            }
        },

        copy: {

            assets: {

                expand: true,
                flatten: true,
                src: [ 'dist/<%= pkg.name %>.js', 'dist/<%= pkg.name %>-min.js' ],
                dest: 'demo/assets/js/',
                filter: 'isFile'

            }
        },

        clean: {

            build: [ 'dist/', 'coverage/', 'demo/assets/js/tmc-web-client*.js' ]

        },

        jasmine: {

            src: [ 'dist/<%= pkg.name %>-templates.js', 'src/<%= pkg.name %>.js', 'src/**/*.js' ],
            options: {

                vendor: [ 'http://cdnjs.cloudflare.com/ajax/libs/handlebars.js/1.3.0/handlebars.runtime.min.js' ],
                specs: 'spec/**/*-spec.js',
                template: require('grunt-template-jasmine-istanbul'),
                templateOptions: {

                    coverage: 'coverage/coverage.json',
                    report: {

                        type: 'lcov',
                        options: {

                            dir: 'coverage/'

                        }
                    }
                }
            }
        }
    });

    /* Load tasks */

    grunt.loadNpmTasks('grunt-contrib-watch');
    grunt.loadNpmTasks('grunt-contrib-handlebars');
    grunt.loadNpmTasks('grunt-contrib-concat');
    grunt.loadNpmTasks('grunt-contrib-uglify');
    grunt.loadNpmTasks('grunt-contrib-jshint');
    grunt.loadNpmTasks('grunt-contrib-sass');
    grunt.loadNpmTasks('grunt-contrib-copy');
    grunt.loadNpmTasks('grunt-contrib-clean');
    grunt.loadNpmTasks('grunt-contrib-jasmine');

    /* Register tasks */

    grunt.registerTask('test', [ 'jshint', 'handlebars', 'jasmine' ]);
    grunt.registerTask('build', [ 'handlebars', 'concat:dist', 'concat:handlebars', 'uglify', 'sass', 'copy' ]);
    grunt.registerTask('default', [ 'test', 'build' ]);
}
<|endoftext|>


<commit_before>/*!
 * OS.js - JavaScript Cloud/Web Desktop Platform
 *
 * Copyright (c) 2011-2017, Anders Evenrud <andersevenrud@gmail.com>
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice, this
 *    list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright notice,
 *    this list of conditions and the following disclaimer in the documentation
 *    and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * @author  Anders Evenrud <andersevenrud@gmail.com>
 * @licence Simplified BSD License
 */
module.exports = function(grunt) {
  'use strict';

  grunt.file.defaultEncoding = 'utf-8';

  grunt.loadNpmTasks('grunt-eslint');
  grunt.loadNpmTasks('grunt-mocha-test');
  grunt.loadNpmTasks('grunt-mocha');
  grunt.loadNpmTasks('grunt-contrib-csslint');
  grunt.loadNpmTasks('grunt-contrib-validate-xml');

  grunt.registerTask('testBuild', 'Tests the build', function() {
    var files = [
      'dist/index.html',
      'dist/favicon.ico',
      'dist/dialogs.html',
      'dist/locales.min.js',
      'dist/osjs.min.js',
      'dist/osjs.min.css',
      'dist/packages.js',
      'dist/settings.js',
      'dist/splash.png'
    ];

    var result = files.every(function(filename) {
      if ( !grunt.file.exists(filename) ) {
        grunt.log.error('Missing file from build: ' + filename);
        return false;
      }
      return true;
    });

    return result;
  });

  grunt.registerTask('test', ['eslint', 'csslint', 'validate_xml', 'mochaTest'/*, 'mocha'*/, 'testBuild']);

  grunt.initConfig({
    pkg: grunt.file.readJSON('package.json'),
    eslint: {
      options: {
        configFile: '.eslintrc'
      },
      target: [
        'Gruntfile.js',
        'src/*.js',
        'src/build/*.js',
        'src/server/node/*.js',
        'src/server/node/**/*.js',
        'src/client/javascript/*.js',
        'src/client/javascript/**/*.js',
        'src/packages/default/**/*.js',
        '!src/packages/default/**/locales.js',
        '!src/packages/default/**/locale.js'
      ]
    },
    csslint: {
      options: {
        csslintrc: '.csslintrc'
      },
      strict: {
        src: [
          'src/client/stylesheets/*.css',
          '!src/client/stylesheets/gui.css',
          '!src/client/stylesheets/debug.css',
          'src/client/themes/fonts/*/*.css',
          'src/client/themes/styles/*/*.css',
          'src/packages/default/*/*.css',
          '!src/packages/default/CoreWM/animations.css'
        ]
      },
      lax: {
        options: {
          'known-properties': false,
          'compatible-vendor-prefixes': false
        },
        src: [
          'src/client/stylesheets/gui.css',
          'src/client/stylesheets/debug.css'
        ]
      }
    },
    mochaTest: {
      test: {
        src: ['src/server/test/node/*.js']
      }
    },
    mocha: {
      test: {
        options: {
          urls: ['http://localhost:8000/test.html']
        }
      }
    },
    validate_xml: {
      all: {
        src: [
          'src/client/dialogs.html',
          'src/packages/default/*/scheme.html'
        ]
      }
    }
  });
};
<commit_msg>Updated Grunt tests<commit_after>/*!
 * OS.js - JavaScript Cloud/Web Desktop Platform
 *
 * Copyright (c) 2011-2017, Anders Evenrud <andersevenrud@gmail.com>
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice, this
 *    list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright notice,
 *    this list of conditions and the following disclaimer in the documentation
 *    and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * @author  Anders Evenrud <andersevenrud@gmail.com>
 * @licence Simplified BSD License
 */
module.exports = function(grunt) {
  'use strict';

  grunt.file.defaultEncoding = 'utf-8';

  grunt.loadNpmTasks('grunt-eslint');
  grunt.loadNpmTasks('grunt-mocha-test');
  grunt.loadNpmTasks('grunt-mocha');
  grunt.loadNpmTasks('grunt-contrib-csslint');
  grunt.loadNpmTasks('grunt-contrib-validate-xml');

  grunt.registerTask('testBuild', 'Tests the build', function() {
    var files = [
      'src/server/settings.json',
      'src/server/packages.json',
      'dist/index.html',
      'dist/favicon.ico',
      'dist/dialogs.html',
      'dist/locales.min.js',
      'dist/osjs.min.js',
      'dist/osjs.min.css',
      'dist/settings.js',
      'dist/splash.png'
    ];

    var result = files.every(function(filename) {
      if ( !grunt.file.exists(filename) ) {
        grunt.log.error('Missing file from build: ' + filename);
        return false;
      }
      return true;
    });

    return result;
  });

  grunt.registerTask('test', ['eslint', 'csslint', 'validate_xml', 'mochaTest'/*, 'mocha'*/, 'testBuild']);

  grunt.initConfig({
    pkg: grunt.file.readJSON('package.json'),
    eslint: {
      options: {
        configFile: '.eslintrc'
      },
      target: [
        'Gruntfile.js',
        'src/*.js',
        'src/build/*.js',
        'src/server/node/*.js',
        'src/server/node/**/*.js',
        'src/client/javascript/*.js',
        'src/client/javascript/**/*.js',
        'src/packages/default/**/*.js',
        '!src/packages/default/**/locales.js',
        '!src/packages/default/**/locale.js'
      ]
    },
    csslint: {
      options: {
        csslintrc: '.csslintrc'
      },
      strict: {
        src: [
          'src/client/stylesheets/*.css',
          '!src/client/stylesheets/gui.css',
          '!src/client/stylesheets/debug.css',
          'src/client/themes/fonts/*/*.css',
          'src/client/themes/styles/*/*.css',
          'src/packages/default/*/*.css',
          '!src/packages/default/CoreWM/animations.css'
        ]
      },
      lax: {
        options: {
          'known-properties': false,
          'compatible-vendor-prefixes': false
        },
        src: [
          'src/client/stylesheets/gui.css',
          'src/client/stylesheets/debug.css'
        ]
      }
    },
    mochaTest: {
      test: {
        src: ['src/server/test/node/*.js']
      }
    },
    mocha: {
      test: {
        options: {
          urls: ['http://localhost:8000/test.html']
        }
      }
    },
    validate_xml: {
      all: {
        src: [
          'src/client/dialogs.html',
          'src/packages/default/*/scheme.html'
        ]
      }
    }
  });
};
<|endoftext|>


<commit_before>// You have a turtle named 'yurt' at the ready.
function t (s) {
  'use strict';
  yurt.pd();
  // decorate with an arc that indicates the orientation of the rhombus
  //yurt.lt(2 * 36);
  //yurt.arc 4 * 36 :s * 0.618034 / 2
  //yurt.rt(2 * 36);

  yurt.rt(2 * 36);
  yurt.fd(s);
  yurt.lt(4 * 36);
  yurt.fd(s);
  yurt.lt(1 * 36);
  yurt.fd(s);
  yurt.lt(4 * 36);
  yurt.fd(s);
  yurt.lt(1 * 36);
  yurt.lt(2 * 36);
  yurt.pu();
}

function w (s) {
  'use strict';
  yurt.pd();
  // decorate with an arc that indicates the orientation of the rhombus
  //yurt.lt(1 * 36
  //arc 2 * 36 :s * 0.618034
  //yurt.rt(1 * 36

  yurt.rt(1 * 36);
  yurt.fd(s);
  yurt.lt(2 * 36);
  yurt.fd(s);
  yurt.lt(3 * 36);
  yurt.fd(s);
  yurt.lt(2 * 36);
  yurt.fd(s);
  yurt.lt(3 * 36);
  yurt.lt(1 * 36);
  yurt.pu();
}

// generate (at_scale, kind[t,w], recursion_depth, paint_all_levels)
function gen (s, k, depth, paint_at_level) {
  'use strict';
  var dep, scale;
  if (depth < 1) {
    //setcolor :depth
    if (k === 't') {
      t(s);
    }
    if (k === 'w') {
      w(s);
    }
  }
  else {
    dep = depth -1;
    scale = s * 0.618034;

    if (k === 't') {
      // generate a t and w
      // first the t
      yurt.fd(scale);
      yurt.rt(3 * 36);
      //setcolor :depth
      if (paint_at_level >= depth) {
        t(scale);
      }
      gen(scale, 't', dep, paint_at_level);

      yurt.lt(2 * 36);
      yurt.fd(scale);
      yurt.rt(3 * 36);
      //setcolor :depth
      if (paint_at_level >= depth) {
        w(scale);
      }
      gen(scale, 'w', dep, paint_at_level);

      yurt.rt(1 * 36);
      yurt.fd(scale);
      yurt.rt(1 * 36);
      yurt.fd(scale);

      yurt.rt(4 * 36);
  }
    if (k === 'w') {
      // w -> w t w
      // first generate w
      yurt.rt(2 * 36);
      yurt.fd(s);
      yurt.rt(5 * 36);
      //setcolor :depth
      if (paint_at_level >= depth) {
        w(scale);
      }
      gen(scale, 'w', dep, paint_at_level);

      yurt.rt(2 * 36);
      yurt.fd(scale);
      yurt.lt(3 * 36);
      //setcolor :depth
      if(paint_at_level >= depth) {
        t(scale);
      }
      gen(scale, 't', dep, paint_at_level);

      // last another w

      yurt.rt(2 * 36);
      yurt.fd(scale);
      yurt.rt(2 * 36);
      yurt.fd(scale);
      yurt.rt(4 * 36);
      //setcolor :depth
      if (paint_at_level >= depth) {
        w(scale);
      }
      gen(scale, 'w', dep, paint_at_level);
      yurt.rt(1 * 36);
      yurt.fd(s * 1.618034);
      yurt.lt(5 * 36);
    }
  }
}
yurt.cs();
yurt.home();
yurt.pu();
yurt.lt(90);
yurt.fd(220);
yurt.rt(90);

yurt.rt(2 * 36);
var level = 0;
var scale = 280;
// level one test of 't'
//t(scale);
gen(scale, 't', level, 1);
yurt.lt(1 * 36);

yurt.bk(scale * 1.618034);
yurt.rt(1 * 36);
yurt.fd(scale * 1.618034);
yurt.lt(1 * 36);

yurt.rt(90 - 36);
yurt.fd(40);
yurt.lt(90 - 36);

// level one test of 'w'
//w(scale);
gen(scale, 'w', level, 1);
<commit_msg>Update fractal_penrose.js<commit_after>// You have a turtle named 'yurt' at the ready.
function t (s, rise) {
  'use strict';
  yurt.pd();
  // decorate with an arc that indicates the orientation of the rhombus
  //yurt.lt(2 * 36);
  //yurt.arc 4 * 36 :s * 0.618034 / 2
  //yurt.rt(2 * 36);

  yurt.rt(2 * 36);
  yurt.fd(s, rise);
  yurt.lt(4 * 36);
  yurt.fd(s, rise);
  yurt.lt(1 * 36);
  yurt.fd(s, -rise);
  yurt.lt(4 * 36);
  yurt.fd(s, -rise);
  yurt.lt(1 * 36);
  yurt.lt(2 * 36);
  yurt.pu();
}

function w (s, rise) {
  'use strict';
  yurt.pd();
  // decorate with an arc that indicates the orientation of the rhombus
  //yurt.lt(1 * 36
  //arc 2 * 36 :s * 0.618034
  //yurt.rt(1 * 36

  yurt.rt(1 * 36);
  yurt.fd(s, rise);
  yurt.lt(2 * 36);
  yurt.fd(s, rise);
  yurt.lt(3 * 36);
  yurt.fd(s, -rise);
  yurt.lt(2 * 36);
  yurt.fd(s, -rise);
  yurt.lt(3 * 36);
  yurt.lt(1 * 36);
  yurt.pu();
}

// generate (at_scale, kind[t,w], recursion_depth, paint_all_levels)
function gen (s, k, depth, paint_at_level) {
  'use strict';
  var dep, scale;
  if (depth < 1) {
    //setcolor :depth
    if (k === 't') {
      t(s);
    }
    if (k === 'w') {
      w(s);
    }
  }
  else {
    dep = depth -1;
    scale = s * 0.618034;

    if (k === 't') {
      // generate a t and w
      // first the t
      yurt.fd(scale);
      yurt.rt(3 * 36);
      //setcolor :depth
      if (paint_at_level >= depth) {
        t(scale);
      }
      gen(scale, 't', dep, paint_at_level);

      yurt.lt(2 * 36);
      yurt.fd(scale);
      yurt.rt(3 * 36);
      //setcolor :depth
      if (paint_at_level >= depth) {
        w(scale);
      }
      gen(scale, 'w', dep, paint_at_level);

      yurt.rt(1 * 36);
      yurt.fd(scale);
      yurt.rt(1 * 36);
      yurt.fd(scale);

      yurt.rt(4 * 36);
  }
    if (k === 'w') {
      // w -> w t w
      // first generate w
      yurt.rt(2 * 36);
      yurt.fd(s);
      yurt.rt(5 * 36);
      //setcolor :depth
      if (paint_at_level >= depth) {
        w(scale);
      }
      gen(scale, 'w', dep, paint_at_level);

      yurt.rt(2 * 36);
      yurt.fd(scale);
      yurt.lt(3 * 36);
      //setcolor :depth
      if(paint_at_level >= depth) {
        t(scale);
      }
      gen(scale, 't', dep, paint_at_level);

      // last another w

      yurt.rt(2 * 36);
      yurt.fd(scale);
      yurt.rt(2 * 36);
      yurt.fd(scale);
      yurt.rt(4 * 36);
      //setcolor :depth
      if (paint_at_level >= depth) {
        w(scale);
      }
      gen(scale, 'w', dep, paint_at_level);
      yurt.rt(1 * 36);
      yurt.fd(s * 1.618034);
      yurt.lt(5 * 36);
    }
  }
}
yurt.cs();
yurt.home();
yurt.pu();
yurt.lt(90);
yurt.fd(220);
yurt.rt(90);

yurt.rt(2 * 36);
var level = 0;
var scale = 280;
// level one test of 't'
//t(scale);
gen(scale, 't', level, 1);
yurt.lt(1 * 36);

yurt.bk(scale * 1.618034);
yurt.rt(1 * 36);
yurt.fd(scale * 1.618034);
yurt.lt(1 * 36);

yurt.rt(90 - 36);
yurt.fd(40);
yurt.lt(90 - 36);

// level one test of 'w'
//w(scale);
gen(scale, 'w', level, 1);
<|endoftext|>


<commit_before>module.exports = function(grunt){

  grunt.initConfig({
    compass: {
      dev: {
        options: {
          sassDir: 'client/src/sass',
          cssDir: 'client/src/css/dev',
          outputStyle: 'expanded',
          noLineComments: false
        }
      },
      prod: {
        options: {
          sassDir: 'client/src/sass',
          cssDir: 'client/src/css/prod',
          outputStyle: 'compressed',
          noLineComments: true,
          force: true
        }
      }
    },
    watch: {
      sass: {
        files: 'client/src/sass/**/*.scss',
        tasks: 'compass:dev'
      }/*,
      js: {
        files: '<%= jshint.files %>',
        tasks: 'jshint'
      }*/
    }
  });

  grunt.loadNpmTasks('grunt-contrib-compass');
  grunt.loadNpmTasks('grunt-contrib-watch');

  grunt.registerTask('server', function(){ require('./server/server.js').listen(3000); });
  grunt.registerTask('start', ['server', 'watch']);

};<commit_msg>Updated Gruntfile with jshint conf.<commit_after>module.exports = function(grunt){

  grunt.initConfig({
    jshint: {
      options: {
        browser: true,
        es5: true
      },
      src: ['client/src/js/**/*.js', '!client/src/js/lib/*.js'],
      test: ['client/test/**/*.js', '!client/test/lib/jasmine-1.2.0/*', '!client/test/lib/jasmine-reporters/*.js'],
      server: ['server/**/*.js', '!server/node_modules/**/*']
    },
    compass: {
      dev: {
        options: {
          sassDir: 'client/src/sass',
          cssDir: 'client/src/css/dev',
          outputStyle: 'expanded',
          noLineComments: false
        }
      },
      prod: {
        options: {
          sassDir: 'client/src/sass',
          cssDir: 'client/src/css/prod',
          outputStyle: 'compressed',
          noLineComments: true,
          force: true
        }
      }
    },
    watch: {
      sass: {
        files: 'client/src/sass/**/*.scss',
        tasks: 'compass:dev'
      },
      jsSrc: {
        files: '<%= jshint.src %>',
        tasks: 'jshint:src'
      },
      jsTest: {
        files: '<%= jshint.test %>',
        tasks: 'jshint:test'
      },
      jsServer: {
        files: '<%= jshint.server %>',
        tasks: 'jshint:server'
      }
    }
  });

  grunt.loadNpmTasks('grunt-contrib-compass');
  grunt.loadNpmTasks('grunt-contrib-jshint');
  grunt.loadNpmTasks('grunt-contrib-watch');

  grunt.registerTask('server', function(){ require('./server/server.js').listen(3000); });
  grunt.registerTask('start', ['server', 'watch']);

};<|endoftext|>


<commit_before>Expression.List.ComplexPolar = function (x){
	x.__proto__ = Expression.List.ComplexPolar.prototype;
}
Expression.List.ComplexPolar.prototype = Object.create(Expression.List);
Expression.List.ComplexPolar.prototype.polar = function(){
	return this;
};
Expression.List.ComplexPolar.prototype.realimag = function() {
	//TODO: Return Expression.List.ComplexCartesian
	return Expression.List.ComplexCartesian([
		this[0].apply("*", Global.cos.apply(undefined, this[1])),
		this[0].apply("*", Global.sin.apply(undefined, this[1])),
	]);
};
Expression.List.ComplexPolar.prototype.real = function() {
	return this[0].apply("*", Global.cos.apply(undefined, this[1]));
};
Expression.List.ComplexPolar.prototype.imag = function() {
	return this[0].apply("*", Global.sin.apply(undefined, this[1]));
};
Expression.List.ComplexPolar.prototype.conjugate = function() {
	return Expression.List.ComplexPolar([
		this[0],
		this[1].apply("@-")
	]);
};
Expression.List.ComplexPolar.prototype.apply = function(o, x) {
	if (x.constructor === this.constructor) {
		switch (o) {
			case "*":
				//Fast
				return Expression.List.ComplexPolar([
					this[0].apply("*", x[0]),
					this[1].apply("+", x[1])
				]);
			case "/":
				//Also fast
				return Expression.List.ComplexPolar([
					this[0].apply("/", x[0]),
					this[1].apply("-", x[1])
				]);
			case "+":
			case "-":
				//Very slow, maybe we should switch to cartesian now?

			case "^":
				//(Ae^(ik)) ^ (Be^(ij))
				//How slow is this?
				//Very fast for real numbers though
			case "!":
			default:

		}
	} else if (x.constructor === Expression.NumericalReal) {
		switch (o) {
			case "*":
				//Fast
				return Expression.List.ComplexPolar([
					this[0].apply("*", x),
					this[1]
				]);
			case "/":
				//Also fast
				return Expression.List.ComplexPolar([
					this[0].apply("/", x),
					this[1]
				]);
			case "+":
			case "-":
				//Very slow, maybe we should switch to cartesian now?

			case "^":
				//Fast:
				return Expression.List.ComplexPolar([
					this[0],
					this[1].apply("*", x)
				]);
			case "!":
			default:

		}
	} else if (x.constructor === Expression.Complex) {
		switch (o) {
			case "*":
				//Fast
				return Expression.List.ComplexPolar([
					this[0].apply("*", new Expression.NumericalReal(x._real)),
					this[1].apply("+", new Expression.NumericalReal(x._imag))
				]);
			case "/":
				//Also fast
				return Expression.List.ComplexPolar([
					this[0].apply("/", new Expression.NumericalReal(x._real)),
					this[1].apply("-", new Expression.NumericalReal(x._imag)
				]);
			case "+":
			case "-":
				//Very slow, maybe we should switch to cartesian now?

			case "^":
				//(Ae^(ik)) ^ (Be^(ij))
				//How slow is this?
				//Very fast for real numbers though
			case "!":
			default:

		}
	}

};
Expression.List.ComplexPolar.abs = function (){
	return this[0];
};
Expression.List.ComplexPolar.arg = function (){
	return this[1];
};
Expression.List.ComplexPolar.prototype.constructor = Expression.List.ComplexPolar;<commit_msg>automatically switch between complex polar and complex cartesian style expressions (lists)<commit_after>Expression.List.ComplexPolar = function (x){
	x.__proto__ = Expression.List.ComplexPolar.prototype;
}
Expression.List.ComplexPolar.prototype = Object.create(Expression.List);
Expression.List.ComplexPolar.prototype.polar = function(){
	return this;
};
Expression.List.ComplexPolar.prototype.realimag = function() {
	//TODO: Return Expression.List.ComplexCartesian
	return Expression.List.ComplexCartesian([
		this[0].apply("*", Global.cos.apply(undefined, this[1])),
		this[0].apply("*", Global.sin.apply(undefined, this[1])),
	]);
};
Expression.List.ComplexPolar.prototype.real = function() {
	return this[0].apply("*", Global.cos.apply(undefined, this[1]));
};
Expression.List.ComplexPolar.prototype.imag = function() {
	return this[0].apply("*", Global.sin.apply(undefined, this[1]));
};
Expression.List.ComplexPolar.prototype.conjugate = function() {
	return Expression.List.ComplexPolar([
		this[0],
		this[1].apply("@-")
	]);
};
Expression.List.ComplexPolar.prototype.apply = function(o, x) {
	if (x.constructor === this.constructor) {
		switch (o) {
			case "*":
				//Fast
				return Expression.List.ComplexPolar([
					this[0].apply("*", x[0]),
					this[1].apply("+", x[1])
				]);
			case "/":
				//Also fast
				return Expression.List.ComplexPolar([
					this[0].apply("/", x[0]),
					this[1].apply("-", x[1])
				]);
			case "+":
			case "-":
				//Very slow, maybe we should switch to cartesian now?

			case "^":
				//(Ae^(ik)) ^ (Be^(ij))
				//How slow is this?
				//Very fast for real numbers though
			case "!":
			default:

		}
	} else if (x.constructor === Expression.NumericalReal) {
		switch (o) {
			case "*":
				//Fast
				return Expression.List.ComplexPolar([
					this[0].apply("*", x),
					this[1]
				]);
			case "/":
				//Also fast
				return Expression.List.ComplexPolar([
					this[0].apply("/", x),
					this[1]
				]);
			case "+":
			case "-":
				//Very slow, maybe we should switch to cartesian now?

			case "^":
				//Fast:
				return Expression.List.ComplexPolar([
					this[0],
					this[1].apply("*", x)
				]);
			case "!":
			default:

		}
	} else if (x.constructor === Expression.Complex) {
		switch (o) {
			case "*":
				//Fast
				return Expression.List.ComplexPolar([
					this[0].apply("*", new Expression.NumericalReal(x._real)),
					this[1].apply("+", new Expression.NumericalReal(x._imag))
				]);
			case "/":
				//Also fast
				return Expression.List.ComplexPolar([
					this[0].apply("/", new Expression.NumericalReal(x._real)),
					this[1].apply("-", new Expression.NumericalReal(x._imag))
				]);
			case "+":
			case "-":
				//Very slow, maybe we should switch to cartesian now?

			case "^":
				//(Ae^(ik)) ^ (Be^(ij))
				//How slow is this?
				//Very fast for real numbers though
			case "!":
			default:

		}
	}

};
Expression.List.ComplexPolar.abs = function (){
	return this[0];
};
Expression.List.ComplexPolar.arg = function (){
	return this[1];
};
Expression.List.ComplexPolar.prototype.constructor = Expression.List.ComplexPolar;<|endoftext|>


<commit_before>module.exports = function(grunt) {
  grunt.initConfig({
    jshint: {
      options: {
        curly: true,
        eqnull: true,
        eqeqeq: true,
        undef: true
      },
      node: {
        options: {
          node: true
        },
        src: ['Gruntfile.js']
      },
      src: {
        options: {
          browser: true
        },
        src: ['EventEmitter.js']
      },
      test: {
        options: {
          globals: {
            EventEmitter: true,
            describe: true,
            beforeEach: true,
            afterEach: true,
            it: true,
            expect: true
          }
        },
        src: ['EventEmitterSpecs.js']
      }
    },
    karma: {
      options: {
        files: ['EventEmitter.js', 'EventEmitterSpecs.js'],
        frameworks: ['jasmine'],
        browsers: ['PhantomJS'],
        reporters: ['dots']
      },
      test: {
        singleRun: true
      },
      coverage: {
        singleRun: true,
        reporters: ['dots', 'coverage'],
        preprocessors: {
          'EventEmitter.js': ['coverage']
        },
        coverageReporter: {
          reporters: [
            { type: 'html', dir: 'coverage/' },
            { type: 'text-summary' }
          ]
        }
      },
      watch: {
        autoWatch: true
      }
    },
    watch: {
      lint: {
        options: {
          atBegin: true
        },
        files: ['*.js'],
        tasks: ['jshint']
      },
      dev: {
        options: {
          atBegin: true
        },
        files: ['*.js'],
        tasks: ['jshint', 'karma:test'],
      }
    }
  });

  grunt.loadNpmTasks('grunt-contrib-jshint');
  grunt.loadNpmTasks('grunt-contrib-watch');
  grunt.loadNpmTasks('grunt-karma');
  grunt.loadNpmTasks('grunt-shell');

  grunt.registerTask('default', ['jshint', 'karma:test']);
  grunt.registerTask('test', ['karma:watch']);
  grunt.registerTask('cover', ['karma:coverage']);
};
<commit_msg>Fix Missing npm Package Ref<commit_after>module.exports = function(grunt) {
  grunt.initConfig({
    jshint: {
      options: {
        curly: true,
        eqnull: true,
        eqeqeq: true,
        undef: true
      },
      node: {
        options: {
          node: true
        },
        src: ['Gruntfile.js']
      },
      src: {
        options: {
          browser: true
        },
        src: ['EventEmitter.js']
      },
      test: {
        options: {
          globals: {
            EventEmitter: true,
            describe: true,
            beforeEach: true,
            afterEach: true,
            it: true,
            expect: true
          }
        },
        src: ['EventEmitterSpecs.js']
      }
    },
    karma: {
      options: {
        files: ['EventEmitter.js', 'EventEmitterSpecs.js'],
        frameworks: ['jasmine'],
        browsers: ['PhantomJS'],
        reporters: ['dots']
      },
      test: {
        singleRun: true
      },
      coverage: {
        singleRun: true,
        reporters: ['dots', 'coverage'],
        preprocessors: {
          'EventEmitter.js': ['coverage']
        },
        coverageReporter: {
          reporters: [
            { type: 'html', dir: 'coverage/' },
            { type: 'text-summary' }
          ]
        }
      },
      watch: {
        autoWatch: true
      }
    },
    watch: {
      lint: {
        options: {
          atBegin: true
        },
        files: ['*.js'],
        tasks: ['jshint']
      },
      dev: {
        options: {
          atBegin: true
        },
        files: ['*.js'],
        tasks: ['jshint', 'karma:test'],
      }
    }
  });

  grunt.loadNpmTasks('grunt-contrib-jshint');
  grunt.loadNpmTasks('grunt-contrib-watch');
  grunt.loadNpmTasks('grunt-karma');

  grunt.registerTask('default', ['jshint', 'karma:test']);
  grunt.registerTask('test', ['karma:watch']);
  grunt.registerTask('cover', ['karma:coverage']);
};
<|endoftext|>