<commit_before>    //  Lux Page
    //  ==============
    //
    //  Design to work with the ``lux.extension.angular``
    angular.module('lux.page', ['lux.form', 'lux.scroll', 'templates-page'])
        //
        .service('pageService', ['$lux', 'dateFilter', function ($lux, dateFilter) {

            this.addInfo = function (page, $scope) {
                if (!page)
                    return $lux.log.error('No page, cannot add page information');
                if (page.head && page.head.title) {
                    document.title = page.head.title;
                }
                if (page.author) {
                    if (page.author instanceof Array)
                        page.authors = page.author.join(', ');
                    else
                        page.authors = page.author;
                }
                var date;
                if (page.date) {
                    try {
                        date = new Date(page.date);
                    } catch (e) {
                        $lux.log.error('Could not parse date');
                    }
                    page.date = date;
                    page.dateText = dateFilter(date, $scope.dateFormat);
                }
                page.toString = function () {
                    return this.name || this.url || '<noname>';
                };

                return page;
            };

            this.formatDate = function (dt, format) {
                if (!dt)
                    dt = new Date();
                return dateFilter(dt, format || 'yyyy-MM-ddTHH:mm:ss');
            };
        }])
        //
        .controller('Page', ['$scope', '$log', '$lux', 'pageService', function ($scope, log, $lux, pageService) {
            //
            $lux.log.info('Setting up angular page');
            //
            var page = $scope.page;
            // If the page is a string, retrieve it from the pages object
            if (typeof page === 'string')
                page = $scope.pages ? $scope.pages[page] : null;
            $scope.page = pageService.addInfo(page, $scope);
            //
            $scope.togglePage = function ($event) {
                $event.preventDefault();
                $event.stopPropagation();
                this.link.active = !this.link.active;
            };

            $scope.loadPage = function ($event) {
                $scope.page = this.link;
            };

            $scope.activeLink = function (url) {
                var loc;
                if (isAbsolute.test(url))
                    loc = $lux.location.absUrl();
                else
                    loc = window.location.pathname;
                var rest = loc.substring(url.length),
                    base = loc.substring(0, url.length),
                    folder = url.substring(url.length-1) === '/';
                return base === url && (folder || (rest === '' || rest.substring(0, 1) === '/'));
            };

            //
            $scope.$on('animIn', function() {
                log.info('Page ' + page.toString() + ' animation in');
            });
            $scope.$on('animOut', function() {
                log.info('Page ' + page.toString() + ' animation out');
            });
        }])

        .service('$breadcrumbs', [function () {

            this.crumbs = function () {
                var loc = window.location,
                    path = loc.pathname,
                    steps = [],
                    last = {
                        href: loc.origin
                    };
                if (last.href.length >= lux.context.url.length)
                    steps.push(last);

                path.split('/').forEach(function (name) {
                    if (name) {
                        last = {
                            label: name.split('-').map(capitalize).join(' '),
                            href: joinUrl(last.href, name+'/')
                        };
                        if (last.href.length >= lux.context.url.length)
                            steps.push(last);
                    }
                });
                if (steps.length) {
                    last = steps[steps.length-1];
                    if (path.substring(path.length-1) !== '/' && last.href.substring(last.href.length-1) === '/')
                        last.href = last.href.substring(0, last.href.length-1);
                    last.last = true;
                    steps[0].label = 'Home';
                }
                return steps;
            };
        }])
        //
        //  Directive for displaying breadcrumbs navigation
        .directive('breadcrumbs', ['$breadcrumbs', '$rootScope', function ($breadcrumbs, $rootScope) {
            return {
                restrict: 'AE',
                replace: true,
                templateUrl: "page/breadcrumbs.tpl.html",
                link: {
                    post: function (scope) {
                        var renderBreadcrumb = function() {
                            scope.steps = $breadcrumbs.crumbs();
                        };

                        $rootScope.$on('$viewContentLoaded', function () {
                            renderBreadcrumb();
                        });

                        renderBreadcrumb();
                    }
                }
            };
        }])
        //
        //  Simply display the current yeat
        .directive('year', function () {
            return {
                restrict: 'AE',
                link: function (scope, element) {
                    var dt = new Date();
                    element.html(dt.getFullYear()+'');
                }
            };
        });
<commit_msg>don't append trailing slash to links in breadcrumb directive<commit_after>    //  Lux Page
    //  ==============
    //
    //  Design to work with the ``lux.extension.angular``
    angular.module('lux.page', ['lux.form', 'lux.scroll', 'templates-page'])
        //
        .service('pageService', ['$lux', 'dateFilter', function ($lux, dateFilter) {

            this.addInfo = function (page, $scope) {
                if (!page)
                    return $lux.log.error('No page, cannot add page information');
                if (page.head && page.head.title) {
                    document.title = page.head.title;
                }
                if (page.author) {
                    if (page.author instanceof Array)
                        page.authors = page.author.join(', ');
                    else
                        page.authors = page.author;
                }
                var date;
                if (page.date) {
                    try {
                        date = new Date(page.date);
                    } catch (e) {
                        $lux.log.error('Could not parse date');
                    }
                    page.date = date;
                    page.dateText = dateFilter(date, $scope.dateFormat);
                }
                page.toString = function () {
                    return this.name || this.url || '<noname>';
                };

                return page;
            };

            this.formatDate = function (dt, format) {
                if (!dt)
                    dt = new Date();
                return dateFilter(dt, format || 'yyyy-MM-ddTHH:mm:ss');
            };
        }])
        //
        .controller('Page', ['$scope', '$log', '$lux', 'pageService', function ($scope, log, $lux, pageService) {
            //
            $lux.log.info('Setting up angular page');
            //
            var page = $scope.page;
            // If the page is a string, retrieve it from the pages object
            if (typeof page === 'string')
                page = $scope.pages ? $scope.pages[page] : null;
            $scope.page = pageService.addInfo(page, $scope);
            //
            $scope.togglePage = function ($event) {
                $event.preventDefault();
                $event.stopPropagation();
                this.link.active = !this.link.active;
            };

            $scope.loadPage = function ($event) {
                $scope.page = this.link;
            };

            $scope.activeLink = function (url) {
                var loc;
                if (isAbsolute.test(url))
                    loc = $lux.location.absUrl();
                else
                    loc = window.location.pathname;
                var rest = loc.substring(url.length),
                    base = loc.substring(0, url.length),
                    folder = url.substring(url.length-1) === '/';
                return base === url && (folder || (rest === '' || rest.substring(0, 1) === '/'));
            };

            //
            $scope.$on('animIn', function() {
                log.info('Page ' + page.toString() + ' animation in');
            });
            $scope.$on('animOut', function() {
                log.info('Page ' + page.toString() + ' animation out');
            });
        }])

        .service('$breadcrumbs', [function () {

            this.crumbs = function () {
                var loc = window.location,
                    path = loc.pathname,
                    steps = [],
                    last = {
                        href: loc.origin
                    };
                if (last.href.length >= lux.context.url.length)
                    steps.push(last);

                path.split('/').forEach(function (name) {
                    if (name) {
                        last = {
                            label: name.split('-').map(capitalize).join(' '),
                            href: joinUrl(last.href, name)
                        };
                        if (last.href.length >= lux.context.url.length)
                            steps.push(last);
                    }
                });
                if (steps.length) {
                    last = steps[steps.length-1];
                    if (path.substring(path.length-1) !== '/' && last.href.substring(last.href.length-1) === '/')
                        last.href = last.href.substring(0, last.href.length-1);
                    last.last = true;
                    steps[0].label = 'Home';
                }
                return steps;
            };
        }])
        //
        //  Directive for displaying breadcrumbs navigation
        .directive('breadcrumbs', ['$breadcrumbs', '$rootScope', function ($breadcrumbs, $rootScope) {
            return {
                restrict: 'AE',
                replace: true,
                templateUrl: "page/breadcrumbs.tpl.html",
                link: {
                    post: function (scope) {
                        var renderBreadcrumb = function() {
                            scope.steps = $breadcrumbs.crumbs();
                        };

                        $rootScope.$on('$viewContentLoaded', function () {
                            renderBreadcrumb();
                        });

                        renderBreadcrumb();
                    }
                }
            };
        }])
        //
        //  Simply display the current yeat
        .directive('year', function () {
            return {
                restrict: 'AE',
                link: function (scope, element) {
                    var dt = new Date();
                    element.html(dt.getFullYear()+'');
                }
            };
        });
<|endoftext|>


<commit_before>$(window).bind('hashchange', function(){
  getHash()
})

$(document).ready(function(){
  initSeed()
  getHash()
})

function getHash(){
  var hash = window.location.hash.substring(1);
  if(hash.length > 0){
    console.log("New Hash: "+hash)
    download(hash);
  }
}

function initTorrent(torrent){
  var holder = document.getElementsByClassName('holder')[0];
  torrent.on('done', function(){
    console.log('torrent finished downloading');
    holder.style.background = ""
  })

  torrent.on('wire', function (wire) {
    console.log('new peer');
    updatePeer(torrent.numPeers)
  })
}

function download(hash){
  cleanBody()
  var client = new WebTorrent()
  client.download({
    infoHash: hash,
    announce: ["wss://tracker.btorrent.xyz",
    "wss://tracker.fastcast.nz",
    "wss://tracker.openwebtorrent.com",
    "wss://tracker.webtorrent.io"]
  }, onTorrentDownload)
}

