<commit_before>'use strict';
angular.module('confRegistrationWebApp', ['ngRoute', 'ngCookies', 'ui.bootstrap'])
  .config(function ($routeProvider, $injector) {
    $routeProvider
      .when('/', {
        templateUrl: 'views/landing.html',
        controller: 'landingCtrl'
      })
      .when('/register/:conferenceId', {
        resolve: {
          redirect: ['$location', '$route', function ($location, $route) {
            $location.path('/register/' + $route.current.params.conferenceId + '/page/');
          }]
        }
      })
      .when('/register/:conferenceId/page/:pageId?', {
        templateUrl: 'views/registration.html',
        controller: 'RegistrationCtrl',
        resolve: {
          enforceAuth: $injector.get('enforceAuth'),
          conference: ['$route', 'ConfCache', function ($route, ConfCache) {
            return ConfCache.get($route.current.params.conferenceId);
          }],
          currentRegistration: ['$route', 'RegistrationCache', function ($route, RegistrationCache) {
            return RegistrationCache.getCurrent($route.current.params.conferenceId);
          }]
        }
      })
      .when('/payment/:conferenceId', {
        templateUrl: 'views/payment.html',
        controller: 'paymentCtrl',
        resolve: {
          enforceAuth: $injector.get('enforceAuth'),
          registration: ['$route', 'RegistrationCache', function ($route, RegistrationCache) {
            return RegistrationCache.getCurrent($route.current.params.conferenceId)
              .then(function (currentRegistration) {
                return currentRegistration;
              });
          }],
          conference: ['$route', 'ConfCache', function ($route, ConfCache) {
            return ConfCache.get($route.current.params.conferenceId);
          }]
        }
      })
      .when('/reviewRegistration/:conferenceId', {
        templateUrl: 'views/reviewRegistration.html',
        controller: 'ReviewRegistrationCtrl',
        resolve: {
          enforceAuth: $injector.get('enforceAuth'),
          registration: ['$route', 'RegistrationCache', function ($route, RegistrationCache) {
            return RegistrationCache.getCurrent($route.current.params.conferenceId)
              .then(function (currentRegistration) {
                return currentRegistration;
              });
          }],
          conference: ['$route', 'ConfCache', function ($route, ConfCache) {
            return ConfCache.get($route.current.params.conferenceId);
          }]
        }
      })
      .when('/preview/:conferenceId/page/:pageId?', {
        templateUrl: 'views/registration.html',
        controller: 'RegistrationCtrl',
        resolve: {
          enforceAuth: $injector.get('enforceAuth'),
          conference: ['$route', 'ConfCache', function ($route, ConfCache) {
            return ConfCache.get($route.current.params.conferenceId);
          }],
          currentRegistration: ['$route', 'RegistrationCache', function ($route, RegistrationCache) {
            return RegistrationCache.getCurrent($route.current.params.conferenceId);
          }]
        }
      })
      .when('/eventDashboard', {
        templateUrl: 'views/eventDashboard.html',
        controller: 'eventDashboardCtrl',
        resolve: {
          enforceAuth: $injector.get('enforceAuth')
        }
      })
      .when('/eventOverview/:conferenceId', {
        templateUrl: 'views/eventOverview.html',
        controller: 'eventOverviewCtrl',
        resolve: {
          enforceAuth: $injector.get('enforceAuth'),
          registrations: ['$route', 'RegistrationCache', function ($route, RegistrationCache) {
            return RegistrationCache.getAllForConference($route.current.params.conferenceId);
          }],
          conference: ['$route', 'ConfCache', function ($route, ConfCache) {
            return ConfCache.get($route.current.params.conferenceId);
          }],
          permissions: ['$route', 'PermissionCache', function ($route, PermissionCache) {
            return PermissionCache.getForConference($route.current.params.conferenceId);
          }]
        }
      })
      .when('/eventRegistrations/:conferenceId', {
        templateUrl: 'views/eventRegistrations.html',
        controller: 'eventRegistrationsCtrl',
        resolve: {
          enforceAuth: $injector.get('enforceAuth'),
          registrations: ['$route', 'RegistrationCache', function ($route, RegistrationCache) {
            return RegistrationCache.getAllForConference($route.current.params.conferenceId);
          }],
          conference: ['$route', 'ConfCache', function ($route, ConfCache) {
            return ConfCache.get($route.current.params.conferenceId);
          }],
          permissions: ['$route', 'PermissionCache', function ($route, PermissionCache) {
            return PermissionCache.getForConference($route.current.params.conferenceId);
          }]
        }
      })
      .when('/eventForm/:conferenceId', {
        template: '<ng-include src="templateUrl"></ng-include>',
        controller: 'eventFormCtrl',
        resolve: {
          enforceAuth: $injector.get('enforceAuth'),
          conference: ['$route', 'ConfCache', function ($route, ConfCache) {
            return ConfCache.get($route.current.params.conferenceId);
          }],
          permissions: ['$route', 'PermissionCache', function ($route, PermissionCache) {
            return PermissionCache.getForConference($route.current.params.conferenceId);
          }]
        }
      })
      .when('/eventDetails/:conferenceId', {
        template: '<ng-include src="templateUrl"></ng-include>',
        controller: 'eventDetailsCtrl',
        resolve: {
          enforceAuth: $injector.get('enforceAuth'),
          conference: ['$route', 'ConfCache', function ($route, ConfCache) {
            return ConfCache.get($route.current.params.conferenceId);
          }],
          permissions: ['$route', 'PermissionCache', function ($route, PermissionCache) {
            return PermissionCache.getForConference($route.current.params.conferenceId);
          }]
        }
      })
      .when('/eventPermissions/:conferenceId', {
        template: '<ng-include src="templateUrl"></ng-include>',
        controller: 'eventPermissionsCtrl',
        resolve: {
          enforceAuth: $injector.get('enforceAuth'),
          conference: ['$route', 'ConfCache', function ($route, ConfCache) {
            return ConfCache.get($route.current.params.conferenceId);
          }],
          permissions: ['$route', 'PermissionCache', function ($route, PermissionCache) {
            return PermissionCache.getForConference($route.current.params.conferenceId);
          }]
        }
      })
      .when('/activatePermission/:permissionAuthCode', {
        template: '{{message}}',
        controller: 'ActiviatePermissionCtrl',
        resolve: {
          enforceAuth: $injector.get('enforceAuth')
        }
      })
      .when('/auth/:token', {
        resolve: {
          redirectToIntendedRoute: ['$location', '$cookies', '$route', '$rootScope', 'ProfileCache',
            function ($location, $cookies, $route, $rootScope, ProfileCache) {
              $cookies.crsAuthProviderType = '';
              if ($cookies.crsToken && ($cookies.crsToken !== $route.current.params.token)) {
                $cookies.crsPreviousToken = $cookies.crsToken;
              }
              $cookies.crsToken = $route.current.params.token;
              $rootScope.crsToken = $cookies.crsToken;
              ProfileCache.getCache(function (data) {
                $cookies.crsAuthProviderType = data.authProviderType;
                if(angular.isDefined($cookies.regType)) {
                  $location.path($cookies.intendedRoute || '/').search('regType', $cookies.regType);
                  delete $cookies.regType;
                } else {
                  $location.path($cookies.intendedRoute || '/');
                }
              });
            }
          ]
        }
      })
      .when('/logout/', {
        resolve: {
          redirect: ['$location', '$cookies', '$window', '$http',
            function ($location, $cookies, $window, $http) {

              /* if RELAY log out, delete the cookies first and then redirect.  cookies must be deleted
               * first b/c the browser is being redirected and will not come back here.  the auth token
               * is not needed server side before logging out */
              if ($cookies.crsAuthProviderType  === 'RELAY') {
                delete $cookies.crsAuthProviderType;
                delete $cookies.crsPreviousToken;
                delete $cookies.crsToken;
                // make sure we come back to home page, not logout page
                var serviceUrl = $location.absUrl().replace("logout","");
                $window.location.href = 'https://signin.cru.org/cas/logout?service=' + serviceUrl;
                /* if FACEBOOK log out, issue an async GET to retrieve the log out URL from the API
                 * the cookies cannot be deleted first b/c the auth token is needed to access the session & identity
                 * server side so the users access_token can be fetched to build the log out URL.
                 * after the GET, if successful, then delete the cookies. */
              } else if ($cookies.crsAuthProviderType === 'FACEBOOK') {
                $http.get('/auth/facebook/logout').success(function (data, status, headers) {
                  delete $cookies.crsAuthProviderType;
                  delete $cookies.crsPreviousToken;
                  delete $cookies.crsToken;
                  $window.location.href = headers('X-Facebook-Logout-URL');
                }).error(function (data, status) {
                  alert('Logout failed: ' + status);
                });
              }
            }
          ]
        }
      })
      .when('/help/', {
        templateUrl: 'views/help.html',
        controller: 'landingCtrl'
      })
      .when('/privacy/', {
        templateUrl: 'views/privacy.html',
        controller: 'landingCtrl'
      })
      .otherwise({
        redirectTo: '/'
      });
  })
  .run(function ($rootScope, $cookies, $location) {
    $rootScope.$on('$locationChangeStart', function () {
      //registration mode
      if (_.contains($location.path(), '/preview/')) {
        $rootScope.registerMode = 'preview';
      } else if(_.contains($location.path(), '/register/')) {
        $rootScope.registerMode = 'register';
      }
    });

    $rootScope.generateTitle = function (title) {
      if (title) {
        return title + ' | Event Registration Tool';
      } else {
        return 'Event Registration Tool';
      }
    };
  })
  .config(function ($httpProvider) {
    $httpProvider.interceptors.push('currentRegistrationInterceptor');
    $httpProvider.interceptors.push('httpUrlInterceptor');
    $httpProvider.interceptors.push('authorizationInterceptor');
    $httpProvider.interceptors.push('unauthorizedInterceptor');
    $httpProvider.interceptors.push('debouncePutsInterceptor');
    $httpProvider.interceptors.push('statusInterceptor');
  })
  .config(function ($provide) {
    $provide.decorator('$exceptionHandler', ['$delegate', function ($delegate) {
      return function (exception) {
        $delegate(exception);
        var error = {
          type: 'Angular',
          message: exception.message,
          params: {
            angularVersion: angular.version.full
          },
          component: exception.stack
        };
        Hoptoad.notify(error);
      };
    }]);
  });
