<commit_before>'use strict';
/*jshint node:true*/
module.exports = function (grunt) {
  require('load-grunt-tasks')(grunt);
  var setup = grunt.file.readJSON(__dirname + '/package.json').setup;

  grunt.initConfig({
    setup: setup,

    copy: {
      themeInfo: {
        files: [{
          expand: true,
          src: ['theme.toml', 'LICENSE'],
          dest: '<%= setup.target %>/'
        }]
      },
      bootstrapFonts: {
        files: [{
          cwd: 'node_modules/camunda-commons-ui/node_modules/bootstrap/fonts/',
          expand: true,
          src: ['**/*'],
          dest: '<%= setup.target %>/static/fonts/'
        }]
      },
      bpmnFonts: {
        files: [{
          cwd: 'node_modules/camunda-commons-ui/node_modules/bpmn-font/dist/font/',
          expand: true,
          src: ['**/*'],
          dest: '<%= setup.target %>/static/fonts/'
        }]
      },
      uiFonts: {
        files: [{
          cwd: 'node_modules/camunda-commons-ui/vendor/fonts/',
          expand: true,
          src: ['**/*'],
          dest: '<%= setup.target %>/static/fonts/'
        }]
      },
      docsFonts: {
        files: [{
          cwd: 'fonts/',
          expand: true,
          src: ['**/*', '!config.json'],
          dest: '<%= setup.target %>/static/fonts/'
        }]
      },
      layouts: {
        files: [{
          cwd: 'layouts/',
          expand: true,
          src: ['**/*'],
          dest: '<%= setup.target %>/layouts/'
        }]
      },
      images: {
        files: [{
          cwd: 'node_modules/camunda-commons-ui/resources/img/',
          expand: true,
          src: ['favicon.ico'],
          dest: '<%= setup.target %>/static/img/'
        },
        {
          cwd: 'images/',
          expand: true,
          src: ['**/*'],
          dest: '<%= setup.target %>/static/img/'
        }]
      }
    },

    less: {
      options: {
        dumpLineNumbers: 'all',
        paths: ['node_modules']
      },
      styles: {
        files: [{
          src: ['styles/docs.less'],
          dest: '<%= setup.target %>/static/css/docs.css'
        }]
      }
    },

    browserify: {
      scripts: {
        files: [{
          src: ['scripts/index.js'],
          dest: '<%= setup.target %>/static/js/docs.js'
        }]
      }
    },

    watch: {
      layouts: {
        files: ['layouts/**/*'],
        tasks: ['copy:layouts']
      },
      styles: {
        files: ['styles/**/*.less'],
        tasks: ['less:styles']
      },
      scripts: {
        files: ['scripts/**/*.js'],
        tasks: ['browserify:scripts']
      }
    },

    cssmin: {
      styles: {
        files: [{
          src: '<%= setup.target %>/static/css/docs.css',
          dest: '<%= setup.target %>/static/css/docs.css'
        }]
      }
    },

    uglify: {
      scripts: {
        files: [{
          src: '<%= setup.target %>/static/js/docs.js',
          dest: '<%= setup.target %>/static/js/docs.js'
        }]
      }
    },

    // -----------------------------------------------

    clean: ['.tmp'],

    gitclone: {
      dist: {
        options: {
          directory: '.tmp',
          repository: 'git@github.com:camunda/camunda-docs-theme.git',

        }
      }
    },

    gitcheckout: {
      dist: {
        options: {
          cwd: '.tmp',
          branch: 'dist'
        }
      }
    },

    gitadd: {
      dist: {
        options: {
          cwd: '.tmp',
          all: true
        }
      }
    },

    gitcommit: {
      dist: {
        options: {
          cwd: '.tmp',
          message: 'chore(update): publish new version of theme',
          noStatus: true,
          allowEmpty: true
        }
      }
    },

    gitpush: {
      dist: {
        options: {
          cwd: '.tmp',
          remote: 'origin',
          branch: 'dist'
        }
      }
    }
  });

  grunt.registerTask('build', ['copy', 'less:styles', 'browserify:scripts']);

  grunt.registerTask('optimize', [
    'uglify:scripts',
    'cssmin:styles'
  ]);

  grunt.registerTask('publish', function () {
    grunt.config.set('setup.target', '.tmp');
    grunt.config.set('setup.minify', true);

    grunt.task.run([
      'clean',
      'gitclone:dist',
      'gitcheckout:dist',
      'build',
      'optimize',
      'gitadd:dist',
      'gitcommit:dist',
      'gitpush:dist'
    ]);
  });

  grunt.registerTask('default', ['build', 'watch']);
};
<commit_msg>impr(grunt): add environment variable support for build target<commit_after>'use strict';
/*jshint node:true*/
module.exports = function (grunt) {
  require('load-grunt-tasks')(grunt);
  var setup = grunt.file.readJSON(__dirname + '/package.json').setup;

  setup.target = process.env.THEME_TARGET || setup.target;

  grunt.initConfig({
    setup: setup,

    copy: {
      themeInfo: {
        files: [{
          expand: true,
          src: ['theme.toml', 'LICENSE'],
          dest: '<%= setup.target %>/'
        }]
      },
      bootstrapFonts: {
        files: [{
          cwd: 'node_modules/camunda-commons-ui/node_modules/bootstrap/fonts/',
          expand: true,
          src: ['**/*'],
          dest: '<%= setup.target %>/static/fonts/'
        }]
      },
      bpmnFonts: {
        files: [{
          cwd: 'node_modules/camunda-commons-ui/node_modules/bpmn-font/dist/font/',
          expand: true,
          src: ['**/*'],
          dest: '<%= setup.target %>/static/fonts/'
        }]
      },
      uiFonts: {
        files: [{
          cwd: 'node_modules/camunda-commons-ui/vendor/fonts/',
          expand: true,
          src: ['**/*'],
          dest: '<%= setup.target %>/static/fonts/'
        }]
      },
      docsFonts: {
        files: [{
          cwd: 'fonts/',
          expand: true,
          src: ['**/*', '!config.json'],
          dest: '<%= setup.target %>/static/fonts/'
        }]
      },
      layouts: {
        files: [{
          cwd: 'layouts/',
          expand: true,
          src: ['**/*'],
          dest: '<%= setup.target %>/layouts/'
        }]
      },
      images: {
        files: [{
          cwd: 'node_modules/camunda-commons-ui/resources/img/',
          expand: true,
          src: ['favicon.ico'],
          dest: '<%= setup.target %>/static/img/'
        },
        {
          cwd: 'images/',
          expand: true,
          src: ['**/*'],
          dest: '<%= setup.target %>/static/img/'
        }]
      }
    },

    less: {
      options: {
        dumpLineNumbers: 'all',
        paths: ['node_modules']
      },
      styles: {
        files: [{
          src: ['styles/docs.less'],
          dest: '<%= setup.target %>/static/css/docs.css'
        }]
      }
    },

    browserify: {
      scripts: {
        files: [{
          src: ['scripts/index.js'],
          dest: '<%= setup.target %>/static/js/docs.js'
        }]
      }
    },

    watch: {
      layouts: {
        files: ['layouts/**/*'],
        tasks: ['copy:layouts']
      },
      styles: {
        files: ['styles/**/*.less'],
        tasks: ['less:styles']
      },
      scripts: {
        files: ['scripts/**/*.js'],
        tasks: ['browserify:scripts']
      }
    },

    cssmin: {
      styles: {
        files: [{
          src: '<%= setup.target %>/static/css/docs.css',
          dest: '<%= setup.target %>/static/css/docs.css'
        }]
      }
    },

    uglify: {
      scripts: {
        files: [{
          src: '<%= setup.target %>/static/js/docs.js',
          dest: '<%= setup.target %>/static/js/docs.js'
        }]
      }
    },

    // -----------------------------------------------

    clean: ['.tmp'],

    gitclone: {
      dist: {
        options: {
          directory: '.tmp',
          repository: 'git@github.com:camunda/camunda-docs-theme.git',

        }
      }
    },

    gitcheckout: {
      dist: {
        options: {
          cwd: '.tmp',
          branch: 'dist'
        }
      }
    },

    gitadd: {
      dist: {
        options: {
          cwd: '.tmp',
          all: true
        }
      }
    },

    gitcommit: {
      dist: {
        options: {
          cwd: '.tmp',
          message: 'chore(update): publish new version of theme',
          noStatus: true,
          allowEmpty: true
        }
      }
    },

    gitpush: {
      dist: {
        options: {
          cwd: '.tmp',
          remote: 'origin',
          branch: 'dist'
        }
      }
    }
  });

  grunt.registerTask('build', ['copy', 'less:styles', 'browserify:scripts']);

  grunt.registerTask('optimize', [
    'uglify:scripts',
    'cssmin:styles'
  ]);

  grunt.registerTask('publish', function () {
    grunt.config.set('setup.target', '.tmp');
    grunt.config.set('setup.minify', true);

    grunt.task.run([
      'clean',
      'gitclone:dist',
      'gitcheckout:dist',
      'build',
      'optimize',
      'gitadd:dist',
      'gitcommit:dist',
      'gitpush:dist'
    ]);
  });

  grunt.registerTask('default', ['build', 'watch']);
};
<|endoftext|>


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

    require('time-grunt')(grunt);

    var version = grunt.option('release'),
        zipName = (version) ? version : 'DEV';

    // Project configuration.
    grunt.initConfig({

        connect: {
            dev: {
                options: {
                    port: 8580,
                    base: '.',
                    keepalive: true
                }
            },
            test: {
                options: {
                    port: 8581,
                    base: '.'
                }
            }
        },

        jshint: {
            all: ['Gruntfile.js', 'src/*.js', 'src/js/**/*.js', 'test/unit/*-test.js', 'test/integration/*.js'],
            options: {
                jshintrc: '.jshintrc'
            }
        },

        mocha: {
            all: {
                options: {
                    urls: [
                        'http://localhost:<%= connect.test.options.port %>/test/unit/index.html',
                        'http://localhost:<%= connect.test.options.port %>/test/integration/index.html'
                    ],
                    run: false,
                    reporter: 'Spec',
                    log: false,

                    // phanotmjs is soooo slow
                    timeout: 100000
                }
            }
        },

        clean: {
            dist: ['dist', 'test/lib', 'test/integration/src']
        },

        sass: {
            dist: {
                files: {
                    'src/css/read-sandbox.css': 'src/sass/read-sandbox.scss',
                    'src/css/all.css': 'src/sass/all.scss'
                }
            }
        },

        autoprefixer: {
            options: {
                browsers: ['last 2 versions']
            },
            dist: {
                files: {
                    'src/css/read-sandbox.css': 'src/css/read-sandbox.css',
                    'src/css/all.css': 'src/css/all.css'
                }
            }
        },

        csso: {
            options: {
                banner: '/*! Copyright © <%= grunt.template.today("yyyy") %>, Whiteout Networks GmbH.*/\n'
            },
            dist: {
                files: {
                    'dist/css/read-sandbox.min.css': 'src/css/read-sandbox.css',
                    'dist/css/all.min.css': 'src/css/all.css'
                }
            }
        },

        watch: {
            css: {
                files: ['src/sass/**/*.scss'],
                tasks: ['dist-css', 'manifest']
            },
            js: {
                files: ['src/js/**/*.js'],
                tasks: ['dist-js', 'copy:integration', 'manifest']
            },
            lib: {
                files: ['src/lib/**/*.js'],
                tasks: ['copy:lib', 'manifest']
            },
            app: {
                files: ['src/*.js', 'src/**/*.html', 'src/**/*.json', 'src/manifest.*', 'src/img/**/*', 'src/font/**/*'],
                tasks: ['copy:app', 'copy:ca', 'copy:tpl', 'copy:img', 'copy:font', 'manifest-dev', 'manifest']
            }
        },

        browserify: {
            app: {
                files: {
                    'dist/js/app.browserified.js': ['src/js/app.js']
                },
                options: {
                    external: ['openpgp', 'node-forge', 'net', 'tls', 'crypto'] // node.js apis not required at build time
                }
            },
            pbkdf2Worker: {
                files: {
                    'dist/js/pbkdf2-worker.browserified.js': ['src/js/crypto/pbkdf2-worker.js']
                }
            },
            unitTest: {
                files: {
                    'test/unit/index.js': ['test/unit/*-test.js']
                },
                options: {
                    external: []
                }
            },
            /*
              TODO:
              mailreader-worker: {},
              integrationTest: {}
            */
        },

        uglify: {
            app: {
                files: {
                    'dist/js/app.min.js': [
                        'src/lib/underscore/underscore-min.js',
                        'node_modules/jquery/dist/jquery.min.js',
                        'src/lib/angular/angular.min.js',
                        'src/lib/angular/angular-route.min.js',
                        'src/lib/angular/angular-animate.min.js',
                        'src/lib/ngtagsinput/ng-tags-input.min.js',
                        'node_modules/ng-infinite-scroll/build/ng-infinite-scroll.min.js',
                        'src/lib/fastclick/fastclick.js',
                        'src/lib/lawnchair/lawnchair-git.js',
                        'src/lib/lawnchair/lawnchair-adapter-webkit-sqlite-git.js',
                        'src/lib/lawnchair/lawnchair-adapter-indexed-db-git.js',
                        'dist/js/app.browserified.js'
                    ]
                },
                options: {
                    mangle: false,
                    sourceMap: true,
                    sourceMapName: 'dist/js/app.min.js.map'
                }
            },
            readSandbox: {
                files: {
                    'dist/js/read-sandbox.min.js': [
                        'node_modules/dompurify/purify.js',
                        'src/js/controller/read-sandbox.js'
                    ]
                },
                options: {
                    sourceMap: true,
                    sourceMapName: 'dist/js/read-sandbox.min.js.map'
                }

            },
            pbkdf2Worker: {
                files: {
                    'dist/js/pbkdf2-worker.min.js': ['dist/js/pbkdf2-worker.browserified.js']
                }
            },
            unitTest: {
                files: {
                    'test/unit/index.js': [
                        'src/lib/underscore/underscore-min.js',
                        'node_modules/jquery/dist/jquery.min.js',
                        'src/lib/openpgp/openpgp.js',
                        'src/lib/angular/angular.min.js',
                        'node_modules/angular-mocks/angular-mocks.js',
                        'src/lib/angular/angular-route.min.js',
                        'src/lib/angular/angular-animate.min.js',
                        'src/lib/ngtagsinput/ng-tags-input.min.js',
                        'src/lib/fastclick/fastclick.js',
                        'node_modules/ng-infinite-scroll/build/ng-infinite-scroll.min.js',
                        'src/lib/lawnchair/lawnchair-git.js',
                        'src/lib/lawnchair/lawnchair-adapter-webkit-sqlite-git.js',
                        'src/lib/lawnchair/lawnchair-adapter-indexed-db-git.js',
                        'node_modules/dompurify/purify.js',
                        'test/lib/angular-mocks.js',
                        'test/unit/index.js'
                    ]
                },
                options: {
                    compress: false
                }
            },
            options: {
                banner: '/*! Copyright © <%= grunt.template.today("yyyy") %>, Whiteout Networks GmbH.*/\n'
            }
        },

        copy: {
            npmDev: {
                expand: true,
                flatten: true,
                cwd: 'node_modules/',
                src: ['mocha/mocha.css', 'mocha/mocha.js', 'chai/chai.js', 'sinon/pkg/sinon.js', 'browsercrow/src/*.js', 'browsersmtp/src/*.js'],
                dest: 'test/lib/'
            },
            lib: {
                expand: true,
                flatten: true,
                cwd: 'src/lib/',
                src: ['openpgp/openpgp.js', 'openpgp/openpgp.worker.js', 'forge/forge.min.js'],
                dest: 'dist/js/'
            },
            font: {
                expand: true,
                cwd: 'src/font/',
                src: ['*'],
                dest: 'dist/font/'
            },
            img: {
                expand: true,
                cwd: 'src/img/',
                src: ['*'],
                dest: 'dist/img/'
            },
            tpl: {
                expand: true,
                cwd: 'src/tpl/',
                src: ['*'],
                dest: 'dist/tpl/'
            },
            app: {
                expand: true,
                cwd: 'src/',
                src: ['*.html', '*.js', '*.json', 'manifest.*'],
                dest: 'dist/'
            },
            integration: {
                expand: true,
                cwd: 'src/',
                src: ['**'],
                dest: 'test/integration/src/'
            }
        },

        compress: {
            main: {
                options: {
                    mode: 'zip',
                    archive: 'release/whiteout-mail_' + zipName + '.zip'
                },
                expand: true,
                cwd: 'dist/',
                src: ['**/*'],
                dest: 'release/'
            }
        },

        manifest: {
            generate: {
                options: {
                    basePath: 'dist/',
                    timestamp: true,
                    hash: true,
                    cache: ['socket.io/socket.io.js'],
                    exclude: [
                        'appcache.manifest',
                        'manifest.webapp',
                        'js/app.min.js.map',
                        'js/app.browserified.js',
                        'js/crypto/pbkdf2-worker.browserified.js',
                        'js/pbkdf2-worker.browserified.js',
                        'js/read-sandbox.min.js.map'
                    ],
                    master: ['index.html']
                },
                src: ['**/*.*'],
                dest: 'dist/appcache.manifest'
            }
        }

    });

    // Load the plugin(s)
    grunt.loadNpmTasks('grunt-browserify');
    grunt.loadNpmTasks('grunt-contrib-uglify');
    grunt.loadNpmTasks('grunt-contrib-connect');
    grunt.loadNpmTasks('grunt-contrib-jshint');
    grunt.loadNpmTasks('grunt-mocha');
    grunt.loadNpmTasks('grunt-contrib-clean');
    grunt.loadNpmTasks('grunt-csso');
    grunt.loadNpmTasks('grunt-contrib-sass');
    grunt.loadNpmTasks('grunt-autoprefixer');
    grunt.loadNpmTasks('grunt-contrib-watch');
    grunt.loadNpmTasks('grunt-contrib-copy');
    grunt.loadNpmTasks('grunt-contrib-compress');
    grunt.loadNpmTasks('grunt-manifest');

    // Build tasks
    grunt.registerTask('dist-npm', ['copy:npmDev']);
    grunt.registerTask('dist-css', ['sass', 'autoprefixer', 'csso']);
    grunt.registerTask('dist-js', ['browserify', 'uglify']);
    grunt.registerTask('dist-copy', ['copy']);
    grunt.registerTask('dist', ['clean', 'dist-npm', 'dist-css', 'dist-js', 'dist-copy', 'manifest']);

    // Test/Dev tasks
    grunt.registerTask('dev', ['connect:dev']);
    grunt.registerTask('test', ['jshint', 'connect:test', 'mocha']);
    grunt.registerTask('prod', ['connect:prod']);

    //
    // Release tasks for Chrome App Release Channels
    //

    grunt.registerTask('manifest-dev', function() {
        patchManifest({
            suffix: ' (DEV)',
            version: '9999.9999.9999.9999'
        });
    });
    grunt.registerTask('manifest-test', function() {
        if (!version) {
            throw new Error('You must specify the version: "--release=1.0"');
        }

        patchManifest({
            suffix: ' (TEST)',
            client_id: '440907777130-bfpgo5fbo4f7hetrg3hn57qolrtubs0u.apps.googleusercontent.com',
            version: version,
            deleteKey: true
        });
    });
    grunt.registerTask('manifest-stable', function() {
        if (!version) {
            throw new Error('You must specify the version: "--release=1.0"');
        }

        patchManifest({
            version: version,
            deleteKey: true,
            keyServer: 'https://keys.whiteout.io/',
            keychainServer: 'https://keychain.whiteout.io/'
        });
    });

    function patchManifest(options) {
        var fs = require('fs'),
            path = './dist/manifest.json',
            manifest = require(path);

        if (options.version) {
            manifest.version = options.version;
        }
        if (options.suffix) {
            manifest.name += options.suffix;
        }
        if (options.client_id) {
            manifest.oauth2.client_id = options.client_id;
        }
        if (options.keyServer) {
            var ksIndex = manifest.permissions.indexOf('https://keys-test.whiteout.io/');
            manifest.permissions[ksIndex] = options.keyServer;
        }
        if (options.keychainServer) {
            var kcsIndex = manifest.permissions.indexOf('https://keychain-test.whiteout.io/');
            manifest.permissions[kcsIndex] = options.keychainServer;
        }
        if (options.deleteKey) {
            delete manifest.key;
        }

        fs.writeFileSync(path, JSON.stringify(manifest, null, 2));
    }

    grunt.registerTask('release-dev', ['dist', 'manifest-dev', 'compress']);
    grunt.registerTask('release-test', ['dist', 'manifest-test', 'compress']);
    grunt.registerTask('release-stable', ['dist', 'manifest-stable', 'compress']);
    grunt.registerTask('default', ['release-dev']);

};<commit_msg>Start unit tests<commit_after>module.exports = function(grunt) {
    'use strict';

    require('time-grunt')(grunt);

    var version = grunt.option('release'),
        zipName = (version) ? version : 'DEV';

    // Project configuration.
    grunt.initConfig({

        connect: {
            dev: {
                options: {
                    port: 8580,
                    base: '.',
                    keepalive: true
                }
            },
            test: {
                options: {
                    port: 8581,
                    base: '.'
                }
            }
        },

        jshint: {
            all: ['Gruntfile.js', 'src/*.js', 'src/js/**/*.js', 'test/unit/*-test.js', 'test/integration/*.js'],
            options: {
                jshintrc: '.jshintrc'
            }
        },

        mocha: {
            all: {
                options: {
                    urls: [
                        'http://localhost:<%= connect.test.options.port %>/test/unit/index.html',
                        'http://localhost:<%= connect.test.options.port %>/test/integration/index.html'
                    ],
                    run: false,
                    reporter: 'Spec',
                    log: false,

                    // phanotmjs is soooo slow
                    timeout: 100000
                }
            }
        },

        clean: {
            dist: ['dist', 'test/lib', 'test/integration/src']
        },

        sass: {
            dist: {
                files: {
                    'src/css/read-sandbox.css': 'src/sass/read-sandbox.scss',
                    'src/css/all.css': 'src/sass/all.scss'
                }
            }
        },

        autoprefixer: {
            options: {
                browsers: ['last 2 versions']
            },
            dist: {
                files: {
                    'src/css/read-sandbox.css': 'src/css/read-sandbox.css',
                    'src/css/all.css': 'src/css/all.css'
                }
            }
        },

        csso: {
            options: {
                banner: '/*! Copyright © <%= grunt.template.today("yyyy") %>, Whiteout Networks GmbH.*/\n'
            },
            dist: {
                files: {
                    'dist/css/read-sandbox.min.css': 'src/css/read-sandbox.css',
                    'dist/css/all.min.css': 'src/css/all.css'
                }
            }
        },

        watch: {
            css: {
                files: ['src/sass/**/*.scss'],
                tasks: ['dist-css', 'manifest']
            },
            js: {
                files: ['src/js/**/*.js'],
                tasks: ['dist-js', 'copy:integration', 'manifest']
            },
            lib: {
                files: ['src/lib/**/*.js'],
                tasks: ['copy:lib', 'manifest']
            },
            app: {
                files: ['src/*.js', 'src/**/*.html', 'src/**/*.json', 'src/manifest.*', 'src/img/**/*', 'src/font/**/*'],
                tasks: ['copy:app', 'copy:ca', 'copy:tpl', 'copy:img', 'copy:font', 'manifest-dev', 'manifest']
            }
        },

        browserify: {
            app: {
                files: {
                    'dist/js/app.browserified.js': ['src/js/app.js']
                },
                options: {
                    external: ['openpgp', 'node-forge', 'net', 'tls', 'crypto'] // node.js apis not required at build time
                }
            },
            pbkdf2Worker: {
                files: {
                    'dist/js/pbkdf2-worker.browserified.js': ['src/js/crypto/pbkdf2-worker.js']
                }
            },
            unitTest: {
                files: {
                    'test/unit/index.js': ['test/unit/*-test.js']
                },
                options: {
                    external: ['openpgp', 'node-forge', 'net', 'tls', 'crypto']
                }
            },
            /*
              TODO:
              mailreader-worker: {},
              integrationTest: {}
            */
        },

        uglify: {
            app: {
                files: {
                    'dist/js/app.min.js': [
                        'src/lib/underscore/underscore-min.js',
                        'node_modules/jquery/dist/jquery.min.js',
                        'src/lib/angular/angular.min.js',
                        'src/lib/angular/angular-route.min.js',
                        'src/lib/angular/angular-animate.min.js',
                        'src/lib/ngtagsinput/ng-tags-input.min.js',
                        'node_modules/ng-infinite-scroll/build/ng-infinite-scroll.min.js',
                        'src/lib/fastclick/fastclick.js',
                        'src/lib/lawnchair/lawnchair-git.js',
                        'src/lib/lawnchair/lawnchair-adapter-webkit-sqlite-git.js',
                        'src/lib/lawnchair/lawnchair-adapter-indexed-db-git.js',
                        'dist/js/app.browserified.js'
                    ]
                },
                options: {
                    mangle: false,
                    sourceMap: true,
                    sourceMapName: 'dist/js/app.min.js.map'
                }
            },
            readSandbox: {
                files: {
                    'dist/js/read-sandbox.min.js': [
                        'node_modules/dompurify/purify.js',
                        'src/js/controller/read-sandbox.js'
                    ]
                },
                options: {
                    sourceMap: true,
                    sourceMapName: 'dist/js/read-sandbox.min.js.map'
                }

            },
            pbkdf2Worker: {
                files: {
                    'dist/js/pbkdf2-worker.min.js': ['dist/js/pbkdf2-worker.browserified.js']
                }
            },
            unitTest: {
                files: {
                    'test/unit/index.js': [
                        'src/lib/underscore/underscore-min.js',
                        'node_modules/jquery/dist/jquery.min.js',
                        'src/lib/forge/forge.min.js',
                        'src/lib/openpgp/openpgp.js',
                        'src/lib/angular/angular.min.js',
                        'node_modules/angular-mocks/angular-mocks.js',
                        'src/lib/angular/angular-route.min.js',
                        'src/lib/angular/angular-animate.min.js',
                        'src/lib/ngtagsinput/ng-tags-input.min.js',
                        'src/lib/fastclick/fastclick.js',
                        'node_modules/ng-infinite-scroll/build/ng-infinite-scroll.min.js',
                        'src/lib/lawnchair/lawnchair-git.js',
                        'src/lib/lawnchair/lawnchair-adapter-webkit-sqlite-git.js',
                        'src/lib/lawnchair/lawnchair-adapter-indexed-db-git.js',
                        'node_modules/dompurify/purify.js',
                        'test/lib/angular-mocks.js',
                        'test/unit/index.js'
                    ]
                },
                options: {
                    compress: false
                }
            },
            options: {
                banner: '/*! Copyright © <%= grunt.template.today("yyyy") %>, Whiteout Networks GmbH.*/\n'
            }
        },

        copy: {
            npmDev: {
                expand: true,
                flatten: true,
                cwd: 'node_modules/',
                src: ['mocha/mocha.css', 'mocha/mocha.js', 'chai/chai.js', 'sinon/pkg/sinon.js', 'browsercrow/src/*.js', 'browsersmtp/src/*.js'],
                dest: 'test/lib/'
            },
            lib: {
                expand: true,
                flatten: true,
                cwd: 'src/lib/',
                src: ['openpgp/openpgp.js', 'openpgp/openpgp.worker.js', 'forge/forge.min.js'],
                dest: 'dist/js/'
            },
            font: {
                expand: true,
                cwd: 'src/font/',
                src: ['*'],
                dest: 'dist/font/'
            },
            img: {
                expand: true,
                cwd: 'src/img/',
                src: ['*'],
                dest: 'dist/img/'
            },
            tpl: {
                expand: true,
                cwd: 'src/tpl/',
                src: ['*'],
                dest: 'dist/tpl/'
            },
            app: {
                expand: true,
                cwd: 'src/',
                src: ['*.html', '*.js', '*.json', 'manifest.*'],
                dest: 'dist/'
            },
            integration: {
                expand: true,
                cwd: 'src/',
                src: ['**'],
                dest: 'test/integration/src/'
            }
        },

        compress: {
            main: {
                options: {
                    mode: 'zip',
                    archive: 'release/whiteout-mail_' + zipName + '.zip'
                },
                expand: true,
                cwd: 'dist/',
                src: ['**/*'],
                dest: 'release/'
            }
        },

        manifest: {
            generate: {
                options: {
                    basePath: 'dist/',
                    timestamp: true,
                    hash: true,
                    cache: ['socket.io/socket.io.js'],
                    exclude: [
                        'appcache.manifest',
                        'manifest.webapp',
                        'js/app.min.js.map',
                        'js/app.browserified.js',
                        'js/crypto/pbkdf2-worker.browserified.js',
                        'js/pbkdf2-worker.browserified.js',
                        'js/read-sandbox.min.js.map'
                    ],
                    master: ['index.html']
                },
                src: ['**/*.*'],
                dest: 'dist/appcache.manifest'
            }
        }

    });

    // Load the plugin(s)
    grunt.loadNpmTasks('grunt-browserify');
    grunt.loadNpmTasks('grunt-contrib-uglify');
    grunt.loadNpmTasks('grunt-contrib-connect');
    grunt.loadNpmTasks('grunt-contrib-jshint');
    grunt.loadNpmTasks('grunt-mocha');
    grunt.loadNpmTasks('grunt-contrib-clean');
    grunt.loadNpmTasks('grunt-csso');
    grunt.loadNpmTasks('grunt-contrib-sass');
    grunt.loadNpmTasks('grunt-autoprefixer');
    grunt.loadNpmTasks('grunt-contrib-watch');
    grunt.loadNpmTasks('grunt-contrib-copy');
    grunt.loadNpmTasks('grunt-contrib-compress');
    grunt.loadNpmTasks('grunt-manifest');

    // Build tasks
    grunt.registerTask('dist-npm', ['copy:npmDev']);
    grunt.registerTask('dist-css', ['sass', 'autoprefixer', 'csso']);
    grunt.registerTask('dist-js', ['browserify', 'uglify']);
    grunt.registerTask('dist-copy', ['copy']);
    grunt.registerTask('dist', ['clean', 'dist-npm', 'dist-css', 'dist-js', 'dist-copy', 'manifest']);

    // Test/Dev tasks
    grunt.registerTask('dev', ['connect:dev']);
    grunt.registerTask('test', ['jshint', 'connect:test', 'mocha']);
    grunt.registerTask('prod', ['connect:prod']);

    //
    // Release tasks for Chrome App Release Channels
    //

    grunt.registerTask('manifest-dev', function() {
        patchManifest({
            suffix: ' (DEV)',
            version: '9999.9999.9999.9999'
        });
    });
    grunt.registerTask('manifest-test', function() {
        if (!version) {
            throw new Error('You must specify the version: "--release=1.0"');
        }

        patchManifest({
            suffix: ' (TEST)',
            client_id: '440907777130-bfpgo5fbo4f7hetrg3hn57qolrtubs0u.apps.googleusercontent.com',
            version: version,
            deleteKey: true
        });
    });
    grunt.registerTask('manifest-stable', function() {
        if (!version) {
            throw new Error('You must specify the version: "--release=1.0"');
        }

        patchManifest({
            version: version,
            deleteKey: true,
            keyServer: 'https://keys.whiteout.io/',
            keychainServer: 'https://keychain.whiteout.io/'
        });
    });

    function patchManifest(options) {
        var fs = require('fs'),
            path = './dist/manifest.json',
            manifest = require(path);

        if (options.version) {
            manifest.version = options.version;
        }
        if (options.suffix) {
            manifest.name += options.suffix;
        }
        if (options.client_id) {
            manifest.oauth2.client_id = options.client_id;
        }
        if (options.keyServer) {
            var ksIndex = manifest.permissions.indexOf('https://keys-test.whiteout.io/');
            manifest.permissions[ksIndex] = options.keyServer;
        }
        if (options.keychainServer) {
            var kcsIndex = manifest.permissions.indexOf('https://keychain-test.whiteout.io/');
            manifest.permissions[kcsIndex] = options.keychainServer;
        }
        if (options.deleteKey) {
            delete manifest.key;
        }

        fs.writeFileSync(path, JSON.stringify(manifest, null, 2));
    }

    grunt.registerTask('release-dev', ['dist', 'manifest-dev', 'compress']);
    grunt.registerTask('release-test', ['dist', 'manifest-test', 'compress']);
    grunt.registerTask('release-stable', ['dist', 'manifest-stable', 'compress']);
    grunt.registerTask('default', ['release-dev']);

};<|endoftext|>


