<commit_before>(function() {

    "use strict";

    var module = angular.module('functal.controllers', []);

    module.controller('AppCtrl', [function() {}]);

    module.controller('ImagesCtrl', ['functalData', '$scope', '$window', '$timeout', '$ionicScrollDelegate', '$ionicLoading', '$cordovaSocialSharing', '$localStorage', '$debounce', '$ionicSideMenuDelegate',
        function(functalData, $scope, $window, $timeout, $ionicScrollDelegate, $ionicLoading, $cordovaSocialSharing, $localStorage, $debounce, $ionicSideMenuDelegate) {

            var vm = this;

            var defaultImageCount = 100;

            //--- get images

            var getImages = function() {

                $ionicLoading.show(
                    {
                        template: 'loading...'
                    });

                // if in New, only returns new images, otherwise returns a random selection

                functalData.getImages(defaultImageCount, vm.sorting.sortBy).then(function(result) {

                    if (result.data.images && result.data.images.length) {

                        // append
                        vm.images = R.unionWith(function(x, y) {
                            return x.name === y.name;
                        }, vm.images || [], result.data.images);

                        // set votes
                        var myLikes = $localStorage.getObject('likes', []);
                        var myDislikes = $localStorage.getObject('dislikes', []);

                        R.forEach(function(img) {

                            if (R.find(function(v) {

                                    return v === img.name;
                                }, myLikes)) {

                                img.vote = 'like';
                            }

                            if (R.find(function(v) {

                                    return v === img.name;
                                }, myDislikes)) {

                                img.vote = 'dislike';
                            }
                        }, vm.images);

                        sort();

                        $localStorage.setObject('images', vm.images);

                        functalData.setImageCount(vm.images.length);
                    }

                }, function() {

                    // error
                    sort();

                }).finally(function() {
                    $scope.$broadcast('scroll.refreshComplete');
                    $ionicLoading.hide();
                });
            };

            // get new images after 5 minutes idle
            var updateImages = $debounce.debounce(
                function() {

                    getImages();
                    cleanVotes('likes');
                    cleanVotes('dislikes');

                }, 5 * 60000);

            //--- clear status after a while

            var clearStatus = function(image) {

                $timeout(function() {

                    image.status = '';
                }, 3000);
            };

            //--- purge

            var purgeDisliked = function() {

                return R.filter(function(img) {

                    return img.vote !== 'disliked' && (typeof img.likes === 'undefined' || img.likes >= img.dislikes);
                }, vm.images);
            };

            // periodic remove unnecessary dislikes

            var cleanVotes = function(vote) {

                // just keep those that are still around

                // vote is 'like' or 'dislikes'

                var votes = $localStorage.getObject(vote, []);

                votes = R.filter(function(n) {

                    return !!R.find(function(i) {

                        return i.name === n;
                    }, images);
                }, votes);

                votes = R.uniq(votes);

                $localStorage.setObject(vote, votes);
            };

            //--- sort

            var sort = function() {

                vm.images = purgeDisliked();

                vm.images = R.sort(function(a, b) {

                    var compare;

                    switch (vm.sorting.sortBy) {

                        case 'new':{
                            compare = - (a.sort < b.sort ? -1 : a.sort > b.sort ? 1 : 0);

                            break;
                            }

                        case 'popular':{
                            var avotes = a.likes - a.dislikes;
                            var bvotes = b.likes - b.dislikes;

                            compare = -(avotes < bvotes ? -1 : avotes > bvotes ? 1 : 0);

                            break;
                            }

                        case 'shuffle':{
                            compare = Math.random() < 0.5 ? -1 : 1;

                            break;
                            }
                    }

                    if (vm.sorting.desc) {

                        compare = -compare;
                    }

                    return compare;
                }, vm.images);

                vm.gotoTop();
            };

            //--- current image list

            vm.imageList = function() {
                return vm.images;
            }

            //--- goto top of screen

            vm.gotoTop = function() {

                $window.location.href = '#top';

                updateImages();

            };

            //--- infinite scroll

            vm.showMore = function() {

                vm.showCount += 4;

                $scope.$broadcast('scroll.infiniteScrollComplete');

                updateImages();
            };

            //--- user sort

            vm.sortBy = function(sorter) {

                if (sorter === vm.sorting.sortBy) {

                    vm.sorting.desc = !vm.sorting.desc;
                }
                else {

                    vm.sorting.desc = false;
                }

                vm.sorting.sortBy = sorter;

                $localStorage.setObject('sorting', vm.sorting);

                sort();

                vm.showCount = 6;

                $ionicScrollDelegate.scrollTop();

                updateImages();

            };

            // pull to refresh

            vm.doRefresh = function() {
                getImages();
            };

            // ---------------- save to camera roll

            var saveToCameraRoll = function(base64DataURL, image) {

                CameraRoll.saveToCameraRoll(base64DataURL, function() {

                    image.saved = true;
                    image.status = 'saved to your photos';
                    clearStatus(image);
                    $scope.$apply();

                }, function(err) {

                    image.error = 'Error : ' + err;
                    $scope.$apply();

                });
            };

            vm.save = function(image) {

                image.status = 'saving to your photos...';

                var url = vm.cdn + image.name;

                convertImgToBase64URL(url, function(base64DataURL, err) {

                    if (err) {

                        // could be cors - try s3

                        console.log('cdn error', err);

                        url = vm.s3 + image.name;

                        convertImgToBase64URL(url, function(base64DataURL, err) {

                            if (err) {

                                console.log('s3 error', err);
                                image.error = "Sorry - a system error prevented saving.";
                            }
                            else {

                                saveToCameraRoll(base64DataURL, image);
                            }
                        }, 'image/jpeg');
                    }
                    else {

                        saveToCameraRoll(base64DataURL, image);
                    }

                }, 'image/jpeg');

                updateImages();

            };

            /**
             * Convert an image
             * to a base64 url
             * @param  {String}   url
             * @param  {Function} callback
             * @param  {String}   [outputFormat=image/jpeg]
             * http://stackoverflow.com/questions/6150289/how-to-convert-image-into-base64-string-using-javascript
             */

            // cors test example
            // curl -sI -H "Origin: codeindeed.com" -H "Access-Control-Request-Method: GET" https://d1aienjtp63qx3.cloudfront.net/functal-20150610070410687.jpg

            function convertImgToBase64URL(url, callback, outputFormat) {

                var img = new Image();
                img.crossOrigin = 'Anonymous';

                img.onload = function() {

                    var canvas = document.createElement('CANVAS'),
                        ctx = canvas.getContext('2d'),
                        dataURL;

                    canvas.height = img.height;
                    canvas.width = img.width;

                    ctx.drawImage(img, 0, 0);

                    dataURL = canvas.toDataURL(outputFormat);

                    callback(dataURL);

                    canvas = null;
                };

                img.onerror = function(e) {

                    console.log("img error", e);
                    callback(null, e);
                };

                img.onabort = img.onerror;

                img.src = url;
            }

            //-------------- sharing

            vm.shareAnywhere = function(image) {

                if (!/sharing/.test(image.status)) {

                    image.status = 'loading sharing...';

                    $ionicLoading.show(
                        {
                            template: 'share...'
                        });

                    $timeout(function() {

                        var imageUrl = vm.cdn + image.name;

                        var msg = '#functal';

                        if (image.title) {
                            msg = '"' + image.title + '" ' + msg;
                        }

                        msg = msg + '#functal';

                        $cordovaSocialSharing.share(msg, null, imageUrl, null).then(function(result) {

                            $ionicLoading.hide();
                            image.status = '';
                            console.log('sharing result', result);
                        }, function(err) {

                            $ionicLoading.hide();
                            image.status = '';
                            console.log('sharing error', err);
                        });
                    }, 0);
                }
            };

            //-------------- sharing

            vm.vote = function(image, isLike) {

                var like, dislike;

                var myLikes = $localStorage.getObject('likes', []);
                var myDislikes = $localStorage.getObject('dislikes', []);

                if (isLike) {

                    if (!image.vote) {

                        // new
                        image.vote = 'like';
                        like = 1;
                        dislike = 0;

                        myLikes.push(image.name);
                    } else if (image.vote === 'like') {

                        // unvote
                        image.vote = '';
                        like = -1;
                        dislike = 0;

                        myLikes = R.filter(function(i) {

                            return i.name !== image.name;
                        }, myLikes);
                    }
                    else {

                        // change
                        image.vote = 'like';
                        like = 1;
                        dislike = -1;

                        myLikes.push(image.name);

                        myDislikes = R.filter(function(i) {

                            return i.name !== image.name;
                        }, myDislikes);

                    }
                }
                else // dislike
                {

                    if (!image.vote) {

                        // new
                        image.vote = 'dislike';
                        like = 0;
                        dislike = 1;

                        myDislikes.push(image.name);
                    } else if (image.vote === 'dislike') {

                        // unvote
                        image.vote = '';
                        like = 0;
                        dislike = -1;

                        myDislikes = R.filter(function(i) {

                            return i.name !== image.name;
                        }, myDislikes);
                    }
                    else {

                        // change
                        image.vote = 'dislike';
                        like = -1;
                        dislike = 1;

                        myDislikes.push(image.name);

                        myLikes = R.filter(function(i) {

                            return i.name !== image.name;
                        }, myLikes);
                    }
                }

                $localStorage.setObject('likes', myLikes);
                $localStorage.setObject('dislikes', myDislikes);

                // local update
                image.likes = Math.max(0, image.likes + like);
                image.dislikes = Math.max(0, image.dislikes + dislike);

                functalData.vote(image, like, dislike).then(function(result) {

                    if (result.status === 'ok') {

                        // db update
                        images.likes = result.likes;
                        images.dislikes = result.dislikes;
                    }

                }, function() {

                    // error
                });

            };

            //----------------- init

            vm.cdn = 'https://d1aienjtp63qx3.cloudfront.net/';
            vm.s3 = 'https://s3.amazonaws.com/functal-images/';

            vm.showCount = 6;

            vm.images = $localStorage.getObject('images', []);

            vm.sorting = $localStorage.getObject('sorting',
                {
                    sortBy: 'shuffle',
                    desc: true
                });

            getImages();
        }
    ]);

    module.controller('HelpCtrl', ['functalData',
        function(functalData) {

            var vm = this;

            vm.imageCount = function() {
                return functalData.imageCount;
            };

        }]);
})();
<commit_msg>local get all images<commit_after>(function() {

    "use strict";

    var module = angular.module('functal.controllers', []);

    module.controller('AppCtrl', [function() {}]);

    module.controller('ImagesCtrl', ['functalData', '$scope', '$window', '$timeout', '$ionicScrollDelegate', '$ionicLoading', '$cordovaSocialSharing', '$localStorage', '$debounce', '$ionicSideMenuDelegate',
        function(functalData, $scope, $window, $timeout, $ionicScrollDelegate, $ionicLoading, $cordovaSocialSharing, $localStorage, $debounce, $ionicSideMenuDelegate) {

            var vm = this;

            var defaultImageCount = 100;

            //--- get images

            var getImages = function() {

                $ionicLoading.show(
                    {
                        template: 'loading...'
                    });

                // if in New, only returns new images, otherwise returns a random selection

                var count = defaultImageCount;

                // get all if running in browser
                if (location && location.href && location.href.indexOf('localhost:8100') >= 0) {
                    count = 100000;
                    console.log('count', count);
                }

                functalData.getImages(count, vm.sorting.sortBy).then(function(result) {

                    if (result.data.images && result.data.images.length) {

                        // append
                        vm.images = R.unionWith(function(x, y) {
                            return x.name === y.name;
                        }, vm.images || [], result.data.images);

                        // set votes
                        var myLikes = $localStorage.getObject('likes', []);
                        var myDislikes = $localStorage.getObject('dislikes', []);

                        R.forEach(function(img) {

                            if (R.find(function(v) {

                                    return v === img.name;
                                }, myLikes)) {

                                img.vote = 'like';
                            }

                            if (R.find(function(v) {

                                    return v === img.name;
                                }, myDislikes)) {

                                img.vote = 'dislike';
                            }
                        }, vm.images);

                        sort();

                        $localStorage.setObject('images', vm.images);

                        functalData.setImageCount(vm.images.length);
                    }

                }, function() {

                    // error
                    sort();

                }).finally(function() {
                    $scope.$broadcast('scroll.refreshComplete');
                    $ionicLoading.hide();
                });
            };

            // get new images after 5 minutes idle
            var updateImages = $debounce.debounce(
                function() {

                    getImages();
                    cleanVotes('likes');
                    cleanVotes('dislikes');

                }, 5 * 60000);

            //--- clear status after a while

            var clearStatus = function(image) {

                $timeout(function() {

                    image.status = '';
                }, 3000);
            };

            //--- purge

            var purgeDisliked = function() {

                return R.filter(function(img) {

                    return img.vote !== 'disliked' && (typeof img.likes === 'undefined' || img.likes >= img.dislikes);
                }, vm.images);
            };

            // periodic remove unnecessary dislikes

            var cleanVotes = function(vote) {

                // just keep those that are still around

                // vote is 'like' or 'dislikes'

                var votes = $localStorage.getObject(vote, []);

                votes = R.filter(function(n) {

                    return !!R.find(function(i) {

                        return i.name === n;
                    }, images);
                }, votes);

                votes = R.uniq(votes);

                $localStorage.setObject(vote, votes);
            };

            //--- sort

            var sort = function() {

                vm.images = purgeDisliked();

                vm.images = R.sort(function(a, b) {

                    var compare;

                    switch (vm.sorting.sortBy) {

                        case 'new':{
                            compare = - (a.sort < b.sort ? -1 : a.sort > b.sort ? 1 : 0);

                            break;
                            }

                        case 'popular':{
                            var avotes = a.likes - a.dislikes;
                            var bvotes = b.likes - b.dislikes;

                            compare = -(avotes < bvotes ? -1 : avotes > bvotes ? 1 : 0);

                            break;
                            }

                        case 'shuffle':{
                            compare = Math.random() < 0.5 ? -1 : 1;

                            break;
                            }
                    }

                    if (vm.sorting.desc) {

                        compare = -compare;
                    }

                    return compare;
                }, vm.images);

                vm.gotoTop();
            };

            //--- current image list

            vm.imageList = function() {
                return vm.images;
            }

            //--- goto top of screen

            vm.gotoTop = function() {

                $window.location.href = '#top';

                updateImages();

            };

            //--- infinite scroll

            vm.showMore = function() {

                vm.showCount += 4;

                $scope.$broadcast('scroll.infiniteScrollComplete');

                updateImages();
            };

            //--- user sort

            vm.sortBy = function(sorter) {

                if (sorter === vm.sorting.sortBy) {

                    vm.sorting.desc = !vm.sorting.desc;
                }
                else {

                    vm.sorting.desc = false;
                }

                vm.sorting.sortBy = sorter;

                $localStorage.setObject('sorting', vm.sorting);

                sort();

                vm.showCount = 6;

                $ionicScrollDelegate.scrollTop();

                updateImages();

            };

            // pull to refresh

            vm.doRefresh = function() {
                getImages();
            };

            // ---------------- save to camera roll

            var saveToCameraRoll = function(base64DataURL, image) {

                CameraRoll.saveToCameraRoll(base64DataURL, function() {

                    image.saved = true;
                    image.status = 'saved to your photos';
                    clearStatus(image);
                    $scope.$apply();

                }, function(err) {

                    image.error = 'Error : ' + err;
                    $scope.$apply();

                });
            };

            vm.save = function(image) {

                image.status = 'saving to your photos...';

                var url = vm.cdn + image.name;

                convertImgToBase64URL(url, function(base64DataURL, err) {

                    if (err) {

                        // could be cors - try s3

                        console.log('cdn error', err);

                        url = vm.s3 + image.name;

                        convertImgToBase64URL(url, function(base64DataURL, err) {

                            if (err) {

                                console.log('s3 error', err);
                                image.error = "Sorry - a system error prevented saving.";
                            }
                            else {

                                saveToCameraRoll(base64DataURL, image);
                            }
                        }, 'image/jpeg');
                    }
                    else {

                        saveToCameraRoll(base64DataURL, image);
                    }

                }, 'image/jpeg');

                updateImages();

            };

            /**
             * Convert an image
             * to a base64 url
             * @param  {String}   url
             * @param  {Function} callback
             * @param  {String}   [outputFormat=image/jpeg]
             * http://stackoverflow.com/questions/6150289/how-to-convert-image-into-base64-string-using-javascript
             */

            // cors test example
            // curl -sI -H "Origin: codeindeed.com" -H "Access-Control-Request-Method: GET" https://d1aienjtp63qx3.cloudfront.net/functal-20150610070410687.jpg

            function convertImgToBase64URL(url, callback, outputFormat) {

                var img = new Image();
                img.crossOrigin = 'Anonymous';

                img.onload = function() {

                    var canvas = document.createElement('CANVAS'),
                        ctx = canvas.getContext('2d'),
                        dataURL;

                    canvas.height = img.height;
                    canvas.width = img.width;

                    ctx.drawImage(img, 0, 0);

                    dataURL = canvas.toDataURL(outputFormat);

                    callback(dataURL);

                    canvas = null;
                };

                img.onerror = function(e) {

                    console.log("img error", e);
                    callback(null, e);
                };

                img.onabort = img.onerror;

                img.src = url;
            }

            //-------------- sharing

            vm.shareAnywhere = function(image) {

                if (!/sharing/.test(image.status)) {

                    image.status = 'loading sharing...';

                    $ionicLoading.show(
                        {
                            template: 'share...'
                        });

                    $timeout(function() {

                        var imageUrl = vm.cdn + image.name;

                        var msg = '#functal';

                        if (image.title) {
                            msg = '"' + image.title + '" ' + msg;
                        }

                        msg = msg + '#functal';

                        $cordovaSocialSharing.share(msg, null, imageUrl, null).then(function(result) {

                            $ionicLoading.hide();
                            image.status = '';
                            console.log('sharing result', result);
                        }, function(err) {

                            $ionicLoading.hide();
                            image.status = '';
                            console.log('sharing error', err);
                        });
                    }, 0);
                }
            };

            //-------------- sharing

            vm.vote = function(image, isLike) {

                var like, dislike;

                var myLikes = $localStorage.getObject('likes', []);
                var myDislikes = $localStorage.getObject('dislikes', []);

                if (isLike) {

                    if (!image.vote) {

                        // new
                        image.vote = 'like';
                        like = 1;
                        dislike = 0;

                        myLikes.push(image.name);
                    } else if (image.vote === 'like') {

                        // unvote
                        image.vote = '';
                        like = -1;
                        dislike = 0;

                        myLikes = R.filter(function(i) {

                            return i.name !== image.name;
                        }, myLikes);
                    }
                    else {

                        // change
                        image.vote = 'like';
                        like = 1;
                        dislike = -1;

                        myLikes.push(image.name);

                        myDislikes = R.filter(function(i) {

                            return i.name !== image.name;
                        }, myDislikes);

                    }
                }
                else // dislike
                {

                    if (!image.vote) {

                        // new
                        image.vote = 'dislike';
                        like = 0;
                        dislike = 1;

                        myDislikes.push(image.name);
                    } else if (image.vote === 'dislike') {

                        // unvote
                        image.vote = '';
                        like = 0;
                        dislike = -1;

                        myDislikes = R.filter(function(i) {

                            return i.name !== image.name;
                        }, myDislikes);
                    }
                    else {

                        // change
                        image.vote = 'dislike';
                        like = -1;
                        dislike = 1;

                        myDislikes.push(image.name);

                        myLikes = R.filter(function(i) {

                            return i.name !== image.name;
                        }, myLikes);
                    }
                }

                $localStorage.setObject('likes', myLikes);
                $localStorage.setObject('dislikes', myDislikes);

                // local update
                image.likes = Math.max(0, image.likes + like);
                image.dislikes = Math.max(0, image.dislikes + dislike);

                functalData.vote(image, like, dislike).then(function(result) {

                    if (result.status === 'ok') {

                        // db update
                        images.likes = result.likes;
                        images.dislikes = result.dislikes;
                    }

                }, function() {

                    // error
                });

            };

            //----------------- init

            vm.cdn = 'https://d1aienjtp63qx3.cloudfront.net/';
            vm.s3 = 'https://s3.amazonaws.com/functal-images/';

            vm.showCount = 6;

            vm.images = $localStorage.getObject('images', []);

            vm.sorting = $localStorage.getObject('sorting',
                {
                    sortBy: 'shuffle',
                    desc: true
                });

            getImages();
        }
    ]);

    module.controller('HelpCtrl', ['functalData',
        function(functalData) {

            var vm = this;

            vm.imageCount = function() {
                return functalData.imageCount;
            };

        }]);
})();
<|endoftext|>