<commit_msg>jshint<commit_after>'use strict';
angular.module('confRegistrationWebApp', ['ngRoute', 'ngCookies', 'ui.bootstrap'])
  .config(function ($routeProvider, $injector) {
    $routeProvider
      .when('/', {
        templateUrl: 'views/landing.html',
        controller: 'landingCtrl'
      })
      .when('/register/:conferenceId', {
        resolve: {
          redirect: ['$location', '$route', function ($location, $route) {
            $location.path('/register/' + $route.current.params.conferenceId + '/page/');
          }]
        }
      })
      .when('/register/:conferenceId/page/:pageId?', {
        templateUrl: 'views/registration.html',
        controller: 'RegistrationCtrl',
        resolve: {
          enforceAuth: $injector.get('enforceAuth'),
          conference: ['$route', 'ConfCache', function ($route, ConfCache) {
            return ConfCache.get($route.current.params.conferenceId);
          }],
          currentRegistration: ['$route', 'RegistrationCache', function ($route, RegistrationCache) {
            return RegistrationCache.getCurrent($route.current.params.conferenceId);
          }]
        }
      })
      .when('/payment/:conferenceId', {
        templateUrl: 'views/payment.html',
        controller: 'paymentCtrl',
        resolve: {
          enforceAuth: $injector.get('enforceAuth'),
          registration: ['$route', 'RegistrationCache', function ($route, RegistrationCache) {
            return RegistrationCache.getCurrent($route.current.params.conferenceId)
              .then(function (currentRegistration) {
                return currentRegistration;
              });
          }],
          conference: ['$route', 'ConfCache', function ($route, ConfCache) {
            return ConfCache.get($route.current.params.conferenceId);
          }]
        }
      })
      .when('/reviewRegistration/:conferenceId', {
        templateUrl: 'views/reviewRegistration.html',
        controller: 'ReviewRegistrationCtrl',
        resolve: {
          enforceAuth: $injector.get('enforceAuth'),
          registration: ['$route', 'RegistrationCache', function ($route, RegistrationCache) {
            return RegistrationCache.getCurrent($route.current.params.conferenceId)
              .then(function (currentRegistration) {
                return currentRegistration;
              });
          }],
          conference: ['$route', 'ConfCache', function ($route, ConfCache) {
            return ConfCache.get($route.current.params.conferenceId);
          }]
        }
      })
      .when('/preview/:conferenceId/page/:pageId?', {
        templateUrl: 'views/registration.html',
        controller: 'RegistrationCtrl',
        resolve: {
          enforceAuth: $injector.get('enforceAuth'),
          conference: ['$route', 'ConfCache', function ($route, ConfCache) {
            return ConfCache.get($route.current.params.conferenceId);
          }],
          currentRegistration: ['$route', 'RegistrationCache', function ($route, RegistrationCache) {
            return RegistrationCache.getCurrent($route.current.params.conferenceId);
          }]
        }
      })
      .when('/eventDashboard', {
        templateUrl: 'views/eventDashboard.html',
        controller: 'eventDashboardCtrl',
        resolve: {
          enforceAuth: $injector.get('enforceAuth')
        }
      })
      .when('/eventOverview/:conferenceId', {
        templateUrl: 'views/eventOverview.html',
        controller: 'eventOverviewCtrl',
        resolve: {
          enforceAuth: $injector.get('enforceAuth'),
          registrations: ['$route', 'RegistrationCache', function ($route, RegistrationCache) {
            return RegistrationCache.getAllForConference($route.current.params.conferenceId);
          }],
          conference: ['$route', 'ConfCache', function ($route, ConfCache) {
            return ConfCache.get($route.current.params.conferenceId);
          }],
          permissions: ['$route', 'PermissionCache', function ($route, PermissionCache) {
            return PermissionCache.getForConference($route.current.params.conferenceId);
          }]
        }
      })
      .when('/eventRegistrations/:conferenceId', {
        templateUrl: 'views/eventRegistrations.html',
        controller: 'eventRegistrationsCtrl',
        resolve: {
          enforceAuth: $injector.get('enforceAuth'),
          registrations: ['$route', 'RegistrationCache', function ($route, RegistrationCache) {
            return RegistrationCache.getAllForConference($route.current.params.conferenceId);
          }],
          conference: ['$route', 'ConfCache', function ($route, ConfCache) {
            return ConfCache.get($route.current.params.conferenceId);
          }],
          permissions: ['$route', 'PermissionCache', function ($route, PermissionCache) {
            return PermissionCache.getForConference($route.current.params.conferenceId);
          }]
        }
      })
      .when('/eventForm/:conferenceId', {
        template: '<ng-include src="templateUrl"></ng-include>',
        controller: 'eventFormCtrl',
        resolve: {
          enforceAuth: $injector.get('enforceAuth'),
          conference: ['$route', 'ConfCache', function ($route, ConfCache) {
            return ConfCache.get($route.current.params.conferenceId);
          }],
          permissions: ['$route', 'PermissionCache', function ($route, PermissionCache) {
            return PermissionCache.getForConference($route.current.params.conferenceId);
          }]
        }
      })
      .when('/eventDetails/:conferenceId', {
        template: '<ng-include src="templateUrl"></ng-include>',
        controller: 'eventDetailsCtrl',
        resolve: {
          enforceAuth: $injector.get('enforceAuth'),
          conference: ['$route', 'ConfCache', function ($route, ConfCache) {
            return ConfCache.get($route.current.params.conferenceId);
          }],
          permissions: ['$route', 'PermissionCache', function ($route, PermissionCache) {
            return PermissionCache.getForConference($route.current.params.conferenceId);
          }]
        }
      })
      .when('/eventPermissions/:conferenceId', {
        template: '<ng-include src="templateUrl"></ng-include>',
        controller: 'eventPermissionsCtrl',
        resolve: {
          enforceAuth: $injector.get('enforceAuth'),
          conference: ['$route', 'ConfCache', function ($route, ConfCache) {
            return ConfCache.get($route.current.params.conferenceId);
          }],
          permissions: ['$route', 'PermissionCache', function ($route, PermissionCache) {
            return PermissionCache.getForConference($route.current.params.conferenceId);
          }]
        }
      })
      .when('/activatePermission/:permissionAuthCode', {
        template: '{{message}}',
        controller: 'ActiviatePermissionCtrl',
        resolve: {
          enforceAuth: $injector.get('enforceAuth')
        }
      })
      .when('/auth/:token', {
        resolve: {
          redirectToIntendedRoute: ['$location', '$cookies', '$route', '$rootScope', 'ProfileCache',
            function ($location, $cookies, $route, $rootScope, ProfileCache) {
              $cookies.crsAuthProviderType = '';
              if ($cookies.crsToken && ($cookies.crsToken !== $route.current.params.token)) {
                $cookies.crsPreviousToken = $cookies.crsToken;
              }
              $cookies.crsToken = $route.current.params.token;
              $rootScope.crsToken = $cookies.crsToken;
              ProfileCache.getCache(function (data) {
                $cookies.crsAuthProviderType = data.authProviderType;
                if(angular.isDefined($cookies.regType)) {
                  $location.path($cookies.intendedRoute || '/').search('regType', $cookies.regType);
                  delete $cookies.regType;
                } else {
                  $location.path($cookies.intendedRoute || '/');
                }
              });
            }
          ]
        }
      })
      .when('/logout/', {
        resolve: {
          redirect: ['$location', '$cookies', '$window', '$http',
            function ($location, $cookies, $window, $http) {

              /* if RELAY log out, delete the cookies first and then redirect.  cookies must be deleted
               * first b/c the browser is being redirected and will not come back here.  the auth token
               * is not needed server side before logging out */
              if ($cookies.crsAuthProviderType  === 'RELAY') {
                delete $cookies.crsAuthProviderType;
                delete $cookies.crsPreviousToken;
                delete $cookies.crsToken;
                // make sure we come back to home page, not logout page
                var serviceUrl = $location.absUrl().replace('logout','');
                $window.location.href = 'https://signin.cru.org/cas/logout?service=' + serviceUrl;
                /* if FACEBOOK log out, issue an async GET to retrieve the log out URL from the API
                 * the cookies cannot be deleted first b/c the auth token is needed to access the session & identity
                 * server side so the users access_token can be fetched to build the log out URL.
                 * after the GET, if successful, then delete the cookies. */
              } else if ($cookies.crsAuthProviderType === 'FACEBOOK') {
                $http.get('/auth/facebook/logout').success(function (data, status, headers) {
                  delete $cookies.crsAuthProviderType;
                  delete $cookies.crsPreviousToken;
                  delete $cookies.crsToken;
                  $window.location.href = headers('X-Facebook-Logout-URL');
                }).error(function (data, status) {
                  alert('Logout failed: ' + status);
                });
              }
            }
          ]
        }
      })
      .when('/help/', {
        templateUrl: 'views/help.html',
        controller: 'landingCtrl'
      })
      .when('/privacy/', {
        templateUrl: 'views/privacy.html',
        controller: 'landingCtrl'
      })
      .otherwise({
        redirectTo: '/'
      });
  })
  .run(function ($rootScope, $cookies, $location) {
    $rootScope.$on('$locationChangeStart', function () {
      //registration mode
      if (_.contains($location.path(), '/preview/')) {
        $rootScope.registerMode = 'preview';
      } else if(_.contains($location.path(), '/register/')) {
        $rootScope.registerMode = 'register';
      }
    });

    $rootScope.generateTitle = function (title) {
      if (title) {
        return title + ' | Event Registration Tool';
      } else {
        return 'Event Registration Tool';
      }
    };
  })
  .config(function ($httpProvider) {
    $httpProvider.interceptors.push('currentRegistrationInterceptor');
    $httpProvider.interceptors.push('httpUrlInterceptor');
    $httpProvider.interceptors.push('authorizationInterceptor');
    $httpProvider.interceptors.push('unauthorizedInterceptor');
    $httpProvider.interceptors.push('debouncePutsInterceptor');
    $httpProvider.interceptors.push('statusInterceptor');
  })
  .config(function ($provide) {
    $provide.decorator('$exceptionHandler', ['$delegate', function ($delegate) {
      return function (exception) {
        $delegate(exception);
        var error = {
          type: 'Angular',
          message: exception.message,
          params: {
            angularVersion: angular.version.full
          },
          component: exception.stack
        };
        Hoptoad.notify(error);
      };
    }]);
  });
<|endoftext|>


<commit_before>
var Map = function(parentDiv) {

    var osm = L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png');

    var osmCycle = L.tileLayer('http://{s}.tile.opencyclemap.org/cycle/{z}/{x}/{y}.png');
    var osmCycleTransport = L.tileLayer('http://{s}.tile2.opencyclemap.org/transport/{z}/{x}/{y}.png');
    var toner = L.tileLayer('http://{s}.tile.stamen.com/toner/{z}/{x}/{y}.png');
    var watercolor = L.tileLayer('http://{s}.tile.stamen.com/watercolor/{z}/{x}/{y}.jpg');

    this.layerPokestops = new L.LayerGroup();
    this.layerCatches = new L.LayerGroup();
    this.layerPath = new L.LayerGroup();

    this.map = L.map(parentDiv, {
        layers: [osm, this.layerPath, this.layerCatches, this.layerPokestops]
    });

   var baseLayers = {
        "OpenStreetMap": osm,
        "OpenCycleMap": osmCycle,
        "OpenCycleMap Transport": osmCycleTransport,
        "Toner": toner,
        "Watercolor": watercolor,
    };
    var overlays = {
        "Path": this.layerPath,
        "Pokestops": this.layerPokestops,
        "Catches": this.layerCatches
    };

    L.control.layers(baseLayers, overlays).addTo(this.map);

    this.path = null;

    this.steps = [];
    this.catches = [];
    this.pokestops = [];
    this.availablePokestops = [];
};

Map.prototype.saveContext = function() {
    sessionStorage.setItem("available", true);
    sessionStorage.setItem("steps", JSON.stringify(this.steps));
    sessionStorage.setItem("catches", JSON.stringify(this.catches));
    sessionStorage.setItem("pokestops", JSON.stringify(this.pokestops));
}