<commit_before>// use chipper's gruntfile
module.exports = require( '../chipper/grunt/Gruntfile.js' );
<commit_msg>move grunt-related build files to chipper/js/grunt/, phetsims/chipper#92<commit_after>// use chipper's gruntfile
module.exports = require( '../chipper/js/grunt/Gruntfile.js' );
<|endoftext|>


<commit_before>'use strict';

var path = require('path');

module.exports = function (grunt) {
	var modernizr = 'bower_components/modernizr/modernizr.js';
	var jsFiles = [
		'bower_components/jquery/jquery.min.js',
		'bower_components/retina.js/src/retina.js',
		'bower_components/knockout.js/knockout.js',
		'bower_components/foundation/js/foundation/foundation.js',
		'assets/js/app.js'
	];

	var cssFiles = [
		'assets/css/app.css'
	];

	grunt.initConfig({
		uglify: {
			deploy: {
				files: {
					'www/assets/js/modernizr.min.js': modernizr,
					'www/assets/js/app.min.js': jsFiles
				}
			},
			dev: {
				options: {
					beautify: {
						width: 80,
						beautify: true
					}
				},
				files: {
					'build/assets/js/app.min.js': jsFiles
				}
			}
		},
		sass: {
			dev: {
				files: {
					'build/assets/css/app.css': 'src/app.scss'
				}
			},
			deploy: {
				files: {
					'www/assets/css/app.min.css': 'src/app.scss'
				},
				options: {
					style: 'compressed'
				}
			}
		},
		jade: {
			deploy: {
				options: {
					data: {
						modernizr: 'assets/js/modernizr.min.js',
						js: ['assets/js/app.min.js'],
						css: ['assets/css/app.min.css']
					}
				},
				files: [
					{
						expand: true,
						cwd: 'src/',
						src: ['*.jade'],
						dest: 'www/',
						ext: '.html'
					}
				]
			},
			dev: {
				options: {
					data: {
						modernizr: modernizr,
						js: jsFiles,
						css: ['assets/css/app.css']
					},
					pretty: true
				},
				files: [
					{
						expand: true,
						cwd: 'src/',
						src: ['*.jade'],
						dest: 'build/',
						ext: '.html'
					}
				]
			}
		},
		copy: {
			dev: {
				files: [
					{expand: true, cwd: 'src/', src: ['*.js'], dest: 'build/assets/js/', filter: 'isFile'},
					{expand: true, cwd: 'src/', src: ['img/*'], dest: 'build/assets/img/', filter: 'isFile'}
				]
			},
			deploy: {
				files: [
					{expand: true, cwd: 'src/', src: ['img/*'], dest: 'www/assets/img/', filter: 'isFile'}
				]
			},
		},
		create_directories: {
			build: ['build/assets/img', 'build/assets/css', 'build/assets/js'],
			www: ['www/assets/img', 'www/assets/css', 'www/assets/js']
		},
		clean: {
			build: "build",
			www: "www",
			tmp: [".sass-cache"]
		},
		watch: {
			files: ['src/*'],
			tasks: ['copy:dev', 'sass:dev', 'jade:dev'],
			options: {
				livereload: true
			}
		},
		connect: {
			all: {
				options: {
					port: 8002,
					base: [path.join(__dirname, 'build'), __dirname],
					livereload: true
				}
			}
		}
	});

	grunt.loadNpmTasks('grunt-contrib-uglify');
	grunt.loadNpmTasks('grunt-contrib-jade');
	grunt.loadNpmTasks('grunt-contrib-sass');
	grunt.loadNpmTasks('grunt-contrib-copy');
	grunt.loadNpmTasks('grunt-contrib-clean');
	grunt.loadNpmTasks('grunt-contrib-watch');
	grunt.loadNpmTasks('grunt-contrib-connect');

	grunt.registerTask('default', ['copy:dev', 'sass:dev', 'jade:dev']);
	grunt.registerTask('dev', [
		'clean:build',
		'create_directories:build',
		'copy:dev',
		'sass:dev',
		'jade:dev',
		'connect',
		'watch'
	]);
	grunt.registerTask('deploy', [
		'clean:www',
		'create_directories:www',
		'sass:deploy',
		'uglify:deploy',
		'jade:deploy',
		'copy:deploy',
	]);
	grunt.registerMultiTask('create_directories', 'Created directory hierarchy', function() {
		console.log('Creating directories for ' + this.target);
		for (var i = 0; i < this.data.length; i++) {
			grunt.file.mkdir(path.join(__dirname, '/', this.data[i]));
		}
	});
};
<commit_msg>Remove 'dev' uglify task since it's unused.<commit_after>'use strict';