<commit_before>"use strict";

// declare public exports
module.exports = {
  upsertAccess: upsertAccess,
  orgAccessList: orgAccessList,
  setupDatabase : setupDatabase
}

var pg = require('pg');

function upsertAccess (access, done) {
    pg.connect(process.env.DATABASE_URL, function(err, client, done) {

        var sql = 'INSERT INTO sforg (id, instanceurl, access_token, refresh_token, userid, orgid) VALUES (DEFAULT, \''+access.instanceUrl+'\', \''+access.access_token+'\', \''+access.refresh_token+'\', \''+access.userid+'\', \''+access.orgid+'\') ON CONFLICT (orgid) DO UPDATE SET access_token = EXCLUDED.access_token, refresh_token = EXCLUDED.refresh_token';

        console.log(sql);
        client.query(sql, function(err, result) {
            if (err) {
                console.log(err);
                done(err);
            } else {
                console.log('row inserted with id: ' + JSON.stringify(result));
                done(result);
            }

        });
    });
};

function orgAccessList(cb) {
    pg.connect(process.env.DATABASE_URL, function(err, client, done) {
        var sql = 'SELECT * FROM sforg';
        client.query(sql, function(err, result) {
            if (err) {
                console.log('ERROR FROM POSTGRES: '+err);
            } else {
                cb(result); // callback with the results
                done(); // indicate that this pg client is done
            }
        });
    });
    pg.end(); // close the pg.connect session
};