Map.prototype.loadContext = function() {
    if (sessionStorage.getItem("available")) {
        try {
            console.log("Load data from storage to restore session");

            this.steps = JSON.parse(sessionStorage.getItem("steps")) || [];
            this.catches = JSON.parse(sessionStorage.getItem("catches")) || [];
            this.pokestops = JSON.parse(sessionStorage.getItem("pokestops")) || [];

            this.initPath();

            for (var i = 0; i < this.catches.length; i++) {
                var pt = this.catches[i];
                var icon = L.icon({ iconUrl: `./assets/pokemon/${pt.id}.png`, iconSize: [45, 45]});
                L.marker([pt.lat, pt.lng], {icon: icon}).addTo(this.map).bindPopup(`${pt.name} (lvl ${pt.lvl})`);
            }
            for (var i = 0; i < this.pokestop.length; i++) {
                var pt = this.pokestop[i];
                var icon = L.icon({ iconUrl: `./assets/img/pokestop.png`, iconSize: [30, 50]});
                L.marker([pt.lat, pt.lng], {icon: icon}).addTo(this.map).bindPopup(pt.name);
            }
        } catch(err) {}
    }
}

Map.prototype.initPath = function() {
    if (this.path != null) return true;
    if (this.steps.length < 2) return false;

    console.log("Init path and markers.");
    $(".loading").hide();

    this.map.setView([this.steps[0].lat, this.steps[0].lng], 16);

    var pts = Array.from(this.steps, pt => L.latLng(pt.lat, pt.lng));
    this.path = L.polyline(pts, { color: 'red' }).addTo(this.layerPath);

    var last = this.steps.pop();
    this.me = L.marker([last.lat, last.lng]).addTo(this.map).bindPopup(`${last.lat},${last.lng}`);

    return true;
}

Map.prototype.addToPath = function(pt) {
    if (this.initPath()) {
        var latLng = L.latLng(pt.lat, pt.lng);
        this.path.addLatLng(latLng);
        this.me.setLatLng(latLng).getPopup().setContent(`${pt.lat},${pt.lng}`);
        if (global.config.followPlayer) {
            this.map.panTo(latLng);
        }
    }
    this.steps.push(pt);
}

Map.prototype.addCatch = function(pt) {
    if (!pt.lat) {
        if (this.steps.length > 0) {
            var pos = this.steps.pop();
            pt.lat = pos.lat;
            pt.lng = pos.lng;
        } else {
            // no position to pin to, abord
            return;
        }
    }

    var pkm = `${pt.name} (lvl ${pt.lvl})`;
    console.log("Catch " + pkm);

    this.catches.push(pt);

    var icon = L.icon({ iconUrl: `./assets/pokemon/${pt.id}.png`, iconSize: [40, 40]});
    L.marker([pt.lat, pt.lng], {icon: icon}).addTo(this.layerCatches).bindPopup(pkm);
}

Map.prototype.addVisitedPokestop = function(pt) {
    if (!pt.lat) return;

    console.log("Pokestop.");

    this.addToPath(pt);
    this.pokestops.push(pt);

    var ps = this.availablePokestops.find(ps => ps.id == pt.id);
    if (ps) {
        ps.marker.setIcon(L.icon({ iconUrl: `./assets/img/pokestop.png`, iconSize: [30, 50]}));
        ps.marker.bindPopup(pt.name);
    } else {
        var icon = L.icon({ iconUrl: `./assets/img/pokestop.png`, iconSize: [30, 50]});
        L.marker([pt.lat, pt.lng], {icon: icon}).bindPopup(pt.name).addTo(this.layerPokestops);
    }
}

Map.prototype.addPokestops = function(forts) {
    for(var i = 0; i < forts.length; i++) {
        var pt = forts[i];
        var ps = this.availablePokestops.find(ps => ps.id == pt.id);
        if (!ps) {
            var icon = L.icon({ iconUrl: `./assets/img/pokestop_available.png`, iconSize: [30, 50]});
            pt.marker = L.marker([pt.lat, pt.lng], {icon: icon}).addTo(this.layerPokestops);
            this.availablePokestops.push(pt);
        }
    }
}

Map.prototype.displayPokemonList = function(all) {
    console.log("Pokemon list");
    var div = $(".inventory .data")
    div.html("");
    all.forEach(function(elt) {
        div.append(`

                CP: ${elt.cp} | IV: ${elt.iv}

                ${elt.name}

        `);
    });
    $(".inventory").show();
}

Map.prototype.displayEggsList = function(eggs) {
    console.log("Eggs list");
    var div = $(".inventory .data")
    div.html("");
    eggs.forEach(function(elt) {
        div.append(`

                ${elt.doneDist.toFixed(1)} / ${elt.totalDist.toFixed(1)} km

        `);
    });
    $(".inventory").show();
}<commit_msg>dont addToPath when pokestop is visited by bot<commit_after>
var Map = function(parentDiv) {

    var osm = L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png');

    var osmCycle = L.tileLayer('http://{s}.tile.opencyclemap.org/cycle/{z}/{x}/{y}.png');
    var osmCycleTransport = L.tileLayer('http://{s}.tile2.opencyclemap.org/transport/{z}/{x}/{y}.png');
    var toner = L.tileLayer('http://{s}.tile.stamen.com/toner/{z}/{x}/{y}.png');
    var watercolor = L.tileLayer('http://{s}.tile.stamen.com/watercolor/{z}/{x}/{y}.jpg');

    this.layerPokestops = new L.LayerGroup();
    this.layerCatches = new L.LayerGroup();
    this.layerPath = new L.LayerGroup();

    this.map = L.map(parentDiv, {
        layers: [osm, this.layerPath, this.layerCatches, this.layerPokestops]
    });

   var baseLayers = {
        "OpenStreetMap": osm,
        "OpenCycleMap": osmCycle,
        "OpenCycleMap Transport": osmCycleTransport,
        "Toner": toner,
        "Watercolor": watercolor,
    };
    var overlays = {
        "Path": this.layerPath,
        "Pokestops": this.layerPokestops,
        "Catches": this.layerCatches
    };

    L.control.layers(baseLayers, overlays).addTo(this.map);

    this.path = null;

    this.steps = [];
    this.catches = [];
    this.pokestops = [];
    this.availablePokestops = [];
};

Map.prototype.saveContext = function() {
    sessionStorage.setItem("available", true);
    sessionStorage.setItem("steps", JSON.stringify(this.steps));
    sessionStorage.setItem("catches", JSON.stringify(this.catches));
    sessionStorage.setItem("pokestops", JSON.stringify(this.pokestops));
}

Map.prototype.loadContext = function() {
    if (sessionStorage.getItem("available")) {
        try {
            console.log("Load data from storage to restore session");

            this.steps = JSON.parse(sessionStorage.getItem("steps")) || [];
            this.catches = JSON.parse(sessionStorage.getItem("catches")) || [];
            this.pokestops = JSON.parse(sessionStorage.getItem("pokestops")) || [];

            this.initPath();

            for (var i = 0; i < this.catches.length; i++) {
                var pt = this.catches[i];
                var icon = L.icon({ iconUrl: `./assets/pokemon/${pt.id}.png`, iconSize: [45, 45]});
                L.marker([pt.lat, pt.lng], {icon: icon}).addTo(this.map).bindPopup(`${pt.name} (lvl ${pt.lvl})`);
            }
            for (var i = 0; i < this.pokestop.length; i++) {
                var pt = this.pokestop[i];
                var icon = L.icon({ iconUrl: `./assets/img/pokestop.png`, iconSize: [30, 50]});
                L.marker([pt.lat, pt.lng], {icon: icon}).addTo(this.map).bindPopup(pt.name);
            }
        } catch(err) {}
    }
}

Map.prototype.initPath = function() {
    if (this.path != null) return true;
    if (this.steps.length < 2) return false;

    console.log("Init path and markers.");
    $(".loading").hide();

    this.map.setView([this.steps[0].lat, this.steps[0].lng], 16);

    var pts = Array.from(this.steps, pt => L.latLng(pt.lat, pt.lng));
    this.path = L.polyline(pts, { color: 'red' }).addTo(this.layerPath);

    var last = this.steps.pop();
    this.me = L.marker([last.lat, last.lng]).addTo(this.map).bindPopup(`${last.lat},${last.lng}`);

    return true;
}

Map.prototype.addToPath = function(pt) {
    if (this.initPath()) {
        var latLng = L.latLng(pt.lat, pt.lng);
        this.path.addLatLng(latLng);
        this.me.setLatLng(latLng).getPopup().setContent(`${pt.lat},${pt.lng}`);
        if (global.config.followPlayer) {
            this.map.panTo(latLng);
        }
    }
    this.steps.push(pt);
}

Map.prototype.addCatch = function(pt) {
    if (!pt.lat) {
        if (this.steps.length > 0) {
            var pos = this.steps.pop();
            pt.lat = pos.lat;
            pt.lng = pos.lng;
        } else {
            // no position to pin to, abort
            return;
        }
    }

    var pkm = `${pt.name} (lvl ${pt.lvl})`;
    console.log("Catch " + pkm);

    this.catches.push(pt);

    var icon = L.icon({ iconUrl: `./assets/pokemon/${pt.id}.png`, iconSize: [40, 40]});
    L.marker([pt.lat, pt.lng], {icon: icon}).addTo(this.layerCatches).bindPopup(pkm);
}

Map.prototype.addVisitedPokestop = function(pt) {
    if (!pt.lat) return;

    console.log("Pokestop visited.");

    this.pokestops.push(pt);

    var ps = this.availablePokestops.find(ps => ps.id == pt.id);
    if (ps) {
        ps.marker.setIcon(L.icon({ iconUrl: `./assets/img/pokestop.png`, iconSize: [30, 50]}));
        ps.marker.bindPopup(pt.name);
    } else {
        var icon = L.icon({ iconUrl: `./assets/img/pokestop.png`, iconSize: [30, 50]});
        L.marker([pt.lat, pt.lng], {icon: icon}).bindPopup(pt.name).addTo(this.layerPokestops);
    }
}

Map.prototype.addPokestops = function(forts) {
    for(var i = 0; i < forts.length; i++) {
        var pt = forts[i];
        var ps = this.availablePokestops.find(ps => ps.id == pt.id);
        if (!ps) {
            var icon = L.icon({ iconUrl: `./assets/img/pokestop_available.png`, iconSize: [30, 50]});
            pt.marker = L.marker([pt.lat, pt.lng], {icon: icon}).addTo(this.layerPokestops);
            this.availablePokestops.push(pt);
        }
    }
}

Map.prototype.displayPokemonList = function(all) {
    console.log("Pokemon list");
    var div = $(".inventory .data")
    div.html("");
    all.forEach(function(elt) {
        div.append(`

                CP: ${elt.cp} | IV: ${elt.iv}

                ${elt.name}

        `);
    });
    $(".inventory").show();
}

Map.prototype.displayEggsList = function(eggs) {
    console.log("Eggs list");
    var div = $(".inventory .data")
    div.html("");
    eggs.forEach(function(elt) {
        div.append(`

                ${elt.doneDist.toFixed(1)} / ${elt.totalDist.toFixed(1)} km

        `);
    });
    $(".inventory").show();
}<|endoftext|>