var path = require('path');

module.exports = function (grunt) {
	var modernizr = 'bower_components/modernizr/modernizr.js';
	var jsFiles = [
		'bower_components/jquery/jquery.min.js',
		'bower_components/retina.js/src/retina.js',
		'bower_components/knockout.js/knockout.js',
		'bower_components/foundation/js/foundation/foundation.js',
		'assets/js/app.js'
	];

	var cssFiles = [
		'assets/css/app.css'
	];

	grunt.initConfig({
		uglify: {
			deploy: {
				files: {
					'www/assets/js/modernizr.min.js': modernizr,
					'www/assets/js/app.min.js': jsFiles
				}
			}
		},
		sass: {
			dev: {
				files: {
					'build/assets/css/app.css': 'src/app.scss'
				}
			},
			deploy: {
				files: {
					'www/assets/css/app.min.css': 'src/app.scss'
				},
				options: {
					style: 'compressed'
				}
			}
		},
		jade: {
			deploy: {
				options: {
					data: {
						modernizr: 'assets/js/modernizr.min.js',
						js: ['assets/js/app.min.js'],
						css: ['assets/css/app.min.css']
					}
				},
				files: [
					{
						expand: true,
						cwd: 'src/',
						src: ['*.jade'],
						dest: 'www/',
						ext: '.html'
					}
				]
			},
			dev: {
				options: {
					data: {
						modernizr: modernizr,
						js: jsFiles,
						css: ['assets/css/app.css']
					},
					pretty: true
				},
				files: [
					{
						expand: true,
						cwd: 'src/',
						src: ['*.jade'],
						dest: 'build/',
						ext: '.html'
					}
				]
			}
		},
		copy: {
			dev: {
				files: [
					{expand: true, cwd: 'src/', src: ['*.js'], dest: 'build/assets/js/', filter: 'isFile'},
					{expand: true, cwd: 'src/', src: ['img/*'], dest: 'build/assets/img/', filter: 'isFile'}
				]
			},
			deploy: {
				files: [
					{expand: true, cwd: 'src/', src: ['img/*'], dest: 'www/assets/img/', filter: 'isFile'}
				]
			},
		},
		create_directories: {
			build: ['build/assets/img', 'build/assets/css', 'build/assets/js'],
			www: ['www/assets/img', 'www/assets/css', 'www/assets/js']
		},
		clean: {
			build: "build",
			www: "www",
			tmp: [".sass-cache"]
		},
		watch: {
			files: ['src/*'],
			tasks: ['copy:dev', 'sass:dev', 'jade:dev'],
			options: {
				livereload: true
			}
		},
		connect: {
			all: {
				options: {
					port: 8002,
					base: [path.join(__dirname, 'build'), __dirname],
					livereload: true
				}
			}
		}
	});

	grunt.loadNpmTasks('grunt-contrib-uglify');
	grunt.loadNpmTasks('grunt-contrib-jade');
	grunt.loadNpmTasks('grunt-contrib-sass');
	grunt.loadNpmTasks('grunt-contrib-copy');
	grunt.loadNpmTasks('grunt-contrib-clean');
	grunt.loadNpmTasks('grunt-contrib-watch');
	grunt.loadNpmTasks('grunt-contrib-connect');

	grunt.registerTask('default', ['copy:dev', 'sass:dev', 'jade:dev']);
	grunt.registerTask('dev', [
		'clean:build',
		'create_directories:build',
		'copy:dev',
		'sass:dev',
		'jade:dev',
		'connect',
		'watch'
	]);
	grunt.registerTask('deploy', [
		'clean:www',
		'create_directories:www',
		'sass:deploy',
		'uglify:deploy',
		'jade:deploy',
		'copy:deploy',
	]);
	grunt.registerMultiTask('create_directories', 'Created directory hierarchy', function() {
		console.log('Creating directories for ' + this.target);
		for (var i = 0; i < this.data.length; i++) {
			grunt.file.mkdir(path.join(__dirname, '/', this.data[i]));
		}
	});
};
<|endoftext|>


