<commit_before>
;(function (w, doc) {

  // Enable strict mode
  "use strict";

  // Local object for method references
  var Corkscrew = {};

  // Namespace
  Corkscrew.ns = "Corkscrew";

  // Start defining methods here
  Corkscrew.init = function() {

    Corkscrew.addHTMLView();

    doc.getElementById('cs-nav-menu-toggle').addEventListener('click', function(e){

      e.preventDefault();
      doc.getElementById('cs-site-nav').classList.toggle('is-open');

    }, false);

  };

  // Convert a hax code to an RGB color value
  Corkscrew.hexToRgb = function ( hex ) {

    // Expand shorthand form (e.g. "03F") to full form (e.g. "0033FF")
    var shorthandRegex = /^#?([a-f\d])([a-f\d])([a-f\d])$/i;
    hex = hex.replace(shorthandRegex, function(m, r, g, b) {
        return r + r + g + g + b + b;
    });

    var result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
    return result ? {
        r: parseInt(result[1], 16),
        g: parseInt(result[2], 16),
        b: parseInt(result[3], 16),
        all: parseInt(result[1], 16) + ',' + parseInt(result[2], 16) + ',' + parseInt(result[3], 16)
    } : null;

  }; // hexToRgb()

  Corkscrew.generateSlug = function( baseName ) {

    var slug = baseName + Math.floor(Math.random() * (9999 - 1)) + 1;

    return slug;

  };

  Corkscrew.addHTMLView = function() {

  var modules = doc.querySelectorAll('.cs-content-section'),
      modulesCount = modules.length,
      moduleHTMLContent, contentTextArea, expandButton, module, moduleHeader, moduleContent, wrap, i, contentLabel, genSlug;

  if( modulesCount ) {

    for ( i = 0; i < modulesCount; i = i + 1 ) {

      module = modules[i];

      if( module.classList.contains('generate-html') ) {

        genSlug = Corkscrew.generateSlug('elem-');
        moduleHeader = module.querySelectorAll('.cs-content-header')[0];
        moduleContent = module.querySelectorAll('.cs-content')[0];
        moduleHTMLContent = moduleContent.innerHTML;
        wrap = doc.createElement("div");
        expandButton = doc.createElement("button");
        contentTextArea = doc.createElement("textarea");
        contentLabel = doc.createElement("label");

        expandButton.classList.add('cs-button');
        expandButton.classList.add('cs-button-html');
        expandButton.setAttribute('type', 'button');
        expandButton.innerHTML = "View HTML";
        wrap.classList.add('cs-view-html');
        contentTextArea.setAttribute("class", "cs-code-block");

        contentTextArea.setAttribute("id", genSlug);
        contentTextArea.setAttribute("name", genSlug);
        contentLabel.setAttribute("for", genSlug);
        contentLabel.setAttribute("class", "cs-is-hidden");

        contentLabel.innerHTML = "HTML Content for this Module";

        contentTextArea.innerHTML = moduleHTMLContent.replace(/^(\r\n)|(\n)/,'').replace(/^(\r\n)|(\n)/,'');
        contentTextArea.classList.add('cs-is-hidden');
        contentTextArea.spellcheck = false;
        contentTextArea.disabled = true;

        moduleHeader.appendChild(contentLabel);
        moduleHeader.appendChild(expandButton);
        wrap.appendChild(contentTextArea);

        moduleHeader.appendChild(wrap);

        expandButton.addEventListener('click', function(){

          var toggleElem = this.parentNode.querySelectorAll('.cs-code-block')[0];

          if( toggleElem.classList.contains('cs-is-hidden') ) {
            toggleElem.classList.remove('cs-is-hidden');
          } else {
            toggleElem.classList.add('cs-is-hidden');
            toggleElem.focus();
          }

        }, false);

      } // if

    } // for

  } // modulesCount

  },

  // Start the application
  Corkscrew.init();

} )( this, this.document );
<commit_msg>HTML blocks<commit_after>
;(function (w, doc) {

  // Enable strict mode
  "use strict";

  // Local object for method references
  var Corkscrew = {};

  // Namespace
  Corkscrew.ns = "Corkscrew";

  // Start defining methods here
  Corkscrew.init = function() {

    Corkscrew.addHTMLView();

    doc.getElementById('cs-nav-menu-toggle').addEventListener('click', function(e){

      e.preventDefault();
      doc.getElementById('cs-site-nav').classList.toggle('is-open');

    }, false);

  };

  // Convert a hax code to an RGB color value
  Corkscrew.hexToRgb = function ( hex ) {

    // Expand shorthand form (e.g. "03F") to full form (e.g. "0033FF")
    var shorthandRegex = /^#?([a-f\d])([a-f\d])([a-f\d])$/i;
    hex = hex.replace(shorthandRegex, function(m, r, g, b) {
        return r + r + g + g + b + b;
    });

    var result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
    return result ? {
        r: parseInt(result[1], 16),
        g: parseInt(result[2], 16),
        b: parseInt(result[3], 16),
        all: parseInt(result[1], 16) + ',' + parseInt(result[2], 16) + ',' + parseInt(result[3], 16)
    } : null;

  }; // hexToRgb()

  Corkscrew.generateSlug = function( baseName ) {

    var slug = baseName + Math.floor(Math.random() * (9999 - 1)) + 1;

    return slug;

  };

  Corkscrew.addHTMLView = function() {

  var modules = doc.querySelectorAll('.cs-content-section'),
      modulesCount = modules.length,
      moduleHTMLContent, contentTextArea, expandButton, module, moduleHeader, moduleContent, wrap, i, contentLabel, genSlug;

  if( modulesCount ) {

    for ( i = 0; i < modulesCount; i = i + 1 ) {

      module = modules[i];

      if( module.classList.contains('generate-html') ) {

        genSlug = Corkscrew.generateSlug('elem-');
        moduleHeader = module.querySelectorAll('.cs-content-header')[0];
        moduleContent = module.querySelectorAll('.cs-content')[0];
        moduleHTMLContent = moduleContent.innerHTML;
        wrap = doc.createElement("div");
        expandButton = doc.createElement("button");
        contentTextArea = doc.createElement("textarea");
        contentLabel = doc.createElement("label");

        expandButton.classList.add('cs-button');
        expandButton.classList.add('cs-button-html');
        expandButton.setAttribute('type', 'button');
        expandButton.innerHTML = "View HTML";
        wrap.classList.add('cs-view-html');
        contentTextArea.setAttribute("class", "cs-code-block");

        contentTextArea.setAttribute("id", genSlug);
        contentTextArea.setAttribute("name", genSlug);
        contentLabel.setAttribute("for", genSlug);
        contentLabel.setAttribute("class", "cs-is-hidden");

        contentLabel.innerHTML = "HTML Content for this Module";

        contentTextArea.innerHTML = moduleHTMLContent.replace(/^(\r\n)|(\n)/,'').replace(/^(\r\n)|(\n)/,'');
        contentTextArea.classList.add('cs-is-hidden');
        contentTextArea.spellcheck = false;
        contentTextArea.setAttribute('readonly', '');

        moduleHeader.appendChild(contentLabel);
        moduleHeader.appendChild(expandButton);
        wrap.appendChild(contentTextArea);

        moduleHeader.appendChild(wrap);

        expandButton.addEventListener('click', function(){

          var toggleElem = this.parentNode.querySelectorAll('.cs-code-block')[0];

          if( toggleElem.classList.contains('cs-is-hidden') ) {
            toggleElem.classList.remove('cs-is-hidden');
          } else {
            toggleElem.classList.add('cs-is-hidden');
            toggleElem.focus();
          }

        }, false);

      } // if

    } // for

  } // modulesCount

  },

  // Start the application
  Corkscrew.init();

} )( this, this.document );
<|endoftext|>


<commit_before> function main() {
         var map = new L.Map('map', {
             zoomControl: false,
             center: [44.908, -75.83],
             zoom: 15
         });
         L.tileLayer(
             'http://server.arcgisonline.com/ArcGIS/rest/services/Canvas/World_Light_Gray_Base/MapServer/tile/{z}/{y}/{x}', {
                 attribution: 'Tiles © Esri — Esri, DeLorme, NAVTEQ',
                 maxZoom: 16
             }).addTo(map);
         // load 10k course route
         $.getJSON("10k.geojson", function(data) {
             // add GeoJSON layer to the map once the file is loaded
             L.geoJson(data).addTo(map);
         });
         // Creates a marker
         var redMarker = L.AwesomeMarkers.icon({
             //prefix: 'fa',
			 //icon: 'flag-checkered',
			 iconColor: 'white',
             markerColor: 'black',
			 text: "1"
         });
         // load 10k course route features
         $.getJSON("features.geojson", function(data) {
             //add GeoJSON layer to the map once the file is loaded
             L.geoJson(data, {
                 pointToLayer: function(feature, latlng) {
                     return new L.marker(latlng, {
                         icon: redMarker
                     });
                 },
                 //onEachFeature: function(feature, layer) {
                 //layer.bindPopup(feature.properties.cng_Meters);
                 //}
             }).addTo(map);
         });
     }
     // you could use $(window).load(main);
 window.onload = main;<commit_msg>update markers<commit_after> function main() {
         var map = new L.Map('map', {
             zoomControl: false,
             center: [44.908, -75.83],
             zoom: 15
         });
         L.tileLayer(
             'http://server.arcgisonline.com/ArcGIS/rest/services/Canvas/World_Light_Gray_Base/MapServer/tile/{z}/{y}/{x}', {
                 attribution: 'Tiles © Esri — Esri, DeLorme, NAVTEQ',
                 maxZoom: 16
             }).addTo(map);
         // load 10k course route
         $.getJSON("10k.geojson", function(data) {
             // add GeoJSON layer to the map once the file is loaded
             L.geoJson(data).addTo(map);
         });
         // Creates a marker
         var redMarker = L.AwesomeMarkers.icon({
             //prefix: 'fa',
			 //icon: 'flag-checkered',
			 iconColor: 'white',
             markerColor: 'cadetblue',
			 html: "1"
         });
         // load 10k course route features
         $.getJSON("features.geojson", function(data) {
             //add GeoJSON layer to the map once the file is loaded
             L.geoJson(data, {
                 pointToLayer: function(feature, latlng) {
                     return new L.marker(latlng, {
                         icon: redMarker
                     });
                 },
                 //onEachFeature: function(feature, layer) {
                 //layer.bindPopup(feature.properties.cng_Meters);
                 //}
             }).addTo(map);
         });
     }
     // you could use $(window).load(main);
 window.onload = main;<|endoftext|>


<commit_before>'use strict';

/**
 * @ngdoc overview
 * @name dormManagementToolApp
 * @description
 * # dormManagementToolApp
 *
 * Main module of the application.
 */