<commit_before>define(
['jquery'], function(jquery) {
    var jQuery = jquery;

    return {
        responsePlugins: [],
        persistentStorage: {},
        sessionStorage: {},
        initializePlugins: function(pluginNames) {
            var that = this;

            // Walk through the list of plugins passed in and load it into
            // memory. Add it to the list of plugins we can use
            //
            // TODO: hook an 'init' method in the plugins
            jQuery.each(pluginNames, function(index, name) {
                requirejs([name],

                function(plugin) {
                    that.responsePlugins.push(plugin);
                    console.log("Loaded plugin: "+name);
                });

            });
        },

        handleQuery: function(input) {
            var that = this;
            var responses = {};

            // TODO: do some NLP here

            jQuery.each(that.responsePlugins, function(index, plugin) {
                console.log("Asking "+plugin.name+" about "+input);
                responses[plugin.name] = plugin.reply({
                    rawInput: input,
                    jQuery: jQuery,
                    sessionStorage: that.sessionStorage,
                    persistentStorage: that.persistentStorage
                });
            });
            return responses;
        }
    }
});
<commit_msg>Add tokenization and part of speech to the plugin.reply args dict.<commit_after>define(
[
    'jquery',
    'pos'
], function(jquery, pos) {
    var jQuery = jquery,
        Pos = pos;
    console.log("Pos",Pos);

    return {
        responsePlugins: [],
        persistentStorage: {},
        sessionStorage: {},
        initializePlugins: function(pluginNames) {
            var that = this;

            // Walk through the list of plugins passed in and load it into
            // memory. Add it to the list of plugins we can use
            //
            // TODO: hook an 'init' method in the plugins
            jQuery.each(pluginNames, function(index, name) {
                requirejs([name],

                function(plugin) {
                    that.responsePlugins.push(plugin);
                    console.log("Loaded plugin: "+name);
                });

            });
        },

        handleQuery: function(input) {
            var that = this;
            var responses = {};
            var tokens = new Pos.Lexer().lex(input);
            var tags = new Pos.Tagger().tag(tokens);
            var args = {
                rawInput: input,
                tokens: tokens,
                pos: tags,
                jQuery: jQuery,
                sessionStorage: that.sessionStorage,
                persistentStorage: that.persistentStorage
            };
            // TODO: do some NLP here

            jQuery.each(that.responsePlugins, function(index, plugin) {
                console.log("Asking "+plugin.name+" about "+input);
                responses[plugin.name] = plugin.reply(args);
            });
            return responses;
        }
    }
});
<|endoftext|>


<commit_before>/*
 * @license
 * Copyright 2016 Google Inc. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * Context Support
 *
 * Contexts, also known as frames, scopes or environments, are used to store
 * named resources. They provide an object-oriented replacement for global
 * variables. Contexts are immutable. New bindings are added by creating
 * "sub-contexts" with new bindings, from an existing parent context.
 * Sub-contexts inherit bindings from their parent.
 *
 * Contexts provide a form of inversion-of-control or dependendency-injection.
 * Normally, contexts are not explicitly used because FOAM's imports/exports
 * mechanism provides a high-level declarative method of dependency management
 * which hides their use.
 *
 * foam.__context__ references the root context, which is the ancestor of all other
 * contexts.
 */

(function() {
  var __context__ = {
    // Temporary: gets replaced in Window.js.
    assert: function(b) { console.assert.apply(console, arguments); return b; },

    /**
     * Lookup a class in the context.  Throws an exception if the value
     * couldn't be found, unless opt_suppress is true.
     *
     * @param id The id of the class to lookup.
     * @param opt_suppress Suppress throwing an error.
     **/
    lookup: function(id, opt_suppress) {
      var ret = typeof id === 'string' && this.__cache__[id];

      if ( ! opt_suppress ) {
        this.assert(
            ret,
            'Could not find any registered class for ' + id);
      }

      return ret;
    },

    /**
     * Register a class into the given context.  After registration
     * the class can be found again by calling foam.lookup('com.foo.SomeClass');
     *
     * @param cls    The class to register.
     * @param opt_id Optional id under which to register class.
     */
    register: function(cls, opt_id) {
      this.assert(
        typeof cls === 'object',
        'Cannot register non-objects into a context.');

      function doRegister(cache, name) {
        console.assert(
          cache.hasOwnProperty(name) === false,
          cls.id + ' is already registerd in this context.');

        cache[name] = cls;
      }

      if ( opt_id ) {
        doRegister(this.__cache__, opt_id);
      } else {
        this.assert(
            typeof cls.id === 'string',
            'Must have an .id property to be registered in a context.');

        doRegister(this.__cache__, cls.id);

        if ( cls.package === 'foam.core' ) {
          doRegister(this.__cache__, cls.name);
        }
      }
    },

    toSlotName_: foam.Function.memoize1(function toSlotName_(key) {
      return key + '$';
    }),

    /**
     * Creates a sub context of the context that this is called upon.
     * @param opt_args A map of bindings to set up in the sub context.
     *     Currently unused.
     */
    createSubContext: function createSubContext(opt_args, opt_name) {
      if ( ! opt_args ) return this;

      this.assert(
          opt_name === undefined || typeof opt_name === 'string',
          'opt_name must be left undefined or be a string.');

      var sub = Object.create(this);

      if ( opt_name ) {
        Object.defineProperty(sub, 'NAME', {
          value: opt_name,
          enumerable: false
        });
      }

      for ( var key in opt_args ) {
        if ( opt_args.hasOwnProperty(key) ) {
          var v = opt_args[key];

          if ( ! foam.core.Slot.isInstance(v) ) {
            Object.defineProperty(sub, this.toSlotName_(key), {
              value: foam.core.ConstantSlot.create({ value: v })
            });

            (function(v) {
              Object.defineProperty(sub, key, {
                value: v
              });
            })(v);
          } else {
            Object.defineProperty(sub, this.toSlotName_(key), {
              value: v
            });

            (function(v) {
              Object.defineProperty(sub, key, {
                get: function() { return v.get(); },
                enumerable: false
              });
            })(v);
          }
        }
      }

      Object.defineProperty(sub, '__cache__', {
        value: Object.create(this.__cache__),
        enumerable: false
      });

      sub.$UID__ = foam.next$UID();
      foam.Object.freeze(sub);

      return sub;
    }
  };

  Object.defineProperty(__context__, '__cache__', {
    value: {},
    enumerable: false
  });

  // Create short-cuts for foam.__context__.[createSubContext, register, lookup]
  // in foam.
  foam.lookup = function(id, opt_suppress) {
    return foam.__context__.lookup(id, opt_suppress);
  };
  foam.register = function(cls) { foam.__context__.register(cls); };
  foam.createSubContext = function(opt_args, opt_name) {
    return foam.__context__.createSubContext(opt_args, opt_name);
  };

  foam.__context__ = __context__;
})();
<commit_msg>Removed redundant setting of  in createSubContext().<commit_after>/*
 * @license
 * Copyright 2016 Google Inc. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * Context Support
 *
 * Contexts, also known as frames, scopes or environments, are used to store
 * named resources. They provide an object-oriented replacement for global
 * variables. Contexts are immutable. New bindings are added by creating
 * "sub-contexts" with new bindings, from an existing parent context.
 * Sub-contexts inherit bindings from their parent.
 *
 * Contexts provide a form of inversion-of-control or dependendency-injection.
 * Normally, contexts are not explicitly used because FOAM's imports/exports
 * mechanism provides a high-level declarative method of dependency management
 * which hides their use.
 *
 * foam.__context__ references the root context, which is the ancestor of all other
 * contexts.
 */

(function() {
  var __context__ = {
    // Temporary: gets replaced in Window.js.
    assert: function(b) { console.assert.apply(console, arguments); return b; },

    /**
     * Lookup a class in the context.  Throws an exception if the value
     * couldn't be found, unless opt_suppress is true.
     *
     * @param id The id of the class to lookup.
     * @param opt_suppress Suppress throwing an error.
     **/
    lookup: function(id, opt_suppress) {
      var ret = typeof id === 'string' && this.__cache__[id];

      if ( ! opt_suppress ) {
        this.assert(
            ret,
            'Could not find any registered class for ' + id);
      }

      return ret;
    },

    /**
     * Register a class into the given context.  After registration
     * the class can be found again by calling foam.lookup('com.foo.SomeClass');
     *
     * @param cls    The class to register.
     * @param opt_id Optional id under which to register class.
     */
    register: function(cls, opt_id) {
      this.assert(
        typeof cls === 'object',
        'Cannot register non-objects into a context.');

      function doRegister(cache, name) {
        console.assert(
          cache.hasOwnProperty(name) === false,
          cls.id + ' is already registerd in this context.');

        cache[name] = cls;
      }

      if ( opt_id ) {
        doRegister(this.__cache__, opt_id);
      } else {
        this.assert(
            typeof cls.id === 'string',
            'Must have an .id property to be registered in a context.');

        doRegister(this.__cache__, cls.id);

        if ( cls.package === 'foam.core' ) {
          doRegister(this.__cache__, cls.name);
        }
      }
    },

    toSlotName_: foam.Function.memoize1(function toSlotName_(key) {
      return key + '$';
    }),

    /**
     * Creates a sub context of the context that this is called upon.
     * @param opt_args A map of bindings to set up in the sub context.
     *     Currently unused.
     */
    createSubContext: function createSubContext(opt_args, opt_name) {
      if ( ! opt_args ) return this;

      this.assert(
          opt_name === undefined || typeof opt_name === 'string',
          'opt_name must be left undefined or be a string.');

      var sub = Object.create(this);

      if ( opt_name ) {
        Object.defineProperty(sub, 'NAME', {
          value: opt_name,
          enumerable: false
        });
      }

      for ( var key in opt_args ) {
        if ( opt_args.hasOwnProperty(key) ) {
          var v = opt_args[key];

          if ( ! foam.core.Slot.isInstance(v) ) {
            Object.defineProperty(sub, this.toSlotName_(key), {
              value: foam.core.ConstantSlot.create({ value: v })
            });

            (function(v) {
              Object.defineProperty(sub, key, {
                value: v
              });
            })(v);
          } else {
            Object.defineProperty(sub, this.toSlotName_(key), {
              value: v
            });

            (function(v) {
              Object.defineProperty(sub, key, {
                get: function() { return v.get(); },
                enumerable: false
              });
            })(v);
          }
        }
      }

      Object.defineProperty(sub, '__cache__', {
        value: Object.create(this.__cache__),
        enumerable: false
      });

      foam.Object.freeze(sub);

      return sub;
    }
  };

  Object.defineProperty(__context__, '__cache__', {
    value: {},
    enumerable: false
  });

  // Create short-cuts for foam.__context__.[createSubContext, register, lookup]
  // in foam.
  foam.lookup = function(id, opt_suppress) {
    return foam.__context__.lookup(id, opt_suppress);
  };
  foam.register = function(cls) { foam.__context__.register(cls); };
  foam.createSubContext = function(opt_args, opt_name) {
    return foam.__context__.createSubContext(opt_args, opt_name);
  };

  foam.__context__ = __context__;
})();
<|endoftext|>


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

var transporter = nodemailer.createTransport({
  service: 'Gmail',
  auth: {
    user: 'zacharysmith4989@gmail.com',
    pass: process.env.GMAIL_PASS
  }
});