function setupDatabase (cb) {

    pg.connect(process.env.DATABASE_URL, function(err, client, done) {

        var sql = 'CREATE TABLE "sforg-test" (id serial primary key, instanceurl text, access_token text, refresh_token text, userid text, orgid text, UNIQUE ("orgid") )';
        client.query(sql, function(err, result) {
            if (err) {
                console.log('ERROR FROM POSTGRES: '+err);
            } else {
                cb(result); // callback with the results
                done(); // indicate that this pg client is done
            }
        });
    });
    pg.end(); // close the pg.connect session

}
<commit_msg>wrong databasetable, remove the -test<commit_after>"use strict";

// declare public exports
module.exports = {
  upsertAccess: upsertAccess,
  orgAccessList: orgAccessList,
  setupDatabase : setupDatabase
}

var pg = require('pg');

function upsertAccess (access, done) {
    pg.connect(process.env.DATABASE_URL, function(err, client, done) {

        var sql = 'INSERT INTO sforg (id, instanceurl, access_token, refresh_token, userid, orgid) VALUES (DEFAULT, \''+access.instanceUrl+'\', \''+access.access_token+'\', \''+access.refresh_token+'\', \''+access.userid+'\', \''+access.orgid+'\') ON CONFLICT (orgid) DO UPDATE SET access_token = EXCLUDED.access_token, refresh_token = EXCLUDED.refresh_token';

        console.log(sql);
        client.query(sql, function(err, result) {
            if (err) {
                console.log(err);
                done(err);
            } else {
                console.log('row inserted with id: ' + JSON.stringify(result));
                done(result);
            }

        });
    });
};

function orgAccessList(cb) {
    pg.connect(process.env.DATABASE_URL, function(err, client, done) {
        var sql = 'SELECT * FROM sforg';
        client.query(sql, function(err, result) {
            if (err) {
                console.log('ERROR FROM POSTGRES: '+err);
            } else {
                cb(result); // callback with the results
                done(); // indicate that this pg client is done
            }
        });
    });
    pg.end(); // close the pg.connect session
};

function setupDatabase (cb) {

    pg.connect(process.env.DATABASE_URL, function(err, client, done) {

        var sql = 'CREATE TABLE "sforg" (id serial primary key, instanceurl text, access_token text, refresh_token text, userid text, orgid text, UNIQUE ("orgid") )';
        client.query(sql, function(err, result) {
            if (err) {
                console.log('ERROR FROM POSTGRES: '+err);
            } else {
                cb(result); // callback with the results
                done(); // indicate that this pg client is done
            }
        });
    });
    pg.end(); // close the pg.connect session

}
<|endoftext|>


<commit_before>angular.module('choona.controllers', [])

  .controller('appCtrl', function ($scope, store, $state, socket, $rootScope) {
    $scope.profile = store.get('profile');
    $scope.name = $scope.profile.given_name || $scope.profile.name;

    $scope.showSearchInput = false;
    $scope.search = {
      text: ''
    };
    $scope.iconClass = 'button button-icon icon search-icon ion-plus-round';

    $scope.searchText = '';
    $scope.searching = false;
    $scope.searchResults = [];

    $scope.handleSearchClick = function () {
      if (!$scope.showSearchInput) {
        $state.go('app.search');
      } else {
        $state.go('app.playlist');
      }
    };

    $rootScope.$on('$stateChangeSuccess', function (event, toState, toParams, fromState) {
      if (fromState.name === "app.search" || toState.name === "app.search") {
        var show = !$scope.showSearchInput;
        $scope.showSearchInput = show;
        var className = 'button button-icon icon search-icon ';
        className += show ? 'ion-minus-round' : 'ion-plus-round';
        $scope.iconClass = className;
        $scope.searchResults = [];
        $scope.searchText = '';
        $scope.searching = false;
        $scope.search.text = '';
      }
    });

    $scope.handleSearch = function () {
      var searchText = $scope.search.text;
      $scope.searchText = searchText;
      $scope.searchResults = [];
      if (searchText.length > 0) {
        $scope.searching = true;
        doSearch(searchText);
      } else {
        $scope.searching = false;
      }
    };

    function doSearch(searchString) {
      socket.emit('playlist:search', searchString, function (searchResults) {
        if ($scope.search.text === searchString) {
          $scope.searching = false;
          $scope.searchResults = searchResults;
        }
      });
    }
  })

  .controller('settingsCtrl', function ($scope, auth, store, $state) {
    $scope.doLogout = function () {
      auth.signout();
      store.remove('token');
      store.remove('profile');
      store.remove('refreshToken');
      $state.go('login');
    };
  })

  .controller('searchCtrl', function ($scope, socket, toaster) {
    $scope.addTrack = function (track) {
      toaster("'" + track.title + "' added to queue");
      socket.emit('playlist:add', track.id);
      $scope.searchResults = $scope.searchResults.filter(function (result) {
        return result.id !== track.id;
      });
    };
    setTimeout(function () {
      document.getElementById("search-input").focus();
    }, 0);
  })

  .controller('introCtrl', function ($scope, $state, store) {
    $scope.activeSlide = 0;

    $scope.finishedTutorial = function () {
      store.set('didTutorial', true);
      $state.go('login');
    };
  })

  .controller('loginCtrl', function ($scope, auth, store, $state, socket) {
    var signinOpts = {
      container: 'lock-container',
      icon: 'img/choona-animated.svg',
      authParams: {
        scope: 'openid offline_access',
        device: 'Mobile device'
      }
    };

    auth.signin(signinOpts, onAuthSuccess);

    function onAuthSuccess(profile, token, accessToken, state, refreshToken) {
      store.set('profile', profile);
      store.set('token', token);
      store.set('refreshToken', refreshToken);
      socket.emit('authenticate', { token: token });
    }
  })

  .controller('playlistCtrl', function ($scope, $ionicModal, socket, toaster) {
    $ionicModal.fromTemplateUrl('templates/nowplaying.html', {
      scope: $scope,
      animation: 'slide-in-up'
    }).then(function(modal) {
      $scope.modal = modal;
    });

    $scope.openModal = function () {
      $scope.modal.show();
    };

    $scope.closeModal = function () {
      $scope.modal.hide();
    };

    $scope.upvote = function (track) {
      socket.emit("playlist:upvote", track.id, function (success) {
        if (success) {
          toaster("Upvoted '" + track.title + "'");
        } else {
          toaster("You have already upvoted '" + track.title + "'");
        }
      });
    };

    $scope.downvote = function (track) {
      socket.emit("playlist:downvote", track.id, function (success) {
        if (success) {
          toaster("Downvoted '" + track.title + "'");
        } else {
          toaster("You have already downvoted '" + track.title + "'");
        }
      });
    };

    $scope.$on('queue-empty', function () {
      $scope.modal.hide();
    });

    $scope.$on('$destroy', function () {
      $scope.modal.remove();
    });
  })

  .controller('activityCtrl', function ($scope) {
    $scope.doRefresh = function () {
      $scope.$broadcast('scroll.refreshComplete');
      $scope.$apply();
    };

    // TODO: sort dynamic time out to text e.g. 16:10 ==> 10 minutes ago
    $scope.activities = [
      { profile: 'img/profile.png', name: 'Jay Vagharia', title: 'Cotton Eye Joe', location: 'Starbucks', message: '#ballin', socialtype:'facebook', time: 'Just now' },
      { profile: 'img/profile.png', name: 'Simon Kerr', title: 'Barbie Girl', location: 'Costa', message: '#imabarbiegirlinabarbieworld', socialtype:'twitter', time: '10 minutes ago' },
      { profile: 'img/profile.png', name: 'Oliver Woodings', title: 'I\'m on a boat!', location: 'Starbucks', message: '#lonelyisland #imonaboat', socialtype: 'googleplus', time: '20 min' }
    ];

  })

  .controller('historyCtrl', function($scope) {
    $scope.visits = [
      { profile: 'img/starbucks.jpeg', name: 'Starbucks', location: 'Leicester', time: 'Today' },
      { profile: 'img/starbucks.jpeg', name: 'Costa', location: 'Loughborough', time: '2 days ago' },
      { profile: 'img/starbucks.jpeg', name: 'Starbucks', location: 'Leicester', time: '3 days ago' },
      { profile: 'img/starbucks.jpeg', name: 'Starbucks', location: 'Loughborough', time: 'A week ago' }
    ];
  });