function onTorrentDownload(torrent){
  var holder = document.getElementsByClassName('holder')[0];
  holder.style.background =  'no-repeat center url("src/css/dashinfinity.gif")';
  console.log("Downloadind "+torrent.name)

  initTorrent(torrent)

  appendHolder(torrent)
}

function cleanBody(){
  $('.download').html('')
}

function initSeed(){
  var holder = document.getElementsByClassName('holder')[0];
  var state = document.getElementsByClassName('status')[0];

  if (typeof window.FileReader === 'undefined') {
    state.id = 'fail';
    state.innerHTML = 'Instant Share indisponible';
  } else {
    state.id = 'success';
    state.innerHTML = 'Instant Share disponible';
  }

  holder.ondragover = function () { this.id = 'hover'; return false; };
  holder.ondragend = function () { this.id = ''; return false; };
  holder.ondrop = function (e) {
    this.id = '';
    e.preventDefault();

    var file = e.dataTransfer.files[0]

    console.log(file);
    var client = new WebTorrent()
    client.seed(file,onTorrentSeed);
  };
}

function onTorrentSeed(torrent){
  window.location.hash = "#"+torrent.infoHash
  var holder = document.getElementsByClassName('holder')[0];
  console.log("Seeding "+torrent.name)
  console.log("Hash: "+torrent.infoHash)

  initTorrent(torrent)

  appendHolder(torrent)

  prompt('Partager le lien:',document.location.hostname+"/#"+torrent.infoHash)
}

function showInputUrl(url){
  document.getElementsByClassName('url-input')[0].value = url;
  document.getElementsByClassName('url-input')[0].hidden = false
}

function showDownloadButton(fileName, url){
  var but = document.getElementsByClassName('download-url')[0]
  but.innerHTML = "Télécharger "+fileName
  but.href = url
  but.download = fileName
}

function appendHolder(torrent){
  var holder = document.getElementsByClassName('holder')[0];
  holder.innerHTML = ""
  torrent.files.forEach(function(file){
    file.getBlobURL(function (err, url) {
      holder.onclick = function(){ window.open(url,'_blank')}
      showDownloadButton(file.name, url)
      showInputUrl(document.location.hostname+"/#"+torrent.infoHash)
      file.appendTo(holder)
    })
  })
}

function updatePeer(peerNum){
  var peer = document.getElementsByClassName('peer')[0]
  peer.innerHTML = "Peers: "+peerNum;
}
<commit_msg>add doc<commit_after>// Get Hash on hashchange
$(window).bind('hashchange', function(){
  getHash()
})

// Get Hash on loading page
$(document).ready(function(){
  initSeed()
  getHash()
})

// Get the hash and start torrent if there is an hash
function getHash(){
  var hash = window.location.hash.substring(1);
  if(hash.length > 0){
    console.log("New Hash: "+hash)
    download(hash);
  }
}

// Initialise event on torrent
function initTorrent(torrent){
  var holder = document.getElementsByClassName('holder')[0];
  torrent.on('done', function(){
    console.log('torrent finished downloading');
    holder.style.background = ""
  })

  torrent.on('wire', function (wire) {
    console.log('new peer');
    updatePeer(torrent.numPeers)
  })
}

// Download a torrent
function download(hash){
  cleanBody()
  var client = new WebTorrent()
  client.download({
    infoHash: hash,
    announce: ["wss://tracker.btorrent.xyz",
    "wss://tracker.fastcast.nz",
    "wss://tracker.openwebtorrent.com",
    "wss://tracker.webtorrent.io"]
  }, onTorrentDownload)
}

// Callback on torrent finish
function onTorrentDownload(torrent){
  var holder = document.getElementsByClassName('holder')[0];
  holder.style.background =  'no-repeat center url("src/css/dashinfinity.gif")';
  console.log("Downloadind "+torrent.name)

  initTorrent(torrent)

  appendHolder(torrent)
}

//Clean holder body
function cleanBody(){
  $('.holder').html('')
}

// Initialise seed torrent
function initSeed(){
  var holder = document.getElementsByClassName('holder')[0];
  var state = document.getElementsByClassName('status')[0];

  if (typeof window.FileReader === 'undefined') {
    state.id = 'fail';
    state.innerHTML = 'Instant Share indisponible';
  } else {
    state.id = 'success';
    state.innerHTML = 'Instant Share disponible';
  }

  holder.ondragover = function () { this.id = 'hover'; return false; };
  holder.ondragend = function () { this.id = ''; return false; };
  holder.ondrop = function (e) {
    this.id = '';
    e.preventDefault();

    var file = e.dataTransfer.files[0]

    console.log(file);
    var client = new WebTorrent()
    client.seed(file,onTorrentSeed);
  };
}

// Callback function when torrent is seeding
function onTorrentSeed(torrent){
  window.location.hash = "#"+torrent.infoHash
  var holder = document.getElementsByClassName('holder')[0];
  console.log("Seeding "+torrent.name)
  console.log("Hash: "+torrent.infoHash)

  initTorrent(torrent)

  appendHolder(torrent)

  prompt('Partager le lien:',document.location.hostname+"/#"+torrent.infoHash)
}

// Show the input with the current url
function showInputUrl(url){
  document.getElementsByClassName('url-input')[0].value = url;
  document.getElementsByClassName('url-input')[0].hidden = false
}

// Show the download button for downloading the file
function showDownloadButton(fileName, url){
  var but = document.getElementsByClassName('download-url')[0]
  but.innerHTML = "Télécharger "+fileName
  but.href = url
  but.download = fileName
}

// append a torrent to the holder
function appendHolder(torrent){
  var holder = document.getElementsByClassName('holder')[0];
  holder.innerHTML = ""
  torrent.files.forEach(function(file){
    file.getBlobURL(function (err, url) {
      holder.onclick = function(){ window.open(url,'_blank')}
      showDownloadButton(file.name, url)
      showInputUrl(document.location.hostname+"/#"+torrent.infoHash)
      file.appendTo(holder)
    })
  })
}

// Update value of peer
function updatePeer(peerNum){
  var peer = document.getElementsByClassName('peer')[0]
  peer.innerHTML = "Peers: "+peerNum;
}
<|endoftext|>