module.exports = {
  mailer: {
    sendMail: transporter.sendMail.bind(transporter)
  },

  send200: function (res, msg) {
    if (msg) {
      console.log(msg);
      res.status(200).send(msg);
    } else {
      res.sendStatus(200);
    }
  },

  send400: function (res, err) {
    if (err) {
      console.error(err);
      res.status(400).send(err);
    } else {
      res.sendStatus(400);
    }
  },

  send500: function (res, err) {
    if (err) {
      console.error(err);
      res.status(500).send(err);
    } else {
      res.sendStatus(500);
    }
  }
};
<commit_msg>(refactor) Update server util.js<commit_after>var nodemailer = require('nodemailer');

var transporter = nodemailer.createTransport({
  service: 'Gmail',
  auth: {
    user: 'zacharysmith4989@gmail.com',
    pass: process.env.GMAIL_PASS
  }
});

module.exports = {
  mailer: {
    sendMail: transporter.sendMail.bind(transporter)
  },

  send200: function (res, data) {
    if (data) {
      // console.log(data);
      res.status(200).send(data);
    } else {
      res.sendStatus(200);
    }
  },

  send400: function (res, err) {
    if (err) {
      // console.error(err);
      res.status(400).send(err);
    } else {
      res.sendStatus(400);
    }
  },

  send500: function (res, err) {
    if (err) {
      // console.error(err);
      res.status(500).send(err);
    } else {
      res.sendStatus(500);
    }
  }
};
<|endoftext|>


<commit_before>/**
 Preload file that will be executed in the renderer process
 */

var ipc = require('electron').ipcRenderer;

// monkeypatch window.Notification
hookNotify(function(title, opt){
  ipc.emit('notification', title, opt);
});

document.addEventListener("DOMContentLoaded", function(event) {
  // do things here
  Notification.requestPermission().then(function(){
    new Notification('test')
  })
});

ipc.on('params', function (event, message) {
    var appArgs = JSON.parse(message);
    console.log('nativefier.json', appArgs);
});

function hookNotify(cb){
  var oldNotify = window.Notification;
  var newNotify = function (title, opt) {
    cb(title, opt);
    return new oldNotify(title, opt);
  };
  newNotify.requestPermission = oldNotify.requestPermission.bind(oldNotify);
  Object.defineProperty(newNotify, 'permission', {
    get: function() {
      return oldNotify.permission;
    }
  });

  window.Notification = newNotify;
}
<commit_msg>clean up<commit_after>/**
 Preload file that will be executed in the renderer process
 */

var ipc = require('electron').ipcRenderer;

// monkeypatch window.Notification
hookNotify(function(title, opt){
  ipc.emit('notification', title, opt);
});

document.addEventListener("DOMContentLoaded", function(event) {
  // do things
});

ipc.on('params', function (event, message) {
    var appArgs = JSON.parse(message);
    console.log('nativefier.json', appArgs);
});

function hookNotify(cb){
  var oldNotify = window.Notification;
  var newNotify = function (title, opt) {
    cb(title, opt);
    return new oldNotify(title, opt);
  };
  newNotify.requestPermission = oldNotify.requestPermission.bind(oldNotify);
  Object.defineProperty(newNotify, 'permission', {
    get: function() {
      return oldNotify.permission;
    }
  });

  window.Notification = newNotify;
}
<|endoftext|>


<commit_before>/* The MIT License

Copyright (c) 2011 Vastardis Capital Services, http://www.vastcap.com/

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
(function($, undefined) {
	var canonicalizationDiv = null,
		typeCache = {},
		waitFunctionCache = {},
		constructionCache = {};

	var utils = {
		getResponseFunc: function(url) {
			return (waitFunctionCache[utils.canonicalize(url)] || { func : $.noop }).func;
		},
		canonicalize: function ComponentFactory$canonicalize(url) {
			///
			/// Creates a absolute url out of the passed in url.
			///
			///<param name="url" type="String">The URL to canonicalize.</param>
			///<remarks>
			/// from http://grack.com/blog/2009/11/17/absolutizing-url-in-javascript/ by Matt Mastracci
			/// CC by Attribution 3.0
			/// adapted to use one time lazy initialization.
			///</remarks>
			if (!canonicalizationDiv) {
				canonicalizationDiv = document.createElement('div');
			}

			var div = canonicalizationDiv;
			div.innerHTML = '';
			div.firstChild.href = url; // Ensures that the href is properly escaped
			div.innerHTML = div.innerHTML; // Run the current innerHTML back through the parser
			return div.firstChild.href;
		},
		require: function(url) {
			var canonUrl = utils.canonicalize(url);

			if (waitFunctionCache[canonUrl]) {
				return waitFunctionCache[canonUrl].dfd.promise();
			} else {
				waitFunctionCache[canonUrl] = {
					func: function(type) {
						var dfd = waitFunctionCache[canonUrl].dfd;
						typeCache[canonUrl] = type;
						delete waitFunctionCache[canonUrl];
						dfd.resolve();
					},
					dfd: $.Deferred()
				};

				yepnope(canonUrl);

				return waitFunctionCache[canonUrl].dfd.promise();
			}
		}
	};

	function doodadConstructor(name) {
		this.name = name;
		this.setupObject = {
			base: null,
			validates: false,
			defaultOptions: {},
			init: $.noop,
			proto: {},
			templates: {},
			inheritsTemplates: false,
			stylesheets: {},
			statics: {}
		};
	}
	doodadConstructor.prototype = {
		inheritsFrom: function(inheritsFrom) {
			this.setupObject.base = inheritsFrom;

			return this;
		},
		constructor: function(func) {
			this.setupObject.init = func;

			return this;
		},
		validates: function() {
			this.setupObject.validates = true;

			return this;
		},
		defaultOptions: function(defaultOptions) {
			this.setupObject.defaultOptions = defaultOptions;

			return this;
		},
		proto: function(proto) {
			$.extend(this.setupObject.proto, proto);

			return this;
		},
		templates: function(templates, inheritsTemplates) {
			$.extend(this.setupObject.templates, templates);

			if (inheritsTemplates) {
				this.setupObject.inheritsTemplates = true;
			}

			return this;
		},
		stylesheets: function(stylesheets) {
			$.extend(this.setupObject.stylesheets, stylesheets);

			return this;
		},
		statics: function(statics) {
			$.extend(this.setupObject.statics, statics);

			return this;
		},
		complete: function() {
			var baseDfd = $.Deferred(),
				baseType,
				setupObject = this.setupObject,
				name = this.name;

			if (setupObject.base) {
				baseType = doodads.getType(setupObject.base);

				if (!baseType) {
					utils.require(setupObject.base).done(function() {
						baseDfd.resolve(doodads.getType(setupObject.base).prototype);
					});
				} else {
					baseDfd.resolve(baseType.prototype);
				}
			} else {
				baseDfd.resolve(Vastardis.UI.Components.Component.prototype);
			}

			baseDfd.promise().done(function(baseType) {
				var new_doodad = function(options, defaultOptions) {
					if (arguments.length === 0) { return; }

					this.base = baseType;
					this.base.constructor.call(this, $.extend({}, defaultOptions, options), new_doodad.defaultOptions);

					setupObject.init.apply(this, []);
				};

				new_doodad.defaultOptions = setupObject.defaultOptions || {};
				new_doodad.defaultOptions.templates = $.extend({},
					setupObject.inheritsTemplates ? baseType.constructor.defaultOptions.templates : {},
					new_doodad.defaultOptions.templates,
					setupObject.templates);

				new_doodad.prototype = $.extend(new baseType.constructor(), setupObject.proto);
				new_doodad.prototype.constructor = new_doodad;

				if (setupObject.validates) {
					Vastardis.UI.Components.Component.addValidationAPI(new_doodad);
				}

				for (var key in setupObject.statics) {
					if (setupObject.statics.hasOwnProperty(key)) {
						new_doodad[key] = setupObject.statics[key];
					}
				}

				// after everything is done..
				utils.getResponseFunc(name)(new_doodad);
				delete constructionCache[name];
			});
		}
	}

	doodads = {
		setup: function(name, definition) {
			if (constructionCache[name]) {
				return constructionCache[name];
			}

			var constructor = new doodadConstructor(name);

			definition = $.extend({
				inheritsTemplates: false,
				templates: null,
				stylesheets: null,
				validates: false
			}, definition);
			if (definition.validates) {
				constructor.validates();
			}
			constructor
				.templates(definition.templates, definition.inheritsTemplates)
				.stylesheets(definition.stylesheets);

			constructionCache[name] = constructor;

			return constructor;
		},
		create: function(url, options) {
			var dfd = $.Deferred(), type = doodads.getType(url);

			options = options || {};

			if (!type) {
				utils.require(url).done(function() {
					type = doodads.getType(url);
					dfd.resolve(new type(options));
				});
			} else {
				dfd.resolve(new type(options));
			}

			return dfd.promise();
		},
		getType: function(url) {
			return typeCache[utils.canonicalize(url)];
		}
	};
})(jQuery);
<commit_msg>rename constructor to builder to match functionality of file.<commit_after>/* The MIT License

Copyright (c) 2011 Vastardis Capital Services, http://www.vastcap.com/

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
(function($, undefined) {
	var canonicalizationDiv = null,
		typeCache = {},
		waitFunctionCache = {},
		constructionCache = {};

	var utils = {
		getResponseFunc: function(url) {
			return (waitFunctionCache[utils.canonicalize(url)] || { func : $.noop }).func;
		},
		canonicalize: function ComponentFactory$canonicalize(url) {
			///
			/// Creates a absolute url out of the passed in url.
			///
			///<param name="url" type="String">The URL to canonicalize.</param>
			///<remarks>
			/// from http://grack.com/blog/2009/11/17/absolutizing-url-in-javascript/ by Matt Mastracci
			/// CC by Attribution 3.0
			/// adapted to use one time lazy initialization.
			///</remarks>
			if (!canonicalizationDiv) {
				canonicalizationDiv = document.createElement('div');
			}

			var div = canonicalizationDiv;
			div.innerHTML = '';
			div.firstChild.href = url; // Ensures that the href is properly escaped
			div.innerHTML = div.innerHTML; // Run the current innerHTML back through the parser
			return div.firstChild.href;
		},
		require: function(url) {
			var canonUrl = utils.canonicalize(url);

			if (waitFunctionCache[canonUrl]) {
				return waitFunctionCache[canonUrl].dfd.promise();
			} else {
				waitFunctionCache[canonUrl] = {
					func: function(type) {
						var dfd = waitFunctionCache[canonUrl].dfd;
						typeCache[canonUrl] = type;
						delete waitFunctionCache[canonUrl];
						dfd.resolve();
					},
					dfd: $.Deferred()
				};

				yepnope(canonUrl);

				return waitFunctionCache[canonUrl].dfd.promise();
			}
		}
	};

	function builder(name) {
		this.name = name;
		this.setupObject = {
			base: null,
			validates: false,
			defaultOptions: {},
			init: $.noop,
			proto: {},
			templates: {},
			inheritsTemplates: false,
			stylesheets: {},
			statics: {}
		};
	}
	builder.prototype = {
		inheritsFrom: function(inheritsFrom) {
			this.setupObject.base = inheritsFrom;

			return this;
		},
		constructor: function(func) {
			this.setupObject.init = func;

			return this;
		},
		validates: function() {
			this.setupObject.validates = true;

			return this;
		},
		defaultOptions: function(defaultOptions) {
			this.setupObject.defaultOptions = defaultOptions;

			return this;
		},
		proto: function(proto) {
			$.extend(this.setupObject.proto, proto);

			return this;
		},
		templates: function(templates, inheritsTemplates) {
			$.extend(this.setupObject.templates, templates);

			if (inheritsTemplates) {
				this.setupObject.inheritsTemplates = true;
			}

			return this;
		},
		stylesheets: function(stylesheets) {
			$.extend(this.setupObject.stylesheets, stylesheets);

			return this;
		},
		statics: function(statics) {
			$.extend(this.setupObject.statics, statics);

			return this;
		},
		complete: function() {
			var baseDfd = $.Deferred(),
				baseType,
				setupObject = this.setupObject,
				name = this.name;

			if (setupObject.base) {
				baseType = doodads.getType(setupObject.base);

				if (!baseType) {
					utils.require(setupObject.base).done(function() {
						baseDfd.resolve(doodads.getType(setupObject.base).prototype);
					});
				} else {
					baseDfd.resolve(baseType.prototype);
				}
			} else {
				baseDfd.resolve(Vastardis.UI.Components.Component.prototype);
			}

			baseDfd.promise().done(function(baseType) {
				var new_doodad = function(options, defaultOptions) {
					if (arguments.length === 0) { return; }

					this.base = baseType;
					this.base.constructor.call(this, $.extend({}, defaultOptions, options), new_doodad.defaultOptions);

					setupObject.init.apply(this, []);
				};

				new_doodad.defaultOptions = setupObject.defaultOptions || {};
				new_doodad.defaultOptions.templates = $.extend({},
					setupObject.inheritsTemplates ? baseType.constructor.defaultOptions.templates : {},
					new_doodad.defaultOptions.templates,
					setupObject.templates);

				new_doodad.prototype = $.extend(new baseType.constructor(), setupObject.proto);
				new_doodad.prototype.constructor = new_doodad;

				if (setupObject.validates) {
					Vastardis.UI.Components.Component.addValidationAPI(new_doodad);
				}

				for (var key in setupObject.statics) {
					if (setupObject.statics.hasOwnProperty(key)) {
						new_doodad[key] = setupObject.statics[key];
					}
				}

				// after everything is done..
				utils.getResponseFunc(name)(new_doodad);
				delete constructionCache[name];
			});
		}
	}

	doodads = {
		setup: function(name, definition) {
			if (constructionCache[name]) {
				return constructionCache[name];
			}

			var constructor = new builder(name);

			definition = $.extend({
				inheritsTemplates: false,
				templates: null,
				stylesheets: null,
				validates: false
			}, definition);
			if (definition.validates) {
				constructor.validates();
			}
			constructor
				.templates(definition.templates, definition.inheritsTemplates)
				.stylesheets(definition.stylesheets);

			constructionCache[name] = constructor;

			return constructor;
		},
		create: function(url, options) {
			var dfd = $.Deferred(), type = doodads.getType(url);

			options = options || {};

			if (!type) {
				utils.require(url).done(function() {
					type = doodads.getType(url);
					dfd.resolve(new type(options));
				});
			} else {
				dfd.resolve(new type(options));
			}

			return dfd.promise();
		},
		getType: function(url) {
			return typeCache[utils.canonicalize(url)];
		}
	};
})(jQuery);
<|endoftext|>


<commit_before>/* global Renderer: true */