<commit_msg>Fix image<commit_after>angular.module('choona.controllers', [])

  .controller('appCtrl', function ($scope, store, $state, socket, $rootScope) {
    $scope.profile = store.get('profile');
    $scope.name = $scope.profile.given_name || $scope.profile.name;

    $scope.showSearchInput = false;
    $scope.search = {
      text: ''
    };
    $scope.iconClass = 'button button-icon icon search-icon ion-plus-round';

    $scope.searchText = '';
    $scope.searching = false;
    $scope.searchResults = [];

    $scope.handleSearchClick = function () {
      if (!$scope.showSearchInput) {
        $state.go('app.search');
      } else {
        $state.go('app.playlist');
      }
    };

    $rootScope.$on('$stateChangeSuccess', function (event, toState, toParams, fromState) {
      if (fromState.name === "app.search" || toState.name === "app.search") {
        var show = !$scope.showSearchInput;
        $scope.showSearchInput = show;
        var className = 'button button-icon icon search-icon ';
        className += show ? 'ion-minus-round' : 'ion-plus-round';
        $scope.iconClass = className;
        $scope.searchResults = [];
        $scope.searchText = '';
        $scope.searching = false;
        $scope.search.text = '';
      }
    });

    $scope.handleSearch = function () {
      var searchText = $scope.search.text;
      $scope.searchText = searchText;
      $scope.searchResults = [];
      if (searchText.length > 0) {
        $scope.searching = true;
        doSearch(searchText);
      } else {
        $scope.searching = false;
      }
    };

    function doSearch(searchString) {
      socket.emit('playlist:search', searchString, function (searchResults) {
        if ($scope.search.text === searchString) {
          $scope.searching = false;
          $scope.searchResults = searchResults;
        }
      });
    }
  })

  .controller('settingsCtrl', function ($scope, auth, store, $state) {
    $scope.doLogout = function () {
      auth.signout();
      store.remove('token');
      store.remove('profile');
      store.remove('refreshToken');
      $state.go('login');
    };
  })

  .controller('searchCtrl', function ($scope, socket, toaster) {
    $scope.addTrack = function (track) {
      toaster("'" + track.title + "' added to queue");
      socket.emit('playlist:add', track.id);
      $scope.searchResults = $scope.searchResults.filter(function (result) {
        return result.id !== track.id;
      });
    };
    setTimeout(function () {
      document.getElementById("search-input").focus();
    }, 0);
  })

  .controller('introCtrl', function ($scope, $state, store) {
    $scope.activeSlide = 0;

    $scope.finishedTutorial = function () {
      store.set('didTutorial', true);
      $state.go('login');
    };
  })

  .controller('loginCtrl', function ($scope, auth, store, $state, socket) {
    var signinOpts = {
      container: 'lock-container',
      icon: 'img/choona-animated.svg',
      authParams: {
        scope: 'openid offline_access',
        device: 'Mobile device'
      }
    };

    auth.signin(signinOpts, onAuthSuccess);

    function onAuthSuccess(profile, token, accessToken, state, refreshToken) {
      store.set('profile', profile);
      store.set('token', token);
      store.set('refreshToken', refreshToken);
      socket.emit('authenticate', { token: token });
    }
  })

  .controller('playlistCtrl', function ($scope, $ionicModal, socket, toaster) {
    $ionicModal.fromTemplateUrl('templates/nowplaying.html', {
      scope: $scope,
      animation: 'slide-in-up'
    }).then(function(modal) {
      $scope.modal = modal;
    });

    $scope.openModal = function () {
      $scope.modal.show();
    };

    $scope.closeModal = function () {
      $scope.modal.hide();
    };

    $scope.upvote = function (track) {
      socket.emit("playlist:upvote", track.id, function (success) {
        if (success) {
          toaster("Upvoted '" + track.title + "'");
        } else {
          toaster("You have already upvoted '" + track.title + "'");
        }
      });
    };

    $scope.downvote = function (track) {
      socket.emit("playlist:downvote", track.id, function (success) {
        if (success) {
          toaster("Downvoted '" + track.title + "'");
        } else {
          toaster("You have already downvoted '" + track.title + "'");
        }
      });
    };

    $scope.$on('queue-empty', function () {
      $scope.modal.hide();
    });

    $scope.$on('$destroy', function () {
      $scope.modal.remove();
    });
  })

  .controller('activityCtrl', function ($scope) {
    $scope.doRefresh = function () {
      $scope.$broadcast('scroll.refreshComplete');
      $scope.$apply();
    };

    // TODO: sort dynamic time out to text e.g. 16:10 ==> 10 minutes ago
    $scope.activities = [
      { profile: 'img/profile.png', name: 'Jay Vagharia', title: 'Cotton Eye Joe', location: 'Starbucks', message: '#ballin', socialtype:'facebook', time: 'Just now' },
      { profile: 'img/profile.png', name: 'Simon Kerr', title: 'Barbie Girl', location: 'Costa', message: '#imabarbiegirlinabarbieworld', socialtype:'twitter', time: '10 minutes ago' },
      { profile: 'img/profile.png', name: 'Oliver Woodings', title: 'I\'m on a boat!', location: 'Starbucks', message: '#lonelyisland #imonaboat', socialtype: 'googleplus', time: '20 min' }
    ];

  })

  .controller('historyCtrl', function($scope) {
    $scope.visits = [
      { profile: 'img/starbucks.png', name: 'Starbucks', location: 'Leicester', time: 'Today' },
      { profile: 'img/starbucks.png', name: 'Costa', location: 'Loughborough', time: '2 days ago' },
      { profile: 'img/starbucks.png', name: 'Starbucks', location: 'Leicester', time: '3 days ago' },
      { profile: 'img/starbucks.png', name: 'Starbucks', location: 'Loughborough', time: 'A week ago' }
    ];
  });
<|endoftext|>


<commit_before>angular.module('starter.controllers', [])

  .controller('AppCtrl', function ($scope, $ionicModal, $timeout, configService, $window) {
    $scope.loggedIn = false;
    var url = configService.get('url');
    var api = configService.get('apikey');

    if (url && api) {
      $scope.loggedIn = true;

      console.log("Logged in!")
    }
    else {
      $scope.loggedIn = false;
      console.log("Not logged in. ")
    }

    $scope.loginData = {};

    // Create the login modal that we will use later
    $ionicModal.fromTemplateUrl('templates/login.html', {
      scope: $scope
    }).then(function (modal) {
      $scope.modal = modal;
    });

    // Triggered in the login modal to close it
    $scope.closeLogin = function () {
      $scope.modal.hide();
    };

    // Open the login modal
    $scope.login = function () {
      $scope.modal.show();
    };

    // Perform the login action when the user submits the login form
    $scope.doLogin = function () {
      console.log('Doing login', $scope.loginData);

      configService.set('url', $scope.loginData.url);
      configService.set('apikey', $scope.loginData.apikey);

      // Simulate a login delay. Remove this and replace with your login
      // code if using a login system
      $timeout(function () {
        $scope.closeLogin();
        $window.location.reload(true)
      }, 1000);
    };

  })

  .controller('PlaylistsCtrl', function ($scope) {
    $scope.playlists = [
      { title: 'Reggae', id: 1 },
      { title: 'Chill', id: 2 },
      { title: 'Dubstep', id: 3 },
      { title: 'Indie', id: 4 },
      { title: 'Rap', id: 5 },
      { title: 'Cowbell', id: 6 }
    ];
  })

  .controller('SettingsCtrl', function ($scope, $window, configService, $state) {
    $scope.doLogout = function () {
      configService.destroy('apikey');
      configService.destroy('url');

      $window.location.reload(true);
      $state.go('app.urls', {}, {reload: true});
    }
  });
<commit_msg>Closes #1<commit_after>angular.module('starter.controllers', [])

  .controller('AppCtrl', function ($scope, $ionicModal, $timeout, configService, $window) {
    $scope.loggedIn = false;
    var url = configService.get('url');
    var api = configService.get('apikey');

    if (url && api) {
      $scope.loggedIn = true;

      console.log("Logged in!")
    }
    else {
      $scope.loggedIn = false;
      console.log("Not logged in. ")
    }

    $scope.loginData = {};

    // Create the login modal that we will use later
    $ionicModal.fromTemplateUrl('templates/login.html', {
      scope: $scope
    }).then(function (modal) {
      $scope.modal = modal;
    });

    // Triggered in the login modal to close it
    $scope.closeLogin = function () {
      $scope.modal.hide();
    };

    // Open the login modal
    $scope.login = function () {
      $scope.modal.show();
    };

    // Perform the login action when the user submits the login form
    $scope.doLogin = function () {
      console.log('Doing login', $scope.loginData);

      configService.set('url', $scope.loginData.url);
      configService.set('apikey', $scope.loginData.apikey);

      // Simulate a login delay. Remove this and replace with your login
      // code if using a login system
      $timeout(function () {
        $scope.closeLogin();
        $window.location.reload(true)
      }, 1000);
    };

  })

  .controller('PlaylistsCtrl', function ($scope) {
    $scope.playlists = [
      { title: 'Reggae', id: 1 },
      { title: 'Chill', id: 2 },
      { title: 'Dubstep', id: 3 },
      { title: 'Indie', id: 4 },
      { title: 'Rap', id: 5 },
      { title: 'Cowbell', id: 6 }
    ];
  })

  .controller('SettingsCtrl', function ($scope, $window, configService, $state) {
    $scope.doLogout = function () {
      configService.destroy('apikey');
      configService.destroy('url');

      $window.location.reload(true);
      $state.go('app.urls', {}, {reload: true});
      console.log("Logged out.");
    }
  });
<|endoftext|>