<commit_before>module.exports = function(grunt) {
  grunt.initConfig({
    pkg: grunt.file.readJSON('package.json'),
    wiredep: {
      target: {
        exclude: ['bootstrap-sass'],
        // Point to the files that should be updated when
        // you run `grunt wiredep`
        src: [
          'src/ustackweb/views/layouts/default.tpl.html'
        ]
      }
    },
    sass: {
      dist: {
        files: [{
          expand: true,
          cwd: 'src/ustackweb/static/scss',
          src: ['*.scss'],
          dest: 'src/ustackweb/static/css',
          ext: '.css'
        }]
      }
    },
    watch: {
      wiredep: {
        files: 'bower.json',
        tasks: ['shell:bower', 'wiredep'],
        options: {
          debounceDelay: 250
        }
      },
      livereload: {
        files: 'src/ustackweb/**/*',
        options: {
          debounceDelay: 250,
          livereload: true
        }
      },
      static: {
        files: 'src/ustackweb/static/**/*',
        tasks: ['sass'],
        options: {
          debounceDelay: 250
        }
      }
    },
    shell: {
        bower: {
            command: 'bower install'
        }
    }
  });

  grunt.loadNpmTasks('grunt-shell');
  grunt.loadNpmTasks('grunt-wiredep');
  grunt.loadNpmTasks('grunt-contrib-watch');
  grunt.loadNpmTasks('grunt-contrib-sass');
  grunt.registerTask('default', ['shell:bower']);
};
<commit_msg>Auto-run go fmt.<commit_after>module.exports = function(grunt) {
  grunt.initConfig({
    pkg: grunt.file.readJSON('package.json'),
    wiredep: {
      target: {
        exclude: ['bootstrap-sass'],
        // Point to the files that should be updated when
        // you run `grunt wiredep`
        src: [
          'src/ustackweb/views/layouts/default.tpl.html'
        ]
      }
    },
    sass: {
      dist: {
        files: [{
          expand: true,
          cwd: 'src/ustackweb/static/scss',
          src: ['*.scss'],
          dest: 'src/ustackweb/static/css',
          ext: '.css'
        }]
      }
    },
    watch: {
      wiredep: {
        files: 'bower.json',
        tasks: ['shell:bower', 'wiredep'],
        options: {
          debounceDelay: 250
        }
      },
      livereload: {
        files: 'src/ustackweb/**/*',
        options: {
          debounceDelay: 250,
          livereload: true
        }
      },
      static: {
        files: 'src/ustackweb/static/**/*',
        tasks: ['sass'],
        options: {
          debounceDelay: 250
        }
      }
    },
    shell: {
        bower: {
            command: 'bower install'
        },
        fmt: {
            command: 'go fmt ./...'
        }
    }
  });

  grunt.loadNpmTasks('grunt-shell');
  grunt.loadNpmTasks('grunt-wiredep');
  grunt.loadNpmTasks('grunt-contrib-watch');
  grunt.loadNpmTasks('grunt-contrib-sass');
  grunt.registerTask('default', ['shell:bower']);
};
<|endoftext|>