<commit_before>define([
    'underscore', 'backbone', 'jquery', 'd3', 'js/models', 'js/views', 'js/data',
    'js/utils'
],
function(_, Backbone, $, d3, Models, Views, Data, utils) {
    "use strict";

    var App = function() {
        this._currentPomodoro = null;
        this.finishedPomodoros = new Models.PomodoroCollection();
        this.dynamicTitleCb = $('#dynamicTitleCb');

        _.extend(this, Backbone.Events);
        _.bindAll(this,
            'onPomodoroFinished', 'onPomodoroCompleted', 'toggleTitle');
    };

    App.prototype.initializeViews = function() {
        this.timerView = new Views.TimerView({el: '#timer'});
        this.timerView._renderTitle = this.dynamicTitleCb.prop('checked');
        this.controlView = new Views.ControlView({el: '#control-bar'});
        this.configurationView = new Views.ConfigurationView({el: '#configuration-form'});

        var weekDataProvider = new Data.Provider(
            this.finishedPomodoros,
            d3.time.day,
            d3.time.day.offset(new Date(), -7),
            d3.time.day(new Date())
        );
        this.weekChartView = new Views.ChartView({
            el: '#weekChart',
            collection: this.finishedPomodoros,
            interval: d3.time.day,
            dateFormat: "%a %b %e",
            dataProvider: weekDataProvider,
        });

        var monthDataProvider = new Data.Provider(
            this.finishedPomodoros,
            d3.time.monday,
            d3.time.week.offset(d3.time.week(new Date()), -10),
            d3.time.week(new Date())
        );
        this.monthChartView = new Views.ChartView({
            el: '#monthChart',
            collection: this.finishedPomodoros,
            interval: d3.time.monday,
            dateFormat: "Week %W, %b",
            dataProvider: monthDataProvider,
        });
    };

    /**
     * Manually starts a pomodoro.
     *
     * Creates the pomodoro object, and run the countdown timer.
     */
    App.prototype.startPomodoro = function(options) {
        // If a pomodoro is already running, do nothing
        if (this._currentPomodoro) {
            return;
        }

        var duration = options.duration;
        var type = options.type;
        this._currentPomodoro= new Models.Pomodoro({
            duration: duration,
            type: type
        });
        this._currentPomodoro.start();

        this.timerView.startRunning(this._currentPomodoro);
        this.controlView.renderForPomodoro(this._currentPomodoro);

        this.listenTo(this._currentPomodoro, 'pomodoroCompleted', this.onPomodoroCompleted);
        this.listenTo(this._currentPomodoro, 'pomodoroFinished', this.onPomodoroFinished);

        this.saveState();
    };

    /**
     * Manually interrupts the pomodoro.
     *
     * Don't perform any other operations, because all the cleanup code
     * will be called when the pomodoro finished event will be raised.
     *
     */
    App.prototype.interruptPomodoro = function() {
        this._currentPomodoro.interrupt();
    };

    /**
     * Perferm all operations required when a pomodoro is completed
     * (not interrupted).
     */
    App.prototype.onPomodoroCompleted = function() {
        this.notifyUser();
        if (this._currentPomodoro.get('type') === 'pomodoro') {
            this.finishedPomodoros.add(this._currentPomodoro);
            this._currentPomodoro.save();
        }
    };

    /**
     * Perform all operations required when a pomodoro is finished,
     * whether it was manually interrupted or not.
     *
     */
    App.prototype.onPomodoroFinished = function() {
        this.timerView.stopRunning(this._currentPomodoro);
        this.controlView.resetView();
        this.stopListening(this._currentPomodoro);
        this._currentPomodoro = null;

        this.saveState();
    };

    /**
     * Notify user of the end of pomodoro.
     */
    App.prototype.notifyUser = function() {
        var audioElt = document.getElementById('audioAlert');
        if (audioElt) {
            audioElt.play();
        }

        if (this._currentPomodoro.get('type') === 'pomodoro') {
            utils.notify('The pomodoro is over', {body: 'Go easy on the coffee.'});
        } else {
            utils.notify('Let\'s get back to work', {body: 'Focus now!'});
        }
    };

    App.prototype.bindEvents = function() {
        this.listenTo(this.controlView, 'timerStarted', this.startPomodoro);
        this.listenTo(this.controlView, 'timerInterrupted', this.interruptPomodoro);

        this.dynamicTitleCb.on('click', this.toggleTitle);
    };

    App.prototype.toggleTitle = function(event) {
        this.timerView._renderTitle = this.dynamicTitleCb.prop('checked');
    };

    /**
     * Save current state in localstorage
     */
    App.prototype.saveState = function() {
        if (!this._currentPomodoro) {
            localStorage.removeItem('pomodoroData');
        } else {
            var data = this._currentPomodoro.toJSON();
            localStorage.setItem('pomodoroData', JSON.stringify(data));
        }
    };

    /**
     * Restore app state if data is present in localstorage.
     *
     * If we detect that a previously started pomodoro should still be running,
     * we restore it and run the application.
     *
     * We won't restore anything if the pomodoro expiration time was
     * already reached.
     */
    App.prototype.restoreState = function() {
        var data = JSON.parse(localStorage.getItem('pomodoroData'));
        if (data) {
            var pomodoro = new Models.Pomodoro(data);

            var remainingTime = pomodoro.remainingTime();
            if (remainingTime !== null) {
                this._currentPomodoro = pomodoro;
                this.timerView.startRunning(this._currentPomodoro);
                this.controlView.renderForPomodoro(this._currentPomodoro);

                this.listenTo(this._currentPomodoro, 'pomodoroCompleted', this.onPomodoroCompleted);
                this.listenTo(this._currentPomodoro, 'pomodoroFinished', this.onPomodoroFinished);
            }
        }

        this.finishedPomodoros.fetch({silent: true});
    };

    App.prototype.run = function() {
        this.initializeViews();
        this.bindEvents();
        this.restoreState();

        this.weekChartView.render();
        this.monthChartView.render();
    };

    return App;
});
<commit_msg>Error in date boundaries<commit_after>define([
    'underscore', 'backbone', 'jquery', 'd3', 'js/models', 'js/views', 'js/data',
    'js/utils'
],
function(_, Backbone, $, d3, Models, Views, Data, utils) {
    "use strict";

    var App = function() {
        this._currentPomodoro = null;
        this.finishedPomodoros = new Models.PomodoroCollection();
        this.dynamicTitleCb = $('#dynamicTitleCb');

        _.extend(this, Backbone.Events);
        _.bindAll(this,
            'onPomodoroFinished', 'onPomodoroCompleted', 'toggleTitle');
    };

    App.prototype.initializeViews = function() {
        this.timerView = new Views.TimerView({el: '#timer'});
        this.timerView._renderTitle = this.dynamicTitleCb.prop('checked');
        this.controlView = new Views.ControlView({el: '#control-bar'});
        this.configurationView = new Views.ConfigurationView({el: '#configuration-form'});

        var weekDataProvider = new Data.Provider(
            this.finishedPomodoros,
            d3.time.day,
            d3.time.day.offset(new Date(), -7),
            d3.time.day.ceil(new Date())
        );
        this.weekChartView = new Views.ChartView({
            el: '#weekChart',
            collection: this.finishedPomodoros,
            interval: d3.time.day,
            dateFormat: "%a %b %e",
            dataProvider: weekDataProvider,
        });

        var monthDataProvider = new Data.Provider(
            this.finishedPomodoros,
            d3.time.monday,
            d3.time.week.offset(new Date(), -10),
            d3.time.week.ceil(new Date())
        );
        this.monthChartView = new Views.ChartView({
            el: '#monthChart',
            collection: this.finishedPomodoros,
            interval: d3.time.monday,
            dateFormat: "Week %W, %b",
            dataProvider: monthDataProvider,
        });
    };

    /**
     * Manually starts a pomodoro.
     *
     * Creates the pomodoro object, and run the countdown timer.
     */
    App.prototype.startPomodoro = function(options) {
        // If a pomodoro is already running, do nothing
        if (this._currentPomodoro) {
            return;
        }

        var duration = options.duration;
        var type = options.type;
        this._currentPomodoro= new Models.Pomodoro({
            duration: duration,
            type: type
        });
        this._currentPomodoro.start();

        this.timerView.startRunning(this._currentPomodoro);
        this.controlView.renderForPomodoro(this._currentPomodoro);

        this.listenTo(this._currentPomodoro, 'pomodoroCompleted', this.onPomodoroCompleted);
        this.listenTo(this._currentPomodoro, 'pomodoroFinished', this.onPomodoroFinished);

        this.saveState();
    };

    /**
     * Manually interrupts the pomodoro.
     *
     * Don't perform any other operations, because all the cleanup code
     * will be called when the pomodoro finished event will be raised.
     *
     */
    App.prototype.interruptPomodoro = function() {
        this._currentPomodoro.interrupt();
    };

    /**
     * Perferm all operations required when a pomodoro is completed
     * (not interrupted).
     */
    App.prototype.onPomodoroCompleted = function() {
        this.notifyUser();
        if (this._currentPomodoro.get('type') === 'pomodoro') {
            this.finishedPomodoros.add(this._currentPomodoro);
            this._currentPomodoro.save();
        }
    };

    /**
     * Perform all operations required when a pomodoro is finished,
     * whether it was manually interrupted or not.
     *
     */
    App.prototype.onPomodoroFinished = function() {
        this.timerView.stopRunning(this._currentPomodoro);
        this.controlView.resetView();
        this.stopListening(this._currentPomodoro);
        this._currentPomodoro = null;

        this.saveState();
    };

    /**
     * Notify user of the end of pomodoro.
     */
    App.prototype.notifyUser = function() {
        var audioElt = document.getElementById('audioAlert');
        if (audioElt) {
            audioElt.play();
        }

        if (this._currentPomodoro.get('type') === 'pomodoro') {
            utils.notify('The pomodoro is over', {body: 'Go easy on the coffee.'});
        } else {
            utils.notify('Let\'s get back to work', {body: 'Focus now!'});
        }
    };

    App.prototype.bindEvents = function() {
        this.listenTo(this.controlView, 'timerStarted', this.startPomodoro);
        this.listenTo(this.controlView, 'timerInterrupted', this.interruptPomodoro);

        this.dynamicTitleCb.on('click', this.toggleTitle);
    };

    App.prototype.toggleTitle = function(event) {
        this.timerView._renderTitle = this.dynamicTitleCb.prop('checked');
    };

    /**
     * Save current state in localstorage
     */
    App.prototype.saveState = function() {
        if (!this._currentPomodoro) {
            localStorage.removeItem('pomodoroData');
        } else {
            var data = this._currentPomodoro.toJSON();
            localStorage.setItem('pomodoroData', JSON.stringify(data));
        }
    };

    /**
     * Restore app state if data is present in localstorage.
     *
     * If we detect that a previously started pomodoro should still be running,
     * we restore it and run the application.
     *
     * We won't restore anything if the pomodoro expiration time was
     * already reached.
     */
    App.prototype.restoreState = function() {
        var data = JSON.parse(localStorage.getItem('pomodoroData'));
        if (data) {
            var pomodoro = new Models.Pomodoro(data);

            var remainingTime = pomodoro.remainingTime();
            if (remainingTime !== null) {
                this._currentPomodoro = pomodoro;
                this.timerView.startRunning(this._currentPomodoro);
                this.controlView.renderForPomodoro(this._currentPomodoro);

                this.listenTo(this._currentPomodoro, 'pomodoroCompleted', this.onPomodoroCompleted);
                this.listenTo(this._currentPomodoro, 'pomodoroFinished', this.onPomodoroFinished);
            }
        }

        this.finishedPomodoros.fetch({silent: true});
    };

    App.prototype.run = function() {
        this.initializeViews();
        this.bindEvents();
        this.restoreState();

        this.weekChartView.render();
        this.monthChartView.render();
    };

    return App;
});
<|endoftext|>