<commit_before>angular.module('starter.controllers', [])
.controller('DashCtrl', function($scope, $state, Arrivals, $ionicPlatform, MioFavs, $ionicListDelegate) {
  var savedPositionString = sessionStorage.getItem('position2');
  if (savedPositionString) {
    $scope.savedPosition = JSON.parse(savedPositionString);
  }
  // not needed i hope
  //$scope.arrivals = Arrivals.latestByStation();
  //$scope.favs = MioFavs.intersection($scope.arrivals);
  $scope.loading = true;
  Arrivals.subscribe('arrivalsChanged', $scope);
  Arrivals.subscribe('apiError', $scope);
  $scope.$on('arrivalsChanged', function(event, rawArrivals, error) {
    $scope.error = null;
    $scope.connectionProblem = false;
    $scope.arrivals = Arrivals.latestByStation();
    $scope.favs = MioFavs.intersection($scope.arrivals);
    $scope.emptyResponse = rawArrivals.length == 0;
    $scope.loading = false;
    if ($scope.savedPosition) {
      $scope.nearbyStations = Arrivals.closestTo($scope.savedPosition, $scope.arrivals);
    }
  });
  $scope.$on('apiError', function(event, resp) {
    if (resp.status == 0) {
      $scope.connectionProblem = new Date();
    } else {
      $scope.error = "code: " + resp.status + ", message: " + resp.statusText;
      $scope.connectionProblem = false;
    }
    $scope.loading = false;
    $scope.emptyResponse = false;
  });

  $scope.refreshArrivals = function() {
    Arrivals.refresh().finally(function() {
      $scope.$broadcast('scroll.refreshComplete');
    });
  };

  $scope.geowait = true;
  $ionicPlatform.ready(function() {
    window.navigator.geolocation.getCurrentPosition(function(position) {
      $scope.savedPosition = {
        latitude: position.coords.latitude,
        longitude: position.coords.longitude
      };
      var newJson = JSON.stringify($scope.savedPosition);
      var oldJson = sessionStorage.getItem('position2');
      if (newJson != oldJson) {
        sessionStorage.setItem('position2', newJson);
      }
      $scope.$apply(function() {
        $scope.nearbyStations = Arrivals.closestTo($scope.savedPosition, $scope.arrivals);
        $scope.geowait = false;
      });
    });
  });

  $scope.stationView = function(stationName) {
    $state.go("station", {stationName: stationName});
  };

  var dirOrder = ['n', 's', 'w', 'e'];
  $scope.byDirection = function(obj) {
    if (!obj) {
      return null;
    }
    var res = {};
    for (var i = 0; i < dirOrder.length; i++) {
      if (obj[dirOrder[i]]) {
        res[dirOrder[i]] = obj[dirOrder[i]];
      }
    }
    return res;
  };

  $scope.timeboxClass = function(arrival) {
    var ret = {
      scheduled: arrival.scheduled
    };
    ret[arrival.line + '-line'] = true;
    return ret;
  };

  $scope.isFavorite = function(stationName) {
    return MioFavs.all().indexOf(stationName) > -1;
  };
  $scope.toggleFavorite = function(stationName) {
    MioFavs.toggle(stationName);
    $ionicListDelegate.closeOptionButtons();
    $scope.favs = MioFavs.intersection($scope.arrivals);
  };

  $scope.timeDisplay = function(arrival) {
    var text = arrival.waiting_time;
    if (['arriving', 'arrived'].indexOf(text) >= 0) {
      return "";
    } else if (text == 'boarding') {
      return "";
    }

    // waiting_time should start with a number, and parse to int
    return ":" + (parseInt(arrival.waiting_time) || 0);
  };
})

.controller('StationCtrl', function($scope, $state, Arrivals) {
  var stationName;
  if ($state.params.stationName === '5 pnts') {
    stationName = "five points station";
  } else {
    stationName =  $state.params.stationName;
  }
  $scope.stationName = stationName;

  $scope.arrivals = Arrivals.by('station', stationName);
  Arrivals.subscribe('arrivalsChanged', $scope);
  $scope.$on('arrivalsChanged', function() {
    $scope.arrivals = Arrivals.by('station', stationName);
  });

  $scope.arrivalClass = function(arrival) {
    var ret = {
      scheduled: arrival.scheduled
    };
    ret[arrival.line + '-line'] = true;
    return ret;
  };

  $scope.trainView = function(trainId) {
    if (!trainId) return;
    $state.go("train", {trainId: trainId});
  };

  $scope.refreshArrivals = function() {
    Arrivals.refresh().finally(function() {
      $scope.$broadcast('scroll.refreshComplete');
    });
  };

})

.controller('TrainCtrl', function($scope, $state, Arrivals) {
  var trainId = $scope.trainId = $state.params.trainId;
  $scope.arrivals = Arrivals.by('train_id', trainId);
  Arrivals.subscribe('arrivalsChanged', $scope);
  $scope.$on('arrivalsChanged', function() {
    $scope.arrivals = Arrivals.by('train_id', trainId);
  });
  $scope.arrivalClass = function(arrival) {
    var ret = {
      scheduled: arrival.scheduled
    };
    ret[arrival.line + '-line'] = true;
    return ret;
  };

  $scope.refreshArrivals = function() {
    Arrivals.refresh().finally(function() {
      $scope.$broadcast('scroll.refreshComplete');
    });
  };

});
<commit_msg>store last location in localStorage, wait is too long<commit_after>angular.module('starter.controllers', [])
.controller('DashCtrl', function($scope, $state, Arrivals, $ionicPlatform, MioFavs, $ionicListDelegate) {
  var savedPositionString = localStorage.getItem('position2');
  if (savedPositionString) {
    $scope.savedPosition = JSON.parse(savedPositionString);
  }
  // not needed i hope
  //$scope.arrivals = Arrivals.latestByStation();
  //$scope.favs = MioFavs.intersection($scope.arrivals);
  $scope.loading = true;
  Arrivals.subscribe('arrivalsChanged', $scope);
  Arrivals.subscribe('apiError', $scope);
  $scope.$on('arrivalsChanged', function(event, rawArrivals, error) {
    $scope.error = null;
    $scope.connectionProblem = false;
    $scope.arrivals = Arrivals.latestByStation();
    $scope.favs = MioFavs.intersection($scope.arrivals);
    $scope.emptyResponse = rawArrivals.length == 0;
    $scope.loading = false;
    if ($scope.savedPosition) {
      $scope.nearbyStations = Arrivals.closestTo($scope.savedPosition, $scope.arrivals);
    }
  });
  $scope.$on('apiError', function(event, resp) {
    if (resp.status == 0) {
      $scope.connectionProblem = new Date();
    } else {
      $scope.error = "code: " + resp.status + ", message: " + resp.statusText;
      $scope.connectionProblem = false;
    }
    $scope.loading = false;
    $scope.emptyResponse = false;
  });

  $scope.refreshArrivals = function() {
    Arrivals.refresh().finally(function() {
      $scope.$broadcast('scroll.refreshComplete');
    });
  };

  $scope.geowait = true;
  $ionicPlatform.ready(function() {
    window.navigator.geolocation.getCurrentPosition(function(position) {
      $scope.savedPosition = {
        latitude: position.coords.latitude,
        longitude: position.coords.longitude
      };
      var newJson = JSON.stringify($scope.savedPosition);
      var oldJson = localStorage.getItem('position2');
      if (newJson != oldJson) {
        localStorage.setItem('position2', newJson);
      }
      $scope.$apply(function() {
        $scope.nearbyStations = Arrivals.closestTo($scope.savedPosition, $scope.arrivals);
        $scope.geowait = false;
      });
    });
  });

  $scope.stationView = function(stationName) {
    $state.go("station", {stationName: stationName});
  };

  var dirOrder = ['n', 's', 'w', 'e'];
  $scope.byDirection = function(obj) {
    if (!obj) {
      return null;
    }
    var res = {};
    for (var i = 0; i < dirOrder.length; i++) {
      if (obj[dirOrder[i]]) {
        res[dirOrder[i]] = obj[dirOrder[i]];
      }
    }
    return res;
  };

  $scope.timeboxClass = function(arrival) {
    var ret = {
      scheduled: arrival.scheduled
    };
    ret[arrival.line + '-line'] = true;
    return ret;
  };

  $scope.isFavorite = function(stationName) {
    return MioFavs.all().indexOf(stationName) > -1;
  };
  $scope.toggleFavorite = function(stationName) {
    MioFavs.toggle(stationName);
    $ionicListDelegate.closeOptionButtons();
    $scope.favs = MioFavs.intersection($scope.arrivals);
  };

  $scope.timeDisplay = function(arrival) {
    var text = arrival.waiting_time;
    if (['arriving', 'arrived'].indexOf(text) >= 0) {
      return "";
    } else if (text == 'boarding') {
      return "";
    }

    // waiting_time should start with a number, and parse to int
    return ":" + (parseInt(arrival.waiting_time) || 0);
  };
})

.controller('StationCtrl', function($scope, $state, Arrivals) {
  var stationName;
  if ($state.params.stationName === '5 pnts') {
    stationName = "five points station";
  } else {
    stationName =  $state.params.stationName;
  }
  $scope.stationName = stationName;

  $scope.arrivals = Arrivals.by('station', stationName);
  Arrivals.subscribe('arrivalsChanged', $scope);
  $scope.$on('arrivalsChanged', function() {
    $scope.arrivals = Arrivals.by('station', stationName);
  });

  $scope.arrivalClass = function(arrival) {
    var ret = {
      scheduled: arrival.scheduled
    };
    ret[arrival.line + '-line'] = true;
    return ret;
  };

  $scope.trainView = function(trainId) {
    if (!trainId) return;
    $state.go("train", {trainId: trainId});
  };

  $scope.refreshArrivals = function() {
    Arrivals.refresh().finally(function() {
      $scope.$broadcast('scroll.refreshComplete');
    });
  };

})

.controller('TrainCtrl', function($scope, $state, Arrivals) {
  var trainId = $scope.trainId = $state.params.trainId;
  $scope.arrivals = Arrivals.by('train_id', trainId);
  Arrivals.subscribe('arrivalsChanged', $scope);
  $scope.$on('arrivalsChanged', function() {
    $scope.arrivals = Arrivals.by('train_id', trainId);
  });
  $scope.arrivalClass = function(arrival) {
    var ret = {
      scheduled: arrival.scheduled
    };
    ret[arrival.line + '-line'] = true;
    return ret;
  };

  $scope.refreshArrivals = function() {
    Arrivals.refresh().finally(function() {
      $scope.$broadcast('scroll.refreshComplete');
    });
  };

});
<|endoftext|>


<commit_before>import co from 'co';
import * as fspp from '../fs-promise-proxy';
import {
	getRenderedTemplate,
	makeDestPath,
	throwStringifiedError,
	getRelativeToBasePath
} from './_common-action-utils';

import actionInterfaceTest from './_common-action-interface-check';

