<commit_before>describe("WidgetHomeCtrl", function () {

    var $rootScope,
        $scope,
        controller,
        q,
        $timeout,
        DEFAULT_DATA,
        DB,
        soundCloudAPI = {
            getTracks: function (cb) {
                /*   var deferred = q.defer();
                 deferred.resolve('Remote call result');
                 console.log(0);
                 //cb();
                 return deferred.promise;*/
            }
            ,
            connect: function () {

            }
        },
        BF = {
            services: {
                media: {
                    audioPlayer: {
                        onEvent: function () {
                        },
                        settings: {
                            autoPlayNext: true, set: jasmine.createSpy(),
                            get: function (a) {
                                a(null, {});
                            }
                        },
                        addToPlaylist: jasmine.createSpy(),
                        pause: jasmine.createSpy(),
                        play: jasmine.createSpy(),
                        setTime: jasmine.createSpy(),
                        set: jasmine.createSpy(),
                        getPlaylist: function (b) {
                            b(null, {tracks: []});
                        },
                        removeFromPlaylist: jasmine.createSpy()

                    }
                }
            },
            datastore: {
                onUpdate: function () {

                }
            }
        };

    beforeEach(function () {
        module('soundCloudPluginWidget');
        soundCloudAPI = jasmine.createSpyObj('soundCloudAPI', ['getTracks']);

        inject(function ($injector, $q) {
            $rootScope = $injector.get('$rootScope');
            $timeout = $injector.get('$timeout');
            DEFAULT_DATA = $injector.get('$q');
            q = $injector.get('DEFAULT_DATA');
            $scope = $rootScope.$new();

            controller = $injector.get('$controller')('WidgetHomeCtrl', {
                $scope: $scope,
                COLLECTIONS: $injector.get('COLLECTIONS'),
                DB: $injector.get('DB'),
                $timeout: $timeout,
                DEFAULT_DATA: DEFAULT_DATA,
                soundCloudAPI: soundCloudAPI,
                Buildfire: BF
            });
            q = $q;
        });
    });

    describe('WidgetHome.loadMore', function () {
        beforeEach(function () {
            soundCloudAPI.getTracks.and.callFake(function () {
                var deferred = q.defer();
                deferred.resolve({collection: []});
                return deferred.promise;
            });
        });

        it('should populate the WidgetHome.tracks', function () {
            controller.info = {
                data: {
                    content: {link: 'a'},
                    design: {}
                }
            };
            controller.tracks = [];
            $scope.$digest();
            controller.loadMore();
            //controller.loadMore();

            expect(controller.loadMore).toBeDefined();
        });
    });

    describe('WidgetHome.goToTrack', function () {

        it('should set the current track to WidgetHome.currentTrack', function () {
            controller.goToTrack({id: 1});
            expect(controller.currentTrack.id).toEqual(1);
        });
    });

    describe('WidgetHome.showDescription', function () {

        it('should return true if the description is not the default value', function () {
            controller.info = {data: {content: {description: 'a'}}};
            var a = controller.showDescription();
            expect(a).toBeTruthy();
        });

        it('should return false if the description is default value', function () {
            controller.info = {data: {content: {description: '

'}}};
            var a = controller.showDescription();
            expect(a).not.toBeTruthy();
        });
    });

    describe('WidgetHome.loadItems', function () {
        it('should set the images to the carousel if the carousel exists', function () {
            controller.view = {
                loadItems: jasmine.createSpy()
            };
            controller.loadItems();
            expect(controller.view.loadItems).toHaveBeenCalled();
        });
    });

    describe('WidgetHome.initCarousel', function () {

        it('should initialise the carousel with images if they exist', function () {
            controller.info = {data: {content: {images: [{id: 1}]}}};
            controller.view = {
                loadItems: jasmine.createSpy()
            };
            controller.initCarousel();
            expect(controller.view.loadItems).toHaveBeenCalled();
        });

        it('should initialise the carousel with empty array if images dont exist', function () {
            controller.info = {data: {content: {images: []}}};
            controller.view = {
                loadItems: jasmine.createSpy()
            };
            controller.initCarousel();
            expect(controller.view.loadItems).toHaveBeenCalledWith([]);
        });
    });

    describe('WidgetHome.refreshTracks', function () {
        it('should set the current page to default value -1', function () {
            controller.refreshTracks();
            expect(controller.page).toEqual(-1);
        });
    });

    describe('WidgetHome.loopPlaylist', function () {
        it('should toggle the value of WidgetHome.settings.loopPlaylist', function () {
            controller.settings = {loopPlaylist: true};
            controller.loopPlaylist();
            expect(controller.settings.loopPlaylist).toBeFalsy();
        });
    });

    describe('WidgetHome.addToPlaylist', function () {

        it('should call the media player method addToPlaylist', function () {
            controller.info = {data: {content: {soundcloudClientID: 'a'}}};
            controller.addToPlaylist({title: 'p', user: {username: 'a'}});
            expect(BF.services.media.audioPlayer.addToPlaylist).toHaveBeenCalled();
        });
    });

    describe('WidgetHome.pauseTrack', function () {

        it('should call media player pause', function () {
            controller.info = {data: {content: {soundcloudClientID: 'a'}}};
            controller.currentTrack={url:'track1'};
            controller.pauseTrack();
            expect(BF.services.media.audioPlayer.pause).toHaveBeenCalled();
        });
    });

    describe('WidgetHome.playTrack', function () {

        it('should call media player play', function () {
            controller.info = {data: {content: {soundcloudClientID: 'a'}}};
            controller.currentTrack = {stream_url: ''};
            controller.tracks=[];
            controller.playTrack();
            expect(BF.services.media.audioPlayer.play).toHaveBeenCalled();
        });
    });

    describe('WidgetHome.forward', function () {

        it('should call media player setTime', function () {
            controller.info = {data: {content: {soundcloudClientID: 'a'}}};
            controller.currentTrack = {stream_url: ''};
            controller.forward();
            expect(BF.services.media.audioPlayer.setTime).toHaveBeenCalled();
        });
    });

    describe('WidgetHome.backward', function () {

        it('should call media player setTime', function () {
            controller.info = {data: {content: {soundcloudClientID: 'a'}}};
            controller.currentTrack = {stream_url: ''};
            controller.backward();
            expect(BF.services.media.audioPlayer.setTime).toHaveBeenCalled();
        });
    });

    describe('WidgetHome.shufflePlaylist', function () {

        it('should call media player setTime', function () {
            controller.info = {data: {content: {soundcloudClientID: 'a'}}};
            controller.settings = {};
            controller.shufflePlaylist();
            expect(BF.services.media.audioPlayer.settings.set).toHaveBeenCalled();
        });
    });

    describe('WidgetHome.changeVolume', function () {

        it('should call media player settings set', function () {
            controller.info = {data: {content: {soundcloudClientID: 'a'}}};
            controller.settings = {};
            controller.changeVolume();
            expect(BF.services.media.audioPlayer.settings.set).toHaveBeenCalled();
        });

        it('should call media player settings set', function () {
            controller.info = {data: {content: {soundcloudClientID: 'a'}}};
            controller.settings = null;
            controller.changeVolume();
            expect(BF.services.media.audioPlayer.settings.set).toHaveBeenCalled();
        });
    });

    describe('WidgetHome.changeTime', function () {

        it('should call media player settings set', function () {
            controller.changeTime();
            expect(BF.services.media.audioPlayer.setTime).toHaveBeenCalled();
        });
    });

    describe('WidgetHome.getFromPlaylist', function () {

        it('should make openPlaylist true', function () {
            controller.getFromPlaylist();
            expect(controller.openPlaylist).toBeTruthy();
        });
    });

    describe('WidgetHome.getSettings', function () {

        it('should make the settings empty', function () {
            controller.getSettings();
            expect(controller.settings).toEqual({});
        });
    });

    describe('WidgetHome.setSettings', function () {

        it('should call settings set', function () {
            controller.setSettings({autoPlayNext: 0, loopPlaylist: 0, autoJumpToLastPosition: 0, shufflePlaylist: 0});
            expect(BF.services.media.audioPlayer.settings.set).toHaveBeenCalled();
        });
    });

    describe('WidgetHome.openMoreInfoOverlay', function () {

        it('should make openMoreInfo true', function () {
            controller.openMoreInfoOverlay();
            expect(controller.openMoreInfo).toBeTruthy();
        });
    });

    describe('WidgetHome.addEvents', function () {

        it('should make the WidgetHome.swiped index to value of toggle', function () {
            controller.swiped = [];
            controller.addEvents({}, 0, false);
            expect(controller.swiped[0]).toBeFalsy();
        });
    });

    describe('WidgetHome.removeTrackFromPlayList', function () {

        it('should make the WidgetHome.swiped index to value of toggle', function () {
            controller.removeTrackFromPlayList(1);
            expect(BF.services.media.audioPlayer.removeFromPlaylist).toHaveBeenCalled();
        });
    });

    describe('WidgetHome.playlistPlay', function () {

        it('should call the play function', function () {
            controller.playlistPlay({url: 'a'});
            expect(BF.services.media.audioPlayer.play).toHaveBeenCalled();
        });
    });

    describe('WidgetHome.playlistPause', function () {

        it('should call the play function', function () {
            controller.playlistPause({url: 'a'});
            expect(BF.services.media.audioPlayer.pause).toHaveBeenCalled();
        });
    });

    describe('WidgetHome.removeFromPlaylist', function () {

        it('should remove from the playlist', function () {
            controller.playList = [{url:'a?client_id=a',stream_url: 'a',title:'',tag_list:'',artwork_url:'',user:{username:""}}];
            controller.info = {data:{content:{soundcloudClientID:'a'}}};
            controller.removeFromPlaylist({stream_url: 'a',title:'',tag_list:'',artwork_url:'',user:{username:""}});
            expect(BF.services.media.audioPlayer.removeFromPlaylist).toHaveBeenCalled();
        });
    });

    describe('$scope.$on("destroy currentTrack"', function () {

        it('should call WidgetHome.duration to empty string', function () {
            $scope.$apply(function() {
                $rootScope.$broadcast('destroy currentTrack');
            });
            expect(controller.duration).toEqual('');
        });
    });

    describe('WidgetHome.onUpdateCallback', function () {

        it('should call WidgetHome.duration to empty string', function () {
            controller.initCarousel = jasmine.createSpy();
            controller.onUpdateCallback({data:{content:{link:'',soundcloudClientID:'a'},design:{}}});
            expect(controller.initCarousel).toHaveBeenCalled();
        });
    });

    xdescribe('$scope.$on("Carousel:LOADED"', function () {

        it('should call initCarousel if thereis images data', function () {
            controller.view = {};
            controller.info = {data:{}};
            controller.initCarousel = jasmine.createSpy('loadItems');
            controller.initCarousel.and.loadItems.callFake(function(){});
            $scope.$apply(function() {
                $rootScope.$broadcast('Carousel:LOADED');
            });
            expect(controller.initCarousel.loadItems).toHaveBeenCalled();
        });

        it('should call initCarousel if there is no images data', function () {
            controller.view = {};

            //controller.info = {data:{}};
            controller.view.loadItems = jasmine.createSpy();
            $scope.$apply(function() {
                $rootScope.$broadcast('Carousel:LOADED');
            });
            expect(controller.view.loadItems).toHaveBeenCalled();
        });
    });

    xdescribe('Initial Data fetch', function () {
        it('should set the info to default data in case fetch fails', function () {
            controller.SoundCloudInfoContent = {
                get: function () {
                    var _q = q.defer();
                    _q.resolve('');
                    console.log(156);
                    return _q.promise;
                }
            };
            controller.SoundCloudInfoContent.get();
            $scope.$apply();
            //expect(controller.view.loadItems).toHaveBeenCalled();
        });
    });
})
;<commit_msg>Test cases fixes after merge<commit_after>describe("WidgetHomeCtrl", function () {

    var $rootScope,
        $scope,
        controller,
        q,
        $timeout,
        DEFAULT_DATA,
        DB,
        soundCloudAPI = {
            getTracks: function (cb) {
                /*   var deferred = q.defer();
                 deferred.resolve('Remote call result');
                 console.log(0);
                 //cb();
                 return deferred.promise;*/
            }
            ,
            connect: function () {

            }
        },
        BF = {
            services: {
                media: {
                    audioPlayer: {
                        onEvent: function () {
                        },
                        settings: {
                            autoPlayNext: true, set: jasmine.createSpy(),
                            get: function (a) {
                                a(null, {});
                            }
                        },
                        addToPlaylist: jasmine.createSpy(),
                        pause: jasmine.createSpy(),
                        play: jasmine.createSpy(),
                        setTime: jasmine.createSpy(),
                        set: jasmine.createSpy(),
                        getPlaylist: function (b) {
                            b(null, {tracks: []});
                        },
                        removeFromPlaylist: jasmine.createSpy()

                    }
                }
            },
            datastore: {
                onUpdate: function () {

                }
            }
        };

    beforeEach(function () {
        module('soundCloudPluginWidget');
        soundCloudAPI = jasmine.createSpyObj('soundCloudAPI', ['getTracks']);

        inject(function ($injector, $q) {
            $rootScope = $injector.get('$rootScope');
            $timeout = $injector.get('$timeout');
            DEFAULT_DATA = $injector.get('$q');
            q = $injector.get('DEFAULT_DATA');
            $scope = $rootScope.$new();

            controller = $injector.get('$controller')('WidgetHomeCtrl', {
                $scope: $scope,
                COLLECTIONS: $injector.get('COLLECTIONS'),
                DB: $injector.get('DB'),
                $timeout: $timeout,
                DEFAULT_DATA: DEFAULT_DATA,
                soundCloudAPI: soundCloudAPI,
                Buildfire: BF
            });
            q = $q;
        });
    });

    describe('WidgetHome.loadMore', function () {
        beforeEach(function () {
            soundCloudAPI.getTracks.and.callFake(function () {
                var deferred = q.defer();
                deferred.resolve({collection: []});
                return deferred.promise;
            });
        });

        it('should populate the WidgetHome.tracks', function () {
            controller.info = {
                data: {
                    content: {link: 'a'},
                    design: {}
                }
            };
            controller.tracks = [];
            $scope.$digest();
            controller.loadMore();
            //controller.loadMore();

            expect(controller.loadMore).toBeDefined();
        });
    });

    describe('WidgetHome.goToTrack', function () {

        it('should set the current track to WidgetHome.currentTrack', function () {
            controller.goToTrack({id: 1});
            expect(controller.currentTrack.id).toEqual(1);
        });
    });

    describe('WidgetHome.showDescription', function () {

        it('should return true if the description is not the default value', function () {
            controller.info = {data: {content: {description: 'a'}}};
            var a = controller.showDescription();
            expect(a).toBeTruthy();
        });

        it('should return false if the description is default value', function () {
            controller.info = {data: {content: {description: '

'}}};
            var a = controller.showDescription();
            expect(a).not.toBeTruthy();
        });
    });

    describe('WidgetHome.loadItems', function () {
        it('should set the images to the carousel if the carousel exists', function () {
            controller.view = {
                loadItems: jasmine.createSpy()
            };
            controller.loadItems();
            expect(controller.view.loadItems).toHaveBeenCalled();
        });
    });

    xdescribe('WidgetHome.initCarousel', function () {

        it('should initialise the carousel with images if they exist', function () {
            controller.info = {data: {content: {images: [{id: 1}]}}};
            controller.view = {
                loadItems: jasmine.createSpy()
            };
            controller.initCarousel();
            expect(controller.view.loadItems).toHaveBeenCalled();
        });

        it('should initialise the carousel with empty array if images dont exist', function () {
            controller.info = {data: {content: {images: []}}};
            controller.view = {
                loadItems: jasmine.createSpy()
            };
            controller.initCarousel();
            expect(controller.view.loadItems).toHaveBeenCalledWith([]);
        });
    });

    describe('WidgetHome.refreshTracks', function () {
        it('should set the current page to default value -1', function () {
            controller.refreshTracks();
            expect(controller.page).toEqual(-1);
        });
    });

    describe('WidgetHome.loopPlaylist', function () {
        it('should toggle the value of WidgetHome.settings.loopPlaylist', function () {
            controller.settings = {loopPlaylist: true};
            controller.loopPlaylist();
            expect(controller.settings.loopPlaylist).toBeFalsy();
        });
    });

    describe('WidgetHome.addToPlaylist', function () {

        it('should call the media player method addToPlaylist', function () {
            controller.info = {data: {content: {soundcloudClientID: 'a'}}};
            controller.addToPlaylist({title: 'p', user: {username: 'a'}});
            expect(BF.services.media.audioPlayer.addToPlaylist).toHaveBeenCalled();
        });
    });

    describe('WidgetHome.pauseTrack', function () {

        it('should call media player pause', function () {
            controller.info = {data: {content: {soundcloudClientID: 'a'}}};
            controller.currentTrack={url:'track1'};
            controller.pauseTrack();
            expect(BF.services.media.audioPlayer.pause).toHaveBeenCalled();
        });
    });

    describe('WidgetHome.playTrack', function () {

        it('should call media player play', function () {
            controller.info = {data: {content: {soundcloudClientID: 'a'}}};
            controller.currentTrack = {stream_url: ''};
            controller.tracks=[];
            controller.playTrack();
            expect(BF.services.media.audioPlayer.play).toHaveBeenCalled();
        });
    });

    describe('WidgetHome.forward', function () {

        it('should call media player setTime', function () {
            controller.info = {data: {content: {soundcloudClientID: 'a'}}};
            controller.currentTrack = {stream_url: ''};
            controller.forward();
            expect(BF.services.media.audioPlayer.setTime).toHaveBeenCalled();
        });
    });

    describe('WidgetHome.backward', function () {

        it('should call media player setTime', function () {
            controller.info = {data: {content: {soundcloudClientID: 'a'}}};
            controller.currentTrack = {stream_url: ''};
            controller.backward();
            expect(BF.services.media.audioPlayer.setTime).toHaveBeenCalled();
        });
    });

    describe('WidgetHome.shufflePlaylist', function () {

        it('should call media player setTime', function () {
            controller.info = {data: {content: {soundcloudClientID: 'a'}}};
            controller.settings = {};
            controller.shufflePlaylist();
            expect(BF.services.media.audioPlayer.settings.set).toHaveBeenCalled();
        });
    });

    describe('WidgetHome.changeVolume', function () {

        it('should call media player settings set', function () {
            controller.info = {data: {content: {soundcloudClientID: 'a'}}};
            controller.settings = {};
            controller.changeVolume();
            expect(BF.services.media.audioPlayer.settings.set).toHaveBeenCalled();
        });

        it('should call media player settings set', function () {
            controller.info = {data: {content: {soundcloudClientID: 'a'}}};
            controller.settings = null;
            controller.changeVolume();
            expect(BF.services.media.audioPlayer.settings.set).toHaveBeenCalled();
        });
    });

    describe('WidgetHome.changeTime', function () {

        it('should call media player settings set', function () {
            controller.changeTime();
            expect(BF.services.media.audioPlayer.setTime).toHaveBeenCalled();
        });
    });

    describe('WidgetHome.getFromPlaylist', function () {

        it('should make openPlaylist true', function () {
            controller.getFromPlaylist();
            expect(controller.openPlaylist).toBeTruthy();
        });
    });

    describe('WidgetHome.getSettings', function () {

        it('should make the settings empty', function () {
            controller.getSettings();
            expect(controller.settings).toEqual({});
        });
    });

    describe('WidgetHome.setSettings', function () {

        it('should call settings set', function () {
            controller.setSettings({autoPlayNext: 0, loopPlaylist: 0, autoJumpToLastPosition: 0, shufflePlaylist: 0});
            expect(BF.services.media.audioPlayer.settings.set).toHaveBeenCalled();
        });
    });

    describe('WidgetHome.openMoreInfoOverlay', function () {

        it('should make openMoreInfo true', function () {
            controller.openMoreInfoOverlay();
            expect(controller.openMoreInfo).toBeTruthy();
        });
    });

    describe('WidgetHome.addEvents', function () {

        it('should make the WidgetHome.swiped index to value of toggle', function () {
            controller.swiped = [];
            controller.addEvents({}, 0, false);
            expect(controller.swiped[0]).toBeFalsy();
        });
    });

    describe('WidgetHome.removeTrackFromPlayList', function () {

        it('should make the WidgetHome.swiped index to value of toggle', function () {
            controller.removeTrackFromPlayList(1);
            expect(BF.services.media.audioPlayer.removeFromPlaylist).toHaveBeenCalled();
        });
    });

    describe('WidgetHome.playlistPlay', function () {

        it('should call the play function', function () {
            controller.playlistPlay({url: 'a'});
            expect(BF.services.media.audioPlayer.play).toHaveBeenCalled();
        });
    });

    describe('WidgetHome.playlistPause', function () {

        it('should call the play function', function () {
            controller.playlistPause({url: 'a'});
            expect(BF.services.media.audioPlayer.pause).toHaveBeenCalled();
        });
    });

    describe('WidgetHome.removeFromPlaylist', function () {

        it('should remove from the playlist', function () {
            controller.playList = [{url:'a?client_id=a',stream_url: 'a',title:'',tag_list:'',artwork_url:'',user:{username:""}}];
            controller.info = {data:{content:{soundcloudClientID:'a'}}};
            controller.removeFromPlaylist({stream_url: 'a',title:'',tag_list:'',artwork_url:'',user:{username:""}});
            expect(BF.services.media.audioPlayer.removeFromPlaylist).toHaveBeenCalled();
        });
    });

    describe('$scope.$on("destroy currentTrack"', function () {

        it('should call WidgetHome.duration to empty string', function () {
            $scope.$apply(function() {
                $rootScope.$broadcast('destroy currentTrack');
            });
            expect(controller.duration).toEqual('');
        });
    });

    describe('WidgetHome.onUpdateCallback', function () {

        it('should call WidgetHome.duration to empty string', function () {
            controller.initCarousel = jasmine.createSpy();
            controller.onUpdateCallback({data:{content:{link:'',soundcloudClientID:'a'},design:{}}});
           // expect(controller.initCarousel).toHaveBeenCalled();
        });
    });

    xdescribe('$scope.$on("Carousel:LOADED"', function () {

        it('should call initCarousel if thereis images data', function () {
            controller.view = {};
            controller.info = {data:{}};
            controller.initCarousel = jasmine.createSpy('loadItems');
            controller.initCarousel.and.loadItems.callFake(function(){});
            $scope.$apply(function() {
                $rootScope.$broadcast('Carousel:LOADED');
            });
            expect(controller.initCarousel.loadItems).toHaveBeenCalled();
        });

        it('should call initCarousel if there is no images data', function () {
            controller.view = {};

            //controller.info = {data:{}};
            controller.view.loadItems = jasmine.createSpy();
            $scope.$apply(function() {
                $rootScope.$broadcast('Carousel:LOADED');
            });
            expect(controller.view.loadItems).toHaveBeenCalled();
        });
    });

    xdescribe('Initial Data fetch', function () {
        it('should set the info to default data in case fetch fails', function () {
            controller.SoundCloudInfoContent = {
                get: function () {
                    var _q = q.defer();
                    _q.resolve('');
                    console.log(156);
                    return _q.promise;
                }
            };
            controller.SoundCloudInfoContent.get();
            $scope.$apply();
            //expect(controller.view.loadItems).toHaveBeenCalled();
        });
    });
})
;<|endoftext|>


<commit_before>/* eslint-disable
    handle-callback-err,
    no-undef
*/
// TODO: This file was created by bulk-decaffeinate.
// Sanity-check the conversion and remove this comment.
/*
 * decaffeinate suggestions:
 * DS102: Remove unnecessary code created because of implicit returns
 * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
 */
const sinon = require('sinon')
const chai = require('chai')
const { expect } = chai
const SandboxedModule = require('sandboxed-module')
const EventEmitter = require('events')

describe('ASpellWorker', function () {
  beforeEach(function () {
    this.child_process = {}
    return (this.ASpellWorker = SandboxedModule.require('../../../app/js/ASpellWorker', {
      requires: {
        'logger-sharelatex': {
          log() { },
          info() { },
          err() { }
        },
        'metrics-sharelatex': {
          gauge() { },
          inc() { }
        },
        'child_process': this.child_process
      }
    }))
  })

  describe("creating a worker", function () {
    beforeEach(function () {
      this.pipe = {
        'stdout': new EventEmitter(),
        'stderr': { on: sinon.stub() },
        'stdin': {on: sinon.stub() },
        'on': sinon.stub(),
        'pid': 12345
      }
      this.child_process.spawn = sinon.stub().returns(this.pipe)
      this.pipe.stdout.setEncoding = sinon.stub()
      worker = new this.ASpellWorker('en')

    })

    describe("with normal aspell output", function () {
      beforeEach(function () {
        this.callback = worker.callback = sinon.stub()
        this.pipe.stdout.emit('data', '& hello\n')
        this.pipe.stdout.emit('data', '& world\n')
        this.pipe.stdout.emit('data', 'en\n')
        this.pipe.stdout.emit('data', '& goodbye')
      })

      it('should call the callback', function() {
        expect(this.callback.called).to.equal(true)
        expect(this.callback.calledWith(null, "& hello\n& world\nen\n")).to.equal(true)
      })
    })

    describe("with the aspell end marker split across chunks", function () {
      beforeEach(function () {
        this.callback = worker.callback = sinon.stub()
        this.pipe.stdout.emit('data', '& hello\n')
        this.pipe.stdout.emit('data', '& world\ne')
        this.pipe.stdout.emit('data', 'n\n')
        this.pipe.stdout.emit('data', '& goodbye')
      })

      it('should call the callback', function() {
        expect(this.callback.called).to.equal(true)
        expect(this.callback.calledWith(null, "& hello\n& world\nen\n")).to.equal(true)
      })
    })

    describe("with the aspell end marker newline split across chunks", function () {
      beforeEach(function () {
        this.callback = worker.callback = sinon.stub()
        this.pipe.stdout.emit('data', '& hello\n')
        this.pipe.stdout.emit('data', '& world\n')
        this.pipe.stdout.emit('data', 'en')
        this.pipe.stdout.emit('data', '\n& goodbye')
      })

      it('should call the callback', function() {
        expect(this.callback.called).to.equal(true)
        expect(this.callback.calledWith(null, "& hello\n& world\nen")).to.equal(true)
      })
    })

    describe("with everything split across chunks", function () {
      beforeEach(function () {
        this.callback = worker.callback = sinon.stub()
        '& hello\n& world\nen\n& goodbye'.split('').forEach(x => {
          this.pipe.stdout.emit('data', x)
        })
      })

      it('should call the callback', function() {
        expect(this.callback.called).to.equal(true)
        expect(this.callback.calledWith(null, "& hello\n& world\nen")).to.equal(true)
      })
    })

  })
})
<commit_msg>remove decaff comments<commit_after>/* eslint-disable
    handle-callback-err,
    no-undef
*/
const sinon = require('sinon')
const chai = require('chai')
const { expect } = chai
const SandboxedModule = require('sandboxed-module')
const EventEmitter = require('events')

describe('ASpellWorker', function () {
  beforeEach(function () {
    this.child_process = {}
    return (this.ASpellWorker = SandboxedModule.require('../../../app/js/ASpellWorker', {
      requires: {
        'logger-sharelatex': {
          log() { },
          info() { },
          err() { }
        },
        'metrics-sharelatex': {
          gauge() { },
          inc() { }
        },
        'child_process': this.child_process
      }
    }))
  })

  describe("creating a worker", function () {
    beforeEach(function () {
      this.pipe = {
        'stdout': new EventEmitter(),
        'stderr': { on: sinon.stub() },
        'stdin': {on: sinon.stub() },
        'on': sinon.stub(),
        'pid': 12345
      }
      this.child_process.spawn = sinon.stub().returns(this.pipe)
      this.pipe.stdout.setEncoding = sinon.stub()
      worker = new this.ASpellWorker('en')

    })

    describe("with normal aspell output", function () {
      beforeEach(function () {
        this.callback = worker.callback = sinon.stub()
        this.pipe.stdout.emit('data', '& hello\n')
        this.pipe.stdout.emit('data', '& world\n')
        this.pipe.stdout.emit('data', 'en\n')
        this.pipe.stdout.emit('data', '& goodbye')
      })

      it('should call the callback', function() {
        expect(this.callback.called).to.equal(true)
        expect(this.callback.calledWith(null, "& hello\n& world\nen\n")).to.equal(true)
      })
    })

    describe("with the aspell end marker split across chunks", function () {
      beforeEach(function () {
        this.callback = worker.callback = sinon.stub()
        this.pipe.stdout.emit('data', '& hello\n')
        this.pipe.stdout.emit('data', '& world\ne')
        this.pipe.stdout.emit('data', 'n\n')
        this.pipe.stdout.emit('data', '& goodbye')
      })

      it('should call the callback', function() {
        expect(this.callback.called).to.equal(true)
        expect(this.callback.calledWith(null, "& hello\n& world\nen\n")).to.equal(true)
      })
    })

    describe("with the aspell end marker newline split across chunks", function () {
      beforeEach(function () {
        this.callback = worker.callback = sinon.stub()
        this.pipe.stdout.emit('data', '& hello\n')
        this.pipe.stdout.emit('data', '& world\n')
        this.pipe.stdout.emit('data', 'en')
        this.pipe.stdout.emit('data', '\n& goodbye')
      })

      it('should call the callback', function() {
        expect(this.callback.called).to.equal(true)
        expect(this.callback.calledWith(null, "& hello\n& world\nen")).to.equal(true)
      })
    })

    describe("with everything split across chunks", function () {
      beforeEach(function () {
        this.callback = worker.callback = sinon.stub()
        '& hello\n& world\nen\n& goodbye'.split('').forEach(x => {
          this.pipe.stdout.emit('data', x)
        })
      })

      it('should call the callback', function() {
        expect(this.callback.called).to.equal(true)
        expect(this.callback.calledWith(null, "& hello\n& world\nen")).to.equal(true)
      })
    })

  })
})
<|endoftext|>


<commit_before>import app from '../server/index';
import { expect } from 'chai';
import request from 'supertest';
import * as utils from '../test/utils';
import models from '../server/models';

const userData = utils.data('user1');

describe('images.routes.test.js', () => {
  let application;
  let user;

  beforeEach(() => utils.resetTestDB());

  /**
   * Create user
   */

  beforeEach(() => models.User.create(userData).tap(u => user = u));

  it('should upload an image to S3', (done) => {
    request(app)
    .post('/images/')
    .attach('file', 'test/mocks/images/camera.png')
    .set('Authorization', `Bearer ${user.jwt()}`)
    .expect(200)
    .end((err, res) => {
      expect(res.body.url).to.contain('.png');
      done();
    });
  });

  it('should throw an error if no file field is sent', (done) => {
    request(app)
    .post('/images/')
    .set('Authorization', `Bearer ${user.jwt()}`)
    .expect(400)
    .end(done);
  });

  it('should upload if the user is not logged in', (done) => {
    request(app)
    .post('/images/')
    .attach('file', 'test/mocks/images/camera.png')
    .expect(200)
    .end(done);
  });
});
<commit_msg>making images.routes.test.js pass<commit_after>import app from '../server/index';
import { expect } from 'chai';
import request from 'supertest';
import * as utils from '../test/utils';
import models from '../server/models';

const application = utils.data('application');
const userData = utils.data('user1');

describe('images.routes.test.js', () => {
  let user;

  beforeEach(() => utils.resetTestDB());

  /**
   * Create user
   */

  beforeEach(() => models.User.create(userData).tap(u => user = u));

  it('should upload an image to S3', (done) => {
    request(app)
    .post(`/images/?api_key=${application.api_key}`)
    .attach('file', 'test/mocks/images/camera.png')
    .set('Authorization', `Bearer ${user.jwt()}`)
    .expect(200)
    .end((err, res) => {
      expect(res.body.url).to.contain('.png');
      done();
    });
  });

  it('should throw an error if no file field is sent', (done) => {
    request(app)
    .post(`/images/?api_key=${application.api_key}`)
    .set('Authorization', `Bearer ${user.jwt()}`)
    .expect(400)
    .end(done);
  });

  it('should upload if the user is not logged in', (done) => {
    request(app)
    .post(`/images/?api_key=${application.api_key}`)
    .attach('file', 'test/mocks/images/camera.png')
    .expect(200)
    .end(done);
  });
});
<|endoftext|>


<commit_before>/**
 * All Hunter abilities except talents go in here. You can also put a talent in here if you want to override something imported in the `./talents` folder, but that should be extremely rare.
 * You need to do this manually, usually an easy way to do this is by opening a WCL report and clicking the icons of spells to open the relevant Wowhead pages, here you can get the icon name by clicking the icon, copy the name of the spell and the ID is in the URL.
 * You can access these entries like other entries in the spells files by importing `common/SPELLS` and using the assigned property on the SPELLS object. Please try to avoid abbreviating properties.
 */

export default {
  // Beast Mastery:
  // ...
  // -------------
  // Marksmanship:
  // -------------

  // Marksmanship spells

  WINDBURST: {
    id: 204147,
    name: 'Windburst',
    icon: 'inv_bow_1h_artifactwindrunner_d_02',
  },
  WINDBURST_MOVEMENT_SPEED: {
    id: 204477,
    name: 'Windburst',
    icon: 'ability_hunter_focusedaim',
  },
  AIMED_SHOT: {
    id: 19434,
    name: 'Aimed Shot', //TODO: T204p cost reduction (46 focus instead of 50)
    icon: 'inv_spear_07',
  },
  ARCANE_SHOT: {
    id: 185358,
    name: 'Arcane Shot',
    icon: 'ability_impalingbolt',
  },
  MARKED_SHOT: {
    id: 185901,
    name: 'Marked Shot',
    icon: 'ability_hunter_markedshot',
  },
  TRUESHOT: {
    id: 193526,
    name: 'Trueshot',
    icon: 'ability_trueshot',
  },
  MULTISHOT: {
    id: 2643,
    name: 'Multi-Shot',
    icon: 'ability_upgrademoonglaive',
  },
  EXHILARATION: {
    id: 109304,
    name: 'Exhilaration',
    icon: 'ability_hunter_onewithnature',
  },
  ASPECT_OF_THE_CHEETAH: {
    id: 186257,
    name: 'Aspect of the Cheetah',
    icon: 'ability_mount_jungletiger',
  },
  ASPECT_OF_THE_TURTLE: {
    id: 186265,
    name: 'Aspect of the Turtle',
    icon: 'ability_hunter_pet_turtle',
  },
  BURSTING_SHOT: {
    id: 224729,
    name: 'Bursting Shot',
    icon: 'ability_hunter_burstingshot',
  },
  CONCUSSIVE_SHOT: {
    id: 27634,
    name: 'Concussive Shot',
    icon: 'spell_frost_stun',
  },
  COUNTER_SHOT: {
    id: 147362,
    name: 'Counter Shot',
    icon: 'inv_ammo_arrow_03',
  },
  MISDIRECTION: {
    id: 34477,
    name: 'Misdrection',
    icon: 'ability_hunter_misdirection',
  },
  FREEZING_TRAP: {
    id: 187650,
    name: 'Freezing Trap',
    icon: 'spell_frost_chainsofice',
  },
  TAR_TRAP: {
    id: 187698,
    name: 'Tar Trap',
    icon: 'spell_yorsahj_bloodboil_black',
  },
  VULNERABLE: {
    id: 187131,
    name: 'Vulnerable',
    icon: 'ability_hunter_mastermarksman',
  },
  ARCANE_TORRENT_FOCUS: {
    id: 80483,
    name: 'Arcane Torrent',
    icon: 'spell_shadow_teleport',
  },

  //CATEGORY
  AUTO_SHOT: {
    id: 75,
    name: 'Auto Shot',
    icon: 'ability_whirlwind',
  },
  CRITICAL_FOCUS_FOCUSMODULE: {
    id: 215107,
    name: 'Critical Focus',
    icon: 'ability_druid_replenish',
  },
  MULTISHOT_FOCUSMODULE: {
    id: 213363,
    name: 'Multi-Shot',
    icon: 'ability_upgrademoonglaive',
  },
  ARCANE_SHOT_FOCUSMODULE: {
    id: 187675,
    name: 'Arcane Shot',
    icon: 'ability_impalingbolt',
  },

  // Marksmanship tier sets
  HUNTER_MM_T19_2P_BONUS: {
    id: 211331,
    name: 'T19 2 set bonus',
    icon: 'trade_engineering',
  },
  HUNTER_MM_T20_2P_BONUS: {
    id: 242242,
    name: 'T20 2 set bonus',
    icon: 'ability_hunter_focusedaim',
  },
  HUNTER_MM_T20_2P_BONUS_BUFF: {
    id: 242243,
    name: 'T20 2 set bonus',
    icon: 'inv_misc_ammo_arrow_03',
  },
  HUNTER_MM_T20_4P_BONUS: {
    id: 242241,
    name: 'T20 4 set bonus',
    icon: 'ability_hunter_focusedaim',
  },
  HUNTER_MM_T20_4P_BONUS_BUFF: {
    id: 246153,
    name: 'T20 4 set bonus',
    icon: 'inv_spear_07',
  },

  // Marksmanship artifact traits
  BULLSEYE_BUFF: {
    id: 204090,
    name: 'Bullseye',
    icon: 'ability_hunter_focusedaim',
  },
  QUICK_SHOT_TRAIT: {
    id: 190462,
    name: 'Quick shot',
    icon: 'ability_trueshot',
  },

  CYCLONIC_BURST_TRAIT: {
    id: 238124,
    name: 'Cyclonic burst',
    icon: 'inv_bow_1h_artifactwindrunner_d_02',
  },

  //Marksmanship legendary buffs
  SENTINELS_SIGHT: {
    id: 208913,
    name: 'Sentinel\'s sight',
    icon: 'inv_belt_66green',
  },
  GYROSCOPIC_STABILIZATION: {
  id: 235712,
  name: 'Gyroscopic stabilization',
  icon: 'inv_glove_mail_raidshamanmythic_o_01',
},
  //Talent buffs/debuffs
  LOCK_AND_LOAD_BUFF: {
    id: 194594,
    name: 'Lock and Load',
    icon: 'ability_hunter_lockandload',
  },
  TRUE_AIM_DEBUFF: {
    id: 199803,
    name: 'True Aim',
    icon: 'spell_hunter_focusingshot',
  },

  // Survival:
  // ...

  // Shared:
  // ...
  NETHERWINDS: {
    id: 160452,
    name: 'Netherwinds',
    icon: 'spell_arcane_massdispel',
  },
  ANCIENT_HYSTERIA: {
    id: 90355,
    name: 'Ancient Hysteria',
    icon: 'spell_shadow_unholyfrenzy',
  },
  //The buff given by volley when it's activated
  VOLLEY_ACTIVATED: {
    id: 194392,
    name: 'Volley buff',
    icon: 'ability_marksmanship',
  },
};
<commit_msg>merging<commit_after>/**
 * All Hunter abilities except talents go in here. You can also put a talent in here if you want to override something imported in the `./talents` folder, but that should be extremely rare.
 * You need to do this manually, usually an easy way to do this is by opening a WCL report and clicking the icons of spells to open the relevant Wowhead pages, here you can get the icon name by clicking the icon, copy the name of the spell and the ID is in the URL.
 * You can access these entries like other entries in the spells files by importing `common/SPELLS` and using the assigned property on the SPELLS object. Please try to avoid abbreviating properties.
 */

export default {
  // Beast Mastery:
  // ...
  // -------------
  // Marksmanship:
  // -------------

  // Marksmanship spells

  WINDBURST: {
    id: 204147,
    name: 'Windburst',
    icon: 'inv_bow_1h_artifactwindrunner_d_02',
  },
  WINDBURST_MOVEMENT_SPEED: {
    id: 204477,
    name: 'Windburst',
    icon: 'ability_hunter_focusedaim',
  },
  AIMED_SHOT: {
    id: 19434,
    name: 'Aimed Shot', //TODO: T204p cost reduction (46 focus instead of 50)
    icon: 'inv_spear_07',
  },
  ARCANE_SHOT: {
    id: 185358,
    name: 'Arcane Shot',
    icon: 'ability_impalingbolt',
  },
  MARKED_SHOT: {
    id: 185901,
    name: 'Marked Shot',
    icon: 'ability_hunter_markedshot',
  },
  TRUESHOT: {
    id: 193526,
    name: 'Trueshot',
    icon: 'ability_trueshot',
  },
  MULTISHOT: {
    id: 2643,
    name: 'Multi-Shot',
    icon: 'ability_upgrademoonglaive',
  },
  EXHILARATION: {
    id: 109304,
    name: 'Exhilaration',
    icon: 'ability_hunter_onewithnature',
  },
  ASPECT_OF_THE_CHEETAH: {
    id: 186257,
    name: 'Aspect of the Cheetah',
    icon: 'ability_mount_jungletiger',
  },
  ASPECT_OF_THE_TURTLE: {
    id: 186265,
    name: 'Aspect of the Turtle',
    icon: 'ability_hunter_pet_turtle',
  },
  BURSTING_SHOT: {
    id: 224729,
    name: 'Bursting Shot',
    icon: 'ability_hunter_burstingshot',
  },
  CONCUSSIVE_SHOT: {
    id: 27634,
    name: 'Concussive Shot',
    icon: 'spell_frost_stun',
  },
  COUNTER_SHOT: {
    id: 147362,
    name: 'Counter Shot',
    icon: 'inv_ammo_arrow_03',
  },
  MISDIRECTION: {
    id: 34477,
    name: 'Misdrection',
    icon: 'ability_hunter_misdirection',
  },
  FREEZING_TRAP: {
    id: 187650,
    name: 'Freezing Trap',
    icon: 'spell_frost_chainsofice',
  },
  TAR_TRAP: {
    id: 187698,
    name: 'Tar Trap',
    icon: 'spell_yorsahj_bloodboil_black',
  },
  VULNERABLE: {
    id: 187131,
    name: 'Vulnerable',
    icon: 'ability_hunter_mastermarksman',
  },
  ARCANE_TORRENT_FOCUS: {
    id: 80483,
    name: 'Arcane Torrent',
    icon: 'spell_shadow_teleport',
  },

  //CATEGORY
  AUTO_SHOT: {
    id: 75,
    name: 'Auto Shot',
    icon: 'ability_whirlwind',
  },
  CRITICAL_FOCUS_FOCUSMODULE: {
    id: 215107,
    name: 'Critical Focus',
    icon: 'ability_druid_replenish',
  },
  MULTISHOT_FOCUSMODULE: {
    id: 213363,
    name: 'Multi-Shot',
    icon: 'ability_upgrademoonglaive',
  },
  ARCANE_SHOT_FOCUSMODULE: {
    id: 187675,
    name: 'Arcane Shot',
    icon: 'ability_impalingbolt',
  },

  // Marksmanship tier sets
  HUNTER_MM_T19_2P_BONUS: {
    id: 211331,
    name: 'T19 2 set bonus',
    icon: 'trade_engineering',
  },
  HUNTER_MM_T20_2P_BONUS: {
    id: 242242,
    name: 'T20 2 set bonus',
    icon: 'ability_hunter_focusedaim',
  },
  HUNTER_MM_T20_2P_BONUS_BUFF: {
    id: 242243,
    name: 'T20 2 set bonus',
    icon: 'inv_misc_ammo_arrow_03',
  },
  HUNTER_MM_T20_4P_BONUS: {
    id: 242241,
    name: 'T20 4 set bonus',
    icon: 'ability_hunter_focusedaim',
  },
  HUNTER_MM_T20_4P_BONUS_BUFF: {
    id: 246153,
    name: 'T20 4 set bonus',
    icon: 'inv_spear_07',
  },

  // Marksmanship artifact traits
  BULLSEYE_BUFF: {
    id: 204090,
    name: 'Bullseye',
    icon: 'ability_hunter_focusedaim',
  },
  QUICK_SHOT_TRAIT: {
    id: 190462,
    name: 'Quick shot',
    icon: 'ability_trueshot',
  },

  CYCLONIC_BURST_TRAIT: {
    id: 238124,
    name: 'Cyclonic burst',
    icon: 'inv_bow_1h_artifactwindrunner_d_02',
  },

  //Marksmanship legendary buffs
  SENTINELS_SIGHT: {
    id: 208913,
    name: 'Sentinel\'s sight',
    icon: 'inv_belt_66green',
  },
  GYROSCOPIC_STABILIZATION: {
  id: 235712,
  name: 'Gyroscopic stabilization',
  icon: 'inv_glove_mail_raidshamanmythic_o_01',
},

  //Talent buffs/debuffs
  LOCK_AND_LOAD_BUFF: {
    id: 194594,
    name: 'Lock and Load',
    icon: 'ability_hunter_lockandload',
  },
  TRUE_AIM_DEBUFF: {
    id: 199803,
    name: 'True Aim',
    icon: 'spell_hunter_focusingshot',
  },

  // Survival:
  // ...

  // Shared:
  // ...
  NETHERWINDS: {
    id: 160452,
    name: 'Netherwinds',
    icon: 'spell_arcane_massdispel',
  },
  ANCIENT_HYSTERIA: {
    id: 90355,
    name: 'Ancient Hysteria',
    icon: 'spell_shadow_unholyfrenzy',
  },
  //The buff given by volley when it's activated
  VOLLEY_ACTIVATED: {
    id: 194392,
    name: 'Volley buff',
    icon: 'ability_marksmanship',
  },
};
<|endoftext|>


<commit_before>(() => {
  "use strict";

  var win = require("nw.gui").Window.get();
  var doc = document.currentScript.ownerDocument;

  var Time = class {

    get hour() {
      return this._h;
    }

    get minute() {
      return this._m;
    }

    get second() {
      return this._s;
    }

    get totalMillisecond() {
      return this._total;
    }

    set totalMillisecond(v) {
      var ts, tm;
      this._total = v;
      ts = ~~(this._total / 1000);
      this._s = ts % 60;
      tm = ~~(ts / 60);
      this._m = tm % 60;
      this._h = ~~(tm / 60);
    }

    constructor() {
      this._total = this._ms = this._s = this._m = this._h = 0;
    }

    toString() {
      return (this._h >= 100 ? this._h : ("0" + this._h).slice(-2)) + ":" +
        ("0" + this._m).slice(-2) + ":" +
        ("0" + this._s).slice(-2);
    }

  };

  var controller = class extends HTMLElement {

    hide() {
      this.shadowRoot.getElementById("container").classList.add("hidden");
    }

    show() {
      this.shadowRoot.getElementById("container").classList.remove("hidden");
    }

    toggle() {
      if (this.isShown) this.hide();
      else this.show();
    }

    get isShown() {
      return !this.shadowRoot.getElementById("container").classList.contains("hidden");
    }

    get adapter() {
      return this._adapter;
    }

    set adapter(v) {
      if (this._adapter === v) return;
      if (this._adapter) {
        this._adapter.off(this._adapterCb);
      }
      this._adapter = v;
      this._adapter.on(this._adapterCb);
      this.refresh();
    }

    refresh() {
      if (!this._adapter) return;
      this._range.max = this._adapter.length;
      this._range.value = this._adapter.position;
      this._time.totalMillisecond = this._adapter.position;
      this._pos.textContent = this._time.toString();
    }

    createdCallback() {
      var root = this.createShadowRoot();
      var template = doc.querySelector("template");
      root.appendChild(document.importNode(template.content, true));
      root.addEventListener("click", e => e.stopPropagation());

      this._adapter = null;
      this._alwaysOnTop = false;

      this._playBtn = root.querySelector(".play");
      this._range = root.querySelector("input[type=range]");
      this._pos = root.querySelector(".pos");
      this._rangeBg = root.querySelector(".range-bg");
      this._alwaysontopBtn = root.querySelector(".alwaysontop");

      this._time = new Time();

      this._adapterCb = ((name, val) => {
        if (name === "position") {
          this._range.value = val;
          this._time.totalMillisecond = val;
          this._pos.textContent = this._time.toString();
          if (this._adapter.length === val) {
            this._btn.classList.remove("pause");
          }
        } else if (name === "length") {
          this._range.max = val;
        }
      }).bind(this);

      var playingBuf = false;

      this._range.addEventListener("mousedown", (() => {
        if (this._adapter.playing) {
          playingBuf = true;
          this._adapter.stop();
        }
      }).bind(this));

      this._range.addEventListener("mouseup", (() => {
        if (playingBuf) {
          this._adapter.start();
          playingBuf = false;
        }
      }).bind(this));

      this._range.addEventListener("input", (() => {
        this._adapter.position = this._range.value;
        if (!this._adapter.playing) this._adapter.draw();
        this._time.totalMillisecond = this._range.value;
        this._pos.textContent = this._time.toString();
      }).bind(this));

      this._playBtn.addEventListener("click", (() => {
        if (!this._adapter.playing) {
          if (this._adapter.length === 0) return;
          if (this._adapter.position === this._adapter.length) {
            this._adapter.position = 0;
            this.refresh();
          }
          this._playBtn.classList.add("pause");
          this._adapter.start();
        } else {
          this._playBtn.classList.remove("pause");
          this._adapter.stop();
        }
      }).bind(this));

      this._rangeBg.addEventListener("click", (e => {
        var pos = (e.clientX - this._rangeBg.offsetLeft) / this._rangeBg.offsetWidth;
        this._adapter.position = ~~(pos * this._adapter.length);
        this.refresh();
        if (!this._adapter.playing) this._adapter.draw();
      }).bind(this));

      this._alwaysontopBtn.addEventListener("click", (() => {
        const on = this._alwaysontop = !this._alwaysontop;
        const cl = this._alwaysontopBtn.classList;
        console.log(cl);
        if (on && !cl.contains("on")) cl.add("on");
        else if (!on && cl.contains("on")) cl.remove("on");
        win.setAlwaysOnTop(on);
      }).bind(this));
    }

  };

  window.JikkyoController = document.registerElement("jikkyo-controller", {
    prototype: controller.prototype
  });

})();
<commit_msg>Fix Controller bugs<commit_after>(() => {
  "use strict";

  var win = require("nw.gui").Window.get();
  var doc = document.currentScript.ownerDocument;

  var Time = class {

    get hour() {
      return this._h;
    }

    get minute() {
      return this._m;
    }

    get second() {
      return this._s;
    }

    get totalMillisecond() {
      return this._total;
    }

    set totalMillisecond(v) {
      var ts, tm;
      this._total = v;
      ts = ~~(this._total / 1000);
      this._s = ts % 60;
      tm = ~~(ts / 60);
      this._m = tm % 60;
      this._h = ~~(tm / 60);
    }

    constructor() {
      this._total = this._ms = this._s = this._m = this._h = 0;
    }

    toString() {
      return (this._h >= 100 ? this._h : ("0" + this._h).slice(-2)) + ":" +
        ("0" + this._m).slice(-2) + ":" +
        ("0" + this._s).slice(-2);
    }

  };

  var Controller = class extends HTMLElement {

    hide() {
      this.shadowRoot.getElementById("container").classList.add("hidden");
    }

    show() {
      this.shadowRoot.getElementById("container").classList.remove("hidden");
    }

    toggle() {
      if (this.isShown) this.hide();
      else this.show();
    }

    get isShown() {
      return !this.shadowRoot.getElementById("container").classList.contains("hidden");
    }

    get adapter() {
      return this._adapter;
    }

    set adapter(v) {
      if (this._adapter === v) return;
      if (this._adapter) {
        this._adapter.off(this._adapterCb);
      }
      this._adapter = v;
      this._adapter.on(this._adapterCb);
      this.refresh();
    }

    refresh() {
      if (!this._adapter) return;
      this._range.max = this._adapter.length;
      this._range.value = this._adapter.position;
      this._time.totalMillisecond = this._adapter.position;
      this._pos.textContent = this._time.toString();
    }

    createdCallback() {
      var root = this.createShadowRoot();
      var template = doc.querySelector("template");
      root.appendChild(document.importNode(template.content, true));
      root.addEventListener("click", e => e.stopPropagation());

      this._adapter = null;
      this._alwaysOnTop = false;

      this._playBtn = root.querySelector(".play");
      this._range = root.querySelector("input[type=range]");
      this._pos = root.querySelector(".pos");
      this._rangeBg = root.querySelector(".range-bg");
      this._alwaysontopBtn = root.querySelector(".alwaysontop");
      this._menuBtn = root.querySelector(".menu");

      this._time = new Time();

      this._adapterCb = ((name, val) => {
        if (name === "position") {
          this._range.value = val;
          this._time.totalMillisecond = val;
          this._pos.textContent = this._time.toString();
          if (this._adapter.length <= val) {
            this._playBtn.classList.remove("pause");
          }
        } else if (name === "length") {
          this._range.max = val;
        }
      }).bind(this);

      var playingBuf = false;

      this._range.addEventListener("mousedown", (() => {
        if (this._adapter.playing) {
          playingBuf = true;
          this._adapter.stop();
        }
      }).bind(this));

      this._range.addEventListener("mouseup", (() => {
        if (playingBuf) {
          this._adapter.start();
          playingBuf = false;
        }
      }).bind(this));

      this._range.addEventListener("input", (() => {
        this._adapter.position = this._range.value;
        if (!this._adapter.playing) this._adapter.draw();
        this._time.totalMillisecond = this._range.value;
        this._pos.textContent = this._time.toString();
      }).bind(this));

      this._rangeBg.addEventListener("click", (e => {
        var rect = this._rangeBg.getBoundingClientRect();
        var pos = (e.clientX - rect.left) / rect.width;
        this._adapter.position = ~~(pos * this._adapter.length);
        this.refresh();
        if (!this._adapter.playing) this._adapter.draw();
      }).bind(this));

      this._playBtn.addEventListener("click", (() => {
        if (!this._adapter.playing) {
          if (this._adapter.length === 0) return;
          if (this._adapter.position === this._adapter.length) {
            this._adapter.position = 0;
            this.refresh();
          }
          this._playBtn.classList.add("pause");
          this._adapter.start();
        } else {
          this._playBtn.classList.remove("pause");
          this._adapter.stop();
        }
      }).bind(this));

      this._alwaysontopBtn.addEventListener("click", (() => {
        const on = this._alwaysontop = !this._alwaysontop;
        const cl = this._alwaysontopBtn.classList;
        if (on && !cl.contains("on")) cl.add("on");
        else if (!on && cl.contains("on")) cl.remove("on");
        win.setAlwaysOnTop(on);
      }).bind(this));
    }

  };

  window.JikkyoController = document.registerElement("jikkyo-controller", {
    prototype: Controller.prototype
  });

})();
<|endoftext|>


<commit_before>import inherited from 'mastodon/locales/en.json';

const messages = {
  'getting_started.open_source_notice': 'Glitchsoc is free open source software forked from {Mastodon}. You can contribute or report issues on GitHub at {github}.',
  'layout.auto': 'Auto',
  'layout.current_is': 'Your current layout is:',
  'layout.desktop': 'Desktop',
  'layout.mobile': 'Mobile',
  'navigation_bar.app_settings': 'App settings',
  'getting_started.onboarding': 'Show me around',
  'onboarding.page_one.federation': '{domain} is an \'instance\' of Mastodon. Mastodon is a network of independent servers joining up to make one larger social network. We call these servers instances.',
  'onboarding.page_one.welcome': 'Welcome to {domain}!',
  'onboarding.page_six.github': '{domain} runs on Glitchsoc. Glitchsoc is a friendly {fork} of {Mastodon}, and is compatible with any Mastodon instance or app. Glitchsoc is entirely free and open-source. You can report bugs, request features, or contribute to the code on {github}.',
  'settings.auto_collapse': 'Automatic collapsing',
  'settings.auto_collapse_all': 'Everything',
  'settings.auto_collapse_lengthy': 'Lengthy toots',
  'settings.auto_collapse_media': 'Toots with media',
  'settings.auto_collapse_notifications': 'Notifications',
  'settings.auto_collapse_reblogs': 'Boosts',
  'settings.auto_collapse_replies': 'Replies',
  'settings.close': 'Close',
  'settings.collapsed_statuses': 'Collapsed toots',
  'settings.enable_collapsed': 'Enable collapsed toots',
  'settings.general': 'General',
  'settings.image_backgrounds': 'Image backgrounds',
  'settings.image_backgrounds_media': 'Preview collapsed toot media',
  'settings.image_backgrounds_users': 'Give collapsed toots an image background',
  'settings.media': 'Media',
  'settings.media_letterbox': 'Letterbox media',
  'settings.media_fullwidth': 'Full-width media previews',
  'settings.preferences': 'User preferences',
  'settings.wide_view': 'Wide view (Desktop mode only)',
  'settings.navbar_under': 'Navbar at the bottom (Mobile only)',
  'status.collapse': 'Collapse',
  'status.uncollapse': 'Uncollapse',

  "favourite_modal.combo": "You can press {combo} to skip this next time",

  'home.column_settings.show_direct': 'Show DMs',

  'notification.markForDeletion': 'Mark for deletion',
  'notifications.clear': 'Clear all my notifications',
  'notifications.marked_clear_confirmation': 'Are you sure you want to permanently clear all selected notifications?',
  'notifications.marked_clear': 'Clear selected notifications',

  'notification_purge.btn_all': 'Select\nall',
  'notification_purge.btn_none': 'Select\nnone',
  'notification_purge.btn_invert': 'Invert\nselection',
  'notification_purge.btn_apply': 'Clear\nselected',
};

export default Object.assign({}, inherited, messages);
<commit_msg>use single quotes in locale entry<commit_after>import inherited from 'mastodon/locales/en.json';

const messages = {
  'getting_started.open_source_notice': 'Glitchsoc is free open source software forked from {Mastodon}. You can contribute or report issues on GitHub at {github}.',
  'layout.auto': 'Auto',
  'layout.current_is': 'Your current layout is:',
  'layout.desktop': 'Desktop',
  'layout.mobile': 'Mobile',
  'navigation_bar.app_settings': 'App settings',
  'getting_started.onboarding': 'Show me around',
  'onboarding.page_one.federation': '{domain} is an \'instance\' of Mastodon. Mastodon is a network of independent servers joining up to make one larger social network. We call these servers instances.',
  'onboarding.page_one.welcome': 'Welcome to {domain}!',
  'onboarding.page_six.github': '{domain} runs on Glitchsoc. Glitchsoc is a friendly {fork} of {Mastodon}, and is compatible with any Mastodon instance or app. Glitchsoc is entirely free and open-source. You can report bugs, request features, or contribute to the code on {github}.',
  'settings.auto_collapse': 'Automatic collapsing',
  'settings.auto_collapse_all': 'Everything',
  'settings.auto_collapse_lengthy': 'Lengthy toots',
  'settings.auto_collapse_media': 'Toots with media',
  'settings.auto_collapse_notifications': 'Notifications',
  'settings.auto_collapse_reblogs': 'Boosts',
  'settings.auto_collapse_replies': 'Replies',
  'settings.close': 'Close',
  'settings.collapsed_statuses': 'Collapsed toots',
  'settings.enable_collapsed': 'Enable collapsed toots',
  'settings.general': 'General',
  'settings.image_backgrounds': 'Image backgrounds',
  'settings.image_backgrounds_media': 'Preview collapsed toot media',
  'settings.image_backgrounds_users': 'Give collapsed toots an image background',
  'settings.media': 'Media',
  'settings.media_letterbox': 'Letterbox media',
  'settings.media_fullwidth': 'Full-width media previews',
  'settings.preferences': 'User preferences',
  'settings.wide_view': 'Wide view (Desktop mode only)',
  'settings.navbar_under': 'Navbar at the bottom (Mobile only)',
  'status.collapse': 'Collapse',
  'status.uncollapse': 'Uncollapse',

  'favourite_modal.combo': 'You can press {combo} to skip this next time',

  'home.column_settings.show_direct': 'Show DMs',

  'notification.markForDeletion': 'Mark for deletion',
  'notifications.clear': 'Clear all my notifications',
  'notifications.marked_clear_confirmation': 'Are you sure you want to permanently clear all selected notifications?',
  'notifications.marked_clear': 'Clear selected notifications',

  'notification_purge.btn_all': 'Select\nall',
  'notification_purge.btn_none': 'Select\nnone',
  'notification_purge.btn_invert': 'Invert\nselection',
  'notification_purge.btn_apply': 'Clear\nselected',
};

export default Object.assign({}, inherited, messages);
<|endoftext|>


<commit_before>/**
 *  Copyright (c) 2010 Marat Nepomnyashy    maratbn@gmail
 *
 *  Module: FILEfox/chrome/content/FILEfox.js
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions are met:
 *      * Redistributions of source code must retain the above copyright
 *        notice, this list of conditions and the following disclaimer.
 *      * 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.
 *      * Neither the name of the <organization> nor the
 *        names of its contributors may be used to endorse or promote products
 *        derived from this software without specific prior written permission.
 *
 *  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 <COPYRIGHT HOLDER> 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.
 *
 *
 *  The main chrome JavaScript for the FILEfox extension is here.
 */

if (!window.extension_FILEfox) {
    window.extension_FILEfox =  {
                                    about: function() {
                                        let string_bundle = document.getElementById('extension_FILEfox_string_bundle');
                                        let text = string_bundle.getString('FILEfox.disclamer');
                                        alert(text);
                                    }
                                }
}<commit_msg>Now displaying the version string in the 'About' dialog box.<commit_after>/**
 *  Copyright (c) 2010 Marat Nepomnyashy    maratbn@gmail
 *
 *  Module: FILEfox/chrome/content/FILEfox.js
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions are met:
 *      * Redistributions of source code must retain the above copyright
 *        notice, this list of conditions and the following disclaimer.
 *      * 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.
 *      * Neither the name of the <organization> nor the
 *        names of its contributors may be used to endorse or promote products
 *        derived from this software without specific prior written permission.
 *
 *  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 <COPYRIGHT HOLDER> 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.
 *
 *
 *  The main chrome JavaScript for the FILEfox extension is here.
 */

if (!window.extension_FILEfox) {
    window.extension_FILEfox =  {
                                    about: function() {
                                        let string_bundle = document.getElementById('extension_FILEfox_string_bundle');
                                        let text = string_bundle.getString('FILEfox.disclamer');
                                        alert("FILEfox version " + nsFILEfox.getVersion() + "\r\n\r\n" + text);
                                    }
                                }
}<|endoftext|>


<commit_before>var list = {

	"Manual": {
		"Introduction": [
			[ "Creating a scene", "manual/introduction/Creating-a-scene" ]
		]
	},

	"Reference": {
		"Cameras": [
			[ "Camera", "api/cameras/Camera" ],
			[ "OrthographicCamera", "api/cameras/OrthographicCamera" ],
			[ "PerspectiveCamera", "api/cameras/PerspectiveCamera" ]
		],

		"Core": [
			[ "BufferGeometry", "api/core/BufferGeometry" ],
			[ "Clock", "api/core/Clock" ],
			[ "EventDispatcher", "api/core/EventDispatcher" ],
			[ "Face3", "api/core/Face3" ],
			[ "Geometry", "api/core/Geometry" ],
			[ "Object3D", "api/core/Object3D" ],
			[ "Projector", "api/core/Projector" ],
			[ "Raycaster", "api/core/Raycaster" ],
		],

		"Lights": [
			[ "Light", "api/lights/Light" ],
			[ "AmbientLight", "api/lights/AmbientLight" ],
			[ "AreaLight", "api/lights/AreaLight" ],
			[ "DirectionalLight", "api/lights/DirectionalLight" ],
			[ "HemisphereLight", "api/lights/HemisphereLight" ],
			[ "PointLight", "api/lights/PointLight" ],
			[ "SpotLight", "api/lights/SpotLight" ]
		],

		"Loaders": [
			[ "Loader", "api/loaders/Loader" ],
			[ "GeometryLoader", "api/loaders/GeometryLoader" ],
			[ "ImageLoader", "api/loaders/ImageLoader" ],
			[ "JSONLoader", "api/loaders/JSONLoader" ],
			[ "LoadingMonitor", "api/loaders/LoadingMonitor" ],
			[ "SceneLoader", "api/loaders/SceneLoader" ],
			[ "TextureLoader", "api/loaders/TextureLoader" ],
		],

		"Materials": [
			[ "Material", "api/materials/Material" ],
			[ "LineBasicMaterial", "api/materials/LineBasicMaterial" ],
			[ "LineDashedMaterial", "api/materials/LineDashedMaterial" ],
			[ "MeshBasicMaterial", "api/materials/MeshBasicMaterial" ],
			[ "MeshDepthMaterial", "api/materials/MeshDepthMaterial" ],
			[ "MeshFaceMaterial", "api/materials/MeshFaceMaterial" ],
			[ "MeshLambertMaterial", "api/materials/MeshLambertMaterial" ],
			[ "MeshNormalMaterial", "api/materials/MeshNormalMaterial" ],
			[ "MeshPhongMaterial", "api/materials/MeshPhongMaterial" ],
			[ "ParticleBasicMaterial", "api/materials/ParticleBasicMaterial" ],
			[ "ParticleCanvasMaterial", "api/materials/ParticleCanvasMaterial" ],
			[ "ParticleDOMMaterial", "api/materials/ParticleDOMMaterial" ],
			[ "ShaderMaterial", "api/materials/ShaderMaterial" ],
			[ "SpriteMaterial", "api/materials/SpriteMaterial" ]

		],

		"Math": [
			[ "Box2", "api/math/Box2" ],
			[ "Box3", "api/math/Box3" ],
			[ "Color", "api/math/Color" ],
			[ "Frustum", "api/math/Frustum" ],
			[ "Math", "api/math/Math" ],
			[ "Matrix3", "api/math/Matrix3" ],
			[ "Matrix4", "api/math/Matrix4" ],
			[ "Plane", "api/math/Plane" ],
			[ "Quaternion", "api/math/Quaternion" ],
			[ "Ray", "api/math/Ray" ],
			[ "Sphere", "api/math/Sphere" ],
			[ "Spline", "api/math/Spline" ],
			[ "Triangle", "api/math/Triangle" ],
			[ "Vector2", "api/math/Vector2" ],
			[ "Vector3", "api/math/Vector3" ],
			[ "Vector4", "api/math/Vector4" ]
		],

		"Objects": [
			[ "Bone", "api/objects/Bone" ],
			[ "Line", "api/objects/Line" ],
			[ "LOD", "api/objects/LOD" ],
			[ "Mesh", "api/objects/Mesh" ],
			[ "MorphAnimMesh", "api/objects/MorphAnimMesh" ],
			[ "Particle", "api/objects/Particle" ],
			[ "ParticleSystem", "api/objects/ParticleSystem" ],
			[ "Ribbon", "api/objects/Ribbon" ],
			[ "SkinnedMesh", "api/objects/SkinnedMesh" ],
			[ "Sprite", "api/objects/Sprite" ]

		],

		"Renderers": [
			[ "CanvasRenderer", "api/renderers/CanvasRenderer" ],
			[ "WebGLRenderer", "api/renderers/WebGLRenderer" ],
			[ "WebGLRenderTarget", "api/renderers/WebGLRenderTarget" ],
			[ "WebGLRenderTargetCube", "api/renderers/WebGLRenderTargetCube" ],
			[ "WebGLShaders", "api/renderers/WebGLShaders" ]
		],

		"Renderers / Renderables": [
			[ "RenderableFace3", "api/renderers/renderables/RenderableFace3" ],
			[ "RenderableLine", "api/renderers/renderables/RenderableLine" ],
			[ "RenderableObject", "api/renderers/renderables/RenderableObject" ],
			[ "RenderableParticle", "api/renderers/renderables/RenderableParticle" ],
			[ "RenderableVertex", "api/renderers/renderables/RenderableVertex" ]
		],

		"Scenes": [
			[ "Fog", "api/scenes/Fog" ],
			[ "FogExp2", "api/scenes/FogExp2" ],
			[ "Scene", "api/scenes/Scene" ]
		],

		"Textures": [
			[ "CompressedTexture", "api/textures/CompressedTexture" ],
			[ "DataTexture", "api/textures/DataTexture" ],
			[ "Texture", "api/textures/Texture" ]
		],

		"Extras": [
			[ "FontUtils", "api/extras/FontUtils" ],
			[ "GeometryUtils", "api/extras/GeometryUtils" ],
			[ "ImageUtils", "api/extras/ImageUtils" ],
			[ "SceneUtils", "api/extras/SceneUtils" ]
		],

		"Extras / Animation": [
			[ "Animation", "api/extras/animation/Animation" ],
			[ "AnimationHandler", "api/extras/animation/AnimationHandler" ],
			[ "AnimationMorphTarget", "api/extras/animation/AnimationMorphTarget" ],
			[ "KeyFrameAnimation", "api/extras/animation/KeyFrameAnimation" ]
		],

		"Extras / Cameras": [
			[ "CombinedCamera", "api/extras/cameras/CombinedCamera" ],
			[ "CubeCamera", "api/extras/cameras/CubeCamera" ]
		],

		"Extras / Core": [
			[ "Curve", "api/extras/core/Curve" ],
			[ "CurvePath", "api/extras/core/CurvePath" ],
			[ "Gyroscope", "api/extras/core/Gyroscope" ],
			[ "Path", "api/extras/core/Path" ],
			[ "Shape", "api/extras/core/Shape" ]
		],

		"Extras / Geometries": [
			[ "CircleGeometry", "api/extras/geometries/CircleGeometry" ],
			[ "ConvexGeometry", "api/extras/geometries/ConvexGeometry" ],
			[ "CubeGeometry", "api/extras/geometries/CubeGeometry" ],
			[ "CylinderGeometry", "api/extras/geometries/CylinderGeometry" ],
			[ "ExtrudeGeometry", "api/extras/geometries/ExtrudeGeometry" ],
			[ "IcosahedronGeometry", "api/extras/geometries/IcosahedronGeometry" ],
			[ "LatheGeometry", "api/extras/geometries/LatheGeometry" ],
			[ "OctahedronGeometry", "api/extras/geometries/OctahedronGeometry" ],
			[ "ParametricGeometry", "api/extras/geometries/ParametricGeometry" ],
			[ "PlaneGeometry", "api/extras/geometries/PlaneGeometry" ],
			[ "PolyhedronGeometry", "api/extras/geometries/PolyhedronGeometry" ],
			[ "ShapeGeometry", "api/extras/geometries/ShapeGeometry" ],
			[ "SphereGeometry", "api/extras/geometries/SphereGeometry" ],
			[ "TetrahedronGeometry", "api/extras/geometries/TetrahedronGeometry" ],
			[ "TextGeometry", "api/extras/geometries/TextGeometry" ],
			[ "TorusGeometry", "api/extras/geometries/TorusGeometry" ],
			[ "TorusKnotGeometry", "api/extras/geometries/TorusKnotGeometry" ],
			[ "TubeGeometry", "api/extras/geometries/TubeGeometry" ]
		],

		"Extras / Helpers": [
			[ "ArrowHelper", "api/extras/helpers/ArrowHelper" ],
			[ "AxisHelper", "api/extras/helpers/AxisHelper" ],
			[ "CameraHelper", "api/extras/helpers/CameraHelper" ],
			[ "DirectionalLightHelper", "api/extras/helpers/DirectionalLightHelper" ],
			[ "HemisphereLightHelper", "api/extras/helpers/HemisphereLightHelper" ],
			[ "PointLightHelper", "api/extras/helpers/PointLightHelper" ],
			[ "SpotLightHelper", "api/extras/helpers/SpotLightHelper" ]
		],

		"Extras / Objects": [
			[ "ImmediateRenderObject", "api/extras/objects/ImmediateRenderObject" ],
			[ "LensFlare", "api/extras/objects/LensFlare" ],
			[ "MorphBlendMesh", "api/extras/objects/MorphBlendMesh" ]
		],

		"Extras / Renderers / Plugins": [
			[ "DepthPassPlugin", "api/extras/renderers/plugins/DepthPassPlugin" ],
			[ "LensFlarePlugin", "api/extras/renderers/plugins/LensFlarePlugin" ],
			[ "ShadowMapPlugin", "api/extras/renderers/plugins/ShadowMapPlugin" ],
			[ "SpritePlugin", "api/extras/renderers/plugins/SpritePlugin" ]
		],

		"Extras / Shaders": [
			[ "ShaderFlares", "api/extras/shaders/ShaderFlares" ],
			[ "ShaderSprite", "api/extras/shaders/ShaderSprite" ]
		]
	}

};

var pages = {};

for ( var section in list ) {

	pages[ section ] = {};

	for ( var category in list[ section ] ) {

		pages[ section ][ category ] = {};

		for ( var i = 0; i < list[ section ][ category ].length; i ++ ) {

			var page = list[ section ][ category ][ i ];
			pages[ section ][ category ][ page[ 0 ] ] = page[ 1 ];

		}

	}

}
<commit_msg>Docs: Added Euler page to list.<commit_after>var list = {

	"Manual": {
		"Introduction": [
			[ "Creating a scene", "manual/introduction/Creating-a-scene" ]
		]
	},

	"Reference": {
		"Cameras": [
			[ "Camera", "api/cameras/Camera" ],
			[ "OrthographicCamera", "api/cameras/OrthographicCamera" ],
			[ "PerspectiveCamera", "api/cameras/PerspectiveCamera" ]
		],

		"Core": [
			[ "BufferGeometry", "api/core/BufferGeometry" ],
			[ "Clock", "api/core/Clock" ],
			[ "EventDispatcher", "api/core/EventDispatcher" ],
			[ "Face3", "api/core/Face3" ],
			[ "Geometry", "api/core/Geometry" ],
			[ "Object3D", "api/core/Object3D" ],
			[ "Projector", "api/core/Projector" ],
			[ "Raycaster", "api/core/Raycaster" ],
		],

		"Lights": [
			[ "Light", "api/lights/Light" ],
			[ "AmbientLight", "api/lights/AmbientLight" ],
			[ "AreaLight", "api/lights/AreaLight" ],
			[ "DirectionalLight", "api/lights/DirectionalLight" ],
			[ "HemisphereLight", "api/lights/HemisphereLight" ],
			[ "PointLight", "api/lights/PointLight" ],
			[ "SpotLight", "api/lights/SpotLight" ]
		],

		"Loaders": [
			[ "Loader", "api/loaders/Loader" ],
			[ "GeometryLoader", "api/loaders/GeometryLoader" ],
			[ "ImageLoader", "api/loaders/ImageLoader" ],
			[ "JSONLoader", "api/loaders/JSONLoader" ],
			[ "LoadingMonitor", "api/loaders/LoadingMonitor" ],
			[ "SceneLoader", "api/loaders/SceneLoader" ],
			[ "TextureLoader", "api/loaders/TextureLoader" ],
		],

		"Materials": [
			[ "Material", "api/materials/Material" ],
			[ "LineBasicMaterial", "api/materials/LineBasicMaterial" ],
			[ "LineDashedMaterial", "api/materials/LineDashedMaterial" ],
			[ "MeshBasicMaterial", "api/materials/MeshBasicMaterial" ],
			[ "MeshDepthMaterial", "api/materials/MeshDepthMaterial" ],
			[ "MeshFaceMaterial", "api/materials/MeshFaceMaterial" ],
			[ "MeshLambertMaterial", "api/materials/MeshLambertMaterial" ],
			[ "MeshNormalMaterial", "api/materials/MeshNormalMaterial" ],
			[ "MeshPhongMaterial", "api/materials/MeshPhongMaterial" ],
			[ "ParticleBasicMaterial", "api/materials/ParticleBasicMaterial" ],
			[ "ParticleCanvasMaterial", "api/materials/ParticleCanvasMaterial" ],
			[ "ParticleDOMMaterial", "api/materials/ParticleDOMMaterial" ],
			[ "ShaderMaterial", "api/materials/ShaderMaterial" ],
			[ "SpriteMaterial", "api/materials/SpriteMaterial" ]

		],

		"Math": [
			[ "Box2", "api/math/Box2" ],
			[ "Box3", "api/math/Box3" ],
			[ "Color", "api/math/Color" ],
			[ "Euler", "api/math/Euler" ],
			[ "Frustum", "api/math/Frustum" ],
			[ "Math", "api/math/Math" ],
			[ "Matrix3", "api/math/Matrix3" ],
			[ "Matrix4", "api/math/Matrix4" ],
			[ "Plane", "api/math/Plane" ],
			[ "Quaternion", "api/math/Quaternion" ],
			[ "Ray", "api/math/Ray" ],
			[ "Sphere", "api/math/Sphere" ],
			[ "Spline", "api/math/Spline" ],
			[ "Triangle", "api/math/Triangle" ],
			[ "Vector2", "api/math/Vector2" ],
			[ "Vector3", "api/math/Vector3" ],
			[ "Vector4", "api/math/Vector4" ]
		],

		"Objects": [
			[ "Bone", "api/objects/Bone" ],
			[ "Line", "api/objects/Line" ],
			[ "LOD", "api/objects/LOD" ],
			[ "Mesh", "api/objects/Mesh" ],
			[ "MorphAnimMesh", "api/objects/MorphAnimMesh" ],
			[ "Particle", "api/objects/Particle" ],
			[ "ParticleSystem", "api/objects/ParticleSystem" ],
			[ "Ribbon", "api/objects/Ribbon" ],
			[ "SkinnedMesh", "api/objects/SkinnedMesh" ],
			[ "Sprite", "api/objects/Sprite" ]

		],

		"Renderers": [
			[ "CanvasRenderer", "api/renderers/CanvasRenderer" ],
			[ "WebGLRenderer", "api/renderers/WebGLRenderer" ],
			[ "WebGLRenderTarget", "api/renderers/WebGLRenderTarget" ],
			[ "WebGLRenderTargetCube", "api/renderers/WebGLRenderTargetCube" ],
			[ "WebGLShaders", "api/renderers/WebGLShaders" ]
		],

		"Renderers / Renderables": [
			[ "RenderableFace3", "api/renderers/renderables/RenderableFace3" ],
			[ "RenderableLine", "api/renderers/renderables/RenderableLine" ],
			[ "RenderableObject", "api/renderers/renderables/RenderableObject" ],
			[ "RenderableParticle", "api/renderers/renderables/RenderableParticle" ],
			[ "RenderableVertex", "api/renderers/renderables/RenderableVertex" ]
		],

		"Scenes": [
			[ "Fog", "api/scenes/Fog" ],
			[ "FogExp2", "api/scenes/FogExp2" ],
			[ "Scene", "api/scenes/Scene" ]
		],

		"Textures": [
			[ "CompressedTexture", "api/textures/CompressedTexture" ],
			[ "DataTexture", "api/textures/DataTexture" ],
			[ "Texture", "api/textures/Texture" ]
		],

		"Extras": [
			[ "FontUtils", "api/extras/FontUtils" ],
			[ "GeometryUtils", "api/extras/GeometryUtils" ],
			[ "ImageUtils", "api/extras/ImageUtils" ],
			[ "SceneUtils", "api/extras/SceneUtils" ]
		],

		"Extras / Animation": [
			[ "Animation", "api/extras/animation/Animation" ],
			[ "AnimationHandler", "api/extras/animation/AnimationHandler" ],
			[ "AnimationMorphTarget", "api/extras/animation/AnimationMorphTarget" ],
			[ "KeyFrameAnimation", "api/extras/animation/KeyFrameAnimation" ]
		],

		"Extras / Cameras": [
			[ "CombinedCamera", "api/extras/cameras/CombinedCamera" ],
			[ "CubeCamera", "api/extras/cameras/CubeCamera" ]
		],

		"Extras / Core": [
			[ "Curve", "api/extras/core/Curve" ],
			[ "CurvePath", "api/extras/core/CurvePath" ],
			[ "Gyroscope", "api/extras/core/Gyroscope" ],
			[ "Path", "api/extras/core/Path" ],
			[ "Shape", "api/extras/core/Shape" ]
		],

		"Extras / Geometries": [
			[ "CircleGeometry", "api/extras/geometries/CircleGeometry" ],
			[ "ConvexGeometry", "api/extras/geometries/ConvexGeometry" ],
			[ "CubeGeometry", "api/extras/geometries/CubeGeometry" ],
			[ "CylinderGeometry", "api/extras/geometries/CylinderGeometry" ],
			[ "ExtrudeGeometry", "api/extras/geometries/ExtrudeGeometry" ],
			[ "IcosahedronGeometry", "api/extras/geometries/IcosahedronGeometry" ],
			[ "LatheGeometry", "api/extras/geometries/LatheGeometry" ],
			[ "OctahedronGeometry", "api/extras/geometries/OctahedronGeometry" ],
			[ "ParametricGeometry", "api/extras/geometries/ParametricGeometry" ],
			[ "PlaneGeometry", "api/extras/geometries/PlaneGeometry" ],
			[ "PolyhedronGeometry", "api/extras/geometries/PolyhedronGeometry" ],
			[ "ShapeGeometry", "api/extras/geometries/ShapeGeometry" ],
			[ "SphereGeometry", "api/extras/geometries/SphereGeometry" ],
			[ "TetrahedronGeometry", "api/extras/geometries/TetrahedronGeometry" ],
			[ "TextGeometry", "api/extras/geometries/TextGeometry" ],
			[ "TorusGeometry", "api/extras/geometries/TorusGeometry" ],
			[ "TorusKnotGeometry", "api/extras/geometries/TorusKnotGeometry" ],
			[ "TubeGeometry", "api/extras/geometries/TubeGeometry" ]
		],

		"Extras / Helpers": [
			[ "ArrowHelper", "api/extras/helpers/ArrowHelper" ],
			[ "AxisHelper", "api/extras/helpers/AxisHelper" ],
			[ "CameraHelper", "api/extras/helpers/CameraHelper" ],
			[ "DirectionalLightHelper", "api/extras/helpers/DirectionalLightHelper" ],
			[ "HemisphereLightHelper", "api/extras/helpers/HemisphereLightHelper" ],
			[ "PointLightHelper", "api/extras/helpers/PointLightHelper" ],
			[ "SpotLightHelper", "api/extras/helpers/SpotLightHelper" ]
		],

		"Extras / Objects": [
			[ "ImmediateRenderObject", "api/extras/objects/ImmediateRenderObject" ],
			[ "LensFlare", "api/extras/objects/LensFlare" ],
			[ "MorphBlendMesh", "api/extras/objects/MorphBlendMesh" ]
		],

		"Extras / Renderers / Plugins": [
			[ "DepthPassPlugin", "api/extras/renderers/plugins/DepthPassPlugin" ],
			[ "LensFlarePlugin", "api/extras/renderers/plugins/LensFlarePlugin" ],
			[ "ShadowMapPlugin", "api/extras/renderers/plugins/ShadowMapPlugin" ],
			[ "SpritePlugin", "api/extras/renderers/plugins/SpritePlugin" ]
		],

		"Extras / Shaders": [
			[ "ShaderFlares", "api/extras/shaders/ShaderFlares" ],
			[ "ShaderSprite", "api/extras/shaders/ShaderSprite" ]
		]
	}

};

var pages = {};

for ( var section in list ) {

	pages[ section ] = {};

	for ( var category in list[ section ] ) {

		pages[ section ][ category ] = {};

		for ( var i = 0; i < list[ section ][ category ].length; i ++ ) {

			var page = list[ section ][ category ][ i ];
			pages[ section ][ category ][ page[ 0 ] ] = page[ 1 ];

		}

	}

}
<|endoftext|>


<commit_before><commit_msg>wip, fog support for annotations<commit_after><|endoftext|>


<commit_before>var fs = require('fs');
var print = function(s) { fs.write('/dev/stdout', s, 'w'); };

var timeoutId = null;
var deferTimeout = function() {
  if (timeoutId) clearTimeout(timeoutId);
  timeoutId = setTimeout(function() {
    console.log("\nTimeout");
    phantom.exit(1);
  }, 5000);
};

var page = require('webpage').create();
page.onError = null;
page.open(require('system').args[1], function() {
  page.evaluate(function() {
    mocha.getTests = function(suite, result) {
      suite = suite || mocha.suite;
      result = result || [];
      result.push.apply(result, suite.tests);
      suite.suites.forEach(function(s) { mocha.getTests(s, result); });
      return result;
    };

    mocha.suite.afterAll(function() {
      mocha.done = true;
    });
  });

  deferTimeout();

  var poll = function() {
    var tests = page.evaluate(function() {
      var result = [];
      mocha.getTests().forEach(function(test) {
        if (test.recorded || !test.state) return;
        test.recorded = true;
        result.push(test.state === 'passed' ? '.' : 'F');
      });
      return result;
    });

    tests.forEach(function(test) {
      print(test);
      deferTimeout();
    });

    var result = page.evaluate(function() {
      if (!mocha.done) return;
      var result = { failures: [] };
      mocha.getTests().forEach(function(test) {
        if (test.state === 'passed') return;
        result.failures.push({title: test.fullTitle(), message: test.err.message});
      });
      result.stats = [].map.call(document.querySelectorAll('li.passes, li.failures, li.duration'), function(el) { return el.textContent; }).join(', ')
      return result;
    });

    if (result) {
      console.log('');
      result.failures.forEach(function(failure) {
        console.log("\n" + failure.title + "\n  " + failure.message);
      });
      console.log(result.stats);
      phantom.exit(result.failures.length === 0 ? 0 : 1);
    } else {
      setTimeout(poll, 100);
    }
  }

  setTimeout(poll, 100);
});
<commit_msg>Improve js test runner<commit_after>var fs = require('fs');
var print = function(s) { fs.write('/dev/stdout', s, 'w'); };

var timeoutId = null;
var deferTimeout = function() {
  if (timeoutId) clearTimeout(timeoutId);
  timeoutId = setTimeout(function() {
    console.log("\nTimeout");
    phantom.exit(1);
  }, 5000);
};

var page = require('webpage').create();
page.onConsoleMessage = function(msg) { console.error(msg); };
page.open(require('system').args[1], function() {
  page.evaluate(function() {
    mocha.getTests = function(suite, result) {
      suite = suite || mocha.suite;
      result = result || [];
      result.push.apply(result, suite.tests);
      suite.suites.forEach(function(s) { mocha.getTests(s, result); });
      return result;
    };

    mocha.suite.afterAll(function() {
      mocha.done = true;
    });
  });

  deferTimeout();

  var poll = function() {
    var tests = page.evaluate(function() {
      var result = [];
      mocha.getTests().forEach(function(test) {
        if (test.recorded || !(test.state || test.pending)) return;
        test.recorded = true;
        result.push(test.state === 'passed' ? '.' : (test.pending ? 'S' : 'F'));
      });
      return result;
    });

    tests.forEach(function(test) {
      print(test);
      deferTimeout();
    });

    var result = page.evaluate(function() {
      if (!mocha.done) return;
      var result = { failures: [], pending: [] };
      mocha.getTests().forEach(function(test) {
        if (test.state === 'passed') return;
        if (test.pending)
          result.pending.push({title: test.fullTitle()});
        else
          result.failures.push({title: test.fullTitle(), message: test.err.message});
      });
      result.stats = [].map.call(document.querySelectorAll('li.passes, li.failures, li.duration'), function(el) { return el.textContent; });
      if (result.pending.length) result.stats.unshift('skips: ' + result.pending.length);
      result.stats = result.stats.join(', ');
      return result;
    });

    if (result) {
      console.log('');
      result.failures.forEach(function(failure) {
        console.log("\n" + failure.title + "\n  " + failure.message);
      });
      console.log(result.stats);
      phantom.exit(result.failures.length === 0 ? 0 : 1);
    } else {
      setTimeout(poll, 100);
    }
  }

  setTimeout(poll, 100);
});
<|endoftext|>


<commit_before>// app.js
//
// Utilities for setting up the app
//
// Copyright 2012-2013 E14N https://e14n.com/
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     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";

var _ = require("lodash"),
    Step = require("step"),
    cluster = require("cluster"),
    mod = require("../../lib/app"),
    fs = require("fs"),
    path = require("path"),
    Dispatch = require("../../lib/dispatch"),
    makeApp = mod.makeApp;

var tc = JSON.parse(fs.readFileSync(path.resolve(__dirname, "..", "config.json")));

var config = _.extend(tc, {
              firehose: false,
              sockjs: false,
              noCDN: true,
              debugClient: true,
              nologger: true}),
    app = null,
    i,
    parts,
    worker;

process.env.NODE_ENV = "test";

for (i = 2; i < process.argv.length; i++) {
    parts = process.argv[i].split("=");
    config[parts[0]] = JSON.parse(parts[1]);
}

config.port = parseInt(config.port, 10);

if (cluster.isMaster) {
    worker = cluster.fork();
    worker.on("message", function(msg) {
        switch (msg.cmd) {
        case "error":
        case "listening":
        case "credkilled":
        case "objectchanged":
            process.send(msg);
            break;
        default:
            break;
        }
    });
    Dispatch.start();
    process.on("message", function(msg) {
        switch (msg.cmd) {
        case "killcred":
        case "changeobject":
            worker.send(msg);
            break;
        }
    });
    process.on('SIGTERM', function () {
        console.error("Got SIGTERM in parent");
        if (_.isFunction(worker.disconnect)) {
            console.error("Disconnecting worker");
            worker.disconnect();
        } else {
            console.error("Killing worker");
            worker.kill();
        }
        process.exit(0);
    });
} else {
    Step(
        function() {
            makeApp(config, this);
        },
        function(err, res) {
            if (err) throw err;
            app = res;
            app.run(this);
        },
        function(err) {
            if (err) {
                process.send({cmd: "error", value: err});
            } else {
                process.send({cmd: "listening"});
            }
        }
    );

    process.on("message", function(msg) {
        switch (msg.cmd) {
        case "killcred":
            // This is to simulate losing the credentials of a remote client
            // It's hard to do without destroying the database values directly,
            // so we essentially do that.
            Step(
                function() {
                    var client = require("../../lib/model/client"),
                        Client = client.Client;
                    Client.search({webfinger: msg.webfinger}, this);
                },
                function(err, results) {
                    if (err) throw err;
                    if (!results || results.length !== 1) {
                        throw new Error("Bad results");
                    }
                    results[0].del(this);
                },
                function(err) {
                    if (err) {
                        process.send({cmd: "credkilled", error: err.message, webfinger: msg.webfinger});
                    } else {
                        process.send({cmd: "credkilled", webfinger: msg.webfinger});
                    }
                }
            );
            break;
        case "changeobject":
            // we break an object
            var DatabankObject = require("databank").DatabankObject,
                db = DatabankObject.bank,
                object = msg.object;
            Step(
                function() {
                    db.update(object.objectType, object.id, object, this);
                },
                function(err) {
                    if (err) {
                        process.send({cmd: "objectchanged", error: err.message, id: object.id});
                    } else {
                        process.send({cmd: "objectchanged", id: object.id});
                    }
                }
            );
            break;
        }
    });
}
<commit_msg>Remove console.error() statements<commit_after>// app.js
//
// Utilities for setting up the app
//
// Copyright 2012-2013 E14N https://e14n.com/
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     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";

var _ = require("lodash"),
    Step = require("step"),
    cluster = require("cluster"),
    mod = require("../../lib/app"),
    fs = require("fs"),
    path = require("path"),
    Dispatch = require("../../lib/dispatch"),
    makeApp = mod.makeApp;

var tc = JSON.parse(fs.readFileSync(path.resolve(__dirname, "..", "config.json")));

var config = _.extend(tc, {
              firehose: false,
              sockjs: false,
              noCDN: true,
              debugClient: true,
              nologger: true}),
    app = null,
    i,
    parts,
    worker;

process.env.NODE_ENV = "test";

for (i = 2; i < process.argv.length; i++) {
    parts = process.argv[i].split("=");
    config[parts[0]] = JSON.parse(parts[1]);
}

config.port = parseInt(config.port, 10);

if (cluster.isMaster) {
    worker = cluster.fork();
    worker.on("message", function(msg) {
        switch (msg.cmd) {
        case "error":
        case "listening":
        case "credkilled":
        case "objectchanged":
            process.send(msg);
            break;
        default:
            break;
        }
    });
    Dispatch.start();
    process.on("message", function(msg) {
        switch (msg.cmd) {
        case "killcred":
        case "changeobject":
            worker.send(msg);
            break;
        }
    });
    process.on('SIGTERM', function () {
        if (_.isFunction(worker.disconnect)) {
            worker.disconnect();
        } else {
            worker.kill();
        }
        process.exit(0);
    });
} else {
    Step(
        function() {
            makeApp(config, this);
        },
        function(err, res) {
            if (err) throw err;
            app = res;
            app.run(this);
        },
        function(err) {
            if (err) {
                process.send({cmd: "error", value: err});
            } else {
                process.send({cmd: "listening"});
            }
        }
    );

    process.on("message", function(msg) {
        switch (msg.cmd) {
        case "killcred":
            // This is to simulate losing the credentials of a remote client
            // It's hard to do without destroying the database values directly,
            // so we essentially do that.
            Step(
                function() {
                    var client = require("../../lib/model/client"),
                        Client = client.Client;
                    Client.search({webfinger: msg.webfinger}, this);
                },
                function(err, results) {
                    if (err) throw err;
                    if (!results || results.length !== 1) {
                        throw new Error("Bad results");
                    }
                    results[0].del(this);
                },
                function(err) {
                    if (err) {
                        process.send({cmd: "credkilled", error: err.message, webfinger: msg.webfinger});
                    } else {
                        process.send({cmd: "credkilled", webfinger: msg.webfinger});
                    }
                }
            );
            break;
        case "changeobject":
            // we break an object
            var DatabankObject = require("databank").DatabankObject,
                db = DatabankObject.bank,
                object = msg.object;
            Step(
                function() {
                    db.update(object.objectType, object.id, object, this);
                },
                function(err) {
                    if (err) {
                        process.send({cmd: "objectchanged", error: err.message, id: object.id});
                    } else {
                        process.send({cmd: "objectchanged", id: object.id});
                    }
                }
            );
            break;
        }
    });
}
<|endoftext|>