angular
  .module('dormManagementToolApp', [
    'ngAnimate',
    'ngAria',
    'ngMessages',
    'ngMaterial',
    'ui.router',
    'angularMoment',
    'config'
  ])
  .config(['$stateProvider', '$urlRouterProvider', '$mdDateLocaleProvider', function ($stateProvider, $urlRouterProvider, $mdDateLocaleProvider) {
    $urlRouterProvider.otherwise('/');

    $stateProvider
      .state('dashboard', {
        url: '/',
        templateUrl: 'views/dashboard.html',
        authenticate: true
      })
      .state('login', {
        url: '/login',
        templateUrl: 'views/login.html',
        controller: 'LoginCtrl as login',
        authenticate: false
      })
      .state('inactive_periods', {
        url: '/inactive_periods',
        templateUrl: 'views/inactive_periods.html',
        authenticate: true
      })
      .state('register', {
        url: '/register',
        templateUrl: 'views/register.html',
        authenticate: true
      })
  }])
  .run(function ($rootScope, $state, AuthService) {
    $rootScope.$on("$stateChangeStart", function (event, toState, toParams, fromState, fromParams) {
      if (toState.authenticate && !AuthService.isAuthenticated()) {
        $state.transitionTo("login");
        event.preventDefault();
      }
    })
  })
  .controller('AppCtrl', ['$mdSidenav', '$state', 'UserService', '$http', '$q', 'ENV', function ($mdSidenav, $state, UserService, $http, $q, ENV) {
    this.toggleSidenav = function (menuId) {
      $mdSidenav(menuId).toggle();
    };
    this.logout = function () {
      localStorage.removeItem('token');
      $state.go('login');
    };
    this.userName = UserService.getName();

    function removeToken() {
      var q = $q.defer();
      localStorage.removeItem('token');
      q.resolve();
      return q.promise;
    }

    function validate_token () {
      var deferred = $q.defer();
      if (!localStorage.getItem('token')) {
        deferred.reject('no existing token');
      } else {
        $http.defaults.headers.common.Authorization = 'Token =  ' + JSON.parse(localStorage.getItem('token')).token;
        $http({
          method: 'GET',
          url: ENV.apiEndpoint + '/users/' + UserService.getId() + '/valid_token'
        })
          .then(
            function () {
              deferred.resolve('valid token');
            },
            function () {
              deferred.reject('invalid token');
            });
      }
      return deferred.promise
    }
    validate_token().then(function (status) {
      console.log(status);
    }, function (status) {
      console.log(status);
      removeToken().then(function () {
        $state.go('login');
      })
    });
  }]);
<commit_msg>Remove hashbang in URL by using HTML5 mode<commit_after>'use strict';

/**
 * @ngdoc overview
 * @name dormManagementToolApp
 * @description
 * # dormManagementToolApp
 *
 * Main module of the application.
 */
angular
  .module('dormManagementToolApp', [
    'ngAnimate',
    'ngAria',
    'ngMessages',
    'ngMaterial',
    'ui.router',
    'angularMoment',
    'config'
  ])
  .config(['$stateProvider', '$urlRouterProvider', '$locationProvider', function ($stateProvider, $urlRouterProvider, $locationProvider) {
    $urlRouterProvider.otherwise('/');

    $locationProvider.html5Mode({
      enabled: true,
      requireBase: false
    });

    $stateProvider
      .state('dashboard', {
        url: '/',
        templateUrl: 'views/dashboard.html',
        authenticate: true
      })
      .state('login', {
        url: '/login',
        templateUrl: 'views/login.html',
        controller: 'LoginCtrl as login',
        authenticate: false
      })
      .state('inactive_periods', {
        url: '/inactive_periods',
        templateUrl: 'views/inactive_periods.html',
        authenticate: true
      })
      .state('register', {
        url: '/register',
        templateUrl: 'views/register.html',
        authenticate: true
      })
  }])
  .run(function ($rootScope, $state, AuthService) {
    $rootScope.$on("$stateChangeStart", function (event, toState, toParams, fromState, fromParams) {
      if (toState.authenticate && !AuthService.isAuthenticated()) {
        $state.transitionTo("login");
        event.preventDefault();
      }
    })
  })
  .controller('AppCtrl', ['$mdSidenav', '$state', 'UserService', '$http', '$q', 'ENV', function ($mdSidenav, $state, UserService, $http, $q, ENV) {
    this.toggleSidenav = function (menuId) {
      $mdSidenav(menuId).toggle();
    };
    this.logout = function () {
      localStorage.removeItem('token');
      $state.go('login');
    };
    this.userName = UserService.getName();

    function removeToken() {
      var q = $q.defer();
      localStorage.removeItem('token');
      q.resolve();
      return q.promise;
    }

    function validate_token () {
      var deferred = $q.defer();
      if (!localStorage.getItem('token')) {
        deferred.reject('no existing token');
      } else {
        $http.defaults.headers.common.Authorization = 'Token =  ' + JSON.parse(localStorage.getItem('token')).token;
        $http({
          method: 'GET',
          url: ENV.apiEndpoint + '/users/' + UserService.getId() + '/valid_token'
        })
          .then(
            function () {
              deferred.resolve('valid token');
            },
            function () {
              deferred.reject('invalid token');
            });
      }
      return deferred.promise
    }
    validate_token().then(function (status) {
      console.log(status);
    }, function (status) {
      console.log(status);
      removeToken().then(function () {
        $state.go('login');
      })
    });
  }]);
<|endoftext|>


<commit_before>'use strict';

const pg = require('pg');
const async = require('async');
const _ = require('underscore');

let pool = new pg.Pool({
    host: 'localhost',
    database: 'booktown'
});

function runQuery(query, callback) {
    pool.connect((err, client, done) => {
        if (err) {
            //likely a connection error that will print to console.
            done();
            throw err;
        }
        client.query(query, (err, results) => {
           done();  //call done to release the client to the connection pool.
           callback(err, results); //make it the callers responsiblity for checking for query errors.
        });
    });
}

//Let's run all of the queries listed in the 'let's explore' section.

async.eachSeries([
   'select * from books',
   'select * from authors',
   'select title, first_name, last_name from books join authors on books.author_id = authors.id',
   "select title from authors join books on authors.id = books.author_id where authors.first_name = 'Mark' and authors.last_name = 'Lutz'",
   'select title, id, isbn from editions join books on editions.book_id = books.id',
   'select sum(cost * stock) as cost, sum(retail * stock) as retail_value from stock'
], (query, callback) => {
    console.log(`Running query: ${query}`);
    runQuery(query, (err, results) => {
        if (err) {
            console.error(`Error running query: ${err}`);
        } else {
            console.log('Rows from query');
            _.each(results.rows, (r) => {
                console.log(r);
            });
        }
        callback();
    });
}, (err) => {
    if (err) {
        throw err;
    }
    console.log('Finished running lets explore queries.');
    pool.close();
});<commit_msg>process.exit after done<commit_after>'use strict';

const pg = require('pg');
const async = require('async');
const _ = require('underscore');

let pool = new pg.Pool({
    host: 'localhost',
    database: 'booktown'
});

function runQuery(query, callback) {
    pool.connect((err, client, done) => {
        if (err) {
            //likely a connection error that will print to console.
            done();
            throw err;
        }
        client.query(query, (err, results) => {
           done();  //call done to release the client to the connection pool.
           callback(err, results); //make it the callers responsiblity for checking for query errors.
        });
    });
}

//Let's run all of the queries listed in the 'let's explore' section.

async.eachSeries([
   'select * from books',
   'select * from authors',
   'select title, first_name, last_name from books join authors on books.author_id = authors.id',
   "select title from authors join books on authors.id = books.author_id where authors.first_name = 'Mark' and authors.last_name = 'Lutz'",
   'select title, id, isbn from editions join books on editions.book_id = books.id',
   'select sum(cost * stock) as cost, sum(retail * stock) as retail_value from stock'
], (query, callback) => {
    console.log(`Running query: ${query}`);
    runQuery(query, (err, results) => {
        if (err) {
            console.error(`Error running query: ${err}`);
        } else {
            console.log('Rows from query');
            _.each(results.rows, (r) => {
                console.log(r);
            });
        }
        callback();
    });
}, (err) => {
    if (err) {
        throw err;
    }
    console.log('Finished running lets explore queries.');
    process.exit();
});<|endoftext|>


<commit_before>#! /usr/bin/env node

/* jshint node: true, esnext: true */
'use strict';

let path = require('path');
let fs = require('fs');
let program = require('commander');
let replaceStream = require('replacestream');

program
  .version('1.0.2')
  .option('-n, --noeol', 'Don\'t end the file with a newline.');
// .option('-w, --write', 'Replace the given file with the uglified one')
// .option('-c, --cheese [type]', 'Add the specified type of cheese [marble]', 'marble')

program.on('--help', function() {
  console.log('  Examples:');
  console.log('');
  console.log('    $ uglify-sql myscript.sql');
  console.log('                   # Outputs to the standard output');
  console.log('');
  console.log('    $ uglify-sql myscript.sql > uglified-script.sql');
  console.log('                   # Redirects the output to the desired file');
  console.log('');
});

program.parse(process.argv);