<commit_before>window.onload = function () {

	// Show the greeting dialog if the user is on the page for the first time.
	if (localStorage.getItem('greetingShown') === null) {
		document.getElementById('greeting-wrapper').className = '';
		localStorage.setItem('greetingShown', 'yup');
	}

	// Close the greeting dialog from the button.
	document.getElementById('close-greeting').addEventListener('click', function () {
		document.getElementById('greeting-wrapper').className = 'hidden';
	});

	// Open the greeting dialog again from the hamburger button.
	document.getElementById('greeting-dialog-opener').addEventListener('click', function () {
		document.getElementById('greeting-wrapper').className = '';
	});

	// Colored marker icons for bike stations.
	var noBikesIcon = new H.map.Icon('gfx/red-marker.svg');
	var someBikesIcon = new H.map.Icon('gfx/yellow-marker.svg');
	var enoughBikesIcon = new H.map.Icon('gfx/green-marker.svg');
	var disabledIcon = new H.map.Icon('gfx/gray-marker.svg');

	// Initialize the map.
	var platform = new H.service.Platform({
		app_id: 'HEREAPPID',
		app_code: 'HEREAPPCODE',
		useCIT: true,
		useHTTPS: true
	});
	var defaultLayers = platform.createDefaultLayers();
	var map = new H.Map(document.getElementById('map'), defaultLayers.normal.map);
	var behavior = new H.mapevents.Behavior(new H.mapevents.MapEvents(map));
	var ui = H.ui.UI.createDefault(map, defaultLayers);
	window.addEventListener('resize', function () {
		map.getViewPort().resize();
	});

	// Try to fetch the coordinates where the map was centered last time.
	var lastMapCoordinatesJson = localStorage.getItem('lastLocation');
	if (lastMapCoordinatesJson !== null) {
		var lastMapCoordinates = JSON.parse(lastMapCoordinatesJson);
		map.setCenter(lastMapCoordinates);
	} else {
		map.setCenter({
			lat: 60.170572,
			lng: 24.941821
		});
	}

	// Try to fetch the zoom level that was used last time.
	var lastMapZoomLevel = localStorage.getItem('lastZoomLevel');
	if (lastMapZoomLevel !== null) {
		map.setZoom(lastMapZoomLevel);
	} else {
		map.setZoom(17);
	}

	// Fetch the status of bike stations immediately and then in intervals.
	var markerGroup = new H.map.Group();
	(function updateStations() {
		var bikeStationRequest = new XMLHttpRequest();
		bikeStationRequest.onreadystatechange = function () {
			if (this.readyState === 4 && this.status === 200) {
				var markerOptions = {
					min: 13
				};

				// Draw a marker on the map for each bike station
				// with marker color representing the amount of available bikes.
				var markers = [];
				JSON.parse(this.response).stations.forEach(function (station) {
					var bubbleContent = '
' + station.name + '
';

					if (station.state === 'Station on') {
						if (station.bikesAvailable === 1) {
							bubbleContent += '
1 bike available
';
						} else {
							bubbleContent += '
' + station.bikesAvailable + ' bikes available
';
						}

						if (station.bikesAvailable === 0) {
							markerOptions.icon = noBikesIcon;
						} else if (station.bikesAvailable <= 2) {
							markerOptions.icon = someBikesIcon;
						} else {
							markerOptions.icon = enoughBikesIcon;
						}
					} else {
						bubbleContent += '
Currently not in use
';
						markerOptions.icon = disabledIcon;
					}

					markerOptions.data = {
						name: station.name,
						bikesAvailable: station.bikesAvailable,
						spacesAvailable: station.spacesAvailable
					};

					var marker = new H.map.Marker({
						lat: station.y,
						lng: station.x
					}, markerOptions);
					marker.addEventListener('tap', function (event) {
						var bubble = new H.ui.InfoBubble(
							event.target.getPosition(),
							{
								content: bubbleContent
							});
						ui.addBubble(bubble);
					});
					markers.push(marker);
				});

				markerGroup.removeAll();
				markerGroup.addObjects(markers);
				map.addObject(markerGroup);
			}
		}
		bikeStationRequest.open('GET', 'https://api.digitransit.fi/routing/v1/routers/hsl/bike_rental', true);
		bikeStationRequest.send();
		setTimeout(updateStations, 180000);
	})();

	// Store the zoom level and center coordinates from the map every time dragging stops.
	map.addEventListener('mapviewchangeend', function () {
		localStorage.setItem('lastZoomLevel', map.getZoom());
		localStorage.setItem('lastLocation', JSON.stringify(map.getCenter()));
	});

	if ('geolocation' in navigator) {
		var currentUserLocation = {
			lat: 0,
			lng: 0
		};

		// Create a placeholder marker for the user location.
		var userLocationMarker = new H.map.Marker(currentUserLocation, {visibility: false});
		map.addObject(userLocationMarker);

		// Create an event handler for centering the map to the location of the user
		// when user locator button has been clicked.
		document.getElementById('user-locator').addEventListener('click', function () {
			map.setCenter(currentUserLocation);
		});

		navigator.geolocation.watchPosition(function (position) {
			currentUserLocation.lat = position.coords.latitude;
			currentUserLocation.lng = position.coords.longitude;

			// Move the user location marker to the actual user position and make it visible.
			userLocationMarker.setPosition(currentUserLocation);

			// Make the user location marker and user locator button visible.
			userLocationMarker.setVisibility(true);
			document.getElementById('user-locator').className = '';
		})
	}
}
<commit_msg>Remove unused bike station rack count<commit_after>window.onload = function () {

	// Show the greeting dialog if the user is on the page for the first time.
	if (localStorage.getItem('greetingShown') === null) {
		document.getElementById('greeting-wrapper').className = '';
		localStorage.setItem('greetingShown', 'yup');
	}

	// Close the greeting dialog from the button.
	document.getElementById('close-greeting').addEventListener('click', function () {
		document.getElementById('greeting-wrapper').className = 'hidden';
	});

	// Open the greeting dialog again from the hamburger button.
	document.getElementById('greeting-dialog-opener').addEventListener('click', function () {
		document.getElementById('greeting-wrapper').className = '';
	});

	// Colored marker icons for bike stations.
	var noBikesIcon = new H.map.Icon('gfx/red-marker.svg');
	var someBikesIcon = new H.map.Icon('gfx/yellow-marker.svg');
	var enoughBikesIcon = new H.map.Icon('gfx/green-marker.svg');
	var disabledIcon = new H.map.Icon('gfx/gray-marker.svg');

	// Initialize the map.
	var platform = new H.service.Platform({
		app_id: 'HEREAPPID',
		app_code: 'HEREAPPCODE',
		useCIT: true,
		useHTTPS: true
	});
	var defaultLayers = platform.createDefaultLayers();
	var map = new H.Map(document.getElementById('map'), defaultLayers.normal.map);
	var behavior = new H.mapevents.Behavior(new H.mapevents.MapEvents(map));
	var ui = H.ui.UI.createDefault(map, defaultLayers);
	window.addEventListener('resize', function () {
		map.getViewPort().resize();
	});

	// Try to fetch the coordinates where the map was centered last time.
	var lastMapCoordinatesJson = localStorage.getItem('lastLocation');
	if (lastMapCoordinatesJson !== null) {
		var lastMapCoordinates = JSON.parse(lastMapCoordinatesJson);
		map.setCenter(lastMapCoordinates);
	} else {
		map.setCenter({
			lat: 60.170572,
			lng: 24.941821
		});
	}

	// Try to fetch the zoom level that was used last time.
	var lastMapZoomLevel = localStorage.getItem('lastZoomLevel');
	if (lastMapZoomLevel !== null) {
		map.setZoom(lastMapZoomLevel);
	} else {
		map.setZoom(17);
	}

	// Fetch the status of bike stations immediately and then in intervals.
	var markerGroup = new H.map.Group();
	(function updateStations() {
		var bikeStationRequest = new XMLHttpRequest();
		bikeStationRequest.onreadystatechange = function () {
			if (this.readyState === 4 && this.status === 200) {
				var markerOptions = {
					min: 13
				};

				// Draw a marker on the map for each bike station
				// with marker color representing the amount of available bikes.
				var markers = [];
				JSON.parse(this.response).stations.forEach(function (station) {
					var bubbleContent = '
' + station.name + '
';

					if (station.state === 'Station on') {
						if (station.bikesAvailable === 1) {
							bubbleContent += '
1 bike available
';
						} else {
							bubbleContent += '
' + station.bikesAvailable + ' bikes available
';
						}

						if (station.bikesAvailable === 0) {
							markerOptions.icon = noBikesIcon;
						} else if (station.bikesAvailable <= 2) {
							markerOptions.icon = someBikesIcon;
						} else {
							markerOptions.icon = enoughBikesIcon;
						}
					} else {
						bubbleContent += '
Currently not in use
';
						markerOptions.icon = disabledIcon;
					}

					markerOptions.data = {
						name: station.name,
						bikesAvailable: station.bikesAvailable
					};

					var marker = new H.map.Marker({
						lat: station.y,
						lng: station.x
					}, markerOptions);
					marker.addEventListener('tap', function (event) {
						var bubble = new H.ui.InfoBubble(
							event.target.getPosition(),
							{
								content: bubbleContent
							});
						ui.addBubble(bubble);
					});
					markers.push(marker);
				});

				markerGroup.removeAll();
				markerGroup.addObjects(markers);
				map.addObject(markerGroup);
			}
		}
		bikeStationRequest.open('GET', 'https://api.digitransit.fi/routing/v1/routers/hsl/bike_rental', true);
		bikeStationRequest.send();
		setTimeout(updateStations, 180000);
	})();

	// Store the zoom level and center coordinates from the map every time dragging stops.
	map.addEventListener('mapviewchangeend', function () {
		localStorage.setItem('lastZoomLevel', map.getZoom());
		localStorage.setItem('lastLocation', JSON.stringify(map.getCenter()));
	});

	if ('geolocation' in navigator) {
		var currentUserLocation = {
			lat: 0,
			lng: 0
		};

		// Create a placeholder marker for the user location.
		var userLocationMarker = new H.map.Marker(currentUserLocation, {visibility: false});
		map.addObject(userLocationMarker);

		// Create an event handler for centering the map to the location of the user
		// when user locator button has been clicked.
		document.getElementById('user-locator').addEventListener('click', function () {
			map.setCenter(currentUserLocation);
		});

		navigator.geolocation.watchPosition(function (position) {
			currentUserLocation.lat = position.coords.latitude;
			currentUserLocation.lng = position.coords.longitude;

			// Move the user location marker to the actual user position and make it visible.
			userLocationMarker.setPosition(currentUserLocation);

			// Make the user location marker and user locator button visible.
			userLocationMarker.setVisibility(true);
			document.getElementById('user-locator').className = '';
		})
	}
}
<|endoftext|>