const doAppend = function*(data, cfg, plop, fileData) {
	const stringToAppend = yield getRenderedTemplate(data, cfg, plop);
	// if the appended string should be unique (default),
	// remove any occurence of it (but only if pattern would match)
	if (cfg.unique !== false && new RegExp(cfg.pattern).test(fileData)) {
		// only remove after "pattern", so that we remove not too much accidentally
		const patternRegexString =
			cfg.pattern instanceof RegExp ? cfg.pattern.source : cfg.pattern;
		const duplicateRegex = new RegExp(
			'((' + patternRegexString + ')(\\s|.)*?)(' + stringToAppend + '\\s?)+',
			'g'
		);

		fileData = fileData.replace(
			duplicateRegex,
			'$1'
		);
	}
	const { separator = '\n' } = cfg;
	return fileData.replace(cfg.pattern, '$&' + separator + stringToAppend);
};

export default co.wrap(function*(data, cfg, plop) {
	const interfaceTestResult = actionInterfaceTest(cfg);
	if (interfaceTestResult !== true) {
		throw interfaceTestResult;
	}
	const fileDestPath = makeDestPath(data, cfg, plop);
	try {
		// check path
		const pathExists = yield fspp.fileExists(fileDestPath);
		if (!pathExists) {
			throw 'File does not exists';
		} else {
			let fileData = yield fspp.readFile(fileDestPath);
			fileData = yield doAppend(data, cfg, plop, fileData);
			yield fspp.writeFile(fileDestPath, fileData);
		}
		return getRelativeToBasePath(fileDestPath, plop);
	} catch (err) {
		throwStringifiedError(err);
	}
});
<commit_msg>remove log<commit_after>import co from 'co';
import * as fspp from '../fs-promise-proxy';

import {
	getRenderedTemplate,
	makeDestPath,
	throwStringifiedError,
	getRelativeToBasePath
} from './_common-action-utils';

import actionInterfaceTest from './_common-action-interface-check';

const doAppend = function*(data, cfg, plop, fileData) {
	const stringToAppend = yield getRenderedTemplate(data, cfg, plop);
	// if the appended string should be unique (default),
	// remove any occurence of it (but only if pattern would match)

	if (cfg.unique !== false && new RegExp(cfg.pattern).test(fileData)) {
		// only remove after "pattern", so that we remove not too much accidentally
		const parts = fileData.split(cfg.pattern);
		const lastPart = parts[parts.length - 1];
		const lastPartWithoutDuplicates = lastPart.replace(
			new RegExp(stringToAppend, 'g'),
			''
		);
		fileData = fileData.replace(lastPart, lastPartWithoutDuplicates);
	}

	const { separator = '\n' } = cfg;
	return fileData.replace(cfg.pattern, '$&' + separator + stringToAppend);
};

export default co.wrap(function*(data, cfg, plop) {
	const interfaceTestResult = actionInterfaceTest(cfg);
	if (interfaceTestResult !== true) {
		throw interfaceTestResult;
	}
	const fileDestPath = makeDestPath(data, cfg, plop);
	try {
		// check path
		const pathExists = yield fspp.fileExists(fileDestPath);
		if (!pathExists) {
			throw 'File does not exists';
		} else {
			let fileData = yield fspp.readFile(fileDestPath);
			fileData = yield doAppend(data, cfg, plop, fileData);
			yield fspp.writeFile(fileDestPath, fileData);
		}
		return getRelativeToBasePath(fileDestPath, plop);
	} catch (err) {
		throwStringifiedError(err);
	}
});
<|endoftext|>


<commit_before>var state_init = function(game) {
    return {
        preload: function() {
            game.stage.backgroundColor = colorPalette.light;

            constants.groundHeight = game.world.height - constants.runnerSize;

            var runnerPolygon = new Phaser.Polygon(
                new Phaser.Point(0, constants.groundHeight),
                new Phaser.Point(0, constants.groundHeight - constants.runnerSize),
                new Phaser.Point(constants.runnerSize, constants.groundHeight - constants.runnerSize),
                new Phaser.Point(constants.runnerSize, constants.groundHeight)
            );
            objects.runner = runner(runnerPolygon, colorPalette.runner, constants.groundHeight);
            objects.runner.moveToX(game.world.centerX - constants.runnerSize / 2);

            var ground = new Phaser.Polygon(
                new Phaser.Point(0, game.world.height),
                new Phaser.Point(0, game.world.height - constants.runnerSize),
                new Phaser.Point(game.world.width, game.world.height - constants.runnerSize),
                new Phaser.Point(game.world.width, game.world.height)
            );
            objects.ground = new ExtendedPolygon(ground, colorPalette.ground);

            objects.chargeBar = new ExtendedPolygon(new Phaser.Polygon(
              new Phaser.Point(0, 0),
              new Phaser.Point(0, constants.runnerSize / 2 ),
              new Phaser.Point(game.world.width, constants.runnerSize / 2),
              new Phaser.Point(game.world.width, 0)
            ), colorPalette.ground);
            objects.chargeBar.moveToX(-game.world.width);
            objects.chargeBar.update = function(percentY){
                var level = chargeLevel(percentY);
                this.color = constants.chargeColors[level];
                objects.chargeBar.moveToX(fromPercent(33.4 * level, game.world.width) -game.world.width);
            };

            var lowIsoscelesTriangle = {
                polygon: function() {
                    return new Phaser.Polygon(
                        new Phaser.Point(0, constants.groundHeight),
                        new Phaser.Point(constants.runnerSize / 4, constants.groundHeight),
                        new Phaser.Point(constants.runnerSize / 8, constants.groundHeight - constants.runnerSize / 4)
                    );
                },
                minimumSpaceBehind: 125,
                color: colorPalette.obstacleLow
            };

            var lowRectangle = {
                polygon: function() {
                    return new Phaser.Polygon(
                        new Phaser.Point(0, constants.groundHeight),
                        new Phaser.Point(0, constants.groundHeight - constants.runnerSize / 4),
                        new Phaser.Point(constants.runnerSize / 5, constants.groundHeight - constants.runnerSize / 4),
                        new Phaser.Point(constants.runnerSize / 5, constants.groundHeight)
                    );
                },
                minimumSpaceBehind: 130,
                color: colorPalette.obstacleLow
            };

            var mediumAcuteTriangle = {
                polygon: function() {
                    return new Phaser.Polygon(
                        new Phaser.Point(0, constants.groundHeight),
                        new Phaser.Point(constants.runnerSize, constants.groundHeight),
                        new Phaser.Point(constants.runnerSize, constants.groundHeight - constants.runnerSize * (2 / 3))
                    );
                },
                minimumSpaceBehind: 150,
                color: colorPalette.obstacleMedium
            };

            var mediumIsoscelesTriangle = {
                polygon: function() {
                    return new Phaser.Polygon(
                        new Phaser.Point(0, constants.groundHeight),
                        new Phaser.Point(constants.runnerSize, constants.groundHeight),
                        new Phaser.Point(constants.runnerSize / 2, constants.groundHeight - constants.runnerSize)
                    );
                },
                minimumSpaceBehind: 150,
                color: colorPalette.obstacleMedium
            };

            var bigSquareLikeRunner = {
                polygon: function() {
                    return new Phaser.Polygon(
                        new Phaser.Point(0, constants.groundHeight),
                        new Phaser.Point(0, constants.groundHeight - constants.runnerSize),
                        new Phaser.Point(constants.runnerSize, constants.groundHeight - constants.runnerSize),
                        new Phaser.Point(constants.runnerSize, constants.groundHeight)
                    );
                },
                minimumSpaceBehind: 200,
                color: colorPalette.obstacleBig
            };

            var bigWallRectangle = {
                polygon: function() {
                    return new Phaser.Polygon(
                        new Phaser.Point(0, constants.groundHeight),
                        new Phaser.Point(0, constants.groundHeight - constants.runnerSize * 2.5),
                        new Phaser.Point(constants.runnerSize / 2, constants.groundHeight - constants.runnerSize * 2.5),
                        new Phaser.Point(constants.runnerSize / 2, constants.groundHeight)
                    );
                },
                minimumSpaceBehind: 255,
                color: colorPalette.obstacleBig
            };

            objects.polygonPrototypes = [lowRectangle, lowIsoscelesTriangle, mediumAcuteTriangle, mediumIsoscelesTriangle, bigSquareLikeRunner, bigWallRectangle];
            objects.makeRandomObstacle = function() {
                var index = Math.floor(Math.random() * (this.polygonPrototypes.length));
                var prototype = this.polygonPrototypes[index];
                return new Obstacle(new ExtendedPolygon(prototype.polygon(), prototype.color), prototype.minimumSpaceBehind);
            };

        },

        create: function() {
            game.state.start('waiting');
        }
    };
};
<commit_msg>BALANCE - Adding more space behind the squares<commit_after>var state_init = function(game) {
    return {
        preload: function() {
            game.stage.backgroundColor = colorPalette.light;

            constants.groundHeight = game.world.height - constants.runnerSize;

            var runnerPolygon = new Phaser.Polygon(
                new Phaser.Point(0, constants.groundHeight),
                new Phaser.Point(0, constants.groundHeight - constants.runnerSize),
                new Phaser.Point(constants.runnerSize, constants.groundHeight - constants.runnerSize),
                new Phaser.Point(constants.runnerSize, constants.groundHeight)
            );
            objects.runner = runner(runnerPolygon, colorPalette.runner, constants.groundHeight);
            objects.runner.moveToX(game.world.centerX - constants.runnerSize / 2);

            var ground = new Phaser.Polygon(
                new Phaser.Point(0, game.world.height),
                new Phaser.Point(0, game.world.height - constants.runnerSize),
                new Phaser.Point(game.world.width, game.world.height - constants.runnerSize),
                new Phaser.Point(game.world.width, game.world.height)
            );
            objects.ground = new ExtendedPolygon(ground, colorPalette.ground);

            objects.chargeBar = new ExtendedPolygon(new Phaser.Polygon(
              new Phaser.Point(0, 0),
              new Phaser.Point(0, constants.runnerSize / 2 ),
              new Phaser.Point(game.world.width, constants.runnerSize / 2),
              new Phaser.Point(game.world.width, 0)
            ), colorPalette.ground);
            objects.chargeBar.moveToX(-game.world.width);
            objects.chargeBar.update = function(percentY){
                var level = chargeLevel(percentY);
                this.color = constants.chargeColors[level];
                objects.chargeBar.moveToX(fromPercent(33.4 * level, game.world.width) -game.world.width);
            };

            var lowIsoscelesTriangle = {
                polygon: function() {
                    return new Phaser.Polygon(
                        new Phaser.Point(0, constants.groundHeight),
                        new Phaser.Point(constants.runnerSize / 4, constants.groundHeight),
                        new Phaser.Point(constants.runnerSize / 8, constants.groundHeight - constants.runnerSize / 4)
                    );
                },
                minimumSpaceBehind: 125,
                color: colorPalette.obstacleLow
            };

            var lowRectangle = {
                polygon: function() {
                    return new Phaser.Polygon(
                        new Phaser.Point(0, constants.groundHeight),
                        new Phaser.Point(0, constants.groundHeight - constants.runnerSize / 4),
                        new Phaser.Point(constants.runnerSize / 5, constants.groundHeight - constants.runnerSize / 4),
                        new Phaser.Point(constants.runnerSize / 5, constants.groundHeight)
                    );
                },
                minimumSpaceBehind: 130,
                color: colorPalette.obstacleLow
            };

            var mediumAcuteTriangle = {
                polygon: function() {
                    return new Phaser.Polygon(
                        new Phaser.Point(0, constants.groundHeight),
                        new Phaser.Point(constants.runnerSize, constants.groundHeight),
                        new Phaser.Point(constants.runnerSize, constants.groundHeight - constants.runnerSize * (2 / 3))
                    );
                },
                minimumSpaceBehind: 150,
                color: colorPalette.obstacleMedium
            };

            var mediumIsoscelesTriangle = {
                polygon: function() {
                    return new Phaser.Polygon(
                        new Phaser.Point(0, constants.groundHeight),
                        new Phaser.Point(constants.runnerSize, constants.groundHeight),
                        new Phaser.Point(constants.runnerSize / 2, constants.groundHeight - constants.runnerSize)
                    );
                },
                minimumSpaceBehind: 150,
                color: colorPalette.obstacleMedium
            };

            var bigSquareLikeRunner = {
                polygon: function() {
                    return new Phaser.Polygon(
                        new Phaser.Point(0, constants.groundHeight),
                        new Phaser.Point(0, constants.groundHeight - constants.runnerSize),
                        new Phaser.Point(constants.runnerSize, constants.groundHeight - constants.runnerSize),
                        new Phaser.Point(constants.runnerSize, constants.groundHeight)
                    );
                },
                minimumSpaceBehind: 220,
                color: colorPalette.obstacleBig
            };

            var bigWallRectangle = {
                polygon: function() {
                    return new Phaser.Polygon(
                        new Phaser.Point(0, constants.groundHeight),
                        new Phaser.Point(0, constants.groundHeight - constants.runnerSize * 2.5),
                        new Phaser.Point(constants.runnerSize / 2, constants.groundHeight - constants.runnerSize * 2.5),
                        new Phaser.Point(constants.runnerSize / 2, constants.groundHeight)
                    );
                },
                minimumSpaceBehind: 255,
                color: colorPalette.obstacleBig
            };

            objects.polygonPrototypes = [lowRectangle, lowIsoscelesTriangle, mediumAcuteTriangle, mediumIsoscelesTriangle, bigSquareLikeRunner, bigWallRectangle];
            objects.makeRandomObstacle = function() {
                var index = Math.floor(Math.random() * (this.polygonPrototypes.length));
                var prototype = this.polygonPrototypes[index];
                return new Obstacle(new ExtendedPolygon(prototype.polygon(), prototype.color), prototype.minimumSpaceBehind);
            };

        },

        create: function() {
            game.state.start('waiting');
        }
    };
};
<|endoftext|>