<commit_before>module.exports = function(grunt) {
  var pkg = grunt.file.readJSON('package.json');

  grunt.initConfig({
    pkg: pkg,
    browserify: {
      dist: {
        files: {
          'out/dist/<%= pkg.name %>.js': ['browser.js']
        }
      }
    },
    jshint: {
      options: {
        eqeqeq: true,
        newcap: true,
        quotmark: true,
        unused: true,
        trailing: true,
        laxbreak: true
      },
      all: ['Gruntfile.js', 'bench/**/*.js', 'lib/**/*.js', 'test/**/*.js']
    },
    mochacov: {
      test: {
        options: {
          reporter: 'dot',
          files: ['test/**/*.js']
        }
      },
      coverage: {
        options: {
          reporter: 'html-cov',
          output: 'out/coverage.html',
          files: ['test/**/*.js']
        }
      }
    },
    moduleName: pkg.name,
    uglify: {
      dist: {
        files: {
          'out/dist/<%= pkg.name %>.min.js': ['out/dist/<%= pkg.name %>.js']
        }
      }
    },
    watch: {
      src: {
        files: ['lib/**/*.js', 'test/**/*.js'],
        tasks: ['test', 'jshint'],
        options: {
          spawn: false
        }
      }
    }
  });

  // Plugins
  grunt.loadNpmTasks('grunt-browserify');
  grunt.loadNpmTasks('grunt-contrib-jshint');
  grunt.loadNpmTasks('grunt-contrib-uglify');
  grunt.loadNpmTasks('grunt-contrib-watch');
  grunt.loadNpmTasks('grunt-mocha-cov');

  // Initialization
  grunt.file.mkdir('out/dist');
  grunt.file.write('lib/version.js', 'module.exports = \'' + pkg.version + '\';');

  // Main invocable targets
  grunt.registerTask('default', ['dist', 'test']);
  grunt.registerTask('dist', ['browserify', 'uglify']);
  grunt.registerTask('test', ['mochacov:test', 'mochacov:coverage']);
  grunt.registerTask('bench', function() {
    var done = this.async();
    var args = ['bench/bench.js'].concat(grunt.file.expand('bench/graphs/*'));
    var child = grunt.util.spawn({
      cmd: 'node',
      args: args
    }, done);
    child.stdout.pipe(process.stdout);
    child.stderr.pipe(process.stderr);
  });
  grunt.registerTask('release', function() {
    var done = this.async();
    var child = grunt.util.spawn({
      cmd: 'src/release/release.sh',
      args: [grunt.config('moduleName'), 'out/dist']
    }, done);
    child.stdout.pipe(process.stdout);
    child.stderr.pipe(process.stderr);
  });
  grunt.registerTask('clean', 'Deletes temporary files and dist files', function() {
    grunt.file.delete('lib/version.js');
    grunt.file.delete('out');
  });
};
<commit_msg>More tweaks to grunt tasks<commit_after>module.exports = function(grunt) {
  var pkg = grunt.file.readJSON('package.json');

  grunt.initConfig({
    pkg: pkg,
    browserify: {
      dist: {
        files: {
          'out/dist/<%= pkg.name %>.js': ['browser.js']
        }
      }
    },
    jshint: {
      options: {
        eqeqeq: true,
        newcap: true,
        quotmark: true,
        unused: true,
        trailing: true,
        laxbreak: true
      },
      all: ['Gruntfile.js', 'bench/**/*.js', 'lib/**/*.js', 'test/**/*.js']
    },
    mochacov: {
      test: {
        options: {
          reporter: 'dot',
          files: ['test/**/*.js']
        }
      },
      coverage: {
        options: {
          reporter: 'html-cov',
          output: 'out/coverage.html',
          files: ['test/**/*.js']
        }
      }
    },
    moduleName: pkg.name,
    uglify: {
      dist: {
        files: {
          'out/dist/<%= pkg.name %>.min.js': ['out/dist/<%= pkg.name %>.js']
        }
      }
    },
    watch: {
      src: {
        files: ['lib/**/*.js', 'test/**/*.js'],
        tasks: ['test', 'jshint'],
        options: {
          spawn: false
        }
      }
    }
  });

  // Plugins
  grunt.loadNpmTasks('grunt-browserify');
  grunt.loadNpmTasks('grunt-contrib-jshint');
  grunt.loadNpmTasks('grunt-contrib-uglify');
  grunt.loadNpmTasks('grunt-contrib-watch');
  grunt.loadNpmTasks('grunt-mocha-cov');

  // Initialization

  // Main invocable targets
  grunt.registerTask('default', ['dist', 'test']);

  grunt.registerTask('dist', ['_init', 'browserify', 'uglify']);

  grunt.registerTask('test', ['_init', 'mochacov:test', 'mochacov:coverage']);

  grunt.registerTask('bench', ['_init', '_bench']);

  grunt.registerTask('release', ['dist', '_release']);

  grunt.registerTask('clean', 'Deletes temporary files and dist files', function() {
    grunt.file.delete('lib/version.js');
    grunt.file.delete('out');
  });

  // Supporting targets (should be private...)
  grunt.registerTask('_init', function() {
    grunt.file.mkdir('out/dist');
    grunt.file.write('lib/version.js', 'module.exports = \'' + pkg.version + '\';');
  });

  grunt.registerTask('_bench', function() {
    var done = this.async();
    var args = ['bench/bench.js'].concat(grunt.file.expand('bench/graphs/*'));
    var child = grunt.util.spawn({
      cmd: 'node',
      args: args
    }, done);
    child.stdout.pipe(process.stdout);
    child.stderr.pipe(process.stderr);
  });

  grunt.registerTask('_release', function() {
    var done = this.async();
    var child = grunt.util.spawn({
      cmd: 'src/release/release.sh',
      args: [grunt.config('moduleName'), 'out/dist']
    }, done);
    child.stdout.pipe(process.stdout);
    child.stderr.pipe(process.stderr);
  });
};
<|endoftext|>


<commit_before>/*********************************************************************
 *                                                                   *
 *   Copyright 2016 Simon M. Werner                                  *
 *                                                                   *
 *   Licensed to the Apache Software Foundation (ASF) under one      *
 *   or more contributor license agreements.  See the NOTICE file    *
 *   distributed with this work for additional information           *
 *   regarding copyright ownership.  The ASF licenses this file      *
 *   to you under the Apache License, Version 2.0 (the               *
 *   "License"); you may not use this file except in compliance      *
 *   with the License.  You may obtain a copy of the License at      *
 *                                                                   *
 *      http://www.apache.org/licenses/LICENSE-2.0                   *
 *                                                                   *
 *   Unless required by applicable law or agreed to in writing,      *
 *   software distributed under the License is distributed on an     *
 *   "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY          *
 *   KIND, either express or implied.  See the License for the       *
 *   specific language governing permissions and limitations         *
 *   under the License.                                              *
 *                                                                   *
 *********************************************************************/

'use strict';

// The datasheet documentation for the ITG 3200 can be found here:
//

var GYRO_ADDRESS = 0x68;

var GYRO_RESET_ADDRESS = 0x3E;
var GYRO_RESET_BYTE = 0x80;             // Power management register: refer to page 27 of datasheet

var GYRO_SAMPLERATE_ADDRESS = 0x15;
var GYRO_SAMPLERATE_DIVIDER = 0x00;     // Sample rate divider: use default value 0x00 for full range: refer to pg 23

var GYRO_DEGREES_ADDRESS = 0x16;
var GYRO_DEGREES_VALUE = 0x18;          // gyro full scale range: refer to pg 24

var GYRO_READ_ADDRESS = 0x1B;
var GYRO_READ_LEN = 8;

var GYRO_SENSITIVITY = 14.375;

// 280 is the sensitivity. refer to pg 7 section temperature sensor.
var TEMP_OFFSET = 0; // (35 - 13200 / 280);  ()
var TEMP_SENSITIVITY = 280;

/**
 * Initalise the gyroscope.
 * @param {number}   i2cBusNum The i2c bus number.
 */
function Gyroscope(i2cBusNum) {

    if (typeof i2cBusNum !== 'number') {
        throw new Error('Gyroscope: i2cBusNum must be a number.');
    }

    this.i2c = require('i2c-bus').openSync(i2cBusNum);

    // Reset the device
    this.i2c.writeByteSync(GYRO_ADDRESS, GYRO_RESET_ADDRESS, GYRO_RESET_BYTE);

    // Set the sample rate
    this.i2c.writeByteSync(GYRO_ADDRESS, GYRO_SAMPLERATE_ADDRESS, GYRO_SAMPLERATE_DIVIDER);

    // Set the degrees value
    this.i2c.writeByteSync(GYRO_ADDRESS, GYRO_DEGREES_ADDRESS, GYRO_DEGREES_VALUE);

}

/**
 * Get the values from the gyroscope.
 * @param  {Function} callback The standard callback -> (err, {temp: number, x:number, y:number, z:number})
 */
Gyroscope.prototype.getValues = function (callback) {

    if (!this.calibrationOffset) {
        console.error('WARNING: The gyroscrope has not yet been calibrated.');
        this.calibrationOffset = {
            x: 0,
            y: 0,
            z: 0
        };
    }

    var buf = new Buffer(GYRO_READ_LEN);
    var self = this;
    this.i2c.readI2cBlock(GYRO_ADDRESS, GYRO_READ_ADDRESS, GYRO_READ_LEN, buf, function (err2) {
        if (err2) {
            callback(err2);
            return;
        }

        var bt1 = buf[0];
        var bt0 = buf[1];
        var bx1 = buf[2];
        var bx0 = buf[3];
        var by1 = buf[4];
        var by0 = buf[5];
        var bz1 = buf[6];
        var bz0 = buf[7];

        var result = {
            temp: convertBytes(bt0, bt1, TEMP_OFFSET, TEMP_SENSITIVITY),
            x: convertBytes(bx0, bx1, self.calibrationOffset.x, GYRO_SENSITIVITY),
            y: convertBytes(by0, by1, self.calibrationOffset.y, GYRO_SENSITIVITY),
            z: convertBytes(bz0, bz1, self.calibrationOffset.z, GYRO_SENSITIVITY)
        };

        callback(null, result);
    });

};