utils.extend(KityMinder, {
    _connectProviders: {},

    _defaultConnectProvider: function(node, parent) {
        return [
            'M', parent.getLayoutPoint(),
            'L', node.getLayoutPoint()
        ];
    },

    registerConnectProvider: function(layout, provider) {
        KityMinder._connectProviders[layout] = provider;
    },

    getConnectProvider: function(layout) {
        return KityMinder._connectProviders[layout] || KityMinder._defaultConnectProvider;
    }
});

kity.extendClass(Minder, {

    createConnect: function(node) {
        if (node.isRoot()) return;

        var strokeColor = node.getStyle('connect-color') || 'white',
            strokeWidth = node.getStyle('connect-width') || 2;

        var connection = new kity.Path()
            .stroke(strokeColor, strokeWidth);

        node._connection = connection;

        if (!this._connectContainer) {
            this._connectContainer = new kity.Group().setId(KityMinder.uuid('minder_connect_group'));
            this.getRenderContainer().prependShape(this._connectContainer);
        }

        this._connectContainer.addShape(connection);
    },

    removeConnect: function(node) {
        var me = this;
        node.traverse(function(node) {
            me._connectContainer.removeShape(node._connection);
        });
    },

    updateConnect: function(node) {

        var connection = node._connection;
        var parent = node.parent;

        if (!parent) return;

        if (parent.isCollapsed()) {
            connection.setVisible(false);
            return;
        }
        connection.setVisible(true);

        var provider = KityMinder.getConnectProvider(node.getLayout());

        provider(node, parent, connection);
    }
});

KityMinder.registerModule('Connect', {
    events: {
        'nodecreate': function(e) {
            this.createConnect(e.node);
        },
        'noderemove': function(e) {
            this.removeConnect(e.node);
        },
        'layoutapply noderender': function(e) {
            this.updateConnect(e.node);
        }
    }
});<commit_msg>fix connect issue<commit_after>/* global Renderer: true */

utils.extend(KityMinder, {
    _connectProviders: {},

    _defaultConnectProvider: function(node, parent, connection) {
        connection.setPathData([
            'M', parent.getLayoutPoint(),
            'L', node.getLayoutPoint()
        ]);
    },

    registerConnectProvider: function(layout, provider) {
        KityMinder._connectProviders[layout] = provider;
    },

    getConnectProvider: function(layout) {
        return KityMinder._connectProviders[layout] || KityMinder._defaultConnectProvider;
    }
});

kity.extendClass(Minder, {

    createConnect: function(node) {
        if (node.isRoot()) return;

        var strokeColor = node.getStyle('connect-color') || 'white',
            strokeWidth = node.getStyle('connect-width') || 2;

        var connection = new kity.Path()
            .stroke(strokeColor, strokeWidth);

        node._connection = connection;

        if (!this._connectContainer) {
            this._connectContainer = new kity.Group().setId(KityMinder.uuid('minder_connect_group'));
            this.getRenderContainer().prependShape(this._connectContainer);
        }

        this._connectContainer.addShape(connection);
    },

    removeConnect: function(node) {
        var me = this;
        node.traverse(function(node) {
            me._connectContainer.removeShape(node._connection);
        });
    },

    updateConnect: function(node) {

        var connection = node._connection;
        var parent = node.parent;

        if (!parent) return;

        if (parent.isCollapsed()) {
            connection.setVisible(false);
            return;
        }
        connection.setVisible(true);

        var provider = KityMinder.getConnectProvider(parent.getLayout());

        provider(node, parent, connection);
    }
});

KityMinder.registerModule('Connect', {
    events: {
        'nodecreate': function(e) {
            this.createConnect(e.node);
        },
        'noderemove': function(e) {
            this.removeConnect(e.node);
        },
        'layoutapply noderender': function(e) {
            this.updateConnect(e.node);
        }
    }
});<|endoftext|>


<commit_before>/**
 * SetupMain component stories.
 *
 * Site Kit by Google, Copyright 2022 Google LLC
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * Internal dependencies
 */
import { MODULES_THANK_WITH_GOOGLE } from '../../datastore/constants';
import {
	createTestRegistry,
	freezeFetch,
	provideModules,
	provideModuleRegistrations,
	provideSiteInfo,
	WithTestRegistry,
} from '../../../../../../tests/js/utils';
import { Cell, Grid, Row } from '../../../../material-components';
import WithRegistrySetup from '../../../../../../tests/js/WithRegistrySetup';
import SetupMain from './SetupMain';

const features = [ 'twgModule' ];

const publicationWithActiveStateA = {
	// eslint-disable-next-line sitekit/acronym-case
	publicationId: 'test-publication-a',
	displayName: 'Test publication title',
	verifiedDomains: [ 'https://example.com' ],
	paymentOptions: {
		virtualGifts: true,
	},
	state: 'ACTIVE',
};
// const publicationWithActiveStateB = {
// 	...publicationWithActiveStateA,
// 	// eslint-disable-next-line sitekit/acronym-case
// 	publicationId: 'test-publication-b',
// };
const publicationActionRequiredStateC = {
	...publicationWithActiveStateA,
	// eslint-disable-next-line sitekit/acronym-case
	publicationId: 'test-publication-c',
	state: 'ACTION_REQUIRED',
};
// const publicationPendingVerificationD = {
// 	...publicationWithActiveStateA,
// 	// eslint-disable-next-line sitekit/acronym-case
// 	publicationId: 'test-publication-d',
// 	state: 'PENDING_VERIFICATION',
// };
// const publicationsWithActiveState = [
// 	publicationWithActiveStateA,
// 	publicationWithActiveStateB,
// ];

function Template( { setupRegistry } ) {
	return (
		<WithRegistrySetup func={ setupRegistry }>

					<Grid>
						<Row>
							<Cell size={ 12 }>
								<SetupMain />
							</Cell>
						</Row>
					</Grid>

		</WithRegistrySetup>
	);
}

export const PublicationsLoading = Template.bind( {} );
PublicationsLoading.storyName = 'Publications Loading';
PublicationsLoading.args = {
	setupRegistry: () => {
		freezeFetch(
			/^\/google-site-kit\/v1\/modules\/thank-with-google\/data\/publications/
		);
	},
};

export const CreatePublication = Template.bind( {} );
CreatePublication.storyName = 'Create Publication';
CreatePublication.args = {
	setupRegistry: ( registry ) => {
		registry
			.dispatch( MODULES_THANK_WITH_GOOGLE )
			.receiveGetPublications( [] );
	},
};

export const PublicationActionRequired = Template.bind( {} );
PublicationActionRequired.storyName = 'Publication Action Required';
PublicationActionRequired.args = {
	setupRegistry: ( registry ) => {
		registry
			.dispatch( MODULES_THANK_WITH_GOOGLE )
			.receiveGetPublications( [ publicationActionRequiredStateC ] );
	},
};

export default {
	title: 'Modules/Thank with Google/Setup/SetupMain',
	component: SetupMain,
	decorators: [
		( Story ) => {
			const registry = createTestRegistry();
			provideModules( registry, [
				{
					slug: 'thank-with-google',
					active: true,
					connected: false,
				},
			] );
			provideSiteInfo( registry );
			provideModuleRegistrations( registry );

			return (
				<WithTestRegistry
					registry={ registry }
					features={ [ 'twgModule' ] }
				>
					<Story />
				</WithTestRegistry>
			);
		},
	],
	parameters: { padding: 0, features },
};
<commit_msg>Add publication pending verification story.<commit_after>/**
 * SetupMain component stories.
 *
 * Site Kit by Google, Copyright 2022 Google LLC
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * Internal dependencies
 */
import { MODULES_THANK_WITH_GOOGLE } from '../../datastore/constants';
import {
	createTestRegistry,
	freezeFetch,
	provideModules,
	provideModuleRegistrations,
	provideSiteInfo,
	WithTestRegistry,
} from '../../../../../../tests/js/utils';
import { Cell, Grid, Row } from '../../../../material-components';
import WithRegistrySetup from '../../../../../../tests/js/WithRegistrySetup';
import SetupMain from './SetupMain';