<commit_before>var timeline = require('timeline');

var PIN_ID = "timeline-push-pin-test";

Pebble.addEventListener('ready', function() {
  console.log('PebbleKit JS ready!');

  // An hour ahead
  var date = new Date();
  date.setHours(date.getHours() + 1);

  // Create the pin
  var pin = {
    "id": "pin-" + PIN_ID,
    "time": date.toISOString(),
    "layout": {
      "type": "genericPin",
      "title": "Example Pin",
      "body": "This is an example pin from the timeline-push-pin example app!",
      "tinyIcon": "system://images/SCHEDULED_EVENT"
    }
  };

  console.log('Inserting pin in the future: ' + JSON.stringify(pin));

  timeline.insertUserPin(pin, function(responseText) {
    console.log('Result: ' + responseText);
  });
});
<commit_msg>Updated require<commit_after>var timeline = require('./timeline');

var PIN_ID = "timeline-push-pin-test";

Pebble.addEventListener('ready', function() {
  console.log('PebbleKit JS ready!');

  // An hour ahead
  var date = new Date();
  date.setHours(date.getHours() + 1);

  // Create the pin
  var pin = {
    "id": "pin-" + PIN_ID,
    "time": date.toISOString(),
    "layout": {
      "type": "genericPin",
      "title": "Example Pin",
      "body": "This is an example pin from the timeline-push-pin example app!",
      "tinyIcon": "system://images/SCHEDULED_EVENT"
    }
  };

  console.log('Inserting pin in the future: ' + JSON.stringify(pin));

  timeline.insertUserPin(pin, function(responseText) {
    console.log('Result: ' + responseText);
  });
});
<|endoftext|>


<commit_before>var ViewModel = function() {
  var self = this;

  self.locations = ko.observableArray();
  self.activeLocation = ko.observable();
  self.types = ko.observableArray(
    [
      { value: 'restaurant', label: 'Restaurants' },
      { value: 'bar', label: 'Bars' },
      { value: 'cafe', label: 'Cafes' },
      { value: 'school', label: 'Schools' }
    ]
  );

  // Behaviors
  // Perform yelp search, using search `term` and `location`
  self.yelpSearch = function(term, location) {
    // Internal URL to return results from search
    var url = "http://localhost:5000/";
    $.getJSON( url, {
      term: term,
      location: location
    }, function( data ) {
      // Map needed data to an object
      data.businesses.forEach(function(business) {
        var location = {
          name: business.name,
          // Store position in a format usable by google maps
          position: {
            lat: business.coordinates.latitude,
            lng: business.coordinates.longitude
          },
          location: business.location,
          price: business.price,
          categoies: business.categories,
          rating: business.rating
        };
        // Create a marker for this location, and assign to location
        location.marker = createMarker(location.position, location.name);
        // Push marker to markers array within map
        markers.push(location.marker);
        // Add new location to `locations` observable array
        self.locations.push(location);
      });
      self.displayMarkers();
    });
  };
  // Display markers on google map
  self.displayMarkers = function() {
    setMarkersMap(map);
  };
  // Toggle active class on list items
  self.selectListItem = function(location) {
    self.activeLocation(location);
    focusMarker(location.marker, location.name);
  };
  // Add a location to observable array
  self.addLocation = function(location) {
    self.locations.push(location);
  };
  // Clear all locations from observable array
  self.clearLocations = function() {
    self.locations.removeAll();
  };
  // Remove all locations and map markers
  self.clearLocationsAndMarkers = function() {
    self.clearLocations();
    clearMarkers();
  };
  // Perform a new search for locations
  self.newSearch = function(type) {
    getPlaceSearch(type.value);
  };
};

var viewModelInstance = new ViewModel();

ko.applyBindings(viewModelInstance);

viewModelInstance.yelpSearch('restaurants', 'playa vista');
<commit_msg>Move initial state function to within viewmodel<commit_after>var ViewModel = function() {
  var self = this;

  self.locations = ko.observableArray();
  self.activeLocation = ko.observable();
  self.types = ko.observableArray(
    [
      { value: 'restaurant', label: 'Restaurants' },
      { value: 'bar', label: 'Bars' },
      { value: 'cafe', label: 'Cafes' },
      { value: 'school', label: 'Schools' }
    ]
  );

  // Behaviors
  // Perform yelp search, using search `term` and `location`
  self.yelpSearch = function(term, location) {
    // Internal URL to return results from search
    var url = "http://localhost:5000/";
    $.getJSON( url, {
      term: term,
      location: location
    }, function( data ) {
      // Map needed data to an object
      data.businesses.forEach(function(business) {
        var location = {
          name: business.name,
          // Store position in a format usable by google maps
          position: {
            lat: business.coordinates.latitude,
            lng: business.coordinates.longitude
          },
          location: business.location,
          price: business.price,
          categoies: business.categories,
          rating: business.rating
        };
        // Create a marker for this location, and assign to location
        location.marker = createMarker(location.position, location.name);
        // Push marker to markers array within map
        markers.push(location.marker);
        // Add new location to `locations` observable array
        self.locations.push(location);
      });
      self.displayMarkers();
    });
  };
  // Display markers on google map
  self.displayMarkers = function() {
    setMarkersMap(map);
  };
  // Toggle active class on list items
  self.selectListItem = function(location) {
    self.activeLocation(location);
    focusMarker(location.marker, location.name);
  };
  // Add a location to observable array
  self.addLocation = function(location) {
    self.locations.push(location);
  };
  // Clear all locations from observable array
  self.clearLocations = function() {
    self.locations.removeAll();
  };
  // Remove all locations and map markers
  self.clearLocationsAndMarkers = function() {
    self.clearLocations();
    clearMarkers();
  };
  // Perform a new search for locations
  self.newSearch = function(type) {
    getPlaceSearch(type.value);
  };

  // Load initial data
  self.yelpSearch('restaurants', 'playa vista');
};

var viewModelInstance = new ViewModel();

ko.applyBindings(viewModelInstance);
<|endoftext|>


<commit_before>'use strict';
var Del = require('ya-del');
require('./tabbable-selector');

function App () {
	this.$savedFocus = undefined;

	this.lastFocused = undefined;

	this.state = false; // false - close, true - open

	this.hasTrigger = false;
}

App._name = 'yapopup';
App.defaults = {
	// If append to body
	bodyAppend: true,

	// Close button html
	close: '<button>x</button>',

	dName: 'popup'
};

App.KEY_CODES = {
	ESC: 27,
	TAB: 9,
	SHIFT: 65
};

App.make = function(options) {
	if ($.data(inst.$el[0], 'yapopup_plugin')) return;
	var inst = new this;
	inst.options = options;
	$.data(inst.$el[0], 'yapopup_plugin', inst);
	return inst;
};

App.init = function(options) {
	var inst = this.make(options);
	if (inst) inst.init();
	return inst;
};

App.prototype = $.extend({}, Del, {
	constructor: App,
	init: function() {
		this.setOptions();
		this.setEl();
		this.name = this.constructor._name;
		this.defineId();
		this.initDel({dName: this.options.dName});
		this.defineEls();
		this.defineEvents();
		this.setAria();
	},

	setOptions: function() {
		this.options = $.extend(true, {}, this.constructor.defaults, this.options);
	},

	setEl: function() {
		if (!this.options.$el || this.options.$el.length !== 1)
			throw new Error('$el options must be defined and exist in DOM');
		this.$el = this.options.$el;
	},

	defineId: function() {
		this.id = this.$el.attr('id');
	},

	defineEls: function() {
		this.$inner = this.find('inner');
		this.$body = $(document.body);
		this.defineTrigger();
		this.defineClose();
	},

	defineTrigger: function() {
		if (!this.id) return;
		this.$trigger = $('[data-yapopup-target=' + this.id + ']');
		this.hasTrigger = true;
	},

	defineClose: function() {
		this.$close = this.find('close');
		if (!this.$close.length) {
			this.$close = $(this.options.close)
				.addClass(this.makeName('close'))
				.appendTo(this.$inner);
		}
	},

	defineEvents: function() {
		var self = this;
		this.$el.on('click.' + this.name, function(e) {
			self.onClick(e);
		});
		if (this.hasTrigger) {
			this.$trigger.on('click.' + this.name, function(e) {
				e.preventDefault();
				self.open();
			});
		}
		$(document).on('focusin.' + this.name, function(e) {
			self.onDocumenFocus(e);
		}).on('keyup.' + this.name, function(e) {
			self.checkEsc(e);
		});
	},

	setAria: function() {
		this.$el.attr('role', 'dialog');
	},

	open: function() {
		this.$body.addClass(this.options.dName + 'BodyOverflow');
		this.saveFocus();
		this.show();
		this.ariaShow();
		this.focusIn();
		if (this.hasTrigger) this.$el.trigger('open.' + this.name);
		this.state = true;
	},

	close: function() {
		this.$body.removeClass(this.options.dName + 'BodyOverflow');
		this.hide();
		this.restorefocus();
		this.ariaHide();
		if (this.hasTrigger) this.$el.trigger('close.' + this.name);
		this.state = false;
	},

	ariaShow: function() {
		this.$el.attr('aria-hidden', false);
	},

	ariaHide: function() {
		this.$el.attr('aria-hidden', true);
	},

	show: function() {
		this.addMod('show');
	},

	hide: function() {
		this.removeMod('show');
	},

	focusIn: function() {
		this.$el.find(':tabbable').first().focus();
	},

	saveFocus: function() {
		this.$savedFocus = $(':focus');
	},

	restorefocus: function() {
		this.$savedFocus.focus();
	},

	onClick: function(e) {
		if (e.target === this.$close[0]) this.close();
		else if (!$.contains(this.$inner[0], e.target) && this.$inner[0] !== e.target) {
			this.close();
		}
	},

	checkEsc: function(e) {
		if (!this.state) return;
		if (e.keyCode == this.constructor.KEY_CODES.ESC)
			this.close();
	},

	onDocumenFocus: function(e) {
		if (!this.state) return;
		if ($.contains(this.$el[0], e.target)) this.lastFocused = e.target;
		else {
			this.setFocusIn();
		}
	},

	/**
	 * Back focus in a popup
	 */
	setFocusIn: function() {
		var $tabbable = this.$el.find(':tabbable');
		var $lastTabbable = $tabbable.last();
		if (this.lastFocused === $lastTabbable[0]) {
			$tabbable.first().focus();
		} else $lastTabbable.focus();
	},
});