/**
 * Calibrate the gyroscope.  Before the gyro is used it should be calibrated, this needs to
 * be done when it is still.
 * @param  {Function} callback The standard callback -> (err, {x:number, y:number, z:number})
 */
Gyroscope.prototype.calibrate = function (callback) {
    this.calibrationOffset = {
        x: 0,
        y: 0,
        z: 0
    };
    var xAve = 0;
    var yAve = 0;
    var zAve = 0;
    var MAX_COUNT = 5;
    var count = 0;
    var self = this;
    var fnInt = setInterval(function () {
        self.getValues(function(err, values) {
            if (err) {
                callback(err);
                clearInterval(fnInt);
                return;
            }
            xAve += values.x;
            yAve += values.y;
            zAve += values.z;
            count += 1;
            if (count >= MAX_COUNT) {
                self.calibrationOffset = {
                    x: -(xAve / count),
                    y: -(yAve / count),
                    z: -(zAve / count)
                };
                callback(null, self.calibrationOffset);
                clearInterval(fnInt);
            }
        });
    }, 50);
};

/**
 * Convert the bytes to actual values.
 * @param  {number} byteLo       The first byte.
 * @param  {number} byteHi       The second byte.
 * @param  {number} offset      The offset value.
 * @param  {number} sensitivity The sensitivity.
 * @return {number}             The actual value.
 */
function convertBytes(byteLo, byteHi, offset, sensitivity) {

    // add the two bytes together (bit-shift x1)
    var byteVal;

    if (byteHi > 15) {
        byteHi = byteHi & 0x0F;                         // don't count the first 4 bits
        byteVal = 0x0FFF - (byteLo + (byteHi << 8));    // Make the value negative
    } else {
        byteVal = byteLo + (byteHi << 8);
    }

    return offset + (byteVal / sensitivity);
}

module.exports = Gyroscope;
<commit_msg>Fixed gyroscope, it now has correct negative values.<commit_after>/*********************************************************************
 *                                                                   *
 *   Copyright 2016 Simon M. Werner                                  *
 *                                                                   *
 *   Licensed to the Apache Software Foundation (ASF) under one      *
 *   or more contributor license agreements.  See the NOTICE file    *
 *   distributed with this work for additional information           *
 *   regarding copyright ownership.  The ASF licenses this file      *
 *   to you under the Apache License, Version 2.0 (the               *
 *   "License"); you may not use this file except in compliance      *
 *   with the License.  You may obtain a copy of the License at      *
 *                                                                   *
 *      http://www.apache.org/licenses/LICENSE-2.0                   *
 *                                                                   *
 *   Unless required by applicable law or agreed to in writing,      *
 *   software distributed under the License is distributed on an     *
 *   "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY          *
 *   KIND, either express or implied.  See the License for the       *
 *   specific language governing permissions and limitations         *
 *   under the License.                                              *
 *                                                                   *
 *********************************************************************/

'use strict';

// The datasheet documentation for the ITG 3200 can be found here:
//     http://www.farnell.com/datasheets/1670762.pdf

var GYRO_ADDRESS = 0x68;

var GYRO_RESET_ADDRESS = 0x3E;
var GYRO_RESET_BYTE = 0x80;             // Power management register: refer to page 27 of datasheet

var GYRO_SAMPLERATE_ADDRESS = 0x15;
var GYRO_SAMPLERATE_DIVIDER = 0x00;     // Sample rate divider: use default value 0x00 for full range: refer to pg 23

var GYRO_DEGREES_ADDRESS = 0x16;
var GYRO_DEGREES_VALUE = 0x18;          // gyro full scale range: refer to pg 24

var GYRO_READ_ADDRESS = 0x1B;
var GYRO_READ_LEN = 8;

var GYRO_SENSITIVITY = 14.375;

// 280 is the sensitivity. refer to pg 7 section temperature sensor.
var TEMP_OFFSET = 0; // (35 - 13200 / 280);  ()
var TEMP_SENSITIVITY = 280;

/**
 * Initalise the gyroscope.
 * @param {number}   i2cBusNum The i2c bus number.
 */
function Gyroscope(i2cBusNum) {

    if (typeof i2cBusNum !== 'number') {
        throw new Error('Gyroscope: i2cBusNum must be a number.');
    }

    this.i2c = require('i2c-bus').openSync(i2cBusNum);

    // Reset the device
    this.i2c.writeByteSync(GYRO_ADDRESS, GYRO_RESET_ADDRESS, GYRO_RESET_BYTE);

    // Set the sample rate
    this.i2c.writeByteSync(GYRO_ADDRESS, GYRO_SAMPLERATE_ADDRESS, GYRO_SAMPLERATE_DIVIDER);

    // Set the degrees value
    this.i2c.writeByteSync(GYRO_ADDRESS, GYRO_DEGREES_ADDRESS, GYRO_DEGREES_VALUE);

}

/**
 * Get the values from the gyroscope.
 * @param  {Function} callback The standard callback -> (err, {temp: number, x:number, y:number, z:number})
 */
Gyroscope.prototype.getValues = function (callback) {

    if (typeof this.calibrationOffset === 'undefined') {
        console.error('WARNING: The gyroscrope has not yet been calibrated.');
        this.calibrationOffset = {
            x: 0,
            y: 0,
            z: 0
        };
    }

    var buf = new Buffer(GYRO_READ_LEN);
    var self = this;
    this.i2c.readI2cBlock(GYRO_ADDRESS, GYRO_READ_ADDRESS, GYRO_READ_LEN, buf, function (err2) {
        if (err2) {
            callback(err2);
            return;
        }

        var bt1 = buf[0];
        var bt0 = buf[1];
        var bx1 = buf[2];
        var bx0 = buf[3];
        var by1 = buf[4];
        var by0 = buf[5];
        var bz1 = buf[6];
        var bz0 = buf[7];

        var result = {
            temp: convertBytes(bt0, bt1, TEMP_OFFSET, TEMP_SENSITIVITY),
            x: convertBytes(bx0, bx1, self.calibrationOffset.x, GYRO_SENSITIVITY),
            y: convertBytes(by0, by1, self.calibrationOffset.y, GYRO_SENSITIVITY),
            z: convertBytes(bz0, bz1, self.calibrationOffset.z, GYRO_SENSITIVITY)
        };

        callback(null, result);
    });

};

/**
 * Calibrate the gyroscope.  Before the gyro is used it should be calibrated, this needs to
 * be done when it is still.
 * @param  {Function} callback The standard callback -> (err, {x:number, y:number, z:number})
 */
Gyroscope.prototype.calibrate = function (callback) {
    this.calibrationOffset = {
        x: 0,
        y: 0,
        z: 0
    };
    var xAve = 0;
    var yAve = 0;
    var zAve = 0;
    var MAX_COUNT = 5;
    var count = 0;
    var self = this;
    var fnInt = setInterval(function () {
        self.getValues(function(err, values) {
            if (err) {
                callback(err);
                clearInterval(fnInt);
                return;
            }
            xAve += values.x;
            yAve += values.y;
            zAve += values.z;
            count += 1;
            if (count >= MAX_COUNT) {
                self.calibrationOffset = {
                    x: -(xAve / count),
                    y: -(yAve / count),
                    z: -(zAve / count)
                };
                callback(null, self.calibrationOffset);
                clearInterval(fnInt);
            }
        });
    }, 50);
};

/**
 * Convert the bytes to actual values.
 * @param  {number} byteLo       The first byte.
 * @param  {number} byteHi       The second byte.
 * @param  {number} offset      The offset value.
 * @param  {number} sensitivity The sensitivity.
 * @return {number}             The actual value.
 */
function convertBytes(byteLo, byteHi, offset, sensitivity) {

    // add the two bytes together (bit-shift x1)
    var byteVal;

    if (byteHi > 15) {
        byteHi = byteHi & 0x0F;                         // don't count the first 4 bits
        byteVal = (byteLo + (byteHi << 8)) - 0x0FFF;    // Make the value negative
    } else {
        byteVal = byteLo + (byteHi << 8);
    }

    return offset + (byteVal / sensitivity);
}

module.exports = Gyroscope;
<|endoftext|>