const features = [ 'twgModule' ];

const publicationWithActiveStateA = {
	// eslint-disable-next-line sitekit/acronym-case
	publicationId: 'test-publication-a',
	displayName: 'Test publication title',
	verifiedDomains: [ 'https://example.com' ],
	paymentOptions: {
		virtualGifts: true,
	},
	state: 'ACTIVE',
};
// const publicationWithActiveStateB = {
// 	...publicationWithActiveStateA,
// 	// eslint-disable-next-line sitekit/acronym-case
// 	publicationId: 'test-publication-b',
// };
const publicationActionRequiredStateC = {
	...publicationWithActiveStateA,
	// eslint-disable-next-line sitekit/acronym-case
	publicationId: 'test-publication-c',
	state: 'ACTION_REQUIRED',
};
const publicationPendingVerificationD = {
	...publicationWithActiveStateA,
	// eslint-disable-next-line sitekit/acronym-case
	publicationId: 'test-publication-d',
	state: 'PENDING_VERIFICATION',
};
// const publicationsWithActiveState = [
// 	publicationWithActiveStateA,
// 	publicationWithActiveStateB,
// ];

function Template( { setupRegistry } ) {
	return (
		<WithRegistrySetup func={ setupRegistry }>

					<Grid>
						<Row>
							<Cell size={ 12 }>
								<SetupMain />
							</Cell>
						</Row>
					</Grid>

		</WithRegistrySetup>
	);
}

export const PublicationsLoading = Template.bind( {} );
PublicationsLoading.storyName = 'Publications Loading';
PublicationsLoading.args = {
	setupRegistry: () => {
		freezeFetch(
			/^\/google-site-kit\/v1\/modules\/thank-with-google\/data\/publications/
		);
	},
};

export const CreatePublication = Template.bind( {} );
CreatePublication.storyName = 'Create Publication';
CreatePublication.args = {
	setupRegistry: ( registry ) => {
		registry
			.dispatch( MODULES_THANK_WITH_GOOGLE )
			.receiveGetPublications( [] );
	},
};

export const PublicationActionRequired = Template.bind( {} );
PublicationActionRequired.storyName = 'Publication Action Required';
PublicationActionRequired.args = {
	setupRegistry: ( registry ) => {
		registry
			.dispatch( MODULES_THANK_WITH_GOOGLE )
			.receiveGetPublications( [ publicationActionRequiredStateC ] );
	},
};

export const PublicationPendingVerification = Template.bind( {} );
PublicationPendingVerification.storyName = 'Publication Pending Verification';
PublicationPendingVerification.args = {
	setupRegistry: ( registry ) => {
		registry
			.dispatch( MODULES_THANK_WITH_GOOGLE )
			.receiveGetPublications( [ publicationPendingVerificationD ] );
	},
};

export default {
	title: 'Modules/Thank with Google/Setup/SetupMain',
	component: SetupMain,
	decorators: [
		( Story ) => {
			const registry = createTestRegistry();
			provideModules( registry, [
				{
					slug: 'thank-with-google',
					active: true,
					connected: false,
				},
			] );
			provideSiteInfo( registry );
			provideModuleRegistrations( registry );

			return (
				<WithTestRegistry
					registry={ registry }
					features={ [ 'twgModule' ] }
				>
					<Story />
				</WithTestRegistry>
			);
		},
	],
	parameters: { padding: 0, features },
};
<|endoftext|>


<commit_before>/*global define, window, WeakMap, console, Proxy */
/*jslint indent: 2, todo: true, nomen: true */

define('blame', [], function () {
  'use strict';

  var blame = Object.create(Object.prototype),
    SEALS = new WeakMap();

  blame.DEBUG = true;

  function unused() { return; }
  unused(unused);

  function is_object(obj) {
    return !!(obj && (typeof obj === 'object'));
  }

  function is_function(value) {
    return typeof value === 'function';
  }

  function is_number(value) {
    return typeof value === 'number';
  }

  function is_boolean(value) {
    return typeof value === 'boolean';
  }

  function is_string(value) {
    return typeof value === 'string';
  }

  function is_array(value) {
    return Array.isArray(value);
  }

  function is_undefined(value) {
    return value === undefined;
  }

  // Type Definition
  function Type(description, contract) {
    if (!(this instanceof Type)) {
      return new Type(description, contract);
    }

    this.description = String(description);

    if (!is_function(contract)) {
      throw new Error(contract + ' is not a function');
    }

    this.contract = contract;
  }

  Type.prototype.contract = function () {
    throw new Error('Empty test');
  };

  // Publish type
  blame.Type = Type;

  // Define a simple contract
  function simple_contract(test) {
    return function (value, label) {
      if (!test(value)) {
        throw new Error(label);
      }
      return value;
    };
  }

  function typedef(name, contract) {
    blame[name] = new Type(name, contract);
  }

  typedef('Num', simple_contract(is_number));
  typedef('Str', simple_contract(is_string));
  typedef('Bool', simple_contract(is_boolean));
  typedef('Fun', simple_contract(is_function));
  typedef('Undefined', simple_contract(is_undefined));

  // Wrapping
  // ========
  function wrap(type, value, label) {
    // TODO: Consider removing this
    if (!(type instanceof Type)) {
      throw new Error('This is not a type!');
    }
    return type.contract(value, label);
  }
  blame.wrap = wrap;

  // Higher Order Contracts
  // ======================

  // Multiple function composition (Chains the contracts)
  function compose() {
    var contracts = Array.prototype.slice.call(arguments || []);

    if (contracts.length < 2) {
      throw new Error('Incorrect Number of contracts: ' + contracts.length);
    }

    return function () {
      var args = Array.prototype.slice.call(arguments || []),
        length = contracts.length,
        interim;

      while (length--) {
        interim = contracts[length].apply(this, args);
        args[0] = interim;
      }

      return args[0];
    };
  }

  // Mapper over the arrays
  function map(array, f) {
    var i, result;

    // For now work only for arrays
    if (!is_array(array)) {
      throw new TypeError(array + 'is not an array');
    }

    result = [];

    for (i = 0; i < array.length; i++) {
      result[i] = f(array[i], i, array);
    }

    return result;
  }

  // Iterate over keys in an objects
  function each(object, f) {
    var key;

    if (!is_object(object)) {
      throw new TypeError(object + 'is not an object');
    }
    for (key in object) {
      if (object.hasOwnProperty(key)) {
        if(f(key)) {
          break;
        }
      }
    }
  }

  // Wrapping Functions
  // ------------------
  function TFun(description, contract) {
    this.description = description;
    this.contract = contract;
  }
  TFun.prototype = Object.create(Type.prototype);

  // Type Variable Context
  // ---------------------
  function Context(old_context) {
    var self = this;
    if (old_context && !(old_context instanceof Context)) {
      throw new TypeError(old_context + ' is not a Context');
    }

    // Inherit from old_context
    if (old_context) {
      each(old_context, function (key) {
        self[key] = old_context[key];
      });
    }
  }

  // Defining the function type
  // --------------------------
  function tfun() {
    // Accept multiple arguments
    var args, description, domain, range;

    args = Array.prototype.slice.call(arguments || []);

    if (args.length < 1) {
      throw new Error('Not enough arguments');
    }

    // Check if all arguments are Type and generate descriptions
    args.forEach(function (arg, index) {
      if (!(arg instanceof Type)) {
        throw new Error('argument ' + index + ' is not a Type');
      }
    });

    description = map(args, function (arg) {
      var new_description = arg.description;
      if (new_description.indexOf(' -> ') !== -1) {
        new_description = '(' + new_description + ')';
      }
      return new_description;
    }).join(' -> ');

    // Domain and range arguments
    domain = args.slice(0, -1);
    range = args[args.length - 1];

    // Proxy Wrapper
    // -------------
    // This contract generates a Proxy wrapper for the functions
    function contract(fun, label, context) {
      var negated, handler;

      negated = '~' + label;

      // Create new Context
      // ------------------
      // Here we create new seals per each function invocation
      // If there are no no tyvar types, the context is simply ignored

      function wrap_argument(arg, index) {
        return domain[index].contract.call(undefined, arg, negated, context);
      }

      handler = {
        apply: function (target, thisArg, args) {
          var wrapped_args, result;

          if (args.length !== domain.length) {
            throw new Error('Wrong number of arguments: got ' + args.length +
                            ', expected ' + domain.length);
          }

          wrapped_args = map(args, wrap_argument);

          result = target.apply(thisArg, wrapped_args);

          return range.contract.call(undefined, result, label, context, true);
        },
        construct: function (target, args) {
          var wrapped_args = map(args, wrap_argument),
          instance = Object.create(target.prototype);

          target.apply(instance, wrapped_args);

          return range.contract.call(undefined, instance, label, context, true);
        }
      };

      return new Proxy(fun, handler);
    }

    return new TFun(description, compose(blame.Fun.contract, contract));
  }
  blame.tfun = tfun;

  function Forall(id, type) {
    var tyvar = String(id);

    if(!(type instanceof TFun)) {
      throw new TypeError(type + 'is not a TFun or Forall');
    }

    this.description = 'forall ' + id + ', ' + type.description;

    this.contract = function (value, label, context) {
      var my_context = new Context(context);

      if (my_context[tyvar]) {
        throw new TypeError('Duplicate type variable: ' + tyvar);
      }

      // Declare a new type variable
      my_context[tyvar] = true;

      return type.contract.call(undefined, value, label, my_context);
    };
  }
  Forall.prototype = Object.create(TFun.prototype);

  function Binding(tyvar, value) {
    this.tyvar = tyvar;
    this.value = value;
  }
  Binding.prototype.tyvar = '';
  Binding.prototype.value = null;

  // Token
  // -----
  // Replaces the sealed value
  function Token(tyvar) {
    this.tyvar = tyvar;
  }
  Token.prototype.tyvar = '';

  // Preventing all object like operations on tokens
  function token(tyvar, label) {
    var handler = {}, t = new Token(tyvar);

    function panic() {
      throw new TypeError(label + ', Accessing properties of token ' + token.tyvar);
    }

    if (!blame.DEBUG) {
      [
        'getOwnPropertyDescriptor',
        'getOwnPropertyNames',
        'defineProperty',
        'deleteProperty',
        'freeze',
        'seal',
        'preventExtensions',
        'has',
        'hasOwn',
        'get',
        'set',
        'enumerate',
        'iterate',
        'keys',
        'apply',
        'construct'
      ].forEach(function (e) {
        handler[e] = panic;
      });
    }

    return new Proxy(t, handler);
  }

  function is_sealed(value) {
    return !!(value && (value instanceof Token) && SEALS.has(value));
  }

  // Sealing function
  // ----------------
  // Sealing the value inside a token by using the method of storing private
  // properties of an object using a WeakMap.
  //
  // References:
  // * https://developer.mozilla.org/en-US/Add-ons/SDK/Guides/Contributor_s_Guide/Private_Properties#Using_WeakMaps
  // * http://fitzgeraldnick.com/weblog/53/
  function seal(value, tyvar, label) {
    // TODO: Unsure if the label is proper here
    var my_token = token(tyvar, label),
      binding = new Binding(tyvar, value);

    // Setting the binding as a private property on my_token
    SEALS.set(my_token, binding);

    return my_token;
  }

  // Unsealing function
  // ------------------
  function unseal(token, tyvar, label) {
    if (!is_sealed(token)) {
      throw new TypeError (label + ', not a sealed token');
    }

    // Retrieving the binding as a private property of token
    var binding = SEALS.get(token);

    if (binding.tyvar !== tyvar) {
      throw new TypeError (label + ', wrong seal, ' + binding.tyvar + ' instead of ' + tyvar);
    }

    return binding.value;
  }

  function Tyvar (id) {
    var tyvar = String(id);
    this.description = tyvar;
    this.contract = function(value, label, context, is_unseal) {
      if(!context[tyvar]) {
        throw new TypeError('Type variable ' + tyvar + ' is not defined');
      }

      if (is_unseal) {
        // This corresponds to the *:X cast
        return unseal(value, tyvar, label, context);
      }

      // This corresponds to the X:* cast
      return seal(value, tyvar, label, context);
    };
  }
  Tyvar.prototype = Object.create(Type.prototype);

  function forall(tyvar, type) {
    return new Forall(tyvar, type);
  }
  blame.forall = forall;

  function tyvar(id) {
    return new Tyvar(id);
  }
  blame.tyvar = tyvar;

  return blame;
});