<commit_before>'use strict';

var parentRequire = require('parent-require');

var fs = require('fs'),
    grunt = parentRequire('grunt'),
    indentString = require('indent-string'),
    mkdirp = require('mkdirp'),
    path = require('path'),
    util = require('../util');

module.exports = {
    configure: function (moduleDescriptor, config) {
        return {
            sources: {options: karmaOptions('sources', '../src', moduleDescriptor.main, false, moduleDescriptor, config)},
            distribution: {options: karmaOptions('distribution', '../dist', moduleDescriptor.basename, false, moduleDescriptor, config)},
            debugDistribution: {options: karmaOptions('debug-distribution', '../dist', moduleDescriptor.debugBasename, false, moduleDescriptor, config)},
            development: {options: karmaOptions('sources', '../src', moduleDescriptor.main, true, moduleDescriptor, config)}
        };
    }
};

function karmaOptions(version, location, karmaMain, interactive, moduleDescriptor, config) {
    var dependencies = moduleDescriptor.dependencies;
    config = config || {};

    var requirejs = config.requirejs || {};
    var paths = []
        .concat([]
            .concat(dependencies.external.map(function (d) {
                return util.singletonObject(d, '../bower_components/' + d + '/' + dependencies.metadata[d].main);
            }))
            .concat(dependencies.internal.map(function (d) {
                return util.singletonObject(d, '../bower_components/' + d + '/' + dependencies.metadata[d].internalMain);
            })).map(function (ps) {
                return util.mapProperties(ps, function (p) { return path.join(path.dirname(p), path.basename(p, '.js')); });
            }))
        .concat([requirejs.additionalPaths || {}])
        .reduce(util.mergeObjects);

    mkdirp.sync('build/karma-requirejs-config');
    fs.writeFileSync('build/karma-requirejs-config/config-' + version + '.js', [
        '\'use strict\';',
        '',
        'requirejs.config({',
        '  baseUrl: \'/base/test\',',
        '  shim: {',
        '    mocha: {',
        '      exports: \'mocha\'',
        '    }',
        '  },',
        '  packages: [{',
        '    name: \'' + moduleDescriptor.name + '\',',
        '    location: \'' + location + '\',',
        '    main: \'' + karmaMain + '\'',
        '  }],',
        '  paths: ' + indentString(JSON.stringify(paths, null, '  '), '  '),
        '});',
        ''
    ].join('\n'));

    var reportsDirectory = grunt.option('reports-directory') || 'build/reports';
    var additionalFiles = config.additionalFiles || [];

    return {
        frameworks: ['mocha', 'requirejs',  'chai', 'chai-as-promised'],
        files: additionalFiles.concat([
            'build/karma-requirejs-config/config-' + version + '.js',
            'test/main.test.js',
            {pattern: 'src/**/*.js', included: false},
            {pattern: 'build/es5src/**/*.js', included: false},
            {pattern: 'test/**/*.js', included: false},
            {pattern: 'dist/*.js', included: false}
        ]).concat(dependencies.external.map(function (d) {
            return {pattern: 'bower_components/' + d + '/' + dependencies.metadata[d].main, included: false}
        })).concat(dependencies.internal.map(function (d) {
            return {pattern: 'bower_components/' + d + '/' + dependencies.metadata[d].internalMain, included: false}
        })),
        preprocessors: {
            'src/**/*.js': interactive ? [] : ['coverage'],
            'test/**/*.js': version === 'sources' ? [] : ['babel'],
            'dist/**/*.js': interactive ? [] : ['coverage']
        },
        reporters: interactive ? ['dots'] : ['html', 'coverage', 'progress'],
        // TODO add phantomjs when it's at v2, add slimerjs at convenience..
        browsers: interactive || version === 'sources' ? ['Firefox'] : ['Chrome', 'Firefox'],
        singleRun: !interactive,
        babelPreprocessor: {
            options: {sourceMap: 'inline'}
        },
        htmlReporter: {
            outputDir: path.join(reportsDirectory, 'test-results', version),
            templatePath: 'node_modules/karma-html-reporter/jasmine_template.html'
        },
        coverageReporter: {
            dir: path.join(reportsDirectory, 'coverage', version),
            type: 'html'
        }
    };
}
<commit_msg>Firefox only on Travis CI.<commit_after>'use strict';

var parentRequire = require('parent-require');

var fs = require('fs'),
    grunt = parentRequire('grunt'),
    indentString = require('indent-string'),
    mkdirp = require('mkdirp'),
    path = require('path'),
    util = require('../util');

module.exports = {
    configure: function (moduleDescriptor, config) {
        return {
            sources: {options: karmaOptions('sources', '../src', moduleDescriptor.main, false, moduleDescriptor, config)},
            distribution: {options: karmaOptions('distribution', '../dist', moduleDescriptor.basename, false, moduleDescriptor, config)},
            debugDistribution: {options: karmaOptions('debug-distribution', '../dist', moduleDescriptor.debugBasename, false, moduleDescriptor, config)},
            development: {options: karmaOptions('sources', '../src', moduleDescriptor.main, true, moduleDescriptor, config)}
        };
    }
};