<commit_before>/**
	_moon.VideoInfoHeader_ is a control that displays various information about a
	video. It is designed to be used within the _infoComponents_ block of a
	moon.VideoPlayer.

	Example:

		{
			kind: "moon.VideoInfoHeader",
			aboveTitle: new Date(),
			title: "Breaking Bad - Live Free Or Die",
			subTitle: "AMC (301) 7:00 PM - 8:00 PM",
			description: "As Walt deals with the aftermath of the Casa Tranquila explosion, Hank works to wrap up his investigation of Gus' empire.",
			components: [
				{content: "3D"},
				{content: "Live"},
				{content: "REC 08:22", classes: "moon-video-player-info-redicon"}
			]
		}
*/
enyo.kind({
	name: "moon.VideoInfoHeader",
	kind: "enyo.Control",
	classes: "",
	published: {
		aboveTitle: "",
		title: "",
		subTitle: "",
		description: ""
	},
	defaultKind: "moon.VideoInfoHeaderBadge",
	components: [
		{kind: "enyo.Control", classes: "moon-video-player-description-info", components: [
			{kind: "enyo.Control", name: "aboveTitle", classes: "moon-header-font moon-video-player-info-datetime"},
			{kind: "enyo.Control", name: "title", classes: "moon-header-font moon-video-player-info-showname"},
			{kind: "enyo.Control", name: "subTitle", classes: "moon-video-player-info-channel"},
			{kind: "enyo.Control", name: "description", classes: "moon-video-player-info-synopsys"}
		]},
		{kind: "enyo.Control", name: "client", classes: "moon-video-player-settings-info"},
		{kind: "enyo.Control", classes: "moon-video-player-rating-info", allowHtml: true, content: "RTV-14
VL SC"}
	],
	bindings: [],
	create: function() {
		this.inherited(arguments);
		this.setupBindings();
	},
	setupBindings: function() {
		this.bindings.push({from: ".aboveTitle", 	to: "$.aboveTitle.content"});
		this.bindings.push({from: ".title", 		to: "$.title.content"});
		this.bindings.push({from: ".subTitle", 		to: "$.subTitle.content"});
		this.bindings.push({from: ".description", 	to: "$.description.content"});
	}
});

//* A simple kind for video info badges.
enyo.kind({
	name: "moon.VideoInfoHeaderBadge",
	kind: "enyo.Control",
	classes: "moon-video-player-info-icon"
});<commit_msg>Tweaking summary comments for 'moon.VideoInfoHeaderBadge'. Enyo-DCO-1.1-Signed-Off-By: Jim Tang (jim.tang@lge.com)<commit_after>/**
	_moon.VideoInfoHeader_ is a control that displays various information about a
	video. It is designed to be used within the _infoComponents_ block of a
	moon.VideoPlayer.

	Example:

		{
			kind: "moon.VideoInfoHeader",
			aboveTitle: new Date(),
			title: "Breaking Bad - Live Free Or Die",
			subTitle: "AMC (301) 7:00 PM - 8:00 PM",
			description: "As Walt deals with the aftermath of the Casa Tranquila explosion, Hank works to wrap up his investigation of Gus' empire.",
			components: [
				{content: "3D"},
				{content: "Live"},
				{content: "REC 08:22", classes: "moon-video-player-info-redicon"}
			]
		}
*/
enyo.kind({
	name: "moon.VideoInfoHeader",
	kind: "enyo.Control",
	classes: "",
	published: {
		aboveTitle: "",
		title: "",
		subTitle: "",
		description: ""
	},
	defaultKind: "moon.VideoInfoHeaderBadge",
	components: [
		{kind: "enyo.Control", classes: "moon-video-player-description-info", components: [
			{kind: "enyo.Control", name: "aboveTitle", classes: "moon-header-font moon-video-player-info-datetime"},
			{kind: "enyo.Control", name: "title", classes: "moon-header-font moon-video-player-info-showname"},
			{kind: "enyo.Control", name: "subTitle", classes: "moon-video-player-info-channel"},
			{kind: "enyo.Control", name: "description", classes: "moon-video-player-info-synopsys"}
		]},
		{kind: "enyo.Control", name: "client", classes: "moon-video-player-settings-info"},
		{kind: "enyo.Control", classes: "moon-video-player-rating-info", allowHtml: true, content: "RTV-14
VL SC"}
	],
	bindings: [],
	create: function() {
		this.inherited(arguments);
		this.setupBindings();
	},
	setupBindings: function() {
		this.bindings.push({from: ".aboveTitle", 	to: "$.aboveTitle.content"});
		this.bindings.push({from: ".title", 		to: "$.title.content"});
		this.bindings.push({from: ".subTitle", 		to: "$.subTitle.content"});
		this.bindings.push({from: ".description", 	to: "$.description.content"});
	}
});

/**
    _moon.VideoInfoHeaderBadge_ is a simple kind used to display a badge
    containing video info.  It is the default kind for components added to
    _moon.VideoInfoHeader_.
*/
enyo.kind({
	name: "moon.VideoInfoHeaderBadge",
	kind: "enyo.Control",
	classes: "moon-video-player-info-icon"
});<|endoftext|>


<commit_before>(function (workerScript) {
	var worker,
		fakeIdToCallback = {};
	if (typeof (Worker) !== 'undefined') {
		function getFakeId (prefix) {
			return prefix + Math.floor(
				Math.random () *
				Number.MAX_VALUE
			);
		}
		try {
			worker = new Worker (workerScript);
			window.setInterval = function (callback, time) {
				var fakeId = getFakeId ('i-');
				fakeIdToCallback[fakeId] = callback;
				worker.postMessage ({
					name: 'setInterval',
					fakeId: fakeId,
					time: time
				});
				return fakeId;
			};
			window.clearInterval = function (fakeId) {
				delete fakeIdToCallback[fakeId];
				worker.postMessage ({
					name: 'clearInterval',
					fakeId: fakeId
				});
			};
			window.setTimeout = function (callback, time) {
				var fakeId = getFakeId ('t-');
				fakeIdToCallback[fakeId] = callback;
				worker.postMessage ({
					name: 'setTimeout',
					fakeId: fakeId,
					time: time
				});
				return fakeId;
			};
			window.clearTimeout = function (fakeId) {
				delete fakeIdToCallback[fakeId];
				worker.postMessage ({
					name: 'clearTimeout',
					fakeId: fakeId
				});
			};
			worker.onmessage = function (event) {
				var data = event.data,
					fakeId = data.fakeId,
					callback = fakeIdToCallback[fakeId];
				callback.call (window);
			};
			worker.onerror = function (event) {
				console.log(event);
			};
			console.log('HackTimer.js by turuslan: Initialisation succeeded');
		} catch (error) {
			console.log('HackTimer.js by turuslan: Initialisation failed');
			console.error(error);
		}
	} else {
		console.log('HackTimer.js by turuslan: Initialisation failed - HTML5 Web Worker is not supported');
	}
})('HackTimerWorker.js');<commit_msg>Checking fake id presence in list before removing (clearTimeout, clearInterval). Checking if callback is a function (worker.onmessage).<commit_after>(function (workerScript) {
	var worker,
		fakeIdToCallback = {};
	if (typeof (Worker) !== 'undefined') {
		function getFakeId (prefix) {
			return prefix + Math.floor(
				Math.random () *
				Number.MAX_VALUE
			);
		}
		try {
			worker = new Worker (workerScript);
			window.setInterval = function (callback, time) {
				var fakeId = getFakeId ('i-');
				fakeIdToCallback[fakeId] = callback;
				worker.postMessage ({
					name: 'setInterval',
					fakeId: fakeId,
					time: time
				});
				return fakeId;
			};
			window.clearInterval = function (fakeId) {
				if (fakeIdToCallback.hasOwnProperty(fakeId)) {
					delete fakeIdToCallback[fakeId];
					worker.postMessage ({
						name: 'clearInterval',
						fakeId: fakeId
					});
				}
			};
			window.setTimeout = function (callback, time) {
				var fakeId = getFakeId ('t-');
				fakeIdToCallback[fakeId] = callback;
				worker.postMessage ({
					name: 'setTimeout',
					fakeId: fakeId,
					time: time
				});
				return fakeId;
			};
			window.clearTimeout = function (fakeId) {
				if (fakeIdToCallback.hasOwnProperty(fakeId)) {
					delete fakeIdToCallback[fakeId];
					worker.postMessage ({
						name: 'clearTimeout',
						fakeId: fakeId
					});
				}
			};
			worker.onmessage = function (event) {
				var data = event.data,
					fakeId = data.fakeId,
					callback;
				if (fakeIdToCallback.hasOwnProperty(fakeId)) {
					callback = fakeIdToCallback[fakeId];
				}
				if (typeof (callback) === 'function') {
					callback.call (window);
				}
			};
			worker.onerror = function (event) {
				console.log(event);
			};
			console.log('HackTimer.js by turuslan: Initialisation succeeded');
		} catch (error) {
			console.log('HackTimer.js by turuslan: Initialisation failed');
			console.error(error);
		}
	} else {
		console.log('HackTimer.js by turuslan: Initialisation failed - HTML5 Web Worker is not supported');
	}
})('HackTimerWorker.js');<|endoftext|>


<commit_before>(function() {
    //Shaders
    var vShader = [
        'varying vec2 pixelCoord;',
        'varying vec2 texCoord;',

        'uniform vec2 mapSize;',
        'uniform vec2 inverseLayerSize;',
        //'uniform vec2 inverseTilesetSize;',

        //'uniform vec2 tileSize;',
        'uniform vec2 inverseTileSize;',
        //'uniform vec2 numTiles;',

        //'uniform sampler2D tileset;',
        //'uniform sampler2D tileIds;'
        //'uniform int repeatTiles;',
        //'uniform float opacity;',

        'void main(void) {',
        '   pixelCoord = (uv * mapSize);',
        '   texCoord = pixelCoord * inverseLayerSize * inverseTileSize;', //calculate the coord on this map
        '   gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);', //hand this position to WebGL
        '}'
    ].join('\n');

    var fShader = [
        //"precision highp float;",

        'varying vec2 pixelCoord;',
        'varying vec2 texCoord;',

        //'uniform vec2 mapSize;',
        //'uniform vec2 inverseLayerSize;',
        'uniform vec2 inverseTilesetSize;',

        'uniform vec2 tileSize;',
        //'uniform vec2 inverseTileSize;',
        'uniform vec2 numTiles;',

        'uniform sampler2D tileset;',
        'uniform sampler2D tileIds;',
        'uniform int repeatTiles;',
        'uniform float opacity;',

        'float decode24(vec3 rgb) {',
        '   const vec3 bit_shift = vec3((256.0*256.0), 256.0, 1.0);',
        '   float fl = dot(rgb, bit_shift);', //shift the values appropriately
        '   return fl * 255.0;', //denormalize the value
        '}',

        'void main(void) {',
        '   if(repeatTiles == 0 && (texCoord.x < 0.0 || texCoord.x > 1.0 || texCoord.y < 0.0 || texCoord.y > 1.0)) { discard; }',

        '   vec3 tileId = texture2D(tileIds, texCoord).rgb;', //grab this tileId from the layer data
        //'   tileId.rgb = tileId.bgr;', //if some hardware is different endian (little?) then we need to flip here
        '   float tileValue = decode24(tileId);', //decode the normalized vec3 into the float ID
        '   vec2 tileLoc = vec2(mod(tileValue, numTiles.x) - 0.5, tileValue / numTiles.x);', //convert the ID into x, y coords; the 0.5 fixes a precision error by making the later floor go down by 1
        '   tileLoc.y = numTiles.y - tileLoc.y;', //convert the coord from bottomleft to topleft

        '   vec2 offset = (floor(tileLoc) * tileSize) + 0.1;', //offset in the tileset; the 0.1 bias reduces tearing between tiles where it just shows space
        '   vec2 coord = mod(pixelCoord, tileSize);', //coord of the tile

        '   vec4 color = texture2D(tileset, (offset + coord) * inverseTilesetSize);', //grab tile from tileset
        '   color.a = opacity;',
        '   gl_FragColor = color;',
        '}'
    ].join('\n');

    //Each tilemap layer is just a Plane object with the map drawn on it
    gf.TilemapLayer = gf.SceneObject.extend({
        init: function(layer, tileSize, tilesets, zIndex, scale) {
            this._super();
            //this.parent = parent;

            //set options
            this.dataBuffer = new ArrayBuffer(layer.data.length * 3);
            this.data = new Uint8Array(this.dataBuffer);
            this.name = layer.name;
            this.size = new THREE.Vector2(layer.width, layer.height);
            this.tileSize = tileSize;
            this.offset = new THREE.Vector2(layer.x, layer.y);

            this.opacity = layer.opacity;
            this.visible = layer.visible;
            this.zIndex = zIndex;

            this.repeat = false;
            this.filtered = false;
            this.scale = scale;

            //set maps
            this.tileset = tilesets[0].texture;

            //pack our layer data array into an 8-bit uint array
            for (var i = 0, y = 0, il = layer.data.length; i < il; ++i, y += 3) {
                var value = layer.data[i];

                //this.data[y + 0] = (value & 0xff000000) >> 24;
                this.data[y + 0] = (value & 0x00ff0000) >> 16;
                this.data[y + 1] = (value & 0x0000ff00) >> 8;
                this.data[y + 2] = (value & 0x000000ff);
            }

            this.dataTex = new THREE.DataTexture(
                                this.data,
                                this.size.x, //width
                                this.size.y, //height
                                THREE.RGBFormat, //format
                                THREE.UnsignedByteType, //type
                                THREE.UVMapping, //mapping
                                THREE.ClampToEdgeWrapping, //wrapS
                                THREE.ClampToEdgeWrapping, //wrapT
                                THREE.NearestFilter, //magFilter
                                THREE.NearestMipMapNearestFilter //minFilter
                            );
            this.dataTex.needsUpdate = true;

            //Setup Tileset
            this.tileset.wrapS = this.tileset.wrapT = THREE.ClampToEdgeWrapping;
            //this.tileset.flipY = false;
            if(this.filtered) {
                this.tileset.magFilter = THREE.LinearFilter;
                this.tileset.minFilter = THREE.LinearMipMapLinearFilter;
            } else {
                this.tileset.magFilter = THREE.NearestFilter;
                this.tileset.minFilter = THREE.NearestMipMapNearestFilter;
            }
            //setup shader uniforms
            //
            //Types:
            // i - integer
            // f - float
            // c - color
            // t - Texture
            // tv - array of Textures
            // m4 - Matrix4
            // m4v - array of Matrix4s
            // iv - array of integers with 3 x N size
            // iv1 - array of integers
            // fv - array of floats with 3 x N size
            // fv1 - array of floats
            // v2 - Vector2
            // v3 - Vector3
            // v4 - Vector4
            // v2v - array of Vector2s
            // v3v - array of Vector3s
            // v4v - array of Vector4s
            this._uniforms = window._uniforms = {
                mapSize:            { type: 'v2', value: new THREE.Vector2(this.size.x * this.tileSize.x, this.size.y * this.tileSize.y) },
                inverseLayerSize:   { type: 'v2', value: new THREE.Vector2(1 / this.size.x, 1 / this.size.y) },
                inverseTilesetSize: { type: 'v2', value: new THREE.Vector2(1 / this.tileset.image.width, 1 / this.tileset.image.height) },

                tileSize:           { type: 'v2', value: this.tileSize },
                inverseTileSize:    { type: 'v2', value: new THREE.Vector2(1 / this.tileSize.x, 1 / this.tileSize.y) },
                numTiles:           { type: 'v2', value: new THREE.Vector2(this.tileset.image.width / this.tileSize.x, this.tileset.image.height / this.tileSize.y) },

                tileset:            { type: 't', value: this.tileset },
                tileIds:            { type: 't', value: this.dataTex },
                repeatTiles:        { type: 'i', value: this.repeat ? 1 : 0 },
                opacity:            { type: 'f', value: this.opacity }
            };

            //create the shader material
            this._material = new THREE.ShaderMaterial({
                uniforms: this._uniforms,
                vertexShader: vShader,
                fragmentShader: fShader,
                transparent: (this.opacity !== 1) //if the opacity isn't 1.0, then this needs to be transparent
            });

            this._plane = new THREE.PlaneGeometry(
                this.size.x * this.tileSize.x * this.scale,
                this.size.y * this.tileSize.y * this.scale
            );

            this._mesh = new THREE.Mesh(this._plane, this._material);
            this._mesh.visible = layer.visible;
            this._mesh.z = this.zIndex;
        }
    });
})();<commit_msg>fix screen tearing<commit_after>(function() {
    //Shaders
    var vShader = [
        'varying vec2 pixelCoord;',
        'varying vec2 texCoord;',

        'uniform vec2 mapSize;',
        'uniform vec2 inverseLayerSize;',
        //'uniform vec2 inverseTilesetSize;',

        //'uniform vec2 tileSize;',
        'uniform vec2 inverseTileSize;',
        //'uniform vec2 numTiles;',

        //'uniform sampler2D tileset;',
        //'uniform sampler2D tileIds;'
        //'uniform int repeatTiles;',
        //'uniform float opacity;',
        'uniform float bias;',
        'uniform float inverseScale;',

        'void main(void) {',
        '   pixelCoord = (uv * mapSize) - ((1.0 - bias) * inverseScale);', //this bias fixes a strange wrapping error
        '   texCoord = pixelCoord * inverseLayerSize * inverseTileSize;', //calculate the coord on this map
        '   gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);', //hand this position to WebGL
        '}'
    ].join('\n');

    var fShader = [
        //"precision highp float;",

        'varying vec2 pixelCoord;',
        'varying vec2 texCoord;',

        //'uniform vec2 mapSize;',
        //'uniform vec2 inverseLayerSize;',
        'uniform vec2 inverseTilesetSize;',

        'uniform vec2 tileSize;',
        //'uniform vec2 inverseTileSize;',
        'uniform vec2 numTiles;',

        'uniform sampler2D tileset;',
        'uniform sampler2D tileIds;',
        'uniform int repeatTiles;',
        'uniform float opacity;',
        'uniform float bias;',
        'uniform float inverseScale;',

        'float decode24(vec3 rgb) {',
        '   const vec3 bit_shift = vec3((256.0*256.0), 256.0, 1.0);',
        '   float fl = dot(rgb, bit_shift);', //shift the values appropriately
        '   return fl * 255.0;', //denormalize the value
        '}',

        'void main(void) {',
        '   if(repeatTiles == 0 && (texCoord.x < 0.0 || texCoord.x > 1.0 || texCoord.y < 0.0 || texCoord.y > 1.0)) { discard; }',

        '   vec3 tileId = texture2D(tileIds, texCoord).rgb;', //grab this tileId from the layer data
        //'   tileId.rgb = tileId.bgr;', //if some hardware is different endian (little?) then we need to flip here
        '   float tileValue = decode24(tileId);', //decode the normalized vec3 into the float ID
        '   vec2 tileLoc = vec2(mod(tileValue, numTiles.x) - (bias * inverseScale), tileValue / numTiles.x);', //convert the ID into x, y coords; the bias fixes a precision error by making the later floor go down by 1
        '   tileLoc.y = numTiles.y - tileLoc.y;', //convert the coord from bottomleft to topleft

        '   vec2 offset = (floor(tileLoc) * tileSize) + (bias * inverseScale);', //offset in the tileset; the bias removes the spacing between tiles
        '   vec2 coord = mod(pixelCoord, tileSize);', //coord of the tile

        '   vec4 color = texture2D(tileset, (offset + coord) * inverseTilesetSize);', //grab tile from tileset
        '   color.a = opacity;',
        '   gl_FragColor = color;',
        '}'
    ].join('\n');

    //Each tilemap layer is just a Plane object with the map drawn on it
    gf.TilemapLayer = gf.SceneObject.extend({
        init: function(layer, tileSize, tilesets, zIndex, scale) {
            this._super();
            //this.parent = parent;

            //set options
            this.dataBuffer = new ArrayBuffer(layer.data.length * 3);
            this.data = new Uint8Array(this.dataBuffer);
            this.name = layer.name;
            this.size = new THREE.Vector2(layer.width, layer.height);
            this.tileSize = tileSize;
            this.offset = new THREE.Vector2(layer.x, layer.y);

            this.opacity = layer.opacity;
            this.visible = layer.visible;
            this.zIndex = zIndex;

            this.repeat = false;
            this.filtered = false;
            this.scale = scale;

            //set maps
            this.tileset = tilesets[0].texture;

            //pack our layer data array into an 8-bit uint array
            for (var i = 0, y = 0, il = layer.data.length; i < il; ++i, y += 3) {
                var value = layer.data[i];

                //this.data[y + 0] = (value & 0xff000000) >> 24;
                this.data[y + 0] = (value & 0x00ff0000) >> 16;
                this.data[y + 1] = (value & 0x0000ff00) >> 8;
                this.data[y + 2] = (value & 0x000000ff);
            }

            this.dataTex = new THREE.DataTexture(
                                this.data,
                                this.size.x, //width
                                this.size.y, //height
                                THREE.RGBFormat, //format
                                THREE.UnsignedByteType, //type
                                THREE.UVMapping, //mapping
                                THREE.ClampToEdgeWrapping, //wrapS
                                THREE.ClampToEdgeWrapping, //wrapT
                                THREE.NearestFilter, //magFilter
                                THREE.NearestMipMapNearestFilter //minFilter
                            );
            this.dataTex.needsUpdate = true;

            //Setup Tileset
            this.tileset.wrapS = this.tileset.wrapT = THREE.ClampToEdgeWrapping;
            //this.tileset.flipY = false;
            if(this.filtered) {
                this.tileset.magFilter = THREE.LinearFilter;
                this.tileset.minFilter = THREE.LinearMipMapLinearFilter;
            } else {
                this.tileset.magFilter = THREE.NearestFilter;
                this.tileset.minFilter = THREE.NearestMipMapNearestFilter;
            }
            //setup shader uniforms
            //
            //Types:
            // i - integer
            // f - float
            // c - color
            // t - Texture
            // tv - array of Textures
            // m4 - Matrix4
            // m4v - array of Matrix4s
            // iv - array of integers with 3 x N size
            // iv1 - array of integers
            // fv - array of floats with 3 x N size
            // fv1 - array of floats
            // v2 - Vector2
            // v3 - Vector3
            // v4 - Vector4
            // v2v - array of Vector2s
            // v3v - array of Vector3s
            // v4v - array of Vector4s
            this._uniforms = window._uniforms = {
                mapSize:            { type: 'v2', value: new THREE.Vector2(this.size.x * this.tileSize.x, this.size.y * this.tileSize.y) },
                inverseLayerSize:   { type: 'v2', value: new THREE.Vector2(1 / this.size.x, 1 / this.size.y) },
                inverseTilesetSize: { type: 'v2', value: new THREE.Vector2(1 / this.tileset.image.width, 1 / this.tileset.image.height) },

                tileSize:           { type: 'v2', value: this.tileSize },
                inverseTileSize:    { type: 'v2', value: new THREE.Vector2(1 / this.tileSize.x, 1 / this.tileSize.y) },
                numTiles:           { type: 'v2', value: new THREE.Vector2(this.tileset.image.width / this.tileSize.x, this.tileset.image.height / this.tileSize.y) },

                tileset:            { type: 't', value: this.tileset },
                tileIds:            { type: 't', value: this.dataTex },
                repeatTiles:        { type: 'i', value: this.repeat ? 1 : 0 },
                opacity:            { type: 'f', value: this.opacity },
                bias:               { type: 'f', value: 0.1 },
                inverseScale:       { type: 'f', value: 1 / this.scale }
            };

            //create the shader material
            this._material = new THREE.ShaderMaterial({
                uniforms: this._uniforms,
                vertexShader: vShader,
                fragmentShader: fShader,
                transparent: (this.opacity !== 1) //if the opacity isn't 1.0, then this needs to be transparent
            });

            this._plane = new THREE.PlaneGeometry(
                this.size.x * this.tileSize.x * this.scale,
                this.size.y * this.tileSize.y * this.scale
            );

            this._mesh = new THREE.Mesh(this._plane, this._material);
            this._mesh.visible = layer.visible;
            this._mesh.z = this.zIndex;
        }
    });
})();<|endoftext|>