module.exports = App;<commit_msg>fix: fix binding instance<commit_after>'use strict';
var Del = require('ya-del');
require('./tabbable-selector');

function App () {
	this.$savedFocus = undefined;

	this.lastFocused = undefined;

	this.state = false; // false - close, true - open

	this.hasTrigger = false;
}

App._name = 'yapopup';
App.defaults = {
	// If append to body
	bodyAppend: true,

	// Close button html
	close: '<button>x</button>',

	dName: 'popup'
};

App.KEY_CODES = {
	ESC: 27,
	TAB: 9,
	SHIFT: 65
};

App.make = function(options) {
	if ($.data(options.$el[0], 'yapopup_plugin')) return;
	var inst = new this;
	inst.options = options;
	$.data(options.$el[0], 'yapopup_plugin', inst);
	return inst;
};

App.init = function(options) {
	var inst = this.make(options);
	if (inst) inst.init();
	return inst;
};

App.prototype = $.extend({}, Del, {
	constructor: App,
	init: function() {
		this.setOptions();
		this.setEl();
		this.name = this.constructor._name;
		this.defineId();
		this.initDel({dName: this.options.dName});
		this.defineEls();
		this.defineEvents();
		this.setAria();
	},

	setOptions: function() {
		this.options = $.extend(true, {}, this.constructor.defaults, this.options);
	},

	setEl: function() {
		if (!this.options.$el || this.options.$el.length !== 1)
			throw new Error('$el options must be defined and exist in DOM');
		this.$el = this.options.$el;
	},

	defineId: function() {
		this.id = this.$el.attr('id');
	},

	defineEls: function() {
		this.$inner = this.find('inner');
		this.$body = $(document.body);
		this.defineTrigger();
		this.defineClose();
	},

	defineTrigger: function() {
		if (!this.id) return;
		this.$trigger = $('[data-yapopup-target=' + this.id + ']');
		this.hasTrigger = true;
	},

	defineClose: function() {
		this.$close = this.find('close');
		if (!this.$close.length) {
			this.$close = $(this.options.close)
				.addClass(this.makeName('close'))
				.appendTo(this.$inner);
		}
	},

	defineEvents: function() {
		var self = this;
		this.$el.on('click.' + this.name, function(e) {
			self.onClick(e);
		});
		if (this.hasTrigger) {
			this.$trigger.on('click.' + this.name, function(e) {
				e.preventDefault();
				self.open();
			});
		}
		$(document).on('focusin.' + this.name, function(e) {
			self.onDocumenFocus(e);
		}).on('keyup.' + this.name, function(e) {
			self.checkEsc(e);
		});
	},

	setAria: function() {
		this.$el.attr('role', 'dialog');
	},

	open: function() {
		this.$body.addClass(this.options.dName + 'BodyOverflow');
		this.saveFocus();
		this.show();
		this.ariaShow();
		this.focusIn();
		if (this.hasTrigger) this.$el.trigger('open.' + this.name);
		this.state = true;
	},

	close: function() {
		this.$body.removeClass(this.options.dName + 'BodyOverflow');
		this.hide();
		this.restorefocus();
		this.ariaHide();
		if (this.hasTrigger) this.$el.trigger('close.' + this.name);
		this.state = false;
	},

	ariaShow: function() {
		this.$el.attr('aria-hidden', false);
	},

	ariaHide: function() {
		this.$el.attr('aria-hidden', true);
	},

	show: function() {
		this.addMod('show');
	},

	hide: function() {
		this.removeMod('show');
	},

	focusIn: function() {
		this.$el.find(':tabbable').first().focus();
	},

	saveFocus: function() {
		this.$savedFocus = $(':focus');
	},

	restorefocus: function() {
		this.$savedFocus.focus();
	},

	onClick: function(e) {
		if (e.target === this.$close[0]) this.close();
		else if (!$.contains(this.$inner[0], e.target) && this.$inner[0] !== e.target) {
			this.close();
		}
	},

	checkEsc: function(e) {
		if (!this.state) return;
		if (e.keyCode == this.constructor.KEY_CODES.ESC)
			this.close();
	},

	onDocumenFocus: function(e) {
		if (!this.state) return;
		if ($.contains(this.$el[0], e.target)) this.lastFocused = e.target;
		else {
			this.setFocusIn();
		}
	},

	/**
	 * Back focus in a popup
	 */
	setFocusIn: function() {
		var $tabbable = this.$el.find(':tabbable');
		var $lastTabbable = $tabbable.last();
		if (this.lastFocused === $lastTabbable[0]) {
			$tabbable.first().focus();
		} else $lastTabbable.focus();
	},
});

module.exports = App;<|endoftext|>


<commit_before>import React     from 'react';
import ReactDOM  from 'react-dom';
import SearchBar from './components/SearchBar';
import GifList   from './components/GifList';

class App extends React.Component
{
    constructor (props)
    {
        super(props);

        this.state = {
            gifs: [
                {
                    id: 1,
                    url: 'http://fakeimg.pl/300/?text=Image+1',
                },
                {
                    id: 2,
                    url: 'http://fakeimg.pl/300/?text=Image+2',
                },
                {
                    id: 3,
                    url: 'http://fakeimg.pl/300/?text=Image+3',
                },
            ]
        };
    }

    handleTermChange (term)
    {
        console.log(term);
    }

    render ()
    {
        return (

                <SearchBar onTermChange={this.handleTermChange} />
                <GifList gifs={this.state.gifs} />

        );
    }
}

ReactDOM.render(<App />, document.getElementById('app'));
<commit_msg>Removing hardcoded gifs to start implementation of Giphy API.<commit_after>import React     from 'react';
import ReactDOM  from 'react-dom';
import SearchBar from './components/SearchBar';
import GifList   from './components/GifList';

class App extends React.Component
{
    constructor (props)
    {
        super(props);

        this.state = {
            gifs: []
        };
    }

    handleTermChange (term)
    {
        console.log(term);
    }

    render ()
    {
        return (

                <SearchBar onTermChange={this.handleTermChange} />
                <GifList gifs={this.state.gifs} />

        );
    }
}

ReactDOM.render(<App />, document.getElementById('app'));
<|endoftext|>


<commit_before>/*jslint nomen: true */
/*global define, navigator, location, window, chrome */
/*https://raw.github.com/alcacoop/gaia-chrono-app/master/www/js/lib/install.js*/
(function() {

  var dispatcher = $({}),
      prop;

  //Create event functions based on dispatcher object

  function createDispatchFn(id) {
    return function() {
      return dispatcher[id].apply(dispatcher, arguments);
    };
  }

  /**
   * Detects if the current app has been installed.
   *
   * See https://github.com/wavysandbox/install/blob/master/README.md
   * for details on how to use.
   *
   */
  App.install = function() {
    var fn = install[install.type + 'Install'];
    if (fn) {
      fn();
    } else {
      install.trigger('error', 'unsupported install: ' + install.type);
    }
  }

  function triggerChange(state) {
    install.state = state;
    install.trigger('change', install.state);
  }

  /**
   *  The install state. Values are:
   *  'unknown': the code has not tried to detect any state.
   *
   * @type {String}
   */

  var install = window.install = {};

  install.state = 'unknown';

  install.check = function() {
    var apps = navigator.mozApps,
      request;

    if (navigator.mozApps) {
      //Mozilla web apps
      install.type = 'mozilla';
      request = navigator.mozApps.checkInstalled(install.mozillaInstallUrl);
      request.onsuccess = function() {
        if (this.result) {
          triggerChange('installed');
        } else {
          triggerChange('uninstalled');
        }
      };

      request.onerror = function(err) {
        // Just console log it, no need to bother the user.
        install.error = err;
        triggerChange('error');
      };

    } else if (typeof chrome !== 'undefined' &&
      chrome.webstore &&
      chrome.app) {
      //Chrome web apps
      install.type = 'chrome';
      if (chrome.app.isInstalled) {
        triggerChange('installed');
      } else {
        triggerChange('uninstalled');
      }
    } else if (typeof window.navigator.standalone !== 'undefined') {
      install.type = 'ios';
      if (window.navigator.standalone) {
        triggerChange('installed');
      } else {
        triggerChange('uninstalled');
      }
    } else {
      install.type = 'unsupported';
      triggerChange('unsupported');
    }
  };

  /* Mozilla/Firefox installation */
  var base = location.href.split("#")[0]; // WORKAROUND: remove hash from url
  base = base.replace("index.html", ""); // WORKAROUND: remove index.html
  install.mozillaInstallUrl = base + 'manifest.webapp';

  install.mozillaInstall = function() {
    var installRequest = navigator.mozApps.install(install.mozillaInstallUrl);

    installRequest.onsuccess = function(data) {
      triggerChange('installed');
    };

    installRequest.onerror = function(err) {
      install.error = err;
      triggerChange('error');
    };
  };

  /* Chrome installation */
  install.chromeInstallUrl = null;
  install.chromeInstall = function() {
    chrome.webstore.install(install.chromeInstallUrl, function() {
      triggerChange('installed');
    }, function(err) {
      install.error = err;
      triggerChange('error');
    });
  };

  /* iOS installation */
  //Right now, just asks that something show a UI
  //element mentioning how to install using the Safari
  //"Add to Home Screen" button.
  install.iosInstall = function() {
    install.trigger('showiOSInstall', navigator.platform.toLowerCase());
  };

  //Allow install to do events.
  install.on = createDispatchFn('on');
  install.off = createDispatchFn('off');
  install.trigger = createDispatchFn('trigger');

  //Start up the checks
  install.check();

  var updateIndex = function() {
    if (install.state == 'uninstalled') {
      $('#install-bar').show();
    } else if (install.state == 'installed' || install.state == 'unsupported') {
      $('#install-bar').hide();
    }

    //If FXOS and is installable show
    if (window.isMobile.FXOS() && App.pkg.settings.installable) {
      $('#install-bar').slideDown('slow');
    } else {
      $('#install-bar').hide();
    }
  }

  $('#install-button').on('click', function() {
    App.install();
  });

  window.install.on('change', updateIndex);

})();<commit_msg>install library added<commit_after>/*jslint nomen: true */
/*global define, navigator, location, window, chrome */
/*https://raw.github.com/alcacoop/gaia-chrono-app/master/www/js/lib/install.js*/
(function() {

  var dispatcher = $({}),
      prop;

  //Create event functions based on dispatcher object

  function createDispatchFn(id) {
    return function() {
      return dispatcher[id].apply(dispatcher, arguments);
    };
  }

  /**
   * Detects if the current app has been installed.
   *
   * See https://github.com/wavysandbox/install/blob/master/README.md
   * for details on how to use.
   *
   */
  App.install = function() {
    var fn = install[install.type + 'Install'];
    if (fn) {
      fn();
    } else {
      install.trigger('error', 'unsupported install: ' + install.type);
    }
  }

  function triggerChange(state) {
    install.state = state;
    install.trigger('change', install.state);
  }

  /**
   *  The install state. Values are:
   *  'unknown': the code has not tried to detect any state.
   *
   * @type {String}
   */

  var install = window.install = {};

  install.state = 'unknown';

  install.check = function() {
    var apps = navigator.mozApps,
      request;

    if (navigator.mozApps) {
      //Mozilla web apps
      install.type = 'mozilla';
      request = navigator.mozApps.checkInstalled(install.mozillaInstallUrl);
      request.onsuccess = function() {
        if (this.result) {
          triggerChange('installed');
        } else {
          triggerChange('uninstalled');
        }
      };

      request.onerror = function(err) {
        // Just console log it, no need to bother the user.
        install.error = err;
        triggerChange('error');
      };

    } else if (typeof chrome !== 'undefined' &&
      chrome.webstore &&
      chrome.app) {
      //Chrome web apps
      install.type = 'chrome';
      if (chrome.app.isInstalled) {
        triggerChange('installed');
      } else {
        triggerChange('uninstalled');
      }
    } else if (typeof window.navigator.standalone !== 'undefined') {
      install.type = 'ios';
      if (window.navigator.standalone) {
        triggerChange('installed');
      } else {
        triggerChange('uninstalled');
      }
    } else {
      install.type = 'unsupported';
      triggerChange('unsupported');
    }
  };

  /* Mozilla/Firefox installation */
  var base = location.href.split("#")[0]; // WORKAROUND: remove hash from url
  base = base.replace("index.html", ""); // WORKAROUND: remove index.html
  install.mozillaInstallUrl = base + 'manifest.webapp';

  install.mozillaInstall = function() {
    var installRequest = navigator.mozApps.install(install.mozillaInstallUrl);

    installRequest.onsuccess = function(data) {
      triggerChange('installed');
    };

    installRequest.onerror = function(err) {
      install.error = err;
      triggerChange('error');
    };
  };

  /* Chrome installation */
  install.chromeInstallUrl = null;
  install.chromeInstall = function() {
    chrome.webstore.install(install.chromeInstallUrl, function() {
      triggerChange('installed');
    }, function(err) {
      install.error = err;
      triggerChange('error');
    });
  };

  /* iOS installation */
  //Right now, just asks that something show a UI
  //element mentioning how to install using the Safari
  //"Add to Home Screen" button.
  install.iosInstall = function() {
    install.trigger('showiOSInstall', navigator.platform.toLowerCase());
  };

  //Allow install to do events.
  install.on = createDispatchFn('on');
  install.off = createDispatchFn('off');
  install.trigger = createDispatchFn('trigger');

  //Start up the checks
  install.check();

  var updateIndex = function() {
    if (install.state == 'uninstalled') {
      $('#install-bar').show();
    } else if (install.state == 'installed' || install.state == 'unsupported') {
      $('#install-bar').hide();
    }

    //If FXOS and is installable show
    var installable = App.pkg.settings.installable || false;
    if (window.isMobile.FXOS() && installable) {
      $('#install-bar').slideDown('slow');
    } else {
      $('#install-bar').hide();
    }
  }

  $('#install-button').on('click', function() {
    App.install();
  });

  window.install.on('change', updateIndex);

})();<|endoftext|>


<commit_before>// > Copyright (c) 2012-2015 Iwan van der Kleijn
// > All rights reserved.
//
// > This source code is licensed under the BSD-style license found in the LICENSE file in the root directory of this source tree
//
// This file is part of [Remedata](remedata.html)

// Import standard ES6 API
import * as corejs from 'core-js';
import * as fs from 'fs';

// Do not test for falsity, 0 and [] are perfectly valid values, but do test if variable is null or undefined
export let isNone = function(data){
  return ((data === null) || (typeof data == 'undefined'));
};

// Represents JSON file, as an in-memory database table. Mutations are written to disk.
class JsonDb {

    // constructor (path to JSON file: string), (property-name used to store key: any): void
    constructor(path, id){
      this.path = path;
      this.id = id;
      this.data = null;
    }

    get Id() {
      return this.id;
    }

    // Retrieve array with all elements / items ('records')
    getAll(callback){
        // Directly return data if already loaded in-memory
        if (!(isNone(this.data))){
          callback(null, this.data);
        } else {
          // If table not initialized, load from disk
          fs.readFile(this.path, {encoding: 'utf8'},(err, data) =>
                      {
                        if (err){
                          this.data = null;
                          callback(err);
                        } else{
                          try {
                            // convert JSON string to JavaScript object.
                            this.data = JSON.parse(data);
                            callback(null, this.data);

                          } catch(error){
                            // Catch error in case of conversion errors.
                            this.data = null;
                            callback(error);
                          }
                        }
                      });
        }
    }

  // private method; get element by value of the default key
  _getByKey(key){

    return this.data.find((e)=>{
      return (e[this.id] == key);
    });
  }

  // Load data from disk if not present in memory
  _guaranteeData(callback){

    if (isNone(this.data)){

      this.getAll((err, data)=>{
        if (err){
          callback(err);
        }else {
          callback(null, data);
        }
      });
    } else {
      callback(null, this.data);
    }
  }

  // remove item from table
  deleteBy(key, callback){
    // load data from file if not loaded in memory
    this._guaranteeData((err, data)=>{
      if (err){
        callback(err);
      }else {
        let l0 = this.data.length;
        // Remove the item from the in-memory collection
        this.data = data.filter((e)=> {
          return !(e[this.id] == key)
        });
        // Determine if the element was removed or not
        let deleted = (l0 != this.data.length);

        // flush changes to disk
        this.saveAll(this.data, (err)=>{

          callback(err, deleted);
        });
      }
    });
  }

  // Get one item from Table
  getBy(key, callback){

    this._guaranteeData((err, data)=>{
      if (err){
        callback(err);
      }else {
        let res = this._getByKey(key);
        callback(null, res);
      }
    });
  }

  // Save item to collection, overwriting an existing item and otherwise inserting it. Changes are flushed to disk.
  save(item, callback){
    this._guaranteeData((err, data)=>{
      if (err){
        callback(err);
      }else {

        let succes = false;
        // map over collection, replacing an existing item with the new ('changed') one
        this.data = data.map((e)=>{
          if(e[this.id] == item[this.id]){
            succes = true;
            return item;
          } else{
            return e;
          }
        });
        // If not existing item was found, the new item is considered to be truly new and
        // appended to the table
        if (!succes){
          this.data.push(item);
        }
        // Data flushed to disk
        this.saveAll(this.data, (err)=>{
          callback(err, item);
        });
      }
    });
  }
  // Save an Array to table, overwriting existing content
  saveAll(data, callback){

    // Arguments validations. 'Data' MUST be an array.
    if (isNone(data)){
      callback(new Error('Invalid parameters'));
    }
    if ((data instanceof Array)){
      callback(new Error('Data needs to be an Array'));
    }
    this.data = data;
    fs.writeFile(this.path, JSON.stringify(data), {encoding: 'utf8'}, (err) => {

      callback(err, data);
    });
  }
}

// Public interface: factory function.
export let jsondb = function(path, options){
  let config = options || {};
  let id = config.id || 'id';
  return new JsonDb(path, id);
};

// Some examples.....
/*
let path = "data/_data.json";
let db = jsondb(path, {key: "id"});

db.getAll(function(err, data){
  console.log('in getAll', err, data, this);
 });

db.getBy(1, function(err, data){
  console.log("Get by: ", err, data);
});

db.getAll(function(err, data){
  console.log('in getAll', err, data);
  if (err) return;
  let d = data;
  d.push({
    id: 7,
    name: "Basje",
    surname: "Goris",
    age: 26
  });
  db.saveAll(d, function(err){
    console.log(err);
    if(err) return;
    db.getAll(function(err, data){

      console.log("2nd getAll", err, data);
    });
  });
});

db.getBy(4, (err, item)=>{
  if(err) {
    console.log("error: ", err);
    return;
  }
  item.name = "BasjeMAN";
  db.save(item, (err)=>{
    if(err) {
    console.log("error: ", err);
      return;
    }
  });
});

db.deleteBy(1, (err)=> {
  if(err) {
    console.log("error: ", err);
    return;
  }
});
*/<commit_msg>inverted the logic of the array check when persisting data<commit_after>// > Copyright (c) 2012-2015 Iwan van der Kleijn
// > All rights reserved.
//
// > This source code is licensed under the BSD-style license found in the LICENSE file in the root directory of this source tree
//
// This file is part of [Remedata](remedata.html)

// Import standard ES6 API
import * as corejs from 'core-js';
import * as fs from 'fs';

// Do not test for falsity, 0 and [] are perfectly valid values, but do test if variable is null or undefined
export let isNone = function(data){
  return ((data === null) || (typeof data == 'undefined'));
};

// Represents JSON file, as an in-memory database table. Mutations are written to disk.
class JsonDb {

    // constructor (path to JSON file: string), (property-name used to store key: any): void
    constructor(path, id){
      this.path = path;
      this.id = id;
      this.data = null;
    }

    get Id() {
      return this.id;
    }

    // Retrieve array with all elements / items ('records')
    getAll(callback){
        // Directly return data if already loaded in-memory
        if (!(isNone(this.data))){
          callback(null, this.data);
        } else {
          // If table not initialized, load from disk
          fs.readFile(this.path, {encoding: 'utf8'},(err, data) =>
                      {
                        if (err){
                          this.data = null;
                          callback(err);
                        } else{
                          try {
                            // convert JSON string to JavaScript object.
                            this.data = JSON.parse(data);
                            callback(null, this.data);

                          } catch(error){
                            // Catch error in case of conversion errors.
                            this.data = null;
                            callback(error);
                          }
                        }
                      });
        }
    }

  // private method; get element by value of the default key
  _getByKey(key){

    return this.data.find((e)=>{
      return (e[this.id] == key);
    });
  }

  // Load data from disk if not present in memory
  _guaranteeData(callback){

    if (isNone(this.data)){

      this.getAll((err, data)=>{
        if (err){
          callback(err);
        }else {
          callback(null, data);
        }
      });
    } else {
      callback(null, this.data);
    }
  }

  // remove item from table
  deleteBy(key, callback){
    // load data from file if not loaded in memory
    this._guaranteeData((err, data)=>{
      if (err){
        callback(err);
      }else {
        let l0 = this.data.length;
        // Remove the item from the in-memory collection
        this.data = data.filter((e)=> {
          return !(e[this.id] == key)
        });
        // Determine if the element was removed or not
        let deleted = (l0 != this.data.length);

        // flush changes to disk
        this.saveAll(this.data, (err)=>{

          callback(err, deleted);
        });
      }
    });
  }

  // Get one item from Table
  getBy(key, callback){

    this._guaranteeData((err, data)=>{
      if (err){
        callback(err);
      }else {
        let res = this._getByKey(key);
        callback(null, res);
      }
    });
  }

  // Save item to collection, overwriting an existing item and otherwise inserting it. Changes are flushed to disk.
  save(item, callback){
    this._guaranteeData((err, data)=>{
      if (err){
        callback(err);
      }else {

        let succes = false;
        // map over collection, replacing an existing item with the new ('changed') one
        this.data = data.map((e)=>{
          if(e[this.id] == item[this.id]){
            succes = true;
            return item;
          } else{
            return e;
          }
        });
        // If not existing item was found, the new item is considered to be truly new and
        // appended to the table
        if (!succes){
          this.data.push(item);
        }
        // Data flushed to disk
        this.saveAll(this.data, (err)=>{
          callback(err, item);
        });
      }
    });
  }
  // Save an Array to table, overwriting existing content
  saveAll(data, callback){

    // Arguments validations. 'Data' MUST be an array.
    if (isNone(data)){
      callback(new Error('Invalid parameters'));
    }
    if (!(data instanceof Array)){
      callback(new Error('Data needs to be an Array'));
    }
    this.data = data;
    fs.writeFile(this.path, JSON.stringify(data), {encoding: 'utf8'}, (err) => {

      callback(err, data);
    });
  }
}

// Public interface: factory function.
export let jsondb = function(path, options){
  let config = options || {};
  let id = config.id || 'id';
  return new JsonDb(path, id);
};

// Some examples.....
/*
let path = "data/_data.json";
let db = jsondb(path, {key: "id"});

db.getAll(function(err, data){
  console.log('in getAll', err, data, this);
 });

db.getBy(1, function(err, data){
  console.log("Get by: ", err, data);
});

db.getAll(function(err, data){
  console.log('in getAll', err, data);
  if (err) return;
  let d = data;
  d.push({
    id: 7,
    name: "Basje",
    surname: "Goris",
    age: 26
  });
  db.saveAll(d, function(err){
    console.log(err);
    if(err) return;
    db.getAll(function(err, data){

      console.log("2nd getAll", err, data);
    });
  });
});

db.getBy(4, (err, item)=>{
  if(err) {
    console.log("error: ", err);
    return;
  }
  item.name = "BasjeMAN";
  db.save(item, (err)=>{
    if(err) {
    console.log("error: ", err);
      return;
    }
  });
});

db.deleteBy(1, (err)=> {
  if(err) {
    console.log("error: ", err);
    return;
  }
});
*/
<|endoftext|>


<commit_before>'use strict';

const Matrix = require('ml-matrix');

const GaussianKernel = require('ml-gaussian-kernel');
const PolynomialKernel = require('ml-polynomial-kernel');

class Kernel {
    constructor (type, options) {
        if (typeof type === 'string') {
            switch (type.toLowerCase()) {
                case 'gaussian':
                case 'rbf':
                    this.kernelFunction = new GaussianKernel(options);
                    break;
                case 'polynomial':
                case 'poly':
                    this.kernelFunction = new PolynomialKernel(options);
                    break;
                default:
                    throw new Error('unsupported kernel type: ' + type);
            }
        } else if (typeof type === 'object' && typeof type.compute === 'function') {
            this.kernelFunction = type;
        } else {
            throw new TypeError('first argument must be a valid kernel type or instance');
        }
    }

    compute(inputs, landmarks) {
        if (landmarks === undefined) {
            landmarks = inputs;
        }
        const kernelMatrix = new Matrix(inputs.length, landmarks.length);
        if (inputs === landmarks) { // fast path, matrix is symmetric
            for (var i = 0; i < inputs.length; i++) {
                for (var j = i; j < inputs.length; j++) {
                    kernelMatrix[i][j] = kernelMatrix[j][i] = this.kernelFunction.compute(inputs[i], inputs[j]);
                }
            }
        } else {
            for (var i = 0; i < inputs.length; i++) {
                for (var j = 0; j < landmarks.length; j++) {
                    kernelMatrix[i][j] = this.kernelFunction.compute(inputs[i], landmarks[j]);
                }
            }
        }
        return kernelMatrix;
    }
}

module.exports = Kernel;
<commit_msg>refactor: don't redeclare variables<commit_after>'use strict';

const Matrix = require('ml-matrix');

const GaussianKernel = require('ml-gaussian-kernel');
const PolynomialKernel = require('ml-polynomial-kernel');

class Kernel {
    constructor (type, options) {
        if (typeof type === 'string') {
            switch (type.toLowerCase()) {
                case 'gaussian':
                case 'rbf':
                    this.kernelFunction = new GaussianKernel(options);
                    break;
                case 'polynomial':
                case 'poly':
                    this.kernelFunction = new PolynomialKernel(options);
                    break;
                default:
                    throw new Error('unsupported kernel type: ' + type);
            }
        } else if (typeof type === 'object' && typeof type.compute === 'function') {
            this.kernelFunction = type;
        } else {
            throw new TypeError('first argument must be a valid kernel type or instance');
        }
    }

    compute(inputs, landmarks) {
        if (landmarks === undefined) {
            landmarks = inputs;
        }
        const kernelMatrix = new Matrix(inputs.length, landmarks.length);
        var i, j;
        if (inputs === landmarks) { // fast path, matrix is symmetric
            for (i = 0; i < inputs.length; i++) {
                for (j = i; j < inputs.length; j++) {
                    kernelMatrix[i][j] = kernelMatrix[j][i] = this.kernelFunction.compute(inputs[i], inputs[j]);
                }
            }
        } else {
            for (i = 0; i < inputs.length; i++) {
                for (j = 0; j < landmarks.length; j++) {
                    kernelMatrix[i][j] = this.kernelFunction.compute(inputs[i], landmarks[j]);
                }
            }
        }
        return kernelMatrix;
    }
}

module.exports = Kernel;
<|endoftext|>