// vim: set ts=2 sw=2 sts=2 et :
<commit_msg>Revert "Merge branch 'simplified'"<commit_after>/*global define, window, WeakMap, console, Proxy */
/*jslint indent: 2, todo: true, nomen: true */

define('blame', [], function () {
  'use strict';

  var blame = Object.create(Object.prototype);

  blame.DEBUG = true;

  function unused() { return; }
  unused(unused);

  function is_object(obj) {
    return !!(obj && (typeof obj === 'object'));
  }

  function is_function(value) {
    return typeof value === 'function';
  }

  function is_number(value) {
    return typeof value === 'number';
  }

  function is_boolean(value) {
    return typeof value === 'boolean';
  }

  function is_string(value) {
    return typeof value === 'string';
  }

  function is_array(value) {
    return Array.isArray(value);
  }

  function is_undefined(value) {
    return value === undefined;
  }

  // Type Definition
  function Type(description, contract) {
    if (!(this instanceof Type)) {
      return new Type(description, contract);
    }

    this.description = String(description);

    if (!is_function(contract)) {
      throw new Error(contract + ' is not a function');
    }

    this.contract = contract;
  }

  Type.prototype.contract = function () {
    throw new Error('Empty test');
  };

  // Publish type
  blame.Type = Type;

  // Define a simple contract
  function simple_contract(test) {
    return function (value, label) {
      if (!test(value)) {
        throw new Error(label);
      }
      return value;
    };
  }

  function typedef(name, contract) {
    blame[name] = new Type(name, contract);
  }

  typedef('Num', simple_contract(is_number));
  typedef('Str', simple_contract(is_string));
  typedef('Bool', simple_contract(is_boolean));
  typedef('Fun', simple_contract(is_function));
  typedef('Undefined', simple_contract(is_undefined));

  // Wrapping
  // ========
  function wrap(type, value, label) {
    // TODO: Consider removing this
    if (!(type instanceof Type)) {
      throw new Error('This is not a type!');
    }
    return type.contract(value, label);
  }
  blame.wrap = wrap;

  // Higher Order Contracts
  // ======================

  // Multiple function composition (Chains the contracts)
  function compose() {
    var contracts = Array.prototype.slice.call(arguments || []);

    if (contracts.length < 2) {
      throw new Error('Incorrect Number of contracts: ' + contracts.length);
    }

    return function () {
      var args = Array.prototype.slice.call(arguments || []),
        length = contracts.length,
        interim;

      while (length--) {
        interim = contracts[length].apply(this, args);
        args[0] = interim;
      }

      return args[0];
    };
  }

  // Mapper over the arrays
  function map(array, f) {
    var i, result;

    // For now work only for arrays
    if (!is_array(array)) {
      throw new TypeError(array + 'is not an array');
    }

    result = [];

    for (i = 0; i < array.length; i++) {
      result[i] = f(array[i], i, array);
    }

    return result;
  }

  // Iterate over keys in an objects
  function each(object, f) {
    var key;

    if (!is_object(object)) {
      throw new TypeError(object + 'is not an object');
    }
    for (key in object) {
      if (object.hasOwnProperty(key)) {
        if(f(key)) {
          break;
        }
      }
    }
  }

  // Wrapping Functions
  // ------------------
  function TFun(description, contract) {
    this.description = description;
    this.contract = contract;
  }
  TFun.prototype = Object.create(Type.prototype);

  // Type Variable Context
  // ---------------------
  // Seals made within a given context are modeled in the following way:
  // - Tyvars - contains a set of type variables declared in the context
  // - Bindings - contains a map from to tokens to objects which contain:
  //   - the type variable they were sealed with
  //   - the value that was sealed *in* the token
  function Context(old_context) {
    var self = this;
    if (old_context && !(old_context instanceof Context)) {
      throw new TypeError(old_context + ' is not a Context');
    }

    this.tyvars = {};
    this.bindings = new WeakMap();
    this.tokens = [];

    // Inherit from old_context
    if (old_context) {
      each(old_context.tyvars, function (key) {
        self.tyvars[key] = old_context.tyvars[key];
      });

      old_context.tokens.forEach(function (token) {
        var binding = old_context.bindings.get(token);

        self.tokens.push(token);
        self.bindings.set(token, binding);
      });
    }
  }

  // Defining the function type
  // --------------------------
  function tfun() {
    // Accept multiple arguments
    var args, description, domain, range;

    args = Array.prototype.slice.call(arguments || []);

    if (args.length < 1) {
      throw new Error('Not enough arguments');
    }

    // Check if all arguments are Type and generate descriptions
    args.forEach(function (arg, index) {
      if (!(arg instanceof Type)) {
        throw new Error('argument ' + index + ' is not a Type');
      }
    });

    description = map(args, function (arg) {
      var new_description = arg.description;
      if (new_description.indexOf(' -> ') !== -1) {
        new_description = '(' + new_description + ')';
      }
      return new_description;
    }).join(' -> ');

    // Domain and range arguments
    domain = args.slice(0, -1);
    range = args[args.length - 1];

    // Proxy Wrapper
    // -------------
    // This contract generates a Proxy wrapper for the functions
    function contract(fun, label, context) {
      var negated, handler, my_context;

      negated = '~' + label;

      // Create new Context
      // ------------------
      // Here we create new seals per each function invocation
      // If there are no no tyvar types, the context is simply ignored
      my_context = new Context(context);

      function wrap_argument(arg, index) {
        return domain[index].contract.call(undefined, arg, negated, my_context);
      }

      handler = {
        apply: function (target, thisArg, args) {
          var wrapped_args, result;

          if (args.length !== domain.length) {
            throw new Error('Wrong number of arguments: got ' + args.length +
                            ', expected ' + domain.length);
          }

          wrapped_args = map(args, wrap_argument);

          result = target.apply(thisArg, wrapped_args);

          return range.contract.call(undefined, result, label, my_context, true);
        },
        construct: function (target, args) {
          var wrapped_args = map(args, wrap_argument),
          instance = Object.create(target.prototype);

          target.apply(instance, wrapped_args);

          return range.contract.call(undefined, instance, label, context, true);
        }
      };

      return new Proxy(fun, handler);
    }

    return new TFun(description, compose(blame.Fun.contract, contract));
  }
  blame.tfun = tfun;

  function Forall(id, type) {
    var tyvar = String(id);

    if(!(type instanceof TFun)) {
      throw new TypeError(type + 'is not a TFun or Forall');
    }

    this.description = 'forall ' + id + ', ' + type.description;

    this.contract = function (value, label, context) {
      var my_context = new Context(context);

      if (my_context.tyvars[tyvar]) {
        throw new TypeError('Duplicate type variable: ' + tyvar);
      }

      // Declare a new type variable
      my_context.tyvars[tyvar] = true;

      return type.contract.call(undefined, value, label, my_context);
    };
  }
  Forall.prototype = Object.create(TFun.prototype);

  function Binding(tyvar, value) {
    this.tyvar = tyvar;
    this.value = value;
  }
  Binding.prototype.tyvar = '';
  Binding.prototype.value = null;

  // Token
  // -----
  // Replaces the sealed value
  function Token(tyvar) {
    this.tyvar = tyvar;
  }
  Token.prototype.tyvar = '';

  // Preventing all object like operations on tokens
  function token(tyvar, label) {
    var handler = {}, t = new Token(tyvar);

    function panic() {
      throw new TypeError(label + ', Accessing properties of token ' + token.tyvar);
    }

    if (!blame.DEBUG) {
      [
        'getOwnPropertyDescriptor',
        'getOwnPropertyNames',
        'defineProperty',
        'deleteProperty',
        'freeze',
        'seal',
        'preventExtensions',
        'has',
        'hasOwn',
        'get',
        'set',
        'enumerate',
        'iterate',
        'keys',
        'apply',
        'construct'
      ].forEach(function (e) {
        handler[e] = panic;
      });
    }

    return new Proxy(t, handler);
  }

  function is_unsealed(value) {
    return !(value instanceof Token);
  }

  // Sealing function
  // ----------------
  // Sealing the value inside a token by using the method of storing private
  // properties of an object using a WeakMap.
  //
  // References:
  // * https://developer.mozilla.org/en-US/Add-ons/SDK/Guides/Contributor_s_Guide/Private_Properties#Using_WeakMaps
  // * http://fitzgeraldnick.com/weblog/53/
  function seal(value, tyvar, label, context) {
    if (!(context instanceof Context)) {
      throw new TypeError(context + ' is not a Context');
    }

    // TODO: Verify what to throw
    if (!context.tyvars[tyvar]) {
      throw new TypeError(tyvar + ' is not defined,' + label);
    }

    // TODO: Unsure if the label is proper here
    var my_token = token(tyvar, label),
      binding = new Binding(tyvar, value);

    context.bindings.set(my_token, binding);
    context.tokens.push(my_token);

    return my_token;
  }

  // Unsealing function
  // ------------------
  function unseal(token, tyvar, label, context) {
    if (is_unsealed(token)) {
      throw new TypeError (label + ', not a token sealed by ' + tyvar);
    }

    if (!context.bindings.has(token)) {
      throw new TypeError (label + ', token sealed by a different forall');
    }

    var binding = context.bindings.get(token);

    if (binding.tyvar !== tyvar) {
      throw new TypeError (label + ', wrong seal, ' + binding.tyvar + ' instead of ' + tyvar);
    }

    return binding.value;
  }

  function Tyvar (id) {
    var tyvar = String(id);
    this.description = tyvar;
    this.contract = function(value, label, context, is_unseal) {
      if (is_unseal) {
        // This corresponds to the *:X cast
        return unseal(value, tyvar, label, context);
      }

      // This corresponds to the X:* cast
      return seal(value, tyvar, label, context);
    };
  }
  Tyvar.prototype = Object.create(Type.prototype);

  function forall(tyvar, type) {
    return new Forall(tyvar, type);
  }
  blame.forall = forall;

  function tyvar(id) {
    return new Tyvar(id);
  }
  blame.tyvar = tyvar;

  return blame;
});

// vim: set ts=2 sw=2 sts=2 et :
<|endoftext|>