function karmaOptions(version, location, karmaMain, interactive, moduleDescriptor, config) {
    var dependencies = moduleDescriptor.dependencies;
    config = config || {};

    var requirejs = config.requirejs || {};
    var paths = []
        .concat([]
            .concat(dependencies.external.map(function (d) {
                return util.singletonObject(d, '../bower_components/' + d + '/' + dependencies.metadata[d].main);
            }))
            .concat(dependencies.internal.map(function (d) {
                return util.singletonObject(d, '../bower_components/' + d + '/' + dependencies.metadata[d].internalMain);
            })).map(function (ps) {
                return util.mapProperties(ps, function (p) { return path.join(path.dirname(p), path.basename(p, '.js')); });
            }))
        .concat([requirejs.additionalPaths || {}])
        .reduce(util.mergeObjects);

    mkdirp.sync('build/karma-requirejs-config');
    fs.writeFileSync('build/karma-requirejs-config/config-' + version + '.js', [
        '\'use strict\';',
        '',
        'requirejs.config({',
        '  baseUrl: \'/base/test\',',
        '  shim: {',
        '    mocha: {',
        '      exports: \'mocha\'',
        '    }',
        '  },',
        '  packages: [{',
        '    name: \'' + moduleDescriptor.name + '\',',
        '    location: \'' + location + '\',',
        '    main: \'' + karmaMain + '\'',
        '  }],',
        '  paths: ' + indentString(JSON.stringify(paths, null, '  '), '  '),
        '});',
        ''
    ].join('\n'));

    var reportsDirectory = grunt.option('reports-directory') || 'build/reports';
    var additionalFiles = config.additionalFiles || [];

    return {
        frameworks: ['mocha', 'requirejs', 'chai', 'chai-as-promised'],
        files: additionalFiles.concat([
            'build/karma-requirejs-config/config-' + version + '.js',
            'test/main.test.js',
            {pattern: 'src/**/*.js', included: false},
            {pattern: 'build/es5src/**/*.js', included: false},
            {pattern: 'test/**/*.js', included: false},
            {pattern: 'dist/*.js', included: false}
        ]).concat(dependencies.external.map(function (d) {
            return {pattern: 'bower_components/' + d + '/' + dependencies.metadata[d].main, included: false}
        })).concat(dependencies.internal.map(function (d) {
            return {pattern: 'bower_components/' + d + '/' + dependencies.metadata[d].internalMain, included: false}
        })),
        preprocessors: {
            'src/**/*.js': interactive ? [] : ['coverage'],
            'test/**/*.js': version === 'sources' ? [] : ['babel'],
            'dist/**/*.js': interactive ? [] : ['coverage']
        },
        reporters: interactive ? ['dots'] : ['html', 'coverage', 'progress'],
        // TODO add phantomjs when it's at v2, add slimerjs at convenience..
        browsers: interactive || version === 'sources' || process.env.TRAVIS ? ['Firefox'] : ['Chrome', 'Firefox'],
        singleRun: !interactive,
        babelPreprocessor: {
            options: {sourceMap: 'inline'}
        },
        htmlReporter: {
            outputDir: path.join(reportsDirectory, 'test-results', version),
            templatePath: 'node_modules/karma-html-reporter/jasmine_template.html'
        },
        coverageReporter: {
            dir: path.join(reportsDirectory, 'coverage', version),
            type: 'html'
        }
    };
}
<|endoftext|>


<commit_before>/**
 * Fit terminal columns and rows to the dimensions of its DOM element.
 *
 * ## Approach
 * - Rows: Truncate the division of the terminal parent element height by the terminal row height.
 *
 * - Columns: Truncate the division of the terminal parent element width by the terminal character
 * width (apply display: inline at the terminal row and truncate its width with the current
 * number of columns).
 * @module xterm/addons/fit/fit
 * @license MIT
 */

(function (fit) {
  if (typeof exports === 'object' && typeof module === 'object') {
    /*
     * CommonJS environment
     */
    module.exports = fit(require('../../xterm'));
  } else if (typeof define == 'function') {
    /*
     * Require.js is available
     */
    define(['../../xterm'], fit);
  } else {
    /*
     * Plain browser environment
     */
    fit(window.Terminal);
  }
})(function (Xterm) {
  var exports = {};

  exports.proposeGeometry = function (term) {
    var parentElementStyle = window.getComputedStyle(term.element.parentElement),
        parentElementHeight = parseInt(parentElementStyle.getPropertyValue('height')),
        parentElementWidth = parseInt(parentElementStyle.getPropertyValue('width')),
        elementStyle = window.getComputedStyle(term.element),
        elementPaddingVer = parseInt(elementStyle.getPropertyValue('padding-top')) + parseInt(elementStyle.getPropertyValue('padding-bottom')),
        elementPaddingHor = parseInt(elementStyle.getPropertyValue('padding-right')) + parseInt(elementStyle.getPropertyValue('padding-left')),
        availableHeight = parentElementHeight - elementPaddingVer,
        availableWidth = parentElementWidth - elementPaddingHor,
        container = term.rowContainer,
        subjectRow = term.rowContainer.firstElementChild,
        contentBuffer = subjectRow.innerHTML,
        characterHeight,
        rows,
        characterWidth,
        cols,
        geometry;

    subjectRow.style.display = 'inline';
    subjectRow.innerHTML = 'W'; // Common character for measuring width, although on monospace
    characterWidth = subjectRow.getBoundingClientRect().width;
    subjectRow.style.display = ''; // Revert style before calculating height, since they differ.
    characterHeight = parseInt(subjectRow.offsetHeight);
    subjectRow.innerHTML = contentBuffer;

    rows = parseInt(availableHeight / characterHeight);
    cols = parseInt(availableWidth / characterWidth) - 1;

    geometry = {cols: cols, rows: rows};
    return geometry;
  };

  exports.fit = function (term) {
    var geometry = exports.proposeGeometry(term);

    term.resize(geometry.cols, geometry.rows);
  };

  Xterm.prototype.proposeGeometry = function () {
    return exports.proposeGeometry(this);
  };

  Xterm.prototype.fit = function () {
    return exports.fit(this);
  };

  return exports;
});
<commit_msg>Use a fixed size to account for the scrollbar<commit_after>/**
 * Fit terminal columns and rows to the dimensions of its DOM element.
 *
 * ## Approach
 * - Rows: Truncate the division of the terminal parent element height by the terminal row height.
 *
 * - Columns: Truncate the division of the terminal parent element width by the terminal character
 * width (apply display: inline at the terminal row and truncate its width with the current
 * number of columns).
 * @module xterm/addons/fit/fit
 * @license MIT
 */

(function (fit) {
  if (typeof exports === 'object' && typeof module === 'object') {
    /*
     * CommonJS environment
     */
    module.exports = fit(require('../../xterm'));
  } else if (typeof define == 'function') {
    /*
     * Require.js is available
     */
    define(['../../xterm'], fit);
  } else {
    /*
     * Plain browser environment
     */
    fit(window.Terminal);
  }
})(function (Xterm) {
  var exports = {};

  exports.proposeGeometry = function (term) {
    var parentElementStyle = window.getComputedStyle(term.element.parentElement),
        parentElementHeight = parseInt(parentElementStyle.getPropertyValue('height')),
        parentElementWidth = Math.max(0, parseInt(parentElementStyle.getPropertyValue('width')) - 17),
        elementStyle = window.getComputedStyle(term.element),
        elementPaddingVer = parseInt(elementStyle.getPropertyValue('padding-top')) + parseInt(elementStyle.getPropertyValue('padding-bottom')),
        elementPaddingHor = parseInt(elementStyle.getPropertyValue('padding-right')) + parseInt(elementStyle.getPropertyValue('padding-left')),
        availableHeight = parentElementHeight - elementPaddingVer,
        availableWidth = parentElementWidth - elementPaddingHor,
        container = term.rowContainer,
        subjectRow = term.rowContainer.firstElementChild,
        contentBuffer = subjectRow.innerHTML,
        characterHeight,
        rows,
        characterWidth,
        cols,
        geometry;

    subjectRow.style.display = 'inline';
    subjectRow.innerHTML = 'W'; // Common character for measuring width, although on monospace
    characterWidth = subjectRow.getBoundingClientRect().width;
    subjectRow.style.display = ''; // Revert style before calculating height, since they differ.
    characterHeight = parseInt(subjectRow.offsetHeight);
    subjectRow.innerHTML = contentBuffer;

    rows = parseInt(availableHeight / characterHeight);
    cols = parseInt(availableWidth / characterWidth);

    geometry = {cols: cols, rows: rows};
    return geometry;
  };

  exports.fit = function (term) {
    var geometry = exports.proposeGeometry(term);

    term.resize(geometry.cols, geometry.rows);
  };

  Xterm.prototype.proposeGeometry = function () {
    return exports.proposeGeometry(this);
  };

  Xterm.prototype.fit = function () {
    return exports.fit(this);
  };

  return exports;
});
<|endoftext|>


<commit_before>'use strict';

var _            = require('underscore');
var Q            = require('q');
var http         = require('http');
var HttpError    = require('./error');
var Extendable   = require('../lib/extendable');

var HttpGateway = Extendable.extend({

    getConfig : function() {
        if (this.config) {
            return this.config;
        }

        throw 'You must extend getConfig or set this.config with a hostname and port';
    },

    _getRequestOptions : function(method, path)
    {
        var config = this.getConfig();

        return {
            hostname : config.hostname,
            port     : config.port,
            method   : method,
            path     : path,
            headers  : {
                'Accept'       : 'application/json',
                'Content-Type' : 'application/json'
            }
        };
    },

    apiRequest : function(method, path, data)
    {
        return Q.Promise(_.bind(function(resolve, reject) {
            var options  = this._getRequestOptions(method, path);

            var req = http.request(options, function(response) {
                var responseText = '';

                response.on('data', function(chunk) {
                    responseText += chunk;
                });

                response.on('end', function() {
                    var responseData;

                    try {
                        responseData = JSON.parse(responseText);
                    } catch (e) {
                        responseData = responseText;
                    }

                    if (response.statusCode >= 400) {
                        reject(new HttpError(responseData, response));
                    } else {
                        resolve(responseData);
                    }
                });
            });

            req.on('error', function(e) {
                reject(e);
            });

            if (data) {
                req.write(JSON.stringify(data));
            }

            req.end();
        }, this));
    }

});

module.exports = HttpGateway;
<commit_msg>do not JSON.stringify data in http gateway<commit_after>'use strict';

var _            = require('underscore');
var Q            = require('q');
var http         = require('http');
var HttpError    = require('./error');
var Extendable   = require('../lib/extendable');

var HttpGateway = Extendable.extend({

    getConfig : function() {
        if (this.config) {
            return this.config;
        }

        throw 'You must extend getConfig or set this.config with a hostname and port';
    },

    _getRequestOptions : function(method, path)
    {
        var config = this.getConfig();

        return {
            hostname : config.hostname,
            port     : config.port,
            method   : method,
            path     : path,
            headers  : {
                'Accept'       : 'application/json',
                'Content-Type' : 'application/json'
            }
        };
    },

    apiRequest : function(method, path, data)
    {
        return Q.Promise(_.bind(function(resolve, reject) {
            var options  = this._getRequestOptions(method, path);

            var req = http.request(options, function(response) {
                var responseText = '';

                response.on('data', function(chunk) {
                    responseText += chunk;
                });

                response.on('end', function() {
                    var responseData;

                    try {
                        responseData = JSON.parse(responseText);
                    } catch (e) {
                        responseData = responseText;
                    }

                    if (response.statusCode >= 400) {
                        reject(new HttpError(responseData, response));
                    } else {
                        resolve(responseData);
                    }
                });
            });

            req.on('error', function(e) {
                reject(e);
            });

            if (data) {
                req.write(data);
            }

            req.end();
        }, this));
    }

});

module.exports = HttpGateway;
<|endoftext|>