program.args.forEach(function(filename) {
  let input = fs.createReadStream(filename)
    .pipe(replaceStream(/--.*\n/g, ''))
    .pipe(replaceStream(/\/\*(?:[\s\S]*?)\*\//g, ''))
    .pipe(replaceStream(' =', '='))
    .pipe(replaceStream('= ', '='))
    .pipe(replaceStream('( ', '('))
    .pipe(replaceStream(' )', ')'))
    .pipe(replaceStream('\n', ' '))
    .pipe(replaceStream(/ +/g, ' '))
    .pipe(replaceStream(/^ /g, ''));

  if (program.write) {
    console.log("Not implemented");
    // input.pipe();
  } else {
    input.pipe(process.stdout);
    input.on('end', function() {
      console.log('');
    });
  }
});<commit_msg>crlf fix<commit_after>#! /usr/bin/env node

/* jshint node: true, esnext: true */
'use strict';

let path = require('path');
let fs = require('fs');
let program = require('commander');
let replaceStream = require('replacestream');

program
  .version('1.0.2')
  .option('-n, --noeol', 'Don\'t end the file with a newline.');
// .option('-w, --write', 'Replace the given file with the uglified one')
// .option('-c, --cheese [type]', 'Add the specified type of cheese [marble]', 'marble')

program.on('--help', function() {
  console.log('  Examples:');
  console.log('');
  console.log('    $ uglify-sql myscript.sql');
  console.log('                   # Outputs to the standard output');
  console.log('');
  console.log('    $ uglify-sql myscript.sql > uglified-script.sql');
  console.log('                   # Redirects the output to the desired file');
  console.log('');
});

program.parse(process.argv);

program.args.forEach(function(filename) {
  let input = fs.createReadStream(filename)
    .pipe(replaceStream(/--.*\n/g, ''))
    .pipe(replaceStream(/\/\*(?:[\s\S]*?)\*\//g, ''))
    .pipe(replaceStream(' =', '='))
    .pipe(replaceStream('= ', '='))
    .pipe(replaceStream('( ', '('))
    .pipe(replaceStream(' )', ')'))
    .pipe(replaceStream('\r\n', '\n'))
    .pipe(replaceStream('\n', ' '))
    .pipe(replaceStream(/ +/g, ' '))
    .pipe(replaceStream(/^ /g, ''));

  if (program.write) {
    console.log("Not implemented");
    // input.pipe();
  } else {
    input.pipe(process.stdout);
    input.on('end', function() {
      console.log('');
    });
  }
});
<|endoftext|>


<commit_before>import React from 'react'

import Games from './Games'
import Teams from './Teams'

import { removeGame } from '../../lib/gamesUtils'

class Dashboard extends React.Component {
  deleteGame = (e) => {
    e.preventDefault()
    removeGame(e.target.getAttribute('name'))
  }
  render () {
    const userId = this.props.userId
    const games = this.props.games || {}
    const teams = this.props.teams || {}
    const fetching = this.props.fetchingGames || this.props.fetchingTeams
    return (

Dashboard

            {fetching ?
Loading...
 : <Games userId={userId} games={games} teams={teams} deleteGame={this.deleteGame} />}

            {fetching ?
Loading...
 : <Teams teams={teams} />}

    )
  }
}

export default Dashboard
<commit_msg>Restyle Dashboard<commit_after>import React from 'react'

import Games from './Games'
import Teams from './Teams'

import { removeGame } from '../../lib/gamesUtils'

class Dashboard extends React.Component {
  deleteGame = (e) => {
    e.preventDefault()
    removeGame(e.target.getAttribute('name'))
  }
  render () {
    const userId = this.props.userId
    const games = this.props.games || {}
    const teams = this.props.teams || {}
    const fetching = this.props.fetchingGames || this.props.fetchingTeams
    return (

Dashboard

Games

Teams

Players

            {fetching ?
Loading...
 : <Games userId={userId} games={games} teams={teams} deleteGame={this.deleteGame} />}

            {fetching ?
Loading...
 : <Teams teams={teams} />}

            {fetching ?
Loading...
 : <Teams teams={teams} />}

    )
  }
}

export default Dashboard
<|endoftext|>


<commit_before>import React from 'react'
import { Link } from 'react-router'
import { ButtonToolbar,Button,Navbar,NavbarHeader,NavbarBrand,NavbarToggle,NavbarCollapse ,Nav,NavItem,MenuItem,NavDropdown} from 'react-bootstrap'

const light = '#fff'
const styles = {}

styles.wrapper = {
    padding: '20px 20px',
    overflow: 'hidden',
    background: '#4D4D60',
    color: light
}

styles.link = {
    padding: 11,
    color: light,
    fontWeight: 220
}

styles.activeLink = {
    ...styles.link,
    background: light,
    color: '#4D4D60'
}
class GlobalNav extends React.Component {
  constructor(props, context) {
    super(props, context)
    this.logOut = this.logOut.bind(this)
  }

  logOut() {
    alert('log out')
  }

  render() {
    const { user } = this.props
    return (

          <Link to="/" style={styles.link}>Home</Link>{' '}
          <Link to="/calendar" style={styles.link} activeStyle={styles.activeLink}>Calendar</Link>{' '}
          <Link to="/grades" style={styles.link} activeStyle={styles.activeLink}>Grades</Link>{' '}
          <Link to="/messages" style={styles.link} activeStyle={styles.activeLink}>Messages</Link>{' '}

          <Link style={styles.link} to="/profile">{user.name}</Link>
            <button onClick={this.logOut}>log out</button>
            登录

    )
  }
}

GlobalNav.defaultProps = {
  user: {
    id: 1,
    name: '常仪彪'
  }
}

export default GlobalNav
<commit_msg>初始化项目结构<commit_after>import React from 'react'
import { Link } from 'react-router'
import { ButtonToolbar,Button,Navbar,NavbarHeader,NavbarBrand,NavbarToggle,NavbarCollapse ,Nav,NavItem,MenuItem,NavDropdown} from 'react-bootstrap'

const light = '#fff'
const styles = {}

styles.wrapper = {
    padding: '20px 20px',
    overflow: 'hidden',
    background: '#4D4D60',
    color: light
}

styles.link = {
    padding: 11,
    color: light,
    fontWeight: 220
}

styles.activeLink = {
    ...styles.link,
    background: light,
    color: '#4D4D60'
}
class GlobalNav extends React.Component {
  constructor(props, context) {
    super(props, context)
    this.logOut = this.logOut.bind(this)
  }

  logOut() {
    alert('log out')
  }

  render() {
    const { user } = this.props
    return (

          <Link to="/" style={styles.link}>主页</Link>{' '}
          <Link to="/calendar" style={styles.link} activeStyle={styles.activeLink}>日历</Link>{' '}
          <Link to="/grades" style={styles.link} activeStyle={styles.activeLink}>级别</Link>{' '}
          <Link to="/messages" style={styles.link} activeStyle={styles.activeLink}>信息</Link>{' '}

          <Link style={styles.link} to="/profile">{user.name}</Link>
            <button onClick={this.logOut}>log out</button>
            登录

    )
  }
}

GlobalNav.defaultProps = {
  user: {
    id: 1,
    name: '常仪彪'
  }
}

export default GlobalNav
<|endoftext|>


<commit_before>let _Map = null;
let _mapMarkers = [];
let _markerCluster = null;
let serverData = [];

function initMap() {

}

const checkChanged = e => {
    const label = e.target.value;

    const found = _mapMarkers.find(x => x.label == label);
    if (!found) return;

    found.setVisible(!found.visible);
    _markerCluster.repaint();
}

const doMarkers = newMarkers => {
    if (_markerCluster) {
        for (var i = 0; i < _mapMarkers.length; i++) {
            _markerCluster.removeMarker(_mapMarkers[i]);
        }
    }
    _mapMarkers = newMarkers.map(x => new google.maps.Marker(x));
    _markerCluster = new MarkerClusterer(_Map,
        _mapMarkers,
        {
            imagePath: 'https://developers.google.com/maps/documentation/javascript/examples/markerclusterer/m' ,
            ignoreHidden: true
        }
    );
}

window.GoogleMap = {
    /**
        Makes a new map instance on the given target
        @param target HTMLElement The HTML element to mount the map onto
        @param config Object
        @param config.width the width of the target
        @param config.height the height of the target
        @param config.options The google map options
    */
	NewMap: (target, config) => {
        const { width, height, options } = config;

        _Map = new google.maps.Map(target, options);

        _Map.addListener('mouseup', function() {
            window.GoogleMap.AddMarkers();
        });
        window.addEventListener("resize", function() {
            google.maps.event.trigger(_Map, "resize");
        });

    },
	AddMarkers: () => {
        // Ping API endpoint
        const { north, east, west, south } = _Map.getBounds().toJSON();

        window.API.GetMarkerLocations({
            lat: _Map.center.lat(),
            lng: _Map.center.lng(),
            threshold: Math.min(Math.max(Math.abs(north - south), Math.abs(west - east)), 0.1)
        })
        .then(response => response.reduce((carry, item) => {
            if (_Map.getZoom() >= 17) {
                carry.push(item);
                return carry;
            }

            if (!carry.find(x => item.park == x.park)) {
                carry.push(item);
            }
            return carry;
        }, []))
        .then(x => {
            serverData  = x.slice();
            return x;
        })
        .then(response => response.map(x => {
            const label = _Map.getZoom() >= 17 ? x.label : x.park;
            return {
                 position: {
                     lat: +x.latitude,
                     lng: +x.longitude
                },
                label: label
            }
        }))
        .then(x => {
            const checkboxContainer = document.getElementById("mapCheckboxes");
            checkboxContainer.innerHTML = "";
            const header = document.createElement("h1");
            header.innerText = "Filter By: ";
            checkboxContainer.appendChild(header);
            x.reduce((carry, item) => {
                if (!carry.find(i => i == item)) {
                    carry.push(item);
                }
                return carry;
            }, [])
            .forEach(x => {
                const check = document.createElement("input");
                check.type = "checkbox";
                check.value = x.label;
                check.id = x.label;
                check.addEventListener("change", checkChanged);

                const label = document.createElement("label");
                label.innerText = x.label;
                label.htmlFor = x.ItemID;

                const container = document.createElement("div");
                container.appendChild(check);
                container.appendChild(label);

                checkboxContainer.appendChild(container);
            })

            return x;
        })
        // .then(response => response.filter(x => true))
        // Filter out unchecked items
        .then(doMarkers)
        .catch(err => {
            throw new Error(err)
        });
    },
    GoTo: to => {
        _Map.setCenter(to.getPosition());
        _Map.setZoom(19);
        window.GoogleMap.AddMarkers();
    },
    GetRandom: () => {

        if (serverData.length) {
            const i = Math.floor(Math.random() * serverData.length);
            return {
                original: serverData[i],
                marker: _mapMarkers[i]
            };
        }
    }
}<commit_msg>Added multiple checks<commit_after>let _Map = null;
let _mapMarkers = [];
let _markerCluster = null;
let serverData = [];

function initMap() {

}

const checkChanged = e => {
    const label = e.target.value;

    const found = _mapMarkers.filter(x => x.label == label);
    console.log(found);
    if (!found.length) return;
    found.forEach(x => {
        x.setVisible(!x.visible);
    })

    _markerCluster.repaint();
}

const doMarkers = newMarkers => {
    if (_markerCluster) {
        for (var i = 0; i < _mapMarkers.length; i++) {
            _markerCluster.removeMarker(_mapMarkers[i]);
        }
    }
    _mapMarkers = newMarkers.map(x => {
        const m = new google.maps.Marker(x);
        m.addListener('click', function(e) {
            if (_Map.getZoom() >= 17) {
                // SHOW VR
                console.log("SHOW VR");
                e.preventDefault();

            }
        });
        return m;
    });
    _markerCluster = new MarkerClusterer(_Map,
        _mapMarkers,
        {
            imagePath: 'https://developers.google.com/maps/documentation/javascript/examples/markerclusterer/m' ,
            ignoreHidden: true
        }
    );
}

window.GoogleMap = {
    /**
        Makes a new map instance on the given target
        @param target HTMLElement The HTML element to mount the map onto
        @param config Object
        @param config.width the width of the target
        @param config.height the height of the target
        @param config.options The google map options
    */
	NewMap: (target, config) => {
        const { width, height, options } = config;

        _Map = new google.maps.Map(target, options);

        _Map.addListener('mouseup', function() {
            window.GoogleMap.AddMarkers();
        });
        window.addEventListener("resize", function() {
            google.maps.event.trigger(_Map, "resize");
        });

    },
	AddMarkers: () => {
        // Ping API endpoint
        const { north, east, west, south } = _Map.getBounds().toJSON();

        window.API.GetMarkerLocations({
            lat: _Map.center.lat(),
            lng: _Map.center.lng(),
            threshold: Math.min(Math.max(Math.abs(north - south), Math.abs(west - east)), 0.1)
        })
        .then(response => response.reduce((carry, item) => {
            if (_Map.getZoom() >= 17) {
                carry.push(item);
                return carry;
            }

            if (!carry.find(x => item.park == x.park)) {
                carry.push(item);
            }
            return carry;
        }, []))
        .then(x => x.filter(i => i.label != ""))
        .then(x => {
            serverData  = x.slice();
            return x;
        })
        .then(response => response.map(x => {
            const label = _Map.getZoom() >= 17 ? x.label : x.park;
            return {
                 position: {
                     lat: +x.latitude,
                     lng: +x.longitude
                },
                label: label
            }
        }))
        .then(x => {
            const checkboxContainer = document.getElementById("mapCheckboxes");
            checkboxContainer.innerHTML = "";
            const header = document.createElement("h1");
            header.innerText = "Filter By: ";
            checkboxContainer.appendChild(header);
            x.reduce((carry, item) => {
                if (!carry.find(i => i.label == item.label)) {
                    carry.push(item);
                }
                return carry;
            }, [])
            .sort((a, b) => a.label.localeCompare(b.label))
            .forEach(x => {
                const check = document.createElement("input");
                check.type = "checkbox";
                check.value = x.label;
                check.id = x.label;
                check.addEventListener("change", checkChanged);

                const label = document.createElement("label");
                label.innerText = x.label;
                label.htmlFor = x.label;

                const container = document.createElement("div");
                container.appendChild(check);
                container.appendChild(label);

                checkboxContainer.appendChild(container);
            })

            return x;
        })
        // .then(response => response.filter(x => true))
        // Filter out unchecked items
        .then(doMarkers)
        .catch(err => {
            throw new Error(err)
        });
    },
    GoTo: to => {
        _Map.setCenter(to.getPosition());
        _Map.setZoom(19);
        window.GoogleMap.AddMarkers();
    },
    GetRandom: () => {

        if (serverData.length) {
            const i = Math.floor(Math.random() * serverData.length);
            return {
                original: serverData[i],
                marker: _mapMarkers[i]
            };
        }
    }
}<|endoftext|>


<commit_before>import React, { Component } from 'react'
import style from './style.css'
import glStyles, { getCompareStyles } from './glstyles'
import Swiper from './swiper'
import FilterButton from '../FilterButton'
import SearchBox from '../SearchBox'
import Legend from '../Legend'
import { bindActionCreators } from 'redux'
import { connect } from 'react-redux'
import * as MapActions from '../../actions/map'
import { bboxPolygon, area, erase } from 'turf'
import { debounce } from 'lodash'
import regionToCoords from './regionToCoords'
import themes from '../../settings/themes'
import settings from '../../settings/settings'

// leaflet plugins
import * as _leafletmapboxgljs from '../../libs/leaflet-mapbox-gl.js'
import * as _leafleteditable from '../../libs/Leaflet.Editable.js'

var map // Leaflet map object
var glLayer // mapbox-gl layer
var glCompareLayers // mapbox-gl layers for before/after view
var boundsLayer = null // selected region layer
var moveDirectly = false

class Map extends Component {
  state = {}

  render() {
    const { view, actions, embed, theme } = this.props
    const containerClassName = (embed === false) ? `${view}View` : ''
    const activeLayer = this.props.layers.find(layer => layer.name === this.props.map.filters[0])
    return (

        {this.props.map.view === 'compare'
          ? <Swiper onMoved={::this.swiperMoved} theme={themes[theme]} />
          : ''
        }

        {embed === false &&

          <SearchBox className="searchbox" selectedRegion={this.props.map.region} {...actions}/>
          or
          <button className="outline" onClick={::this.setViewportRegion}>Outline Custom Area</button>
          <FilterButton
            layers={this.props.layers}
            enabledFilters={this.props.map.filters}
            {...actions}
          />

}

        <Legend
          layer={activeLayer}
          zoom={this.state.mapZoomLevel}
          showHighlighted={!!this.props.stats.timeFilter || !!this.props.stats.experienceFilter}
          theme={theme}
        />

    )
  }

  componentDidMount() {
    const { theme, embed, layers } = this.props

    const activeLayer = layers.find(layer => layer.name === this.props.map.filters[0])

    map = L.map(
      'map', {
      editable: true,
      minZoom: 2,
      scrollWheelZoom: !embed
    })
    .setView([0, 35], 2)
    map.on('editable:editing', debounce(::this.setCustomRegion, 200))
    map.on('zoomend', (e) => { this.setState({ mapZoomLevel:map.getZoom() }) })

    L.control.scale({ position: 'bottomright' }).addTo(map)
    map.zoomControl.setPosition('bottomright')

    L.tileLayer(settings['map-background-tile-layer'], {
      attribution: settings['map-attribution'],
      zIndex: -1
    }).addTo(map)

    if (!mapboxgl.supported()) {
      alert('This browser does not support WebGL which is required to run this application. Please check that you are using a supported browser and that WebGL is enabled.')
    }
    glLayer = L.mapboxGL({
      updateInterval: 0,
      style: glStyles(layers, activeLayer, { theme }),
      hash: false
    })

    const glCompareLayerStyles = getCompareStyles(layers, activeLayer, this.props.map.times, theme)
    glCompareLayers = {
      before: L.mapboxGL({
        updateInterval: 0,
        style: glCompareLayerStyles.before,
        hash: false
      }),
      after: L.mapboxGL({
        updateInterval: 0,
        style: glCompareLayerStyles.after,
        hash: false
      })
    }

    // add glLayers if map state is already initialized
    if (this.props.map.view === 'country' || this.props.map.view === 'default') {
      glLayer.addTo(map)
    } else if (this.props.map.view === 'compare') {
      glCompareLayers.before.addTo(map)
      glCompareLayers.after.addTo(map)
    }

    // init from route params
    if (this.props.region) {
      moveDirectly = true
      this.mapSetRegion(this.props.map.region, this.props.embed === false, this.props.embed === false)
    }

    if (this.props.stats.timeFilter) {
      glLayer._glMap.on('load', () =>
        this.setTimeFilter(this.props.stats.timeFilter)
      )
    }
  }

  componentWillReceiveProps(nextProps) {
    const { theme, layers } = this.props

    // ceck for changed url parameters
    if (nextProps.region !== this.props.region) {
      this.props.actions.setRegionFromUrl(nextProps.region)
    }
    if (nextProps.filters !== this.props.filters) {
      this.props.actions.setFiltersFromUrl(nextProps.filters)
    }
    if (nextProps.overlay !== this.props.overlay) {
      this.props.actions.setOverlayFromUrl(nextProps.overlay)
    }
    if (nextProps.overlay !== this.props.overlay) {
      this.props.actions.setOverlayFromUrl(nextProps.overlay)
    }
    if (nextProps.view !== this.props.view) {
      this.props.actions.setViewFromUrl(nextProps.view)
    }
    if (nextProps.times !== this.props.times) {
      this.props.actions.setTimesFromUrl(nextProps.times)
    }
    // check for changed map parameters
    if (nextProps.map.region !== this.props.map.region) {
      this.mapSetRegion(nextProps.map.region, nextProps.embed === false, nextProps.embed === false)
    }
    const nextActiveLayer = layers.find(layer => layer.name === nextProps.map.filters[0])
    if (nextProps.map.filters.join() !== this.props.map.filters.join()) { // todo: handle this in reducer?
      glLayer.setStyle(glStyles(layers, nextActiveLayer, {
        timeFilter: nextProps.stats.timeFilter,
        experienceFilter: nextProps.stats.experienceFilter,
        theme
      }))
      let glCompareLayerStyles = getCompareStyles(layers, nextActiveLayer, nextProps.map.times, theme)
      glCompareLayers.before.setStyle(glCompareLayerStyles.before)
      glCompareLayers.after.setStyle(glCompareLayerStyles.after)
    }
    if (nextProps.map.times !== this.props.map.times) {
      let glCompareLayerStyles = getCompareStyles(layers, nextActiveLayer, nextProps.map.times, theme)
      if (nextProps.map.times[0] !== this.props.map.times[0]) {
        glCompareLayers.before.setStyle(glCompareLayerStyles.before)
      }
      if (nextProps.map.times[1] !== this.props.map.times[1]) {
        glCompareLayers.after.setStyle(glCompareLayerStyles.after)
      }
    }
    // check for changed time/experience filter
    if (nextProps.stats.timeFilter !== this.props.stats.timeFilter) {
      this.setTimeFilter(nextProps.stats.timeFilter)
    }
    if (nextProps.stats.experienceFilter !== this.props.stats.experienceFilter) {
      this.setExperienceFilter(nextProps.stats.experienceFilter)
    }
    // check for switched map views (country/compare)
    if (nextProps.map.view !== this.props.map.view) {
      if (!(this.props.map.view === 'country' || this.props.map.view === 'default')
        && (nextProps.map.view === 'country' || nextProps.map.view === 'default')) {
        glCompareLayers.before.removeFrom(map)
        glCompareLayers.after.removeFrom(map)
        glLayer.addTo(map)
      }
      if (nextProps.map.view === 'compare') {
        glLayer.removeFrom(map)
        glCompareLayers.before.addTo(map)
        glCompareLayers.after.addTo(map)
        this.swiperMoved(window.innerWidth/2)
      }
    }
  }

  setViewportRegion() {
    var pixelBounds = map.getPixelBounds()
    var paddedLatLngBounds = L.latLngBounds(
      map.unproject(
        pixelBounds.getBottomLeft().add([30,-(20+212)])
      ),
      map.unproject(
        pixelBounds.getTopRight().subtract([30,-(70+52)])
      )
    ).pad(-0.15)
    this.props.actions.setRegion({
      type: 'bbox',
      coords: paddedLatLngBounds
        .toBBoxString()
        .split(',')
        .map(Number)
    })
  }

  setCustomRegion() {
    if (!boundsLayer) return
    this.props.actions.setRegion({
      type: 'polygon',
      coords: L.polygon(boundsLayer.getLatLngs()[1]).toGeoJSON().geometry.coordinates[0].slice(0,-1)
    })
  }

  mapSetRegion(region, isEditable, fitBoundsWithBottomPadding) {
    const { swiper: { poly } } = themes[this.props.theme]

    if (boundsLayer !== null && region === null) {
      map.removeLayer(boundsLayer)
      return
    }
    regionToCoords(region, 'leaflet')
    .then(function(region) {
      let coords = region.geometry.coordinates

      if (boundsLayer !== null) {
        map.removeLayer(boundsLayer)
      }
      boundsLayer = L[poly.shape](
        [[[-85.0511287798,-1E5],[85.0511287798,-1E5],[85.0511287798,2E5],[-85.0511287798,2E5],[-85.0511287798,-1E5]]]
        .concat(coords), {
        weight: poly.weight,
        color: poly.color,
        interactive: false
      }).addTo(map)

      if (isEditable) {
        boundsLayer.enableEdit()
      }

      // set map view to region
      try { // geometry calculcation are a bit hairy for invalid geometries (which may happen during polygon editing)
        let viewPort = bboxPolygon(map.getBounds().toBBoxString().split(',').map(Number))
        let xorAreaViewPort = erase(viewPort, L.polygon(boundsLayer.getLatLngs()[1]).toGeoJSON())
        let fitboundsFunc
        if (moveDirectly) {
          fitboundsFunc = ::map.fitBounds
          moveDirectly = false
        } else if (
          !xorAreaViewPort // new region fully includes viewport
          || area(xorAreaViewPort) > area(viewPort)*(1-0.01) // region is small compared to current viewport (<10% of the area covered) or feature is outside current viewport
        ) {
          fitboundsFunc = ::map.flyToBounds
        } else {
          fitboundsFunc = () => {}
        }
        fitboundsFunc(
          // zoom to inner ring!
          boundsLayer.getLatLngs().slice(1)
            .map(coords => L.polygon(coords).getBounds())
            .reduce((bounds1, bounds2) => bounds1.extend(bounds2)),
        {
          paddingTopLeft: [20, 10+52],
          paddingBottomRight: [20, 10+ ((fitBoundsWithBottomPadding) ? 212 : 52)]
        })
      } catch(e) {}
    });
  }

  setTimeFilter(timeFilter) {
    const { theme, layers } = this.props

    const activeLayer = layers.find(layer => layer.name === this.props.map.filters[0])
    const highlightLayers = glStyles(layers, activeLayer, { theme }).layers.filter(l => l.id.match(/highlight/))
    if (timeFilter === null) {
      // reset time filter
      highlightLayers.forEach(highlightLayer => {
        glLayer._glMap.setFilter(highlightLayer.id, ["==", "_timestamp", -1])
      })
    } else {
      highlightLayers.forEach(highlightLayer => {
        let layerFilter = ["any",
          ["all",
            [">=", "_timestamp", timeFilter[0]],
            ["<=", "_timestamp", timeFilter[1]]
          ],
          ["all",
            [">=", "_timestampMin", timeFilter[0]],
            ["<=", "_timestampMax", timeFilter[1]]
          ]
        ]
        if (highlightLayer.densityFilter) {
          layerFilter = ["all",
            highlightLayer.densityFilter,
            layerFilter
          ]
        }
        glLayer._glMap.setFilter(highlightLayer.id, layerFilter)
      })
    }
  }

  setExperienceFilter(experienceFilter) {
    const { theme, layers } = this.props

    const activeLayer = layers.find(layer => layer.name === this.props.map.filters[0])
    const highlightLayers = glStyles(layers, activeLayer, { theme }).layers.map(l => l.id).filter(id => id.match(/highlight/))
    if (experienceFilter === null) {
      // reset time filter
      highlightLayers.forEach(highlightLayer => {
        glLayer._glMap.setFilter(highlightLayer, ["==", "_timestamp", -1])
      })
    } else {
      highlightLayers.forEach(highlightLayer => {
        glLayer._glMap.setFilter(highlightLayer, ["all",
          [">=", "_userExperience", experienceFilter[0]],
          ["<=", "_userExperience", experienceFilter[1]]
        ])
      })
    }
  }

  swiperMoved(x) {
    if (!map) return
    const mapPanePos = map._getMapPanePos()
    const nw = map.containerPointToLayerPoint([0, 0])
    const se = map.containerPointToLayerPoint(map.getSize())
    const clipX = nw.x + (se.x - nw.x) * x / window.innerWidth
    glCompareLayers.before._glContainer.style.clip = 'rect(' + [nw.y+mapPanePos.y, clipX+mapPanePos.x, se.y+mapPanePos.y, nw.x+mapPanePos.x].join('px,') + 'px)'
    glCompareLayers.after._glContainer.style.clip = 'rect(' + [nw.y+mapPanePos.y, se.x+mapPanePos.x, se.y+mapPanePos.y, clipX+mapPanePos.x].join('px,') + 'px)'
  }

}

function mapStateToProps(state) {
  return {
    map: state.map,
    stats: state.stats
  }
}

function mapDispatchToProps(dispatch) {
  return {
    actions: bindActionCreators(MapActions, dispatch)
  }
}

export default connect(
  mapStateToProps,
  mapDispatchToProps
)(Map)
<commit_msg>make sure swiper map panes are initialized when starting in compare mode<commit_after>import React, { Component } from 'react'
import style from './style.css'
import glStyles, { getCompareStyles } from './glstyles'
import Swiper from './swiper'
import FilterButton from '../FilterButton'
import SearchBox from '../SearchBox'
import Legend from '../Legend'
import { bindActionCreators } from 'redux'
import { connect } from 'react-redux'
import * as MapActions from '../../actions/map'
import { bboxPolygon, area, erase } from 'turf'
import { debounce } from 'lodash'
import regionToCoords from './regionToCoords'
import themes from '../../settings/themes'
import settings from '../../settings/settings'

// leaflet plugins
import * as _leafletmapboxgljs from '../../libs/leaflet-mapbox-gl.js'
import * as _leafleteditable from '../../libs/Leaflet.Editable.js'

var map // Leaflet map object
var glLayer // mapbox-gl layer
var glCompareLayers // mapbox-gl layers for before/after view
var boundsLayer = null // selected region layer
var moveDirectly = false

class Map extends Component {
  state = {}

  render() {
    const { view, actions, embed, theme } = this.props
    const containerClassName = (embed === false) ? `${view}View` : ''
    const activeLayer = this.props.layers.find(layer => layer.name === this.props.map.filters[0])
    return (

        {this.props.map.view === 'compare'
          ? <Swiper onMoved={::this.swiperMoved} theme={themes[theme]} />
          : ''
        }

        {embed === false &&

          <SearchBox className="searchbox" selectedRegion={this.props.map.region} {...actions}/>
          or
          <button className="outline" onClick={::this.setViewportRegion}>Outline Custom Area</button>
          <FilterButton
            layers={this.props.layers}
            enabledFilters={this.props.map.filters}
            {...actions}
          />

}

        <Legend
          layer={activeLayer}
          zoom={this.state.mapZoomLevel}
          showHighlighted={!!this.props.stats.timeFilter || !!this.props.stats.experienceFilter}
          theme={theme}
        />

    )
  }

  componentDidMount() {
    const { theme, embed, layers } = this.props

    const activeLayer = layers.find(layer => layer.name === this.props.map.filters[0])

    map = L.map(
      'map', {
      editable: true,
      minZoom: 2,
      scrollWheelZoom: !embed
    })
    .setView([0, 35], 2)
    map.on('editable:editing', debounce(::this.setCustomRegion, 200))
    map.on('zoomend', (e) => { this.setState({ mapZoomLevel:map.getZoom() }) })

    L.control.scale({ position: 'bottomright' }).addTo(map)
    map.zoomControl.setPosition('bottomright')

    L.tileLayer(settings['map-background-tile-layer'], {
      attribution: settings['map-attribution'],
      zIndex: -1
    }).addTo(map)

    if (!mapboxgl.supported()) {
      alert('This browser does not support WebGL which is required to run this application. Please check that you are using a supported browser and that WebGL is enabled.')
    }
    glLayer = L.mapboxGL({
      updateInterval: 0,
      style: glStyles(layers, activeLayer, { theme }),
      hash: false
    })

    const glCompareLayerStyles = getCompareStyles(layers, activeLayer, this.props.map.times, theme)
    glCompareLayers = {
      before: L.mapboxGL({
        updateInterval: 0,
        style: glCompareLayerStyles.before,
        hash: false
      }),
      after: L.mapboxGL({
        updateInterval: 0,
        style: glCompareLayerStyles.after,
        hash: false
      })
    }

    // add glLayers if map state is already initialized
    if (this.props.map.view === 'country' || this.props.map.view === 'default') {
      glLayer.addTo(map)
    } else if (this.props.map.view === 'compare') {
      glCompareLayers.before.addTo(map)
      glCompareLayers.after.addTo(map)
      this.swiperMoved(window.innerWidth/2)
    }

    // init from route params
    if (this.props.region) {
      moveDirectly = true
      this.mapSetRegion(this.props.map.region, this.props.embed === false, this.props.embed === false)
    }

    if (this.props.stats.timeFilter) {
      glLayer._glMap.on('load', () =>
        this.setTimeFilter(this.props.stats.timeFilter)
      )
    }
  }

  componentWillReceiveProps(nextProps) {
    const { theme, layers } = this.props

    // ceck for changed url parameters
    if (nextProps.region !== this.props.region) {
      this.props.actions.setRegionFromUrl(nextProps.region)
    }
    if (nextProps.filters !== this.props.filters) {
      this.props.actions.setFiltersFromUrl(nextProps.filters)
    }
    if (nextProps.overlay !== this.props.overlay) {
      this.props.actions.setOverlayFromUrl(nextProps.overlay)
    }
    if (nextProps.overlay !== this.props.overlay) {
      this.props.actions.setOverlayFromUrl(nextProps.overlay)
    }
    if (nextProps.view !== this.props.view) {
      this.props.actions.setViewFromUrl(nextProps.view)
    }
    if (nextProps.times !== this.props.times) {
      this.props.actions.setTimesFromUrl(nextProps.times)
    }
    // check for changed map parameters
    if (nextProps.map.region !== this.props.map.region) {
      this.mapSetRegion(nextProps.map.region, nextProps.embed === false, nextProps.embed === false)
    }
    const nextActiveLayer = layers.find(layer => layer.name === nextProps.map.filters[0])
    if (nextProps.map.filters.join() !== this.props.map.filters.join()) { // todo: handle this in reducer?
      glLayer.setStyle(glStyles(layers, nextActiveLayer, {
        timeFilter: nextProps.stats.timeFilter,
        experienceFilter: nextProps.stats.experienceFilter,
        theme
      }))
      let glCompareLayerStyles = getCompareStyles(layers, nextActiveLayer, nextProps.map.times, theme)
      glCompareLayers.before.setStyle(glCompareLayerStyles.before)
      glCompareLayers.after.setStyle(glCompareLayerStyles.after)
    }
    if (nextProps.map.times !== this.props.map.times) {
      let glCompareLayerStyles = getCompareStyles(layers, nextActiveLayer, nextProps.map.times, theme)
      if (nextProps.map.times[0] !== this.props.map.times[0]) {
        glCompareLayers.before.setStyle(glCompareLayerStyles.before)
      }
      if (nextProps.map.times[1] !== this.props.map.times[1]) {
        glCompareLayers.after.setStyle(glCompareLayerStyles.after)
      }
    }
    // check for changed time/experience filter
    if (nextProps.stats.timeFilter !== this.props.stats.timeFilter) {
      this.setTimeFilter(nextProps.stats.timeFilter)
    }
    if (nextProps.stats.experienceFilter !== this.props.stats.experienceFilter) {
      this.setExperienceFilter(nextProps.stats.experienceFilter)
    }
    // check for switched map views (country/compare)
    if (nextProps.map.view !== this.props.map.view) {
      if (!(this.props.map.view === 'country' || this.props.map.view === 'default')
        && (nextProps.map.view === 'country' || nextProps.map.view === 'default')) {
        glCompareLayers.before.removeFrom(map)
        glCompareLayers.after.removeFrom(map)
        glLayer.addTo(map)
      }
      if (nextProps.map.view === 'compare') {
        glLayer.removeFrom(map)
        glCompareLayers.before.addTo(map)
        glCompareLayers.after.addTo(map)
        this.swiperMoved(window.innerWidth/2)
      }
    }
  }

  setViewportRegion() {
    var pixelBounds = map.getPixelBounds()
    var paddedLatLngBounds = L.latLngBounds(
      map.unproject(
        pixelBounds.getBottomLeft().add([30,-(20+212)])
      ),
      map.unproject(
        pixelBounds.getTopRight().subtract([30,-(70+52)])
      )
    ).pad(-0.15)
    this.props.actions.setRegion({
      type: 'bbox',
      coords: paddedLatLngBounds
        .toBBoxString()
        .split(',')
        .map(Number)
    })
  }

  setCustomRegion() {
    if (!boundsLayer) return
    this.props.actions.setRegion({
      type: 'polygon',
      coords: L.polygon(boundsLayer.getLatLngs()[1]).toGeoJSON().geometry.coordinates[0].slice(0,-1)
    })
  }

  mapSetRegion(region, isEditable, fitBoundsWithBottomPadding) {
    const { swiper: { poly } } = themes[this.props.theme]

    if (boundsLayer !== null && region === null) {
      map.removeLayer(boundsLayer)
      return
    }
    regionToCoords(region, 'leaflet')
    .then(function(region) {
      let coords = region.geometry.coordinates

      if (boundsLayer !== null) {
        map.removeLayer(boundsLayer)
      }
      boundsLayer = L[poly.shape](
        [[[-85.0511287798,-1E5],[85.0511287798,-1E5],[85.0511287798,2E5],[-85.0511287798,2E5],[-85.0511287798,-1E5]]]
        .concat(coords), {
        weight: poly.weight,
        color: poly.color,
        interactive: false
      }).addTo(map)

      if (isEditable) {
        boundsLayer.enableEdit()
      }

      // set map view to region
      try { // geometry calculcation are a bit hairy for invalid geometries (which may happen during polygon editing)
        let viewPort = bboxPolygon(map.getBounds().toBBoxString().split(',').map(Number))
        let xorAreaViewPort = erase(viewPort, L.polygon(boundsLayer.getLatLngs()[1]).toGeoJSON())
        let fitboundsFunc
        if (moveDirectly) {
          fitboundsFunc = ::map.fitBounds
          moveDirectly = false
        } else if (
          !xorAreaViewPort // new region fully includes viewport
          || area(xorAreaViewPort) > area(viewPort)*(1-0.01) // region is small compared to current viewport (<10% of the area covered) or feature is outside current viewport
        ) {
          fitboundsFunc = ::map.flyToBounds
        } else {
          fitboundsFunc = () => {}
        }
        fitboundsFunc(
          // zoom to inner ring!
          boundsLayer.getLatLngs().slice(1)
            .map(coords => L.polygon(coords).getBounds())
            .reduce((bounds1, bounds2) => bounds1.extend(bounds2)),
        {
          paddingTopLeft: [20, 10+52],
          paddingBottomRight: [20, 10+ ((fitBoundsWithBottomPadding) ? 212 : 52)]
        })
      } catch(e) {}
    });
  }

  setTimeFilter(timeFilter) {
    const { theme, layers } = this.props

    const activeLayer = layers.find(layer => layer.name === this.props.map.filters[0])
    const highlightLayers = glStyles(layers, activeLayer, { theme }).layers.filter(l => l.id.match(/highlight/))
    if (timeFilter === null) {
      // reset time filter
      highlightLayers.forEach(highlightLayer => {
        glLayer._glMap.setFilter(highlightLayer.id, ["==", "_timestamp", -1])
      })
    } else {
      highlightLayers.forEach(highlightLayer => {
        let layerFilter = ["any",
          ["all",
            [">=", "_timestamp", timeFilter[0]],
            ["<=", "_timestamp", timeFilter[1]]
          ],
          ["all",
            [">=", "_timestampMin", timeFilter[0]],
            ["<=", "_timestampMax", timeFilter[1]]
          ]
        ]
        if (highlightLayer.densityFilter) {
          layerFilter = ["all",
            highlightLayer.densityFilter,
            layerFilter
          ]
        }
        glLayer._glMap.setFilter(highlightLayer.id, layerFilter)
      })
    }
  }

  setExperienceFilter(experienceFilter) {
    const { theme, layers } = this.props

    const activeLayer = layers.find(layer => layer.name === this.props.map.filters[0])
    const highlightLayers = glStyles(layers, activeLayer, { theme }).layers.map(l => l.id).filter(id => id.match(/highlight/))
    if (experienceFilter === null) {
      // reset time filter
      highlightLayers.forEach(highlightLayer => {
        glLayer._glMap.setFilter(highlightLayer, ["==", "_timestamp", -1])
      })
    } else {
      highlightLayers.forEach(highlightLayer => {
        glLayer._glMap.setFilter(highlightLayer, ["all",
          [">=", "_userExperience", experienceFilter[0]],
          ["<=", "_userExperience", experienceFilter[1]]
        ])
      })
    }
  }

  swiperMoved(x) {
    if (!map) return
    const mapPanePos = map._getMapPanePos()
    const nw = map.containerPointToLayerPoint([0, 0])
    const se = map.containerPointToLayerPoint(map.getSize())
    const clipX = nw.x + (se.x - nw.x) * x / window.innerWidth
    glCompareLayers.before._glContainer.style.clip = 'rect(' + [nw.y+mapPanePos.y, clipX+mapPanePos.x, se.y+mapPanePos.y, nw.x+mapPanePos.x].join('px,') + 'px)'
    glCompareLayers.after._glContainer.style.clip = 'rect(' + [nw.y+mapPanePos.y, se.x+mapPanePos.x, se.y+mapPanePos.y, clipX+mapPanePos.x].join('px,') + 'px)'
  }

}

function mapStateToProps(state) {
  return {
    map: state.map,
    stats: state.stats
  }
}

function mapDispatchToProps(dispatch) {
  return {
    actions: bindActionCreators(MapActions, dispatch)
  }
}

export default connect(
  mapStateToProps,
  mapDispatchToProps
)(Map)
<|endoftext|>


<commit_before>import React, {Component} from 'react';
import {Card, CardActions, CardHeader, CardMedia, CardTitle, CardText} from 'material-ui';
import FlatButton from 'material-ui/FlatButton';

class EventItem extends Component {
  constructor(props) {
    super(props);
    this.state = {
      openEvent: false
    };
  }

  render() {
    return (
      <Card >
        <CardHeader
          className="card-top"
          title={this.props.event.title}
          subtitle={this.props.event.location}
          avatar="http://enadcity.org/enadcity/wp-content/uploads/2017/02/profile-pictures.png"
        />
         <CardMedia
          overlay={<CardTitle title={this.props.event.location}
          subtitle={this.props.event.date} />}
        >

        </CardMedia>
        <CardTitle className="description-card" title={this.props.event.title} subtitle={this.props.event.category} />
        <CardText className="description-card">
           { this.props.event.description }
        </CardText>
        <CardActions className="actions">
           <FlatButton className="btn" label="Would Love To Go!" onClick={() => this.props.handleEventClick(this.props.event)}/>
           <FlatButton className="btn" label="I'm Gonna Pass for Now" />
        </CardActions>
      </Card>
      );
    }
}

export {EventItem};
<commit_msg>Fixed date in eventItem<commit_after>import React, {Component} from 'react';
import {Card, CardActions, CardHeader, CardMedia, CardTitle, CardText} from 'material-ui';
import FlatButton from 'material-ui/FlatButton';
import moment from 'moment';

class EventItem extends Component {
  constructor(props) {
    super(props);
    this.state = {
      openEvent: false
    };
  }

  render() {
    return (
      <Card >
        <CardHeader
          className="card-top"
          title={this.props.event.title}
          subtitle={this.props.event.location}
          avatar="http://enadcity.org/enadcity/wp-content/uploads/2017/02/profile-pictures.png"
        />
         <CardMedia
          overlay={<CardTitle title={this.props.event.location}
          subtitle={moment(this.props.event.date)
           .format('MMMM DD, YYYY')} />}
        >

        </CardMedia>
        <CardTitle className="description-card" title={this.props.event.title} subtitle={this.props.event.category} />
        <CardText className="description-card">
           { this.props.event.description }
        </CardText>
        <CardActions className="actions">
           <FlatButton className="btn" label="Would Love To Go!" onClick={() => this.props.handleEventClick(this.props.event)}/>
           <FlatButton className="btn" label="I'm Gonna Pass for Now" />
        </CardActions>
      </Card>
      );
    }
}

export {EventItem};
<|endoftext|>


<commit_before>import Ember from 'ember';
import { task } from 'ember-concurrency';
import { on } from '@ember/object/evented';
import { translationMacro as t } from 'ember-i18n';
import triggerAnalytics from 'irene/utils/trigger-analytics';

const {inject: {service}} = Ember;

export default Ember.Component.extend({
  me: service(),
  i18n: service(),
  ajax: service(),
  session: service(),
  organization: service(),

  isLoaded: false,
  isSecurityEnabled: false,
  isSecurityDashboard: false,

  tSomethingWentWrong: t("somethingWentWrong"),
  tOrganizationNameUpdated: t("organizationNameUpdated"),

  securityEnabled() {
    this.get("ajax").request("projects", {namespace: 'hudson-api'})
    .then(() => {
      this.set("isSecurityEnabled", true);
      this.securityDashboard();
    }, () => {
      this.set("isSecurityEnabled", false);
      this.securityDashboard();
    });
  },

  isEmptyOrganization: (function() {
    const organization = this.get("organization");
    const isOwner = this.get("me.org.is_owner")
    if(isOwner) {
      const orgName = organization.selected.get("name");
      if(!orgName) {
        return true;
      }
    }
  }).property("me.org.is_owner"),

  securityDashboard() {
    if(window.location.pathname.startsWith("/security")) {
      const isSecurityEnabled = this.get("isSecurityEnabled");
      if(isSecurityEnabled) {
        this.set("isSecurityDashboard", true);
      }
      else {
        Ember.getOwner(this).lookup('route:authenticated').transitionTo("authenticated.projects");
      }
      this.set("isLoaded", true);
    }
    else {
      this.set("isLoaded", true);
    }
  },

  didInsertElement() {
    this.securityEnabled();
  },

  /* Update org name */
  updateOrgName: task(function * () {
    const org = this.get('organization').selected;
    org.set('name', this.get("organizationName"));
    yield org.save();
  }).evented(),

  updateOrgNameSucceeded: on('updateOrgName:succeeded', function() {
    this.get('notify').success(this.get('tOrganizationNameUpdated'));
    this.set("isEmptyOrganization", false);
    this.set("isUpdatingOrg", false);
  }),

  updateOrgNameErrored: on('updateOrgName:errored', function(_, err) {
    let errMsg = this.get('tSomethingWentWrong');
    if (err.errors && err.errors.length) {
      errMsg = err.errors[0].detail || errMsg;
    } else if(err.message) {
      errMsg = err.message;
    }
    this.set("isUpdatingOrg", false);
    this.get("notify").error(errMsg);
  }),

  actions: {
    invalidateSession() {
      triggerAnalytics('logout');
      this.get('session').invalidate();
    }
  }

});
<commit_msg>use computed property instead of property<commit_after>import Ember from 'ember';
import { task } from 'ember-concurrency';
import { on } from '@ember/object/evented';
import { translationMacro as t } from 'ember-i18n';
import triggerAnalytics from 'irene/utils/trigger-analytics';

const {inject: {service}} = Ember;

export default Ember.Component.extend({
  me: service(),
  i18n: service(),
  ajax: service(),
  session: service(),
  organization: service(),

  isLoaded: false,
  isSecurityEnabled: false,
  isSecurityDashboard: false,

  tSomethingWentWrong: t("somethingWentWrong"),
  tOrganizationNameUpdated: t("organizationNameUpdated"),

  securityEnabled() {
    this.get("ajax").request("projects", {namespace: 'hudson-api'})
    .then(() => {
      this.set("isSecurityEnabled", true);
      this.securityDashboard();
    }, () => {
      this.set("isSecurityEnabled", false);
      this.securityDashboard();
    });
  },

  isEmptyOrganization: Ember.computed("me.org.is_owner", function() {
    const organization = this.get("organization");
    const isOwner = this.get("me.org.is_owner")
    if(isOwner) {
      const orgName = organization.selected.get("name");
      if(!orgName) {
        return true;
      }
    }
  }),

  securityDashboard() {
    if(window.location.pathname.startsWith("/security")) {
      const isSecurityEnabled = this.get("isSecurityEnabled");
      if(isSecurityEnabled) {
        this.set("isSecurityDashboard", true);
      }
      else {
        Ember.getOwner(this).lookup('route:authenticated').transitionTo("authenticated.projects");
      }
      this.set("isLoaded", true);
    }
    else {
      this.set("isLoaded", true);
    }
  },

  didInsertElement() {
    this.securityEnabled();
  },

  /* Update org name */
  updateOrgName: task(function * () {
    const org = this.get('organization').selected;
    org.set('name', this.get("organizationName"));
    yield org.save();
  }).evented(),

  updateOrgNameSucceeded: on('updateOrgName:succeeded', function() {
    this.get('notify').success(this.get('tOrganizationNameUpdated'));
    this.set("isEmptyOrganization", false);
    this.set("isUpdatingOrg", false);
  }),

  updateOrgNameErrored: on('updateOrgName:errored', function(_, err) {
    let errMsg = this.get('tSomethingWentWrong');
    if (err.errors && err.errors.length) {
      errMsg = err.errors[0].detail || errMsg;
    } else if(err.message) {
      errMsg = err.message;
    }
    this.set("isUpdatingOrg", false);
    this.get("notify").error(errMsg);
  }),

  actions: {
    invalidateSession() {
      triggerAnalytics('logout');
      this.get('session').invalidate();
    }
  }

});
<|endoftext|>


<commit_before>/*jslint browser: true */

/*global tangelo, google, d3, $ */

(function () {
    "use strict";

    if (!window.google) {
        tangelo.GoogleMapSVG = function () {
            throw "Use of the GoogleMapSVG class requires loading the Google Map API *before* loading Tangelo.";
        };
        return;
    }

    tangelo.GoogleMapSVG = function (elem, mapoptions, cfg) {
        var that,
            idle,
            sel;

        // Obtain a unique id for this class.
        this.id = "gmsvg-" + tangelo.uniqueID();

        // Create a div element to put in the container element.
        this.mapdiv = d3.select(elem)
            .append("div")
            .attr("id", this.id)
            .style("width", $(elem).width() + "px")
            .style("height", $(elem).height() + "px")
            .node();

        // Create the map and place it in the "map div".
        this.map = new google.maps.Map(this.mapdiv, mapoptions);
        this.setMap(this.map);

        // Compute the size of the map div.
        this.size = {
            width: $(this.mapdiv).width(),
            height: $(this.mapdiv).height()
        };

        // When the map is dragged, resized, or zoomed, emit the appropriate
        // events and/or redraw the SVG layer.
        that = this;
        google.maps.event.addListener(this.map, "drag", function () {
            that.draw();
        });
        google.maps.event.addListener(this.map, "zoom_changed", function () {
            that.draw();
        });
        $(this.mapdiv).resize(function () {
            google.maps.event.trigger(this.map, "resize");
        });

        // Store the config for later use.
        this.cfg = cfg || {};
    };

    tangelo.GoogleMapSVG.prototype = new google.maps.OverlayView();

    tangelo.GoogleMapSVG.prototype.onAdd = function () {
        // Put an SVG element in the mouse target overlay.
        this.svg = d3.select(this.getPanes().overlayMouseTarget)
            .append("svg")
            .attr("width", this.size.width)
            .attr("height", this.size.height);

        if (this.cfg.initialize) {
            this.cfg.initialize.call(this, this.svg.node(), this.getProjection(), this.map);
        }

    };

    tangelo.GoogleMapSVG.prototype.draw = function () {
        var mattrans,
            xtrans,
            ytrans,
            setTimeout;

        // Find the matrix transform for the overlay.
        mattrans = d3.select("#" + this.id + " [style*='webkit-transform: matrix']")
            .style("-webkit-transform")
            .split(" ")
            .map(function (v, i) {
                var retval;

                if (i === 0) {
                    retval = v.slice("matrix(".length, -1);
                } else {
                    retval = v.slice(0, -1);
                }

                return retval;
            });

        // If the map is in the middle of a zooming transform, abort the draw
        // operation and try again in a little while.
        if (mattrans[0] !== "1" || mattrans[3] !== "1") {
            window.setTimeout(google.maps.event.trigger, 100, this.map, "drag");
            return;
        }

        // Extract the translation component.
        xtrans = mattrans[4];
        ytrans = mattrans[5];

        // Give the svg element an opposite transform to hold it in place.
        this.svg.style("-webkit-transform", "translate(" + (-xtrans) + "px," + (-ytrans) + "px)");

        // Call the user's draw method, if there is one.
        if (this.cfg.draw) {
            this.cfg.draw.call(this, this.svg.node(), this.getProjection(), this.map);
        }
    };
}());
<commit_msg>Ability to pass a continuation callback to GoogleMapSVG constructor.<commit_after>/*jslint browser: true */

/*global tangelo, google, d3, $ */

(function () {
    "use strict";

    if (!window.google) {
        tangelo.GoogleMapSVG = function () {
            throw "Use of the GoogleMapSVG class requires loading the Google Map API *before* loading Tangelo.";
        };
        return;
    }

    tangelo.GoogleMapSVG = function (elem, mapoptions, cfg, cont) {
        var that,
            idle,
            sel;

        // Obtain a unique id for this class.
        this.id = "gmsvg-" + tangelo.uniqueID();

        // Create a div element to put in the container element.
        this.mapdiv = d3.select(elem)
            .append("div")
            .attr("id", this.id)
            .style("width", $(elem).width() + "px")
            .style("height", $(elem).height() + "px")
            .node();

        // Create the map and place it in the "map div".
        this.map = new google.maps.Map(this.mapdiv, mapoptions);
        this.setMap(this.map);

        // Compute the size of the map div.
        this.size = {
            width: $(this.mapdiv).width(),
            height: $(this.mapdiv).height()
        };

        // When the map is dragged, resized, or zoomed, emit the appropriate
        // events and/or redraw the SVG layer.
        that = this;
        google.maps.event.addListener(this.map, "drag", function () {
            that.draw();
        });
        google.maps.event.addListener(this.map, "zoom_changed", function () {
            that.draw();
        });
        $(this.mapdiv).resize(function () {
            google.maps.event.trigger(this.map, "resize");
        });

        // Store the config for later use.
        this.cfg = cfg || {};

        if (cont) {
            google.maps.event.addListenerOnce(this.map, "idle", function () {
                cont(that);
            });
        }
    };

    tangelo.GoogleMapSVG.prototype = new google.maps.OverlayView();

    tangelo.GoogleMapSVG.prototype.getSVG = function () {
        return this.svg.node();
    };

    tangelo.GoogleMapSVG.prototype.onAdd = function () {
        // Put an SVG element in the mouse target overlay.
        this.svg = d3.select(this.getPanes().overlayMouseTarget)
            .append("svg")
            .attr("width", this.size.width)
            .attr("height", this.size.height);

        if (this.cfg.initialize) {
            this.cfg.initialize.call(this, this.svg.node(), this.getProjection(), this.map);
        }

    };

    tangelo.GoogleMapSVG.prototype.draw = function () {
        var mattrans,
            xtrans,
            ytrans,
            setTimeout;

        // Find the matrix transform for the overlay.
        mattrans = d3.select("#" + this.id + " [style*='webkit-transform: matrix']")
            .style("-webkit-transform")
            .split(" ")
            .map(function (v, i) {
                var retval;

                if (i === 0) {
                    retval = v.slice("matrix(".length, -1);
                } else {
                    retval = v.slice(0, -1);
                }

                return retval;
            });

        // If the map is in the middle of a zooming transform, abort the draw
        // operation and try again in a little while.
        if (mattrans[0] !== "1" || mattrans[3] !== "1") {
            window.setTimeout(google.maps.event.trigger, 100, this.map, "drag");
            return;
        }

        // Extract the translation component.
        xtrans = mattrans[4];
        ytrans = mattrans[5];

        // Give the svg element an opposite transform to hold it in place.
        this.svg.style("-webkit-transform", "translate(" + (-xtrans) + "px," + (-ytrans) + "px)");

        // Call the user's draw method, if there is one.
        if (this.cfg.draw) {
            this.cfg.draw.call(this, this.svg.node(), this.getProjection(), this.map);
        }
    };
}());
<|endoftext|>


<commit_before>/*!
 * Copyright 2011 France Télécom
 * This software is distributed under the terms of either the MIT
 * License or the GNU General Public License (GPL) Version 2.
 * See GPL-LICENSE.txt and MIT-LICENSE.txt files for more details.
 */

(function(window, document, undefined) {

/* cssrule.js
 * Version : 1
 *
 * Authors: Julien Wajsberg <julien.wajsberg@orange.com>
 *
 * This module can insert CSS rules in a cross-browser way.
 * It was inspired by http://code.google.com/p/doctype/wiki/ArticleInstallStyles
 *
*/

	var propToSet, stylesheet;

	function insertInPage(elt) {
		var firstScript = document.getElementsByTagName('script')[0];
		firstScript.parentNode.insertBefore(elt, firstScript);
	}

	function createStylesheet() {
		if (document.createStyleSheet) {
			// in IE
			stylesheet = document.createStyleSheet();
		} else {
			stylesheet = document.createElement("style");
			stylesheet.id = "cssrule";
			insertInPage(stylesheet);
		}
	}

	function findPropToSet() {
		var possibleprops = "cssText,innerText,innerHTML".split(",");

		for (i = 0; i < possibleprops.length; i++) {
			cur = possibleprops[i];
			if (stylesheet[cur] !== undefined) {
				propToSet = cur;
				break;
			}
		}
	}

	function init() {
		var i, cur;

		createStylesheet();
		findPropToSet();
	}

	function add(style) {
		stylesheet[propToSet] += style;
		return cssrule;
	}

	window.cssrule = {
		/**
		 * you must call "init" function on dom ready
		 * TODO: should we run it automatically when "add" is used the first time ?
		 */
		init: init,
		add: add
	};
})(this, document);
<commit_msg>add the current year in the copyright<commit_after>/*!
 * Copyright 2011,2012 France Télécom
 * This software is distributed under the terms of either the MIT
 * License or the GNU General Public License (GPL) Version 2.
 * See GPL-LICENSE.txt and MIT-LICENSE.txt files for more details.
 */

(function(window, document, undefined) {

/* cssrule.js
 * Version : 1
 *
 * Authors: Julien Wajsberg <julien.wajsberg@orange.com>
 *
 * This module can insert CSS rules in a cross-browser way.
 * It was inspired by http://code.google.com/p/doctype/wiki/ArticleInstallStyles
 *
*/

	var propToSet, stylesheet;

	function insertInPage(elt) {
		var firstScript = document.getElementsByTagName('script')[0];
		firstScript.parentNode.insertBefore(elt, firstScript);
	}

	function createStylesheet() {
		if (document.createStyleSheet) {
			// in IE
			stylesheet = document.createStyleSheet();
		} else {
			stylesheet = document.createElement("style");
			stylesheet.id = "cssrule";
			insertInPage(stylesheet);
		}
	}

	function findPropToSet() {
		var possibleprops = "cssText,innerText,innerHTML".split(",");

		for (i = 0; i < possibleprops.length; i++) {
			cur = possibleprops[i];
			if (stylesheet[cur] !== undefined) {
				propToSet = cur;
				break;
			}
		}
	}

	function init() {
		var i, cur;

		createStylesheet();
		findPropToSet();
	}

	function add(style) {
		stylesheet[propToSet] += style;
		return cssrule;
	}

	window.cssrule = {
		/**
		 * you must call "init" function on dom ready
		 * TODO: should we run it automatically when "add" is used the first time ?
		 */
		init: init,
		add: add
	};
})(this, document);
<|endoftext|>


<commit_before>'use strict';
const Conversation = require('./Conversation');
const EventEmitter = require('eventemitter3');
const express = require('express');
const bodyParser = require('body-parser');
const crypto = require('crypto');
const fetch = require('node-fetch');

class BootBot extends EventEmitter {
  constructor(options) {
    super();
    this.access_token = options.access_token;
    this.verify_token = options.verify_token;
    this.app_secret = options.app_secret;
    this.app = express();
    this.app.use(bodyParser.json({ verify: this._verifyRequestSignature.bind(this) }));
    this._hearMap = [];
    this._conversations = [];
    this._initWebhook();
  }

  start(port) {
    this.app.set('port', port || 3000);
    this.app.listen(this.app.get('port'), () => {
      console.log('BootBot running on port', this.app.get('port'));
    });
  }

  sendTextMessage(text, recipientId) {
    return this.sendMessage({ text }, recipientId);
  }

  sendButtonMessage(text, buttons, recipientId) {
    const message = {
      'attachment': {
        'type': 'template',
        'payload': {
          'template_type': 'button',
          'text': text,
          'buttons': buttons
        }
      }
    };
    return this.sendMessage(message, recipientId);
  }

  sendGenericTemplate(cards, recipientId) {
    const message = {
      'attachment': {
        'type': 'template',
        'payload': {
          'template_type': 'generic',
          'elements': cards
        }
      }
    };
    return this.sendMessage(message, recipientId);
  }

  sendMessage(message, recipientId) {
    return fetch(`https://graph.facebook.com/v2.6/me/messages?access_token=${this.access_token}`, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({
        recipient: {
          id: recipientId
        },
        message
      })
    })
    .then(res => res.json())
    .catch(err => console.log(`Error sending message: ${err}`));
  }

  say(text, recipientId) {
    return this.sendTextMessage(text, recipientId);
  }

  hear(keywords, callback) {
    keywords = Array.isArray(keywords) ? keywords : [ keywords ];
    keywords.forEach(keyword => this._hearMap.push({ keyword, callback }));
    return this;
  }

  module(factory) {
    return factory(this);
  }

  conversation(recipientId, factory) {
    if (!recipientId || !factory || typeof factory !== 'function') {
      return console.error(`You need to specify a recipient and a callback to start a conversation`);
    }
    const convo = new Conversation(this, recipientId);
    this._conversations.push(convo);
    convo.on('end', (endedConvo) => {
      const removeIndex = this._conversations.indexOf(endedConvo);
      this._conversations.splice(removeIndex, 1);
    });
    factory.apply(this, [ convo ]);
    return convo;
  }

  _handleEvent(type, event, data) {
    this.emit(type, event, data);
  }

  _handleMessageEvent(event) {
    if (this._handleConversationResponse(event)) { return; }
    const text = event.message.text;
    let captured = false;
    if (!text) { return; }

    this._hearMap.forEach(hear => {
      if (hear.keyword.toLowerCase() === text.toLowerCase()) {
        captured = true;
        return hear.callback.apply(this, [event, {
          keyword: hear.keyword
        }]);
      } else if (hear.keyword instanceof RegExp && hear.keyword.test(text)) {
        captured = true;
        return hear.callback.apply(this, [event, {
          keyword: hear.keyword,
          match: text.match(hear.keyword)
        }]);
      }
    });

    this._handleEvent('message', event, { captured });
  }

  _handleAttachmentEvent(event) {
    if (this._handleConversationResponse(event)) { return; }
    this._handleEvent('attachment', event);
  }

  _handlePostbackEvent(event) {
    if (this._handleConversationResponse(event)) { return; }
    this._handleEvent('postback', event);
  }

  _handleConversationResponse(event) {
    const userId = event.sender.id;
    let captured = false;
    this._conversations.forEach(convo => {
      if (userId && userId === convo.userId && convo.isActive()) {
        captured = true;
        return convo.respond(event, {});
      }
    });
    return captured;
  }

  _initWebhook() {
    this.app.get('/webhook', (req, res) => {
      if (req.query['hub.mode'] === 'subscribe' && req.query['hub.verify_token'] === this.verify_token) {
        console.log('Validation Succeded.')
        res.status(200).send(req.query['hub.challenge']);
      } else {
        console.error('Failed validation. Make sure the validation tokens match.');
        res.sendStatus(403);
      }
    });

    this.app.post('/webhook', (req, res) => {
      var data = req.body;
      if (data.object !== 'page') {
        return;
      }

      // Iterate over each entry. There may be multiple if batched.
      data.entry.forEach((entry) => {
          // Iterate over each messaging event
          entry.messaging.forEach((event) => {
            if (event.optin) {
              this._handleEvent('authentication', event);
            } else if (event.message && event.message.text) {
              this._handleMessageEvent(event);
            } else if (event.message && event.message.attachments) {
              this._handleAttachmentEvent(event);
            } else if (event.postback) {
              this._handlePostbackEvent(event);
            } else if (event.delivery) {
              this._handleEvent('delivery', event);
            } else if (event.read) {
              this._handleEvent('read', event);
            } else {
              console.log('Webhook received unknown event: ', event);
            }
          });
        });

        // Must send back a 200 within 20 seconds or the request will time out.
        res.sendStatus(200);
    });
  }

  _verifyRequestSignature(req, res, buf) {
    var signature = req.headers['x-hub-signature'];
    if (!signature) {
      throw new Error('Couldn\'t validate the request signature.');
    } else {
      var elements = signature.split('=');
      var method = elements[0];
      var signatureHash = elements[1];
      var expectedHash = crypto.createHmac('sha1', this.app_secret)
                          .update(buf)
                          .digest('hex');

      if (signatureHash != expectedHash) {
        throw new Error("Couldn't validate the request signature.");
      }
    }
  }
}

module.exports = BootBot;
<commit_msg>Added close method to kill the server<commit_after>'use strict';
const Conversation = require('./Conversation');
const EventEmitter = require('eventemitter3');
const express = require('express');
const bodyParser = require('body-parser');
const crypto = require('crypto');
const fetch = require('node-fetch');

class BootBot extends EventEmitter {
  constructor(options) {
    super();
    if (!options || (options && (!options.access_token || !options.verify_token || !options.app_secret))) {
      throw new Error('You need to specify an access_token, verify_token and app_secret');
    }
    this.access_token = options.access_token;
    this.verify_token = options.verify_token;
    this.app_secret = options.app_secret;
    this.app = express();
    this.app.use(bodyParser.json({ verify: this._verifyRequestSignature.bind(this) }));
    this._hearMap = [];
    this._conversations = [];
    this._initWebhook();
  }

  start(port) {
    this.app.set('port', port || 3000);
    this.server = this.app.listen(this.app.get('port'), () => {
      console.log('BootBot running on port', this.app.get('port'));
    });
  }

  close() {
    this.server.close();
  }

  sendTextMessage(text, recipientId) {
    return this.sendMessage({ text }, recipientId);
  }

  sendButtonMessage(text, buttons, recipientId) {
    const message = {
      'attachment': {
        'type': 'template',
        'payload': {
          'template_type': 'button',
          'text': text,
          'buttons': buttons
        }
      }
    };
    return this.sendMessage(message, recipientId);
  }

  sendGenericTemplate(cards, recipientId) {
    const message = {
      'attachment': {
        'type': 'template',
        'payload': {
          'template_type': 'generic',
          'elements': cards
        }
      }
    };
    return this.sendMessage(message, recipientId);
  }

  sendMessage(message, recipientId) {
    return fetch(`https://graph.facebook.com/v2.6/me/messages?access_token=${this.access_token}`, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({
        recipient: {
          id: recipientId
        },
        message
      })
    })
    .then(res => res.json())
    .catch(err => console.log(`Error sending message: ${err}`));
  }

  say(text, recipientId) {
    return this.sendTextMessage(text, recipientId);
  }

  hear(keywords, callback) {
    keywords = Array.isArray(keywords) ? keywords : [ keywords ];
    keywords.forEach(keyword => this._hearMap.push({ keyword, callback }));
    return this;
  }

  module(factory) {
    return factory(this);
  }

  conversation(recipientId, factory) {
    if (!recipientId || !factory || typeof factory !== 'function') {
      return console.error(`You need to specify a recipient and a callback to start a conversation`);
    }
    const convo = new Conversation(this, recipientId);
    this._conversations.push(convo);
    convo.on('end', (endedConvo) => {
      const removeIndex = this._conversations.indexOf(endedConvo);
      this._conversations.splice(removeIndex, 1);
    });
    factory.apply(this, [ convo ]);
    return convo;
  }

  _handleEvent(type, event, data) {
    this.emit(type, event, data);
  }

  _handleMessageEvent(event) {
    if (this._handleConversationResponse(event)) { return; }
    const text = event.message.text;
    let captured = false;
    if (!text) { return; }

    this._hearMap.forEach(hear => {
      if (hear.keyword.toLowerCase() === text.toLowerCase()) {
        captured = true;
        return hear.callback.apply(this, [event, {
          keyword: hear.keyword
        }]);
      } else if (hear.keyword instanceof RegExp && hear.keyword.test(text)) {
        captured = true;
        return hear.callback.apply(this, [event, {
          keyword: hear.keyword,
          match: text.match(hear.keyword)
        }]);
      }
    });

    this._handleEvent('message', event, { captured });
  }

  _handleAttachmentEvent(event) {
    if (this._handleConversationResponse(event)) { return; }
    this._handleEvent('attachment', event);
  }

  _handlePostbackEvent(event) {
    if (this._handleConversationResponse(event)) { return; }
    this._handleEvent('postback', event);
  }

  _handleConversationResponse(event) {
    const userId = event.sender.id;
    let captured = false;
    this._conversations.forEach(convo => {
      if (userId && userId === convo.userId && convo.isActive()) {
        captured = true;
        return convo.respond(event, {});
      }
    });
    return captured;
  }

  _initWebhook() {
    this.app.get('/webhook', (req, res) => {
      if (req.query['hub.mode'] === 'subscribe' && req.query['hub.verify_token'] === this.verify_token) {
        console.log('Validation Succeded.')
        res.status(200).send(req.query['hub.challenge']);
      } else {
        console.error('Failed validation. Make sure the validation tokens match.');
        res.sendStatus(403);
      }
    });

    this.app.post('/webhook', (req, res) => {
      var data = req.body;
      if (data.object !== 'page') {
        return;
      }

      // Iterate over each entry. There may be multiple if batched.
      data.entry.forEach((entry) => {
          // Iterate over each messaging event
          entry.messaging.forEach((event) => {
            if (event.optin) {
              this._handleEvent('authentication', event);
            } else if (event.message && event.message.text) {
              this._handleMessageEvent(event);
            } else if (event.message && event.message.attachments) {
              this._handleAttachmentEvent(event);
            } else if (event.postback) {
              this._handlePostbackEvent(event);
            } else if (event.delivery) {
              this._handleEvent('delivery', event);
            } else if (event.read) {
              this._handleEvent('read', event);
            } else {
              console.log('Webhook received unknown event: ', event);
            }
          });
        });

        // Must send back a 200 within 20 seconds or the request will time out.
        res.sendStatus(200);
    });
  }

  _verifyRequestSignature(req, res, buf) {
    var signature = req.headers['x-hub-signature'];
    if (!signature) {
      throw new Error('Couldn\'t validate the request signature.');
    } else {
      var elements = signature.split('=');
      var method = elements[0];
      var signatureHash = elements[1];
      var expectedHash = crypto.createHmac('sha1', this.app_secret)
                          .update(buf)
                          .digest('hex');

      if (signatureHash != expectedHash) {
        throw new Error("Couldn't validate the request signature.");
      }
    }
  }
}

module.exports = BootBot;
<|endoftext|>