<commit_before>import MetaWithOptions from 'appkit/utils/meta-options';

export default Ember.Route.extend({
  beforeModel: function (transition) {

    if (!this.get('buildEnvironment.local')) {
      this.transitionTo('wh');
    }
    this._super.apply(this, arguments);

    var formRoute = this;

    var promises = Ember.A([]);

    promises.push(this.store.find('control-type-group').then(function (controlTypeGroups) {
      formRoute.set('controlTypeGroups', controlTypeGroups);
    }));

    promises.push(this.store.find('content-type').then(function (contentTypes) {
      formRoute.set('contentTypes', contentTypes);
    }));

    return Ember.RSVP.all(promises);
  },
  model: function (params) {
    return this.store.getById('content-type', params.id);
  },
  setupController: function (controller, model) {

    controller.set('addedControls', Ember.A([]));
    controller.set('removedControls', Ember.A([]));
    controller.set('changedNameControls', Ember.A([]));
    controller.set('changedRadioControls', Ember.A([]));
    controller.set('changedRelationTypeControls', Ember.A([]));

    // Save original name for comparison when saving
    // If control name changes, data keys must be updated
    model.get('controls').forEach(function (control) {
      control.set('originalName', control.get('name'));
    });

    // Save original related content types for comparison when saving
    // If contentTypeId changes
    // - old reverse relations must be removed
    // - new reverse relations must be added
    model.get('controls').filterBy('controlType.widget', 'relation').forEach(function (control) {
      control.set('originalRelatedContentTypeId', control.get('meta.contentTypeId'));
      control.set('originalRelatedIsSingle', control.get('meta.isSingle'));
    });

    controller.set('isEditingTypeId', false);

    controller.set('editingControl', null);
    controller.set('isEditing', false);

    controller.set('controlTypeGroups', this.get('controlTypeGroups'));

    if (this.get('session.supportedMessages.layouts')) {

      if (model.get('oneOff') || model.get('controls').isAny('controlType.widget', 'layout')) {
        this.store.getById('control-type', 'layout').set('isHidden', true);
      } else {
        this.store.getById('control-type', 'layout').set('isHidden', false);
      }

    } else {

      this.store.getById('control-type', 'layout').set('isHidden', true);

    }

    controller.set('contentTypes', this.get('contentTypes'));

    model.get('controls').setEach('widgetIsValid', true);
    model.get('controls').setEach('value', null);

    // controls with meta.options (checkbox, radio, tabular, select)
    // get special treatment
    model.get('controls').filter(function (control) {
      switch (control.get('controlType.widget')) {
        case 'checkbox':
        case 'radio':
        case 'select':
        case 'tabular':
        case 'layout':
          return true;
        default:
          return false;
      }
    }).forEach(function (control) {
      control.set('meta', MetaWithOptions.create(control.get('meta')));
    });

    model.get('controls').filterBy('controlType.widget', 'checkbox').forEach(function (control) {
      control.get('meta.options').setEach('value', undefined);
    });

    model.get('controls').filterBy('controlType.widget', 'radio').forEach(function (control) {
      control.set('originalOptions', control.get('meta.options').getEach('value'));
    });

    model.get('controls').filterBy('controlType.widget', 'tabular').forEach(function (control) {

      var value = Ember.A([]);
      var emptyRow = Ember.A([]);
      control.get('meta.options').forEach(function () {
        emptyRow.pushObject("");
      });
      value.pushObject(emptyRow);

      control.set('value', value);

    });

    if (typeof model.get('customUrls') === 'undefined') {
      model.set('customUrls', {
        individualUrl: null,
        listUrl: null
      });
    }

    this._super.apply(this, arguments);
  }
});
<commit_msg>rollback unsaved changes when you transition away. fixes #187<commit_after>import MetaWithOptions from 'appkit/utils/meta-options';

export default Ember.Route.extend({
  beforeModel: function (transition) {

    if (!this.get('buildEnvironment.local')) {
      this.transitionTo('wh');
    }
    this._super.apply(this, arguments);

    var formRoute = this;

    var promises = Ember.A([]);

    promises.push(this.store.find('control-type-group').then(function (controlTypeGroups) {
      formRoute.set('controlTypeGroups', controlTypeGroups);
    }));

    promises.push(this.store.find('content-type').then(function (contentTypes) {
      formRoute.set('contentTypes', contentTypes);
    }));

    return Ember.RSVP.all(promises);
  },
  model: function (params) {
    return this.store.getById('content-type', params.id);
  },
  setupController: function (controller, model) {

    controller.set('addedControls', Ember.A([]));
    controller.set('removedControls', Ember.A([]));
    controller.set('changedNameControls', Ember.A([]));
    controller.set('changedRadioControls', Ember.A([]));
    controller.set('changedRelationTypeControls', Ember.A([]));

    // Save original name for comparison when saving
    // If control name changes, data keys must be updated
    model.get('controls').forEach(function (control) {
      control.set('originalName', control.get('name'));
    });

    // Save original related content types for comparison when saving
    // If contentTypeId changes
    // - old reverse relations must be removed
    // - new reverse relations must be added
    model.get('controls').filterBy('controlType.widget', 'relation').forEach(function (control) {
      control.set('originalRelatedContentTypeId', control.get('meta.contentTypeId'));
      control.set('originalRelatedIsSingle', control.get('meta.isSingle'));
    });

    controller.set('isEditingTypeId', false);

    controller.set('editingControl', null);
    controller.set('isEditing', false);

    controller.set('controlTypeGroups', this.get('controlTypeGroups'));

    if (this.get('session.supportedMessages.layouts')) {

      if (model.get('oneOff') || model.get('controls').isAny('controlType.widget', 'layout')) {
        this.store.getById('control-type', 'layout').set('isHidden', true);
      } else {
        this.store.getById('control-type', 'layout').set('isHidden', false);
      }

    } else {

      this.store.getById('control-type', 'layout').set('isHidden', true);

    }

    controller.set('contentTypes', this.get('contentTypes'));

    model.get('controls').setEach('widgetIsValid', true);
    model.get('controls').setEach('value', null);

    // controls with meta.options (checkbox, radio, tabular, select)
    // get special treatment
    model.get('controls').filter(function (control) {
      switch (control.get('controlType.widget')) {
        case 'checkbox':
        case 'radio':
        case 'select':
        case 'tabular':
        case 'layout':
          return true;
        default:
          return false;
      }
    }).forEach(function (control) {
      control.set('meta', MetaWithOptions.create(control.get('meta')));
    });

    model.get('controls').filterBy('controlType.widget', 'checkbox').forEach(function (control) {
      control.get('meta.options').setEach('value', undefined);
    });

    model.get('controls').filterBy('controlType.widget', 'radio').forEach(function (control) {
      control.set('originalOptions', control.get('meta.options').getEach('value'));
    });

    model.get('controls').filterBy('controlType.widget', 'tabular').forEach(function (control) {

      var value = Ember.A([]);
      var emptyRow = Ember.A([]);
      control.get('meta.options').forEach(function () {
        emptyRow.pushObject("");
      });
      value.pushObject(emptyRow);

      control.set('value', value);

    });

    if (typeof model.get('customUrls') === 'undefined') {
      model.set('customUrls', {
        individualUrl: null,
        listUrl: null
      });
    }

    this._super.apply(this, arguments);
  },

  actions: {
    willTransition: function () {
      this.controllerFor('form').get('model').rollback();
    }
  }
});
<|endoftext|>


<commit_before>import Ember from 'ember';

export default Ember.Route.extend({
  model: function() {
  }
});
<commit_msg>look up the model for a step<commit_after>import Ember from 'ember';

export default Ember.Route.extend({
  model: function(params) {
    return this.store.find('step', params.step);
  }
});
<|endoftext|>


<commit_before>'use strict';

/**
 * @ngdoc overview
 * @name translapediaApp
 * @description
 * # translapediaApp
 *
 * Main module of the application.
 */
angular
  .module('translapediaApp', [
    'ngAnimate',
    'ngRoute',
    'ngSanitize'
  ])

	.constant('languageCodes', {
		en: 'English',
		pt: 'Portuguese',
		sv: 'Swedish'
	})

  .config(function ($routeProvider) {
    $routeProvider
      .when('/', {
        templateUrl: 'views/main.html',
        controller: 'MainCtrl'
      })
      .when('/about', {
        templateUrl: 'views/about.html',
        controller: 'AboutCtrl'
      })
      .when('/translate', {
        templateUrl: 'views/translate.html',
        controller: 'TranslateCtrl'
      })
      .when('/found', {
        templateUrl: 'views/found.html',
        controller: 'FoundCtrl'
      })
      .when('/found-redirect', {
        templateUrl: 'views/found-redirect.html',
        controller: 'FoundRedirectCtrl'
      })
      .when('/found-ambiguous', {
        templateUrl: 'views/found-ambiguous.html',
        controller: 'FoundAmbiguousCtrl'
      })
      .when('/not-found', {
        templateUrl: 'views/not-found.html',
        controller: 'NotFoundCtrl'
      })
      .when('/not-found-translation', {
        templateUrl: 'views/not-found-translation.html',
        controller: 'NotFoundTranslationCtrl'
      })
      .when('/not-found-ambiguous', {
        templateUrl: 'views/not-found-ambiguous.html',
        controller: 'NotFoundAmbiguousCtrl'
      })
			.when('/error', {
				templateUrl: 'views/error.html'
			})
      .otherwise({
        redirectTo: '/'
      });
  });
<commit_msg>Add more languages.<commit_after>'use strict';

/**
 * @ngdoc overview
 * @name translapediaApp
 * @description
 * # translapediaApp
 *
 * Main module of the application.
 */
angular
  .module('translapediaApp', [
    'ngAnimate',
    'ngRoute',
    'ngSanitize'
  ])

	.constant('languageCodes', {
		en: 'English',
		fr: 'French',
		de: 'German',
		it: 'Italian',
		pl: 'Polish',
		pt: 'Portuguese',
		es: 'Spanish',
		sv: 'Swedish'
	})

  .config(function ($routeProvider) {
    $routeProvider
      .when('/', {
        templateUrl: 'views/main.html',
        controller: 'MainCtrl'
      })
      .when('/about', {
        templateUrl: 'views/about.html',
        controller: 'AboutCtrl'
      })
      .when('/translate', {
        templateUrl: 'views/translate.html',
        controller: 'TranslateCtrl'
      })
      .when('/found', {
        templateUrl: 'views/found.html',
        controller: 'FoundCtrl'
      })
      .when('/found-redirect', {
        templateUrl: 'views/found-redirect.html',
        controller: 'FoundRedirectCtrl'
      })
      .when('/found-ambiguous', {
        templateUrl: 'views/found-ambiguous.html',
        controller: 'FoundAmbiguousCtrl'
      })
      .when('/not-found', {
        templateUrl: 'views/not-found.html',
        controller: 'NotFoundCtrl'
      })
      .when('/not-found-translation', {
        templateUrl: 'views/not-found-translation.html',
        controller: 'NotFoundTranslationCtrl'
      })
      .when('/not-found-ambiguous', {
        templateUrl: 'views/not-found-ambiguous.html',
        controller: 'NotFoundAmbiguousCtrl'
      })
			.when('/error', {
				templateUrl: 'views/error.html'
			})
      .otherwise({
        redirectTo: '/'
      });
  });
<|endoftext|>


<commit_before>'use strict';

/**
 * @ngdoc overview
 * @name timelinerApp
 * @description
 * # timelinerApp
 *
 * Main module of the application.
 */
angular
  .module('timelinerApp', [
    'ngAnimate',
    'ngCookies',
    'ngResource',
    'ngSanitize',
    'ui.router',
    'htk.common',
    'vcRecaptcha',
    'ngMaterial',
    'ngMessages',
    'pascalprecht.translate'
  ]);

angular.module('timelinerApp')
  .run(['$rootScope', '$state', '$timeout', '$translate', function ($rootScope, $state, $timeout, $translate) {
    $rootScope.$on('$stateChangeSuccess', function() {
      function getFullTitle(title) {
        var titlePrefix = 'Timeliner - ';
        return titlePrefix + title;
      }

      $timeout(function () {
        $translate($state.$current.locals.globals.$title).then(function (translation) {
          document.title = getFullTitle(translation);
        });
      });

    });
  }])
  .config(function($mdThemingProvider) {
    var tlPalette = $mdThemingProvider.extendPalette('blue-grey', {
      '50': 'd5d5d7',
      '100': 'c0c1c3',
      '200': 'abacaf',
      '300': '96989b',
      '400': '818387',
      '500': '6c6e73',
      '600': '575a5f',
      '700': '42454b',
      '800': '2e3138',
      '900': '222222'
    });

  $mdThemingProvider.definePalette('tlPalette', tlPalette);

    $mdThemingProvider
      .theme('default')
      .dark()
      .primaryPalette('tlPalette', {
        'default': '500',
        'hue-1': '900',
        'hue-3': '700'
      })
      .backgroundPalette('tlPalette', {
        'default': '800',
        'hue-1': '900'
      })
      .accentPalette('light-blue');
      $mdThemingProvider.theme('info-toast');
      $mdThemingProvider.theme('success-toast');
      $mdThemingProvider.theme('warning-toast');
      $mdThemingProvider.theme('error-toast');
  })
  .config(function ($mdDateLocaleProvider, $windowProvider) {
    var $window = $windowProvider.$get();

    $mdDateLocaleProvider.formatDate = function(date) {
      if(date){
        return $window.moment(date).format('DD.MM.YYYY');
      }
      return date;
    };
    $mdDateLocaleProvider.firstDayOfWeek = 1;
  })
  .config(function($translateProvider) {
    $translateProvider.useStaticFilesLoader({
      prefix: '/locales/locale-',
      suffix: '.json'
    });
    $translateProvider.preferredLanguage('en_US');
    $translateProvider.useSanitizeValueStrategy('sanitize');
    $translateProvider.useMissingTranslationHandlerLog();
  });
<commit_msg>Disabled aria-label warnings in angular-material<commit_after>'use strict';

/**
 * @ngdoc overview
 * @name timelinerApp
 * @description
 * # timelinerApp
 *
 * Main module of the application.
 */
angular
  .module('timelinerApp', [
    'ngAnimate',
    'ngCookies',
    'ngResource',
    'ngSanitize',
    'ui.router',
    'htk.common',
    'vcRecaptcha',
    'ngMaterial',
    'ngMessages',
    'pascalprecht.translate'
  ]);

angular.module('timelinerApp')
  .run(['$rootScope', '$state', '$timeout', '$translate', function ($rootScope, $state, $timeout, $translate) {
    $rootScope.$on('$stateChangeSuccess', function() {
      function getFullTitle(title) {
        var titlePrefix = 'Timeliner - ';
        return titlePrefix + title;
      }

      $timeout(function () {
        $translate($state.$current.locals.globals.$title).then(function (translation) {
          document.title = getFullTitle(translation);
        });
      });

    });
  }])
  .config(function($mdThemingProvider) {
    var tlPalette = $mdThemingProvider.extendPalette('blue-grey', {
      '50': 'd5d5d7',
      '100': 'c0c1c3',
      '200': 'abacaf',
      '300': '96989b',
      '400': '818387',
      '500': '6c6e73',
      '600': '575a5f',
      '700': '42454b',
      '800': '2e3138',
      '900': '222222'
    });

  $mdThemingProvider.definePalette('tlPalette', tlPalette);

    $mdThemingProvider
      .theme('default')
      .dark()
      .primaryPalette('tlPalette', {
        'default': '500',
        'hue-1': '900',
        'hue-3': '700'
      })
      .backgroundPalette('tlPalette', {
        'default': '800',
        'hue-1': '900'
      })
      .accentPalette('light-blue');
      $mdThemingProvider.theme('info-toast');
      $mdThemingProvider.theme('success-toast');
      $mdThemingProvider.theme('warning-toast');
      $mdThemingProvider.theme('error-toast');
  })
  .config(function ($mdDateLocaleProvider, $windowProvider) {
    var $window = $windowProvider.$get();

    $mdDateLocaleProvider.formatDate = function(date) {
      if(date){
        return $window.moment(date).format('DD.MM.YYYY');
      }
      return date;
    };
    $mdDateLocaleProvider.firstDayOfWeek = 1;
  })
  .config(function($translateProvider) {
    $translateProvider.useStaticFilesLoader({
      prefix: '/locales/locale-',
      suffix: '.json'
    });
    $translateProvider.preferredLanguage('en_US');
    $translateProvider.useSanitizeValueStrategy('sanitize');
    $translateProvider.useMissingTranslationHandlerLog();
  })
  .config(['$mdAriaProvider', function ($mdAriaProvider) {
    $mdAriaProvider.disableWarnings();
  }]);
<|endoftext|>


<commit_before>'use strict';

/**
 * @ngdoc overview
 * @name panaxuiApp
 * @description
 * # panaxuiApp
 *
 * Main module of the application.
 */
angular
  .module('panaxuiApp', [
    'ngCookies',
    'ngResource',
    'ngSanitize',
    'ngTouch',
    // 'ngAnimate',
    'ui.router',

    'ui.bootstrap',
    'angularBootstrapNavTree',
    'ui.grid.autoResize',
    'ui.grid.pagination',
    'ui.grid.selection',
    'ui.grid.edit',
    'ui.grid.rowEdit',

    'ngUrlify',
    'angular-md5',

    'formly',
    'formlyBootstrap',
    'ui.select'
  ])

  .config(function config($httpProvider, $stateProvider, $urlRouterProvider) {

    /**
     * HTTP Interceptors
     */
    $httpProvider.interceptors.push('ErrorInterceptor');
    $httpProvider.interceptors.push('AuthInterceptor');

    /**
     * UI Router
     */

    // Fallback URL Route
    // Bug Fix: https://github.com/angular-ui/ui-router/issues/1022
    //$urlRouterProvider.otherwise('/');
    $urlRouterProvider.otherwise(function($injector) {
      var $state = $injector.get('$state');
      $state.go('main.home');
    });

    // Set up states
    $stateProvider

      /*
      Login state
       */
      .state('login', {
          url: '/login',
          templateUrl: 'views/shell/login.html'
      })

      /*
      Main `abstract` root state
       */
      .state('main', {
          abstract: true,
          templateUrl: 'views/shell/main.html',
          controller: 'MainCtrl',
          data: {
            authRequired: true
          }
      })

      /*
      Home state
       */
      .state('main.home', {
          url: '/',
          templateUrl: 'views/shell/home.html'
      })

      /*
      Category state
       */
      .state('main.category', {
          url: 'category/{name}',
          templateUrl: 'views/shell/category.html',
          controller: 'CategoryCtrl'
      })

      /*
      Panel `parent` state
       */
      .state('main.panel', {
          templateUrl: 'views/shell/panel.html'
      })

      /*
      Grid `abstract` state
       */
      .state('main.panel.grid', {
        abstract: true,
        url: 'grid/{catalogName}/{mode}',
        controller: 'GridCtrl',
        templateUrl: 'views/grid.html'
      })

      /*
      GridView state
       */
      .state('main.panel.grid.view', {
          views: {
            'main': {
              templateUrl: 'views/grid.main.html'
            },
            'header': {
              templateUrl: 'views/grid.header.html'
            },
            'footer': {
              templateUrl: 'views/grid.footer.html'
            }
          }
      })

      /*
      Form `abstract` state
       */
      .state('main.panel.form', {
        abstract: true,
        url: 'form/{catalogName}/{mode}/{id}',
        controller: 'FormCtrl',
        templateUrl: 'views/form.html'
      })

      /*
      FormView state
       */
      .state('main.panel.form.view', {
          views: {
            'main': {
              templateUrl: 'views/form.main.html'
            },
            'footer': {
              templateUrl: 'views/form.footer.html'
            }
          }
      })

      // .state('main.panel.cardsView', {
      //     url: 'cards/{catalogName}/{mode}',
      //     templateUrl: 'views/cards.html',
      //     controller: 'CardsCtrl'
      // })

      // filters: https://github.com/angular-ui/ui-router/wiki/Multiple-Named-Views
      // .state('main.panel.filtersView', {
      //     url: 'filters/{catalogName}/{mode}',
      //     views: {
      //       'filters':
      //       'results':
      //     }
      // })
    ;
  })

  // At application startup :
  .run(function ($rootScope, $state, AUTH_EVENTS, AuthService, AlertService) {

    /**
     * Try to see if it's already logged in (by getting session info)
     */

    // AuthService.sessionInfo().then(function () {
    //   $rootScope.$broadcast(AUTH_EVENTS.loginSuccess);
    //   $state.go("main.home"); // redundant?
    // });

    /**
     * Ping server every 5 minutes to check session
     */

    // var poller = function () {
    //   AuthService.ping();
    //   $timeout(poller, 300000);
    // };
    // $timeout(poller, 300000);

    /**
     * State change listener
     */

    // $rootScope.$on('$stateChangeStart', function (event, next) {
    //   if(next.data && next.data.authRequired) {
    //     if (!AuthService.isAuthenticated()) {
    //       event.preventDefault();
    //       //$rootScope.$broadcast(AUTH_EVENTS.notAuthenticated); // redundant
    //     }
    //   } else if (AuthService.isAuthenticated()) {
    //     $rootScope.$broadcast(AUTH_EVENTS.loginSuccess);
    //     $state.go("main.home"); // redundant?
    //   }
    // });

    /**
     * Error Events listeners
     */

    $rootScope.$on('error-internal-server', function (event, next) {
      console.info("#EVENT: error-internal-server");
      AlertService.show('danger', 'Error', next.data.message);
    });

    /**
     * Authentication Events listeners
     */

    $rootScope.$on('auth-login-success', function (event, next) {
      console.info("#EVENT: auth-login-success");
      $state.go("main.home");
    });
    //$rootScope.$on('auth-login-failed', function (event, next) {
    //  console.info("#EVENT: auth-login-failed");
    //});
    $rootScope.$on('auth-session-timeout', function (event, next) {
      console.info("#EVENT: auth-session-timeout");
      $state.go("login");
    });
    $rootScope.$on('auth-not-authenticated', function (event, next) {
      console.info("#EVENT: auth-not-authenticated");
      AlertService.show('warning', 'Authentication', next.data.message);
      $state.go("login");
    });
    $rootScope.$on('auth-logout-success', function (event, next) {
      console.info("#EVENT: auth-logout-success");
      $state.go("login");
    });
  })
;
<commit_msg>Auth BUG FIX: Check Auth status at startup. Regression for 2cc2201c Because 'EVENT: auth-not-authenticated' thus `$state.go("login")` was sometimes not triggered when reloading the page Regression for commit: 2cc2201c3f02b12194893547306dcf3ffc9423d5<commit_after>'use strict';

/**
 * @ngdoc overview
 * @name panaxuiApp
 * @description
 * # panaxuiApp
 *
 * Main module of the application.
 */
angular
  .module('panaxuiApp', [
    'ngCookies',
    'ngResource',
    'ngSanitize',
    'ngTouch',
    // 'ngAnimate',
    'ui.router',

    'ui.bootstrap',
    'angularBootstrapNavTree',
    'ui.grid.autoResize',
    'ui.grid.pagination',
    'ui.grid.selection',
    'ui.grid.edit',
    'ui.grid.rowEdit',

    'ngUrlify',
    'angular-md5',

    'formly',
    'formlyBootstrap',
    'ui.select'
  ])

  .config(function config($httpProvider, $stateProvider, $urlRouterProvider) {

    /**
     * HTTP Interceptors
     */
    $httpProvider.interceptors.push('ErrorInterceptor');
    $httpProvider.interceptors.push('AuthInterceptor');

    /**
     * UI Router
     */

    // Fallback URL Route
    // Bug Fix: https://github.com/angular-ui/ui-router/issues/1022
    //$urlRouterProvider.otherwise('/');
    $urlRouterProvider.otherwise(function($injector) {
      var $state = $injector.get('$state');
      $state.go('main.home');
    });

    // Set up states
    $stateProvider

      /*
      Login state
       */
      .state('login', {
          url: '/login',
          templateUrl: 'views/shell/login.html'
      })

      /*
      Main `abstract` root state
       */
      .state('main', {
          abstract: true,
          templateUrl: 'views/shell/main.html',
          controller: 'MainCtrl',
          data: {
            authRequired: true
          }
      })

      /*
      Home state
       */
      .state('main.home', {
          url: '/',
          templateUrl: 'views/shell/home.html'
      })

      /*
      Category state
       */
      .state('main.category', {
          url: 'category/{name}',
          templateUrl: 'views/shell/category.html',
          controller: 'CategoryCtrl'
      })

      /*
      Panel `parent` state
       */
      .state('main.panel', {
          templateUrl: 'views/shell/panel.html'
      })

      /*
      Grid `abstract` state
       */
      .state('main.panel.grid', {
        abstract: true,
        url: 'grid/{catalogName}/{mode}',
        controller: 'GridCtrl',
        templateUrl: 'views/grid.html'
      })

      /*
      GridView state
       */
      .state('main.panel.grid.view', {
          views: {
            'main': {
              templateUrl: 'views/grid.main.html'
            },
            'header': {
              templateUrl: 'views/grid.header.html'
            },
            'footer': {
              templateUrl: 'views/grid.footer.html'
            }
          }
      })

      /*
      Form `abstract` state
       */
      .state('main.panel.form', {
        abstract: true,
        url: 'form/{catalogName}/{mode}/{id}',
        controller: 'FormCtrl',
        templateUrl: 'views/form.html'
      })

      /*
      FormView state
       */
      .state('main.panel.form.view', {
          views: {
            'main': {
              templateUrl: 'views/form.main.html'
            },
            'footer': {
              templateUrl: 'views/form.footer.html'
            }
          }
      })

      // .state('main.panel.cardsView', {
      //     url: 'cards/{catalogName}/{mode}',
      //     templateUrl: 'views/cards.html',
      //     controller: 'CardsCtrl'
      // })

      // filters: https://github.com/angular-ui/ui-router/wiki/Multiple-Named-Views
      // .state('main.panel.filtersView', {
      //     url: 'filters/{catalogName}/{mode}',
      //     views: {
      //       'filters':
      //       'results':
      //     }
      // })
    ;
  })

  // At application startup :
  .run(function ($rootScope, $state, AUTH_EVENTS, AuthService, AlertService) {

    /**
     * Ensure it's already logged in (by getting session info)
     */

    AuthService.sessionInfo()
      .then(function () {
        //$rootScope.$broadcast(AUTH_EVENTS.loginSuccess);
        $state.go("main.home");
      }, function () {
        //$rootScope.$broadcast(AUTH_EVENTS.notAuthenticated);
        $state.go("login");
      });

    /**
     * Ping server every 5 minutes to check session
     */

    // var poller = function () {
    //   AuthService.ping();
    //   $timeout(poller, 300000);
    // };
    // $timeout(poller, 300000);

    /**
     * State change listener
     */

    // $rootScope.$on('$stateChangeStart', function (event, next) {
    //   if(next.data && next.data.authRequired) {
    //     if (!AuthService.isAuthenticated()) {
    //       event.preventDefault();
    //       //$rootScope.$broadcast(AUTH_EVENTS.notAuthenticated); // redundant
    //     }
    //   } else if (AuthService.isAuthenticated()) {
    //     $rootScope.$broadcast(AUTH_EVENTS.loginSuccess);
    //     $state.go("main.home"); // redundant?
    //   }
    // });

    /**
     * Error Events listeners
     */

    $rootScope.$on('error-internal-server', function (event, next) {
      console.info("#EVENT: error-internal-server");
      AlertService.show('danger', 'Error', next.data.message);
    });

    /**
     * Authentication Events listeners
     */

    $rootScope.$on('auth-login-success', function (event, next) {
      console.info("#EVENT: auth-login-success");
      $state.go("main.home");
    });
    //$rootScope.$on('auth-login-failed', function (event, next) {
    //  console.info("#EVENT: auth-login-failed");
    //});
    $rootScope.$on('auth-session-timeout', function (event, next) {
      console.info("#EVENT: auth-session-timeout");
      $state.go("login");
    });
    $rootScope.$on('auth-not-authenticated', function (event, next) {
      console.info("#EVENT: auth-not-authenticated");
      AlertService.show('warning', 'Authentication', next.data.message);
      $state.go("login");
    });
    $rootScope.$on('auth-logout-success', function (event, next) {
      console.info("#EVENT: auth-logout-success");
      $state.go("login");
    });
  })
;
<|endoftext|>


<commit_before>function config($stateProvider, $locationProvider) {
    $locationProvider
        .html5Mode({
            enabled: true,
            requireBase: false
        });

    $stateProvider
        .state('home', {
            url: '/',
            controller: 'RoomController as ctrl',
            templateUrl: '/templates/home.html'
        })
}

function BlocChatCookies($cookies) {
    var currentUser = $cookies.get('blocChatCurrentUser');
    if (!currentUser || currentUser === '') {
      // Do something to allow users to set their username
      currentUser = prompt("Please enter your username", "");
    }
  }

var blocChat = angular
    .module('blocChat', ['ui.router', 'ui.bootstrap', 'firebase', 'ngCookies'])
    .config(config);
    .run(['$cookies', BlocChatCookies]);

blocChat.controller('RoomController', ['$state', 'Room', 'Message', '$uibModal',
    function($state, Room, Message, $uibModal) {
        this.rooms = Room.all;

        this.addRoom = function addRoom() {
            var modalInstance = $uibModal.open({
                templateUrl: '/templates/modal.html',
                controller: 'ModalController',
                controllerAs: 'modal'
            });

            modalInstance.result.then(function(roomName) {
                Room.add(roomName);
            });
        }; //- addRoom()

        this.setRoom = function setRoom(roomId) {
            this.messages = Message.getMessages(roomId);
        };
    }
]);

blocChat.factory('Message', ['$firebaseArray',
    function Message($firebaseArray) {
        var ref = firebase.database().ref().child("messages");

        var getMessages = function getMessages(roomId) {
            return $firebaseArray(ref.orderByChild('roomId').equalTo(roomId));
        };

        return {
            getMessages: getMessages
        };
    }
]);<commit_msg>app.js update<commit_after>function config($stateProvider, $locationProvider) {
    $locationProvider
        .html5Mode({
            enabled: true,
            requireBase: false
        });

    $stateProvider
        .state('home', {
            url: '/',
            controller: 'RoomController as ctrl',
            templateUrl: '/templates/home.html'
        })
}

function BlocChatCookies($cookies, $uibModal) {
    var currentUser = $cookies.get('blocChatCurrentUser');
    if (!currentUser || currentUser === '') {
      $uibModal.open({
        // Modal configuration object properties
      })
    }
  }

var blocChat = angular
    .module('blocChat', ['ui.router', 'ui.bootstrap', 'firebase', 'ngCookies'])
    .config(config);
    .run(['$cookies', '$uibModal', BlocChatCookies]);

blocChat.controller('RoomController', ['$state', 'Room', 'Message', '$uibModal',
    function($state, Room, Message, $uibModal) {
        this.rooms = Room.all;

        this.addRoom = function addRoom() {
            var modalInstance = $uibModal.open({
                templateUrl: '/templates/modal.html',
                controller: 'ModalController',
                controllerAs: 'modal'
            });

            modalInstance.result.then(function(roomName) {
                Room.add(roomName);
            });
        }; //- addRoom()

        this.setRoom = function setRoom(roomId) {
            this.messages = Message.getMessages(roomId);
        };
    }
]);

blocChat.factory('Message', ['$firebaseArray',
    function Message($firebaseArray) {
        var ref = firebase.database().ref().child("messages");

        var getMessages = function getMessages(roomId) {
            return $firebaseArray(ref.orderByChild('roomId').equalTo(roomId));
        };

        return {
            getMessages: getMessages
        };
    }
]);<|endoftext|>


<commit_before>import API from 'src/util/api';
import Versioning from 'src/util/versioning';

let defaultOptions = {
  group: 'all',
  varName: 'sampleToc',
  viewName: 'sample_toc',
  sort: (a, b) => {
    if (a.value.modificationDate > b.value.modificationDate) {
      return -1;
    } else if (a.value.modificationDate < b.value.modificationDate) {
      return 1;
    } else {
      return 0;
    }
  }
};

class SampleToc {
  /**
   * Create an object managing the Toc
   * @param {object} [options={}]
   * @param {object} [roc=undefined]
   * @param {string} [options.group='mine'] Group to retrieve products. mine, all of a specific group name
   * @param {string} [options.varName='sampleToc']
   * @param {string} [options.viewName='sample_toc']
   * @param {function} [options.sort] Callback, by default sort by reverse date
   * @param {function} [options.filter] Callback to filter the result
   */
  constructor(roc, options = {}) {
    this.roc = roc;
    this.options = Object.assign({}, defaultOptions, options);
  }

  /**
   * Retrieve the sample_toc and put the result in `sampleToc` variable
   */
  refresh(options = {}) {
    let { group, sort, filter, viewName } =
        Object.assign({}, this.options, options);
    let mine = 0;
    let groups = '';

    if (group === 'mine') {
      mine = 1;
    } else if (group !== 'all') {
      groups = group;
    }

    return this.roc.query(
      viewName, { groups, mine, sort, filter, varName: this.options.varName });
  }

  /**
   * Retrieve the allowed groups for the logged in user and create 'groupForm'
   * variable and 'groupFormSchema' (for onde module). It will keep in a cookie
   * the last selected group. Calling this method should reload automatically
   * the TOC
   * @param {*} roc
   * @param {object} [options={}]
   * @param {string} [varName='groupForm'] contains the name of the variable containing the form value
   * @param {string} [schemaVarName='groupFormSchema'] contains the name of the variable containing the form schema
   * @param {string} [cookieName='eln-default-sample-group''] cookie name containing the last selected group
   * @return {string} the form to select group}
   */
  async initializeGroupForm(options = {}) {
    const {
      schemaVarName = 'groupFormSchema',
      varName = 'groupForm',
      cookieName = 'eln-default-sample-group'
    } = options;

    let groups = (await this.roc.getGroupMembership()).map((g) => g.name);
    var possibleGroups = ['all', 'mine'].concat(groups);
    var defaultGroup = localStorage.getItem(cookieName);
    if (possibleGroups.indexOf(defaultGroup) === -1) {
      defaultGroup = 'all';
    }
    var schema = {
      type: 'object',
      properties: {
        group: {
          type: 'string',
          enum: possibleGroups,
          default: defaultGroup,
          required: true
        }
      }
    };
    API.createData(schemaVarName, schema);

    let groupForm = await API.createData(varName, { group: defaultGroup });

    this.options.group = groupForm.group;
    await this.refresh();

    let mainData = Versioning.getData();
    mainData.onChange((evt) => {
      if (evt.jpath[0] === varName) {
        localStorage.setItem(cookieName, groupForm.group);
        this.options.group = String(groupForm.group);
        this.refresh();
      }
    });

    return groupForm;
  }
}

module.exports = SampleToc;
<commit_msg>ensure the group is of type string for SampleToc search<commit_after>import API from 'src/util/api';
import Versioning from 'src/util/versioning';

let defaultOptions = {
  group: 'all',
  varName: 'sampleToc',
  viewName: 'sample_toc',
  sort: (a, b) => {
    if (a.value.modificationDate > b.value.modificationDate) {
      return -1;
    } else if (a.value.modificationDate < b.value.modificationDate) {
      return 1;
    } else {
      return 0;
    }
  }
};

class SampleToc {
  /**
   * Create an object managing the Toc
   * @param {object} [options={}]
   * @param {object} [roc=undefined]
   * @param {string} [options.group='mine'] Group to retrieve products. mine, all of a specific group name
   * @param {string} [options.varName='sampleToc']
   * @param {string} [options.viewName='sample_toc']
   * @param {function} [options.sort] Callback, by default sort by reverse date
   * @param {function} [options.filter] Callback to filter the result
   */
  constructor(roc, options = {}) {
    this.roc = roc;
    this.options = Object.assign({}, defaultOptions, options);
  }

  /**
   * Retrieve the sample_toc and put the result in `sampleToc` variable
   */
  refresh(options = {}) {
    let { group, sort, filter, viewName } = Object.assign(
      {},
      this.options,
      options
    );
    let mine = 0;
    let groups = '';
    group = String(group);
    if (group === 'mine') {
      mine = 1;
    } else if (group !== 'all') {
      groups = group;
    }
    return this.roc.query(viewName, {
      groups,
      mine,
      sort,
      filter,
      varName: this.options.varName
    });
  }

  /**
   * Retrieve the allowed groups for the logged in user and create 'groupForm'
   * variable and 'groupFormSchema' (for onde module). It will keep in a cookie
   * the last selected group. Calling this method should reload automatically
   * the TOC
   * @param {*} roc
   * @param {object} [options={}]
   * @param {string} [varName='groupForm'] contains the name of the variable containing the form value
   * @param {string} [schemaVarName='groupFormSchema'] contains the name of the variable containing the form schema
   * @param {string} [cookieName='eln-default-sample-group''] cookie name containing the last selected group
   * @return {string} the form to select group}
   */
  async initializeGroupForm(options = {}) {
    const {
      schemaVarName = 'groupFormSchema',
      varName = 'groupForm',
      cookieName = 'eln-default-sample-group'
    } = options;

    let groups = (await this.roc.getGroupMembership()).map((g) => g.name);
    var possibleGroups = ['all', 'mine'].concat(groups);
    var defaultGroup = localStorage.getItem(cookieName);
    if (possibleGroups.indexOf(defaultGroup) === -1) {
      defaultGroup = 'all';
    }
    var schema = {
      type: 'object',
      properties: {
        group: {
          type: 'string',
          enum: possibleGroups,
          default: defaultGroup,
          required: true
        }
      }
    };
    API.createData(schemaVarName, schema);

    let groupForm = await API.createData(varName, { group: defaultGroup });

    this.options.group = groupForm.group;
    await this.refresh();

    let mainData = Versioning.getData();
    mainData.onChange((evt) => {
      if (evt.jpath[0] === varName) {
        localStorage.setItem(cookieName, groupForm.group);
        this.options.group = String(groupForm.group);
        this.refresh();
      }
    });

    return groupForm;
  }
}

module.exports = SampleToc;
<|endoftext|>


<commit_before>'use strict';

/** @type {typeof import('../../lib/fs').FS} */
const FS = require(/** @type {any} */('../../.lib-dist/fs')).FS;

const DAY = 24 * 60 * 60 * 1000;
const SPOTLIGHT_FILE = 'config/chat-plugins/spotlights.json';

/** @type {{[k: string]: {[k: string]: {image: string?, description: string}[]}}} */
let spotlights = {};
try {
	spotlights = require(`../../${SPOTLIGHT_FILE}`);
} catch (e) {
	if (e.code !== 'MODULE_NOT_FOUND' && e.code !== 'ENOENT') throw e;
}
if (!spotlights || typeof spotlights !== 'object') spotlights = {};

function saveSpotlights() {
	FS(SPOTLIGHT_FILE).writeUpdate(() => JSON.stringify(spotlights));
}

function nextDaily() {
	for (const roomid in spotlights) {
		for (const key in spotlights[roomid]) {
			if (spotlights[roomid][key].length > 1) {
				spotlights[roomid][key].shift();
			}
		}
	}

	saveSpotlights();
	timeout = setTimeout(nextDaily, DAY);
}

const midnight = new Date();
midnight.setHours(24, 0, 0, 0);
let timeout = setTimeout(nextDaily, midnight.valueOf() - Date.now());

/**
 * @param {string?} image
 * @param {string} description
 */
async function renderSpotlight(image, description) {
	let imgHTML = '';

	if (image) {
		const [width, height] = await Chat.fitImage(image, 150, 300);
		imgHTML = `<td><img src="${image}" width="${width}" height="${height}" style="vertical-align:middle;"></td>`;
	}

	return `<table style="text-align:center;margin:auto"><tr><td style="padding-right:10px;">${Chat.formatText(description, true).replace(/\n/g, `
`)}</td>${imgHTML}</tr></table>`;
}

exports.destroy = function () {
	clearTimeout(timeout);
};

/** @type {PageTable} */
const pages = {
	async spotlights(query, user, connection) {
		this.title = 'Daily Spotlights';
		this.extractRoom();
		let buf = `<div class="pad ladder"><h2>Daily Spotlights</h2>`;
		if (!spotlights[this.room.id]) {
			buf += `<p>This room has no daily spotlights.</p></div>`;
		} else {
			for (let key in spotlights[this.room.id]) {
				buf += `<table style="margin-bottom:30px;"><th colspan="2"><h3>${key}:</h3></th>`;
				for (const [i, spotlight] of spotlights[this.room.id][key].entries()) {
					const html = await renderSpotlight(spotlight.image, spotlight.description);
					buf += `<tr><td>${i ? i : 'Current'}</td><td>${html}</td></tr>`;
					// @ts-ignore room is definitely a proper room here.
					if (!user.can('announce', null, this.room)) break;
				}
				buf += '
';
			}
		}
		return buf;
	},
};
exports.pages = pages;

/** @type {ChatCommands} */
const commands = {
	async removedaily(target, room, user) {
		let [key, rest] = target.split(',');
		key = toId(key);
		if (!key) return this.parse('/help daily');
		if (!spotlights[room.id][key]) return this.errorReply(`Cannot find a daily spotlight with name '${key}'`);

		if (!this.can('announce', null, room)) return false;
		if (rest) {
			const queueNumber = parseInt(rest);
			if (isNaN(queueNumber) || queueNumber < 1) return this.errorReply("Invalid queue number");
			if (queueNumber >= spotlights[room.id][key].length) {
				return this.errorReply(`Queue number needs to be between 1 and ${spotlights[room.id][key].length - 1}`);
			}
			spotlights[room.id][key].splice(queueNumber, 1);
			saveSpotlights();

			this.modlog(`DAILY REMOVE`, `${key}[${queueNumber}]`);
			this.sendReply(`Removed the ${queueNumber}th entry from the queue of the daily spotlight named '${key}'.`);
		} else {
			spotlights[room.id][key].shift();
			if (!spotlights[room.id][key].length) {
				delete spotlights[room.id][key];
			}
			saveSpotlights();
			this.modlog(`DAILY REMOVE`, key);
			this.sendReply(`The daily spotlight named '${key}' has been successfully removed.`);
		}
	},
	queuedaily: 'setdaily',
	async setdaily(target, room, user, connection, cmd) {
		let [key, ...rest] = target.split(',');
		key = toId(key);
		if (!key) return this.parse('/help daily');
		if (key.length > 20) return this.errorReply("Spotlight names can be a maximum of 20 characters long.");
		if (key === 'constructor') return false;

		if (!this.can('announce', null, room)) return false;
		if (!rest.length) return this.parse('/help daily');
		let image, description;
		if (rest[0].trim().startsWith('http://') || rest[0].trim().startsWith('https://')) {
			[image, ...rest] = rest;
			image = image.trim();
			const ret = await Chat.getImageDimensions(image);
			if (ret.err) return this.errorReply(`Invalid image url: ${image}`);
		}
		description = rest.join(',');
		if (description.length > 500) return this.errorReply("Descriptions can be at most 500 characters long.");
		const obj = {image: image || null, description: description};
		if (!spotlights[room.id]) spotlights[room.id] = {};
		if (!spotlights[room.id][key]) spotlights[room.id][key] = [];
		if (cmd === 'setdaily') {
			spotlights[room.id][key].shift();
			spotlights[room.id][key].unshift(obj);

			this.modlog('SETDAILY', key, `${image ? `${image}, ` : ''}${description}`);
			this.privateModAction(`${user.name} set the daily ${key}.`);
		} else {
			spotlights[room.id][key].push(obj);
			this.modlog('QUEUEDAILY', key, `${image ? `${image}, ` : ''}${description}`);
			this.privateModAction(`${user.name} queued a daily ${key}.`);
		}

		saveSpotlights();
	},
	async daily(target, room, user) {
		let key = toId(target);
		if (!key) return this.parse('/help daily');

		if (!spotlights[room.id] || !spotlights[room.id][key]) {
			return this.errorReply(`Cannot find a daily spotlight with name '${key}'`);
		}

		if (!this.runBroadcast()) return;

		const {image, description} = spotlights[room.id][key][0];
		const html = await renderSpotlight(image, description);

		this.sendReplyBox(html);
		room.update();
	},
	viewspotlights(target, room, user) {
		return this.parse(`/join view-spotlights-${room.id}`);
	},

	dailyhelp: [
		`Daily spotlights plugin:`,
		`- /daily [name] - Shows the daily spotlight.`,
		`- !daily [name] - Shows the daily spotlight to everyone. Requires: + % @ # & ~`,
		`- /setdaily [name], [image], [description] - Sets the daily spotlight. Image can be left out. Requires: % @ # & ~`,
		`- /queuedaily [name], [image], [description] - Queues a daily spotlight. At midnight, the spotlight with this name will automatically switch to the next queued spotlight. Image can be left out. Requires: % @ # & ~`,
		`- /removedaily [name][, queue number] - If no queue number is provided, deletes all queued and current spotlights with the given name. If a number is provided, removes a specific future spotlight from the queue. Requires: % @ # & ~`,
		`- /viewspotlights - Shows all current spotlights in the room. For staff, also shows queued spotlights.`,
	],
};

exports.commands = commands;

process.nextTick(() => {
	Chat.multiLinePattern.register('/(queue|set)daily ');
});
<commit_msg>Spotlights: disable spotlights in temp rooms<commit_after>'use strict';

/** @type {typeof import('../../lib/fs').FS} */
const FS = require(/** @type {any} */('../../.lib-dist/fs')).FS;

const DAY = 24 * 60 * 60 * 1000;
const SPOTLIGHT_FILE = 'config/chat-plugins/spotlights.json';

/** @type {{[k: string]: {[k: string]: {image: string?, description: string}[]}}} */
let spotlights = {};
try {
	spotlights = require(`../../${SPOTLIGHT_FILE}`);
} catch (e) {
	if (e.code !== 'MODULE_NOT_FOUND' && e.code !== 'ENOENT') throw e;
}
if (!spotlights || typeof spotlights !== 'object') spotlights = {};

function saveSpotlights() {
	FS(SPOTLIGHT_FILE).writeUpdate(() => JSON.stringify(spotlights));
}

function nextDaily() {
	for (const roomid in spotlights) {
		for (const key in spotlights[roomid]) {
			if (spotlights[roomid][key].length > 1) {
				spotlights[roomid][key].shift();
			}
		}
	}

	saveSpotlights();
	timeout = setTimeout(nextDaily, DAY);
}

const midnight = new Date();
midnight.setHours(24, 0, 0, 0);
let timeout = setTimeout(nextDaily, midnight.valueOf() - Date.now());

/**
 * @param {string?} image
 * @param {string} description
 */
async function renderSpotlight(image, description) {
	let imgHTML = '';

	if (image) {
		const [width, height] = await Chat.fitImage(image, 150, 300);
		imgHTML = `<td><img src="${image}" width="${width}" height="${height}" style="vertical-align:middle;"></td>`;
	}

	return `<table style="text-align:center;margin:auto"><tr><td style="padding-right:10px;">${Chat.formatText(description, true).replace(/\n/g, `
`)}</td>${imgHTML}</tr></table>`;
}

exports.destroy = function () {
	clearTimeout(timeout);
};

/** @type {PageTable} */
const pages = {
	async spotlights(query, user, connection) {
		this.title = 'Daily Spotlights';
		this.extractRoom();
		let buf = `<div class="pad ladder"><h2>Daily Spotlights</h2>`;
		if (!spotlights[this.room.id]) {
			buf += `<p>This room has no daily spotlights.</p></div>`;
		} else {
			for (let key in spotlights[this.room.id]) {
				buf += `<table style="margin-bottom:30px;"><th colspan="2"><h3>${key}:</h3></th>`;
				for (const [i, spotlight] of spotlights[this.room.id][key].entries()) {
					const html = await renderSpotlight(spotlight.image, spotlight.description);
					buf += `<tr><td>${i ? i : 'Current'}</td><td>${html}</td></tr>`;
					// @ts-ignore room is definitely a proper room here.
					if (!user.can('announce', null, this.room)) break;
				}
				buf += '
';
			}
		}
		return buf;
	},
};
exports.pages = pages;

/** @type {ChatCommands} */
const commands = {
	async removedaily(target, room, user) {
		if (!room.chatRoomData) return this.errorReply("This command is unavailable in temporary rooms.");
		let [key, rest] = target.split(',');
		key = toId(key);
		if (!key) return this.parse('/help daily');
		if (!spotlights[room.id][key]) return this.errorReply(`Cannot find a daily spotlight with name '${key}'`);

		if (!this.can('announce', null, room)) return false;
		if (rest) {
			const queueNumber = parseInt(rest);
			if (isNaN(queueNumber) || queueNumber < 1) return this.errorReply("Invalid queue number");
			if (queueNumber >= spotlights[room.id][key].length) {
				return this.errorReply(`Queue number needs to be between 1 and ${spotlights[room.id][key].length - 1}`);
			}
			spotlights[room.id][key].splice(queueNumber, 1);
			saveSpotlights();

			this.modlog(`DAILY REMOVE`, `${key}[${queueNumber}]`);
			this.sendReply(`Removed the ${queueNumber}th entry from the queue of the daily spotlight named '${key}'.`);
		} else {
			spotlights[room.id][key].shift();
			if (!spotlights[room.id][key].length) {
				delete spotlights[room.id][key];
			}
			saveSpotlights();
			this.modlog(`DAILY REMOVE`, key);
			this.sendReply(`The daily spotlight named '${key}' has been successfully removed.`);
		}
	},
	queuedaily: 'setdaily',
	async setdaily(target, room, user, connection, cmd) {
		if (!room.chatRoomData) return this.errorReply("This command is unavailable in temporary rooms.");
		let [key, ...rest] = target.split(',');
		key = toId(key);
		if (!key) return this.parse('/help daily');
		if (key.length > 20) return this.errorReply("Spotlight names can be a maximum of 20 characters long.");
		if (key === 'constructor') return false;

		if (!this.can('announce', null, room)) return false;
		if (!rest.length) return this.parse('/help daily');
		let image, description;
		if (rest[0].trim().startsWith('http://') || rest[0].trim().startsWith('https://')) {
			[image, ...rest] = rest;
			image = image.trim();
			const ret = await Chat.getImageDimensions(image);
			if (ret.err) return this.errorReply(`Invalid image url: ${image}`);
		}
		description = rest.join(',');
		if (description.length > 500) return this.errorReply("Descriptions can be at most 500 characters long.");
		const obj = {image: image || null, description: description};
		if (!spotlights[room.id]) spotlights[room.id] = {};
		if (!spotlights[room.id][key]) spotlights[room.id][key] = [];
		if (cmd === 'setdaily') {
			spotlights[room.id][key].shift();
			spotlights[room.id][key].unshift(obj);

			this.modlog('SETDAILY', key, `${image ? `${image}, ` : ''}${description}`);
			this.privateModAction(`${user.name} set the daily ${key}.`);
		} else {
			spotlights[room.id][key].push(obj);
			this.modlog('QUEUEDAILY', key, `${image ? `${image}, ` : ''}${description}`);
			this.privateModAction(`${user.name} queued a daily ${key}.`);
		}

		saveSpotlights();
	},
	async daily(target, room, user) {
		if (!room.chatRoomData) return this.errorReply("This command is unavailable in temporary rooms.");
		let key = toId(target);
		if (!key) return this.parse('/help daily');

		if (!spotlights[room.id] || !spotlights[room.id][key]) {
			return this.errorReply(`Cannot find a daily spotlight with name '${key}'`);
		}

		if (!this.runBroadcast()) return;

		const {image, description} = spotlights[room.id][key][0];
		const html = await renderSpotlight(image, description);

		this.sendReplyBox(html);
		room.update();
	},
	viewspotlights(target, room, user) {
		if (!room.chatRoomData) return this.errorReply("This command is unavailable in temporary rooms.");
		return this.parse(`/join view-spotlights-${room.id}`);
	},

	dailyhelp: [
		`Daily spotlights plugin:`,
		`- /daily [name] - Shows the daily spotlight.`,
		`- !daily [name] - Shows the daily spotlight to everyone. Requires: + % @ # & ~`,
		`- /setdaily [name], [image], [description] - Sets the daily spotlight. Image can be left out. Requires: % @ # & ~`,
		`- /queuedaily [name], [image], [description] - Queues a daily spotlight. At midnight, the spotlight with this name will automatically switch to the next queued spotlight. Image can be left out. Requires: % @ # & ~`,
		`- /removedaily [name][, queue number] - If no queue number is provided, deletes all queued and current spotlights with the given name. If a number is provided, removes a specific future spotlight from the queue. Requires: % @ # & ~`,
		`- /viewspotlights - Shows all current spotlights in the room. For staff, also shows queued spotlights.`,
	],
};

exports.commands = commands;

process.nextTick(() => {
	Chat.multiLinePattern.register('/(queue|set)daily ');
});
<|endoftext|>


<commit_before>/*
 *    Copyright 2013 APPNEXUS INC
 *
 *    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.
*/

(function() {

	// Set up some variables
	var mraid = window.mraid = {};
	mraid.util = {};
	var listeners = [];
	listeners['ready']=[];
	listeners['error']=[];
	listeners['stateChange']=[];
	listeners['viewableChange']=[];
	listeners['sizeChange']=[];
	var state='loading'; //Can be loading, default, expanded, hidden, or resized
	var placement_type='inline';
	var is_viewable=false;
	var expand_properties={width:-1, height:-1, useCustomClose:false, isModal:true};
	var orientation_properties={allowOrientationChange:true, forceOrientation:"none"};
	var resize_properties={width:-1, height:-1, offsetX: 0, offsetY: 0, customClosePosition: 'top-right', allowOffscreen: true};

	// ----- MRAID AD API FUNCTIONS -----

	// getVersion() returns string '2.0'
	mraid.getVersion=function(){ return '2.0'};

	/** Adds a listener to a specific event. For example, a function onReady might be defined, and then mraid.addEventListener('ready', onReady)
	  * is called. When the ready event is fired, onReady will be called.
	  * Events 'error', 'viewableChange', 'stateChange', have parameters.
         */
	mraid.addEventListener=function(event_name, method){
		if(listeners[event_name].indexOf(method) > -1) return; // Listener is already registered
		listeners[event_name].push(method);
	};

	// Removes a listener from the registry
	mraid.removeEventListener=function(event_name, method){
	    //If no method name is given, remove all listeners from event
	    if(method == null){
	        listeners[event_name].length=0;
	    }

		var method_index = listeners[event_name].indexOf(method);
		if(method_index > -1){ //Don't try to remove unregistered listeners
			listeners[event_name].splice(method_index,1);
		}else{
		    mraid.util.errorEvent("An unregistered listener was requested to be removed.", "mraid.removeEventListener()")
		}
	};

	//returns 'loading', 'default', 'expanded', or 'hidden'
	mraid.getState=function(){
		return state;
	};

	//returns 'inline' or 'interstitial'
	mraid.getPlacementType=function(){
		return placement_type;
	};

	//returns true or false
	mraid.isViewable=function(){
		return is_viewable;
	};

	// ----- MRAID JS TO NATIVE FUNCTIONS -----

	//Closes an expanded ad or hides an ad in default state
	mraid.close=function(){
		switch(mraid.getState()){
		case 'loading':
			mraid.util.errorEvent("mraid.close() called while state is 'loading'.", "mraid.close()");
			break;
		case 'default':
			window.open("mraid://close/");
			mraid.util.stateChangeEvent('hidden');
			break;
		case 'expanded':
			window.open("mraid://close/");
			mraid.util.stateChangeEvent('default');
			break;
		case 'hidden':
			mraid.util.errorEvent("mraid.close() called while ad was already hidden", "mraid.close()");
			break;
        case 'resized':
            window.open("mraid://close/");
            mraid.util.stateChangeEvent('default');
		}
	};

	// Expands a default state ad, or unhides a hidden ad. Optionally takes a URL to load in the expanded view
	mraid.expand=function(url){
		switch(mraid.getState()){
		case 'loading':
			mraid.util.errorEvent("mraid.expand() called while state is 'loading'.", "mraid.expand()");
			break;
		case 'default':
			window.open("mraid://expand/"+"?w="+mraid.getExpandProperties().width+"&h="+mraid.getExpandProperties().height+"&useCustomClose="+mraid.getExpandProperties().useCustomClose+(url!=null ? "&url="+url:""));
			mraid.util.stateChangeEvent('expanded');
			if(url!=null){
			    window.open(url);
			}
			break;
		case 'expanded':
			mraid.util.errorEvent("mraid.expand() called while state is 'expanded'.", "mraid.expand()");
			break;
		case 'hidden':
            mraid.util.errorEvent("mraid.expand() called while state is 'hidden'.", "mraid.expand()");
			break;
        case 'resized':
            mraid.util.stateChangeEvent('expanded');
		}
	};

	// Takes an object... {width:300, height:250, useCustomClose:false, isModal:false};
	mraid.setExpandProperties=function(properties){
		properties.isModal=true; // Read only property.
		expand_properties=properties;
	};

	//returns a json object... {width:300, height:250, useCustomClose:false, isModal:false};
	mraid.getExpandProperties=function(){
		return expand_properties;
	};

	// Takes a boolean
	mraid.useCustomClose=function(well_is_it){
		ep = mraid.getExpandProperties();
		ep.useCustomClose = well_is_it;
		mraid.setExpandProperties(ep);
	};

	// Loads a given URL
	mraid.open=function(url){
		window.open(url);
	};

    // MRAID 2.0 Stuff.
    mraid.resize=function(){
        if(resize_properties.height<0 || resize_properties.width<0){
            mraid.util.errorEvent("mraid.resize() called before mraid.setResizeProperties()", "mraid.resize()");
            return;
        }
        switch(mraid.getState()){
        case 'loading':
            mraid.util.errorEvent("mraid.resize() called while state is 'loading'.", "mraid.resize()");
            break;
        case 'expanded':
            mraid.util.errorEvent("mraid.resize() called while state is 'expanded'.", "mraid.resize()");
            break;
        case 'resized':
        case 'default':
            window.open("mraid://resize/?w="+resize_properties.width
                       +"&h="+resize_properties.height
                       +"&offset_x="+resize_properties.offsetX
                       +"&offset_y="+resize_properties.offsetY
                       +"&custom_close_position="+resize_properties.customClosePosition
                       +"&allow_offscreen="+resize_properties.allowOffscreen); //TODO: sizechange events must be fired from native side, after successful resize
            mraid.util.stateChangeEvent('resized');
            break;
        case 'hidden':
            break;

        }

    }

    mraid.setResizeProperties=function(props){
        resize_properties=props;
    }

    mraid.getResizeProperties=function(){
        return resize_properties;
    }

    //returns a json object... {allowOrientationChange:true, forceOrientation:"none"};
    mraid.getOrientationProperties=function(){
        return orientation_properties;
    }

    // Takes an object... {allowOrientationChange:true, forceOrientation:"none"};
    mraid.setOrientationProperties=function(properties){
        orientation_properties=properties;

        window.open("mraid://setOrientationProperties/?allow_orientation_change"+properties.allowOrientationChange
                   +"&force_orientation="+properties.forceOrientation);
    }

    // Creates a calendar event when passed a W3C-formatted json object
    mraid.createCalendarEvent=function(event){
        window.open("mraid://createCalendarEvent/?p="+encodeURIComponent(JSON.stringify(event)));
    }

    // Creates a calendar event when passed a W3C-formatted json object
    mraid.createCalendarEvent=function(uri){
        window.open("mraid://playVideo/?uri="+encodeURIComponent(uri));
    }

    // Stores a picture on the device
    mraid.storePicture=function(uri){
        window.open("mraid://storePicture/?uri="+encodeURIComponent(uri));
    }

    // Convenience function to modify useCustomClose attribute of expandProperties
    mraid.useCustomClose=function(value){
        expand_properties.useCustomClose = value;
    }

	// ----- MRAID UTILITY FUNCTIONS -----
	// These functions are called by the native SDK to drive events and update information

	mraid.util.setPlacementType=function(type){
		placement_type=type;
	};

	mraid.util.readyEvent=function(){
		for(var i=0;i<listeners['ready'].length;i++){
			listeners['ready'][i]();
		}
	};

	mraid.util.errorEvent=function(message, what_doing){
		for(var i=0;i<listeners['error'].length;i++){
			listeners['error'][i](message, what_doing);
		}
	};

	mraid.util.viewableChangeEvent=function(is_viewable_now){
		is_viewable = is_viewable_now;
		for(var i=0;i<listeners['viewableChange'].length;i++){
			listeners['viewableChange'][i](is_viewable_now);
		}
	};

	mraid.util.setIsViewable=function(is_it_viewable){
		if(is_viewable===is_it_viewable) return;
		is_viewable=is_it_viewable;
		mraid.util.viewableChangeEvent(is_viewable);
	};

	mraid.util.stateChangeEvent=function(new_state){
		if(state===new_state) return;
		state=new_state;
		if(new_state==='hidden'){
			mraid.util.setIsViewable(false);
		}
		for(var i=0;i<listeners['stateChange'].length;i++){
			listeners['stateChange'][i](new_state);
		}
	};

	mraid.util.sizeChangeEvent=function(width, height){
        for(var i=0;i<listeners['sizeChange'].length;i++){
            listeners['sizeChange'][i](width, height);
        }
	}

}());
<commit_msg>Add support for supports()<commit_after>/*
 *    Copyright 2013 APPNEXUS INC
 *
 *    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.
*/

(function() {

	// Set up some variables
	var mraid = window.mraid = {};
	mraid.util = {};
	var listeners = [];
	listeners['ready']=[];
	listeners['error']=[];
	listeners['stateChange']=[];
	listeners['viewableChange']=[];
	listeners['sizeChange']=[];
	var state='loading'; //Can be loading, default, expanded, hidden, or resized
	var placement_type='inline';
	var is_viewable=false;
	var expand_properties={width:-1, height:-1, useCustomClose:false, isModal:true};
	var orientation_properties={allowOrientationChange:true, forceOrientation:"none"};
	var resize_properties={width:-1, height:-1, offsetX: 0, offsetY: 0, customClosePosition: 'top-right', allowOffscreen: true};

	// ----- MRAID AD API FUNCTIONS -----

	// getVersion() returns string '2.0'
	mraid.getVersion=function(){ return '2.0'};

	/** Adds a listener to a specific event. For example, a function onReady might be defined, and then mraid.addEventListener('ready', onReady)
	  * is called. When the ready event is fired, onReady will be called.
	  * Events 'error', 'viewableChange', 'stateChange', have parameters.
         */
	mraid.addEventListener=function(event_name, method){
		if(listeners[event_name].indexOf(method) > -1) return; // Listener is already registered
		listeners[event_name].push(method);
	};

	// Removes a listener from the registry
	mraid.removeEventListener=function(event_name, method){
	    //If no method name is given, remove all listeners from event
	    if(method == null){
	        listeners[event_name].length=0;
	    }

		var method_index = listeners[event_name].indexOf(method);
		if(method_index > -1){ //Don't try to remove unregistered listeners
			listeners[event_name].splice(method_index,1);
		}else{
		    mraid.util.errorEvent("An unregistered listener was requested to be removed.", "mraid.removeEventListener()")
		}
	};

	//returns 'loading', 'default', 'expanded', or 'hidden'
	mraid.getState=function(){
		return state;
	};

	//returns 'inline' or 'interstitial'
	mraid.getPlacementType=function(){
		return placement_type;
	};

	//returns true or false
	mraid.isViewable=function(){
		return is_viewable;
	};

	// ----- MRAID JS TO NATIVE FUNCTIONS -----

	//Closes an expanded ad or hides an ad in default state
	mraid.close=function(){
		switch(mraid.getState()){
		case 'loading':
			mraid.util.errorEvent("mraid.close() called while state is 'loading'.", "mraid.close()");
			break;
		case 'default':
			window.open("mraid://close/");
			mraid.util.stateChangeEvent('hidden');
			break;
		case 'expanded':
			window.open("mraid://close/");
			mraid.util.stateChangeEvent('default');
			break;
		case 'hidden':
			mraid.util.errorEvent("mraid.close() called while ad was already hidden", "mraid.close()");
			break;
        case 'resized':
            window.open("mraid://close/");
            mraid.util.stateChangeEvent('default');
		}
	};

	// Expands a default state ad, or unhides a hidden ad. Optionally takes a URL to load in the expanded view
	mraid.expand=function(url){
		switch(mraid.getState()){
		case 'loading':
			mraid.util.errorEvent("mraid.expand() called while state is 'loading'.", "mraid.expand()");
			break;
		case 'default':
			window.open("mraid://expand/"+"?w="+mraid.getExpandProperties().width+"&h="+mraid.getExpandProperties().height+"&useCustomClose="+mraid.getExpandProperties().useCustomClose+(url!=null ? "&url="+url:""));
			mraid.util.stateChangeEvent('expanded');
			if(url!=null){
			    window.open(url);
			}
			break;
		case 'expanded':
			mraid.util.errorEvent("mraid.expand() called while state is 'expanded'.", "mraid.expand()");
			break;
		case 'hidden':
            mraid.util.errorEvent("mraid.expand() called while state is 'hidden'.", "mraid.expand()");
			break;
        case 'resized':
            mraid.util.stateChangeEvent('expanded');
		}
	};

	// Takes an object... {width:300, height:250, useCustomClose:false, isModal:false};
	mraid.setExpandProperties=function(properties){
		properties.isModal=true; // Read only property.
		expand_properties=properties;
	};

	//returns a json object... {width:300, height:250, useCustomClose:false, isModal:false};
	mraid.getExpandProperties=function(){
		return expand_properties;
	};

	// Takes a boolean
	mraid.useCustomClose=function(well_is_it){
		ep = mraid.getExpandProperties();
		ep.useCustomClose = well_is_it;
		mraid.setExpandProperties(ep);
	};

	// Loads a given URL
	mraid.open=function(url){
		window.open(url);
	};

    // MRAID 2.0 Stuff.
    mraid.resize=function(){
        if(resize_properties.height<0 || resize_properties.width<0){
            mraid.util.errorEvent("mraid.resize() called before mraid.setResizeProperties()", "mraid.resize()");
            return;
        }
        switch(mraid.getState()){
        case 'loading':
            mraid.util.errorEvent("mraid.resize() called while state is 'loading'.", "mraid.resize()");
            break;
        case 'expanded':
            mraid.util.errorEvent("mraid.resize() called while state is 'expanded'.", "mraid.resize()");
            break;
        case 'resized':
        case 'default':
            window.open("mraid://resize/?w="+resize_properties.width
                       +"&h="+resize_properties.height
                       +"&offset_x="+resize_properties.offsetX
                       +"&offset_y="+resize_properties.offsetY
                       +"&custom_close_position="+resize_properties.customClosePosition
                       +"&allow_offscreen="+resize_properties.allowOffscreen); //TODO: sizechange events must be fired from native side, after successful resize
            mraid.util.stateChangeEvent('resized');
            break;
        case 'hidden':
            break;

        }

    }

    mraid.setResizeProperties=function(props){
        resize_properties=props;
    }

    mraid.getResizeProperties=function(){
        return resize_properties;
    }

    //returns a json object... {allowOrientationChange:true, forceOrientation:"none"};
    mraid.getOrientationProperties=function(){
        return orientation_properties;
    }

    // Takes an object... {allowOrientationChange:true, forceOrientation:"none"};
    mraid.setOrientationProperties=function(properties){
        orientation_properties=properties;

        window.open("mraid://setOrientationProperties/?allow_orientation_change"+properties.allowOrientationChange
                   +"&force_orientation="+properties.forceOrientation);
    }

    // Creates a calendar event when passed a W3C-formatted json object
    mraid.createCalendarEvent=function(event){
        window.open("mraid://createCalendarEvent/?p="+encodeURIComponent(JSON.stringify(event)));
    }

    // Creates a calendar event when passed a W3C-formatted json object
    mraid.createCalendarEvent=function(uri){
        window.open("mraid://playVideo/?uri="+encodeURIComponent(uri));
    }

    // Stores a picture on the device
    mraid.storePicture=function(uri){
        window.open("mraid://storePicture/?uri="+encodeURIComponent(uri));
    }

    // Convenience function to modify useCustomClose attribute of expandProperties
    mraid.useCustomClose=function(value){
        expand_properties.useCustomClose = value;
    }

    // Checks if a feature is supported by this device
    mraid.supports=function(feature){
        if(mraid.getState()=="loading"){
            mraid.util.errorEvent("Method 'mraid.supports()' called during loading state.", "mraid.supports()");
            return;
        }
        switch(feature){
        case 'sms':
            return supports_sms;
        case 'tel':
            return supports_tel;
        case 'calendar':
            return supports_calendar;
        case 'storePicture':
            return supports_storePicture;
        case 'inlineVideo':
            return supports_inlineVideo;
        }
        mraid.util.errorEvent("Unknown feature to check for support: "+feature, "mraid.supports()");
    }

	// ----- MRAID UTILITY FUNCTIONS -----
	// These functions are called by the native SDK to drive events and update information

	mraid.util.setPlacementType=function(type){
		placement_type=type;
	};

	mraid.util.readyEvent=function(){
		for(var i=0;i<listeners['ready'].length;i++){
			listeners['ready'][i]();
		}
	};

	mraid.util.errorEvent=function(message, what_doing){
		for(var i=0;i<listeners['error'].length;i++){
			listeners['error'][i](message, what_doing);
		}
	};

	mraid.util.viewableChangeEvent=function(is_viewable_now){
		is_viewable = is_viewable_now;
		for(var i=0;i<listeners['viewableChange'].length;i++){
			listeners['viewableChange'][i](is_viewable_now);
		}
	};

	mraid.util.setIsViewable=function(is_it_viewable){
		if(is_viewable===is_it_viewable) return;
		is_viewable=is_it_viewable;
		mraid.util.viewableChangeEvent(is_viewable);
	};

	mraid.util.stateChangeEvent=function(new_state){
		if(state===new_state) return;
		state=new_state;
		if(new_state==='hidden'){
			mraid.util.setIsViewable(false);
		}
		for(var i=0;i<listeners['stateChange'].length;i++){
			listeners['stateChange'][i](new_state);
		}
	};

	mraid.util.sizeChangeEvent=function(width, height){
        for(var i=0;i<listeners['sizeChange'].length;i++){
            listeners['sizeChange'][i](width, height);
        }
	}

	var supports_sms = false;
	var supports_tel = false;
	var supports_calendar = false;
	var supports_storePicture = false;
	var supports_inlineVideo = false;
	mraid.util.setSupportsSMS=function(val){
	    supports_sms = val;
	}

	mraid.util.setSupportsTel=function(val){
	    supports_tel=val;
	}

	mraid.util.setSupportsCalendar=function(val){
	    supports_calendar=val;
	}

	mraid.util.setSupportsStorePicture=function(val){
	    supports_storePicture=val;
	}

	mraid.util.setSupportsInlineVideo=function(val){
	    supports_inlineVideo=val;
	}

}());
<|endoftext|>


<commit_before>function toggleMainNav() {
	$('#left ol').slideToggle();
}

function openSubwindow( id ) {
	if ($(this).hasClass( 'active' ))
		return;
	$('#left ul li.active').removeClass( 'active' );
	$(this).addClass( 'active' );
	// these were cool, you can uncomment these and
	// comment the rest, but I got tired of them quickly
	//$('.subwindow').fadeOut(200);
	//$('#'+id).fadeIn(200);
	$('.subwindow').hide();
	$('#'+id).show();
}

function openSplashScreen() {
    $('#splashscreen').show();
}
function removeSplashScreen() {
    $('#splashscreen').hide();
}

// on the load of the document
$(document).ready( function() {
    $('#left ul li').first().click();
});
<commit_msg>Always open the splash-screen<commit_after>function toggleMainNav() {
	$('#left ol').slideToggle();
}

function openSubwindow( id ) {
	if ($(this).hasClass( 'active' ))
		return;
	$('#left ul li.active').removeClass( 'active' );
	$(this).addClass( 'active' );
	// these were cool, you can uncomment these and
	// comment the rest, but I got tired of them quickly
	//$('.subwindow').fadeOut(200);
	//$('#'+id).fadeIn(200);
	$('.subwindow').hide();
	$('#'+id).show();
}

function openSplashScreen() {
    $('#splashscreen').show();
}
function removeSplashScreen() {
    $('#splashscreen').hide();
}

// on the load of the document
$(document).ready( function() {
    $('#left ul li').first().click();
    openSplashScreen();
});
<|endoftext|>


<commit_before>'use strict';

module.exports = exports = require('../../view/base');

var isReadOnlyRender = require('mano/client/utils/is-read-only-render');

exports.title = "eRegistrations: Prototype demo";

exports.head = function () {
	meta({ name: 'viewport', content: 'width=device-width' });

	if (isReadOnlyRender) {
		// SPA takeover
		script(function (appUrl) {
			var isStrict;
			if (typeof Object.getPrototypeOf !== 'function') return;
			if (typeof Object.defineProperty !== 'function') return;
			if (!window.history) return;
			isStrict = !(function () { return this; }());
			if (!isStrict) return;
			if (Object.getPrototypeOf({ __proto__: Function.prototype }) !== Function.prototype) return;
			if (Object.defineProperty({}, 'foo',  { get: function () { return 'bar'; } }).foo !== 'bar') {
				return;
			}
			document.write('<scr' + 'ipt async src="' + appUrl + '"></sc' + 'ript>');
		}, stUrl('prototype.js'));
	}

	script({ src: stUrl('prototype.legacy.js') });
	link({ href: stUrl('prototype.css'), rel: 'stylesheet' });
};

exports._logo = function () { return img({ src: '/img/logo-2.png' }); };

exports._bodyAppend = function () {
	return dialog(
		{ id: 'dialog-app-nav', open: true, class: 'app-nav-dialog' },
		header(
			h4("Application navigation"),
			a({ onclick: '$(\'dialog-app-nav\').exclude()' }, span({ class: 'fa fa-close' }, "Close"))
		),
		section(ol(
			li(
				a({ href: '/' }, span("Login"), span({ class: 'label-reg' }, "Public"))
			),
			li(
				a({ href: '/reset-password/' }, span("Reset password"),
					span({ class: 'label-reg' }, "Public"))
			),
			li(
				a({ href: '/guide/' }, span("User - guide"), span({ class: 'label-reg' }, "Part A"))
			),
			li(
				a({ href: '/guide-lomas/' }, span("User - Lomas like guide "),
						span({ class: 'label-reg' }, "Part A"))
			),
			li(
				a({ href: '/guide/costs-print/' }, span("User - costs print list"),
					span({ class: 'label-reg' }, "Part A"))
			),
			li(
				a({ href: '/forms/' }, span("User - forms"), span({ class: 'label-reg' }, "Part A"))
			),
			li(
				a({ href: '/forms/disabled/' }, span("User - forms (disabled)"),
					span({ class: 'label-reg' }, "Part A"))
			),
			li(
				a({ href: '/forms/partner-id/' }, span("User - forms, partner"),
					span({ class: 'label-reg' }, "Part A"))
			),
			li(
				a({ href: '/partner-add/' }, span("User - forms, add partner"),
					span({ class: 'label-reg' }, "Part A"))
			),
			li(
				a({ href: '/documents/' }, span("User - documents"),
					span({ class: 'label-reg' }, "Part A"))
			),
			li(
				a({ href: '/documents/disabled/' }, span("User - documents (disabled)"),
					span({ class: 'label-reg' }, "Part A"))
			),
			li(
				a({ href: '/submission/' }, span("User - submission"),
					span({ class: 'label-reg' }, "Part A"))
			),
			li(
				a({ href: '/profile/' }, span("User - profile"), span({ class: 'label-reg' }, "Part A"))
			),
			li(
				a({ href: '/user-submitted/' }, span("User submitted"),
					span({ class: 'label-reg' }, "Part B"))
			),
			li(
				a({ href: '/user-submitted/data-print/' }, span("User submitted - data print"),
					span({ class: 'label-reg' }, "Part B"))
			),
			li(
				a({ href: '/user-submitted/history-print/' }, span("User history print"),
					span({ class: 'label-reg' }, "Part B"))
			),
			li(
				a({ href: '/official/' }, span("Official"),
					span({ class: 'label-reg' }, "Part B"))
			),
			li(
				a({ href: '/revision/user-id/' }, span("Official - user at revision"),
					span({ class: 'label-reg' }, "Part B"))
			),
			li(
				a({ href: '/official/user-id/' }, span("Official - user"),
					span({ class: 'label-reg' }, "Part B"))
			),
			li(
				a({ href: '/official/user-id/document/' },
						span("Official - user, document"), span({ class: 'label-reg' }, "Part B"))
			),
			li(
				a({ href: '/official/user-id/certificates/' },
						span("Official - user at certificate process"),
						span({ class: 'label-reg' }, "Part B"))
			),
			li(
				a({ href: '/front-desk/user-id/' },
						span("Official - user at front-desk"), span({ class: 'label-reg' }, "Part B"))
			),
			li(
				a({ href: '/official/users-list/print/' },
						span("Official - users print list"), span({ class: 'label-reg' }, "Part B"))
			),
			li(
				a({ href: '/users-admin/' }, span("Users admin"), span({ class: 'label-reg' }, "Admin"))
			),
			li(
				a({ href: '/users-admin/user-id/' }, span("Users admin - user"),
					span({ class: 'label-reg' }, "Admin"))
			),
			li(
				a({ href: '/users-admin/add-user/' }, span("Users admin - add user"),
					span({ class: 'label-reg' }, "Admin"))
			),
			li(
				a({ href: '/users-admin/edit-user-id/' }, span("Users admin - edit user"),
					span({ class: 'label-reg' }, "Admin"))
			),
			li(
				a({ href: '/statistics/' },
						span("Statistics"), span({ class: 'label-reg' }, "Statistics"))
			),
			li(
				a({ href: '/i18n/' },
						span("Translations"), span({ class: 'label-reg' }, "Meta"))
			)
		)),
		footer()
	);
};

exports._footerContent = function () {
	return div({ class: 'content' },
		div({ class: 'footer-logos-container' },
			img({ src: '/img/logo.png' }),
			img({ src: '/img/logo.png' })
			)
		);
};
<commit_msg>Support legacy=1 setting<commit_after>'use strict';

module.exports = exports = require('../../view/base');

var isReadOnlyRender = require('mano/client/utils/is-read-only-render');

exports.title = "eRegistrations: Prototype demo";

exports.head = function () {
	meta({ name: 'viewport', content: 'width=device-width' });

	if (isReadOnlyRender) {
		// SPA takeover
		script(function (appUrl) {
			var isStrict;
			if (typeof Object.getPrototypeOf !== 'function') return;
			if (typeof Object.defineProperty !== 'function') return;
			if (!window.history) return;
			isStrict = !(function () { return this; }());
			if (!isStrict) return;
			if (Object.getPrototypeOf({ __proto__: Function.prototype }) !== Function.prototype) return;
			if (Object.defineProperty({}, 'foo',  { get: function () { return 'bar'; } }).foo !== 'bar') {
				return;
			}
			if (document.cookie.indexOf('legacy=1') !== -1) return;
			document.write('<scr' + 'ipt async src="' + appUrl + '"></sc' + 'ript>');
		}, stUrl('prototype.js'));
	}

	script({ src: stUrl('prototype.legacy.js') });
	link({ href: stUrl('prototype.css'), rel: 'stylesheet' });
};

exports._logo = function () { return img({ src: '/img/logo-2.png' }); };

exports._bodyAppend = function () {
	return dialog(
		{ id: 'dialog-app-nav', open: true, class: 'app-nav-dialog' },
		header(
			h4("Application navigation"),
			a({ onclick: '$(\'dialog-app-nav\').exclude()' }, span({ class: 'fa fa-close' }, "Close"))
		),
		section(ol(
			li(
				a({ href: '/' }, span("Login"), span({ class: 'label-reg' }, "Public"))
			),
			li(
				a({ href: '/reset-password/' }, span("Reset password"),
					span({ class: 'label-reg' }, "Public"))
			),
			li(
				a({ href: '/guide/' }, span("User - guide"), span({ class: 'label-reg' }, "Part A"))
			),
			li(
				a({ href: '/guide-lomas/' }, span("User - Lomas like guide "),
						span({ class: 'label-reg' }, "Part A"))
			),
			li(
				a({ href: '/guide/costs-print/' }, span("User - costs print list"),
					span({ class: 'label-reg' }, "Part A"))
			),
			li(
				a({ href: '/forms/' }, span("User - forms"), span({ class: 'label-reg' }, "Part A"))
			),
			li(
				a({ href: '/forms/disabled/' }, span("User - forms (disabled)"),
					span({ class: 'label-reg' }, "Part A"))
			),
			li(
				a({ href: '/forms/partner-id/' }, span("User - forms, partner"),
					span({ class: 'label-reg' }, "Part A"))
			),
			li(
				a({ href: '/partner-add/' }, span("User - forms, add partner"),
					span({ class: 'label-reg' }, "Part A"))
			),
			li(
				a({ href: '/documents/' }, span("User - documents"),
					span({ class: 'label-reg' }, "Part A"))
			),
			li(
				a({ href: '/documents/disabled/' }, span("User - documents (disabled)"),
					span({ class: 'label-reg' }, "Part A"))
			),
			li(
				a({ href: '/submission/' }, span("User - submission"),
					span({ class: 'label-reg' }, "Part A"))
			),
			li(
				a({ href: '/profile/' }, span("User - profile"), span({ class: 'label-reg' }, "Part A"))
			),
			li(
				a({ href: '/user-submitted/' }, span("User submitted"),
					span({ class: 'label-reg' }, "Part B"))
			),
			li(
				a({ href: '/user-submitted/data-print/' }, span("User submitted - data print"),
					span({ class: 'label-reg' }, "Part B"))
			),
			li(
				a({ href: '/user-submitted/history-print/' }, span("User history print"),
					span({ class: 'label-reg' }, "Part B"))
			),
			li(
				a({ href: '/official/' }, span("Official"),
					span({ class: 'label-reg' }, "Part B"))
			),
			li(
				a({ href: '/revision/user-id/' }, span("Official - user at revision"),
					span({ class: 'label-reg' }, "Part B"))
			),
			li(
				a({ href: '/official/user-id/' }, span("Official - user"),
					span({ class: 'label-reg' }, "Part B"))
			),
			li(
				a({ href: '/official/user-id/document/' },
						span("Official - user, document"), span({ class: 'label-reg' }, "Part B"))
			),
			li(
				a({ href: '/official/user-id/certificates/' },
						span("Official - user at certificate process"),
						span({ class: 'label-reg' }, "Part B"))
			),
			li(
				a({ href: '/front-desk/user-id/' },
						span("Official - user at front-desk"), span({ class: 'label-reg' }, "Part B"))
			),
			li(
				a({ href: '/official/users-list/print/' },
						span("Official - users print list"), span({ class: 'label-reg' }, "Part B"))
			),
			li(
				a({ href: '/users-admin/' }, span("Users admin"), span({ class: 'label-reg' }, "Admin"))
			),
			li(
				a({ href: '/users-admin/user-id/' }, span("Users admin - user"),
					span({ class: 'label-reg' }, "Admin"))
			),
			li(
				a({ href: '/users-admin/add-user/' }, span("Users admin - add user"),
					span({ class: 'label-reg' }, "Admin"))
			),
			li(
				a({ href: '/users-admin/edit-user-id/' }, span("Users admin - edit user"),
					span({ class: 'label-reg' }, "Admin"))
			),
			li(
				a({ href: '/statistics/' },
						span("Statistics"), span({ class: 'label-reg' }, "Statistics"))
			),
			li(
				a({ href: '/i18n/' },
						span("Translations"), span({ class: 'label-reg' }, "Meta"))
			)
		)),
		footer()
	);
};

exports._footerContent = function () {
	return div({ class: 'content' },
		div({ class: 'footer-logos-container' },
			img({ src: '/img/logo.png' }),
			img({ src: '/img/logo.png' })
			)
		);
};
<|endoftext|>