<commit_before>// German (Standard)
const messages = {
  default: 'Please fill in this field.',
  required: 'This field is required.',
  prepositions: {
    and: ' and ',
    or: ' or '
  },

  // Numbers, Sizes
  less: 'The value needs to be less than {val}.',
  less_equal: 'The value needs to be less than or equal to {val}.',
  bigger: 'The value needs to be bigger than {val}.',
  bigger_equal: 'The value needs to be less than or equal to {val}.',
  between: 'The value must be between {val}',
  number: 'Please enter a valid number.',

  // Strings
  exact: 'Must contain the following characters: {val}',
  extensions: 'Please upload a filen de with the following extensions: {val}.',
  contains: 'Must contain the following value: {val}.',
  minlength: 'Must be at least {val} characters long.',
  maxlength: 'Must be less than {val} characters long.',
  starts: 'This field should start with "{val}".',
  ends: 'This field should end with "{val}".',

  // Booleans
  boolean: 'This field needs to be "true" or "false".',

  // Regex
  email: 'Please provide a valid email address. (ex: user@gmail.com)',
  url: 'Please provide a valid URL address with http:// or https://',
  https: 'Your URL must start with https://',
  credit_card: 'Please enter a valid credit card number.',
  ip_v4: 'Please enter a valid IPV4 address. (ex: 172.16.254.1)',
  ip_v6: 'Please enter a valid IPV6 address. (ex: 3ffe:1900:4545:3:200:f8ff:fe21:67cf)',
  alpha: 'Only letters are allowed.',
  alpha_numeric: 'No special characters allowed, just numbers and letters.',
};

module.exports = messages;
<commit_msg>German translation completed<commit_after>// German (Standard)
const messages = {
  default: 'Bitte füllen Sie dieses Feld aus.',
  required: 'Dieses Feld muss ausgefüllt werden.',
  prepositions: {
    and: ' und ',
    or: ' oder '
  },

  // Numbers, Sizes
  less: 'Der Wert muss kleiner als {val} sein.',
  less_equal: 'Der Wert muss kleiner oder gleich {val} sein.',
  bigger: 'Der Wert muss größer als {val} sein.',
  bigger_equal: 'Der Wert muss kleiner oder gleich {val} sein.',
  between: 'Der Wert muss zwischen {val} liegen',
  number: 'Bitte geben Sie eine gültige Zahl ein.',

  // Strings
  exact: 'Muss die folgenden Zeichen enthalten: {val}',
  extensions: 'Bitte laden Sie eine Datei mit einer der folgenden Dateiendungen hoch: {val}.',
  contains: 'Muss folgenden Wert enthalten: {val}.',
  minlength: 'Muss mindestens {val} Zeichen lang sein.',
  maxlength: 'Muss weniger als {val} Zeichen lang sein.',
  starts: 'Dieses Feld sollte mit "{val}" beginnen.',
  ends: 'Dieses Feld sollte mit "{val}" enden.',

  // Booleans
  boolean: 'Dieses Feld muss "wahr" oder "falsch" sein.',

  // Regex
  email: 'Bitte geben Sie eine gültige Email-Adresse an. (z.B.: user@gmail.com)',
  url: 'Bitte geben Sie eine gültige URL-Adresse mit http:// oder https:// an',
  https: 'Ihre URL muss mit https:// beginnen',
  credit_card: 'Bitte geben Sie eine gültige Kreditkartennummer ein.',
  ip_v4: 'Bitte geben Sie eine gültige IPV4-Adresse ein. (z.B.: 172.16.254.1)',
  ip_v6: 'Bitte geben Sie eine gültige IPV6-Adresse ein. (z.B.: 3ffe:1900:4545:3:200:f8ff:fe21:67cf)',
  alpha: 'Nur Buchstaben sind erlaubt.',
  alpha_numeric: 'Keine Sonderzeichen erlaubt, nur Zahlen und Buchstaben.',
};

module.exports = messages;
<|endoftext|>


<commit_before>'use strict';

module.exports = {
  app: {
    title: 'ECM',
    description: 'Exam Copies Manager',
    keywords: 'Exam, copies, manager, ecam, alexis, paques, sébastien, combéfis'
  },
  port: process.env.PORT || 3000,
  templateEngine: 'swig',
  sessionSecret: 'mean',
  sessionCollection: 'sessions',
  assets: {
    lib: {
      css: [
    'public/lib/bootstrap/dist/css/bootstrap.css',
    'public/lib/bootstrap/dist/css/bootstrap-theme.css',
   ],
      js: [
    'public/lib/angular/angular.js',
    'public/lib/angular-resource/angular-resource.min.js',
    'public/lib/angular-cookies/angular-cookies.min.js',
    'public/lib/angular-animate/angular-animate.min.js',
    'public/lib/angular-route/angular-route.min.js',
    'public/lib/ng-file-upload/ng-file-upload-all.min.js',
    'public/lib/ng-tags-input/ng-tags-input.min.js',
    'public/lib/angular-touch/angular-touch.min.js',
    'public/lib/angular-sanitize/angular-sanitize.min.js',
    'public/lib/angular-ui-router/release/angular-ui-router.min.js',
    'public/lib/angular-ui-utils/ui-utils.min.js',
    'public/lib/angular-bootstrap/ui-bootstrap-tpls.js'
   ]
    },
    css: [
      'public/lib/ng-tags-input/ng-tags-input.bootstrap.min.css',
      'public/modules/**/css/*.css'
  ],
    js: [
   'public/config.js',
   'public/application.js',
   'public/modules/*/*.js',
   'public/modules/*/*[!tests]*/*.js'
  ],
    tests: [
   'public/lib/angular-mocks/angular-mocks.js',
   'public/modules/*/tests/*.js'
  ]
  }
};
<commit_msg>Clean configuration file<commit_after>'use strict';

module.exports = {
	app: {
		title: 'ECM',
		description: 'Exam Copies Manager',
		keywords: 'Exam, copies, manager, ecam, alexis, paques, sébastien, combéfis'
	},
	port: process.env.PORT || 3000,
	templateEngine: 'swig',
	sessionSecret: 'mean',
	sessionCollection: 'sessions',
	assets: {
		lib: {
			css: [
				'public/lib/bootstrap/dist/css/bootstrap.css',
				'public/lib/bootstrap/dist/css/bootstrap-theme.css',
				'public/lib/ng-tags-input/ng-tags-input.css',
				'public/lib/ng-tags-input/ng-tags-input.bootstrap.css'
			],
			js: [
				'public/lib/angular/angular.js',
				'public/lib/angular-resource/angular-resource.min.js',
				'public/lib/angular-cookies/angular-cookies.min.js',
				'public/lib/angular-animate/angular-animate.min.js',
				'public/lib/angular-route/angular-route.min.js',
				'public/lib/angular-touch/angular-touch.min.js',
				'public/lib/angular-sanitize/angular-sanitize.min.js',
				'public/lib/angular-ui-router/release/angular-ui-router.min.js',
				'public/lib/angular-ui-utils/ui-utils.min.js',
				'public/lib/angular-bootstrap/ui-bootstrap-tpls.js',
				'public/lib/ng-file-upload/ng-file-upload-all.min.js',
				'public/lib/ng-tags-input/ng-tags-input.min.js'
			]
		},
		css: [
			'public/lib/ng-tags-input/ng-tags-input.bootstrap.min.css',
			'public/modules/**/css/*.css'
		],
		js: [
			'public/config.js',
			'public/application.js',
			'public/modules/*/*.js',
			'public/modules/*/*[!tests]*/*.js'
			],
		tests: [
			'public/lib/angular-mocks/angular-mocks.js',
			'public/modules/*/tests/*.js'
		]
	}
};
<|endoftext|>


<commit_before>E2.plugins["aspect_ratio_generator"] = function(core, node) {
	var self = this;

	this.desc = 'Emits current renderer aspect ratio (width / height).';
	this.input_slots = [];
	this.output_slots = [ { name: 'aspect', dt: core.datatypes.FLOAT, desc: 'The current renderer aspect ratio.' } ];

	this.update_output = function(slot)
	{
		var c = core.renderer.canvas;

		return c.width() / c.height();
	};
};
<commit_msg>Refactored the aspect ratio generator plugin to use prototype. Fixed bug where the plugin would not re-emit its value when playback is restarted after having been stopped.<commit_after>E2.p = E2.plugins["aspect_ratio_generator"] = function(core, node)
{
	this.desc = 'Emits current renderer aspect ratio (width / height).';

	this.input_slots = [];

	this.output_slots = [ { name: 'aspect', dt: core.datatypes.FLOAT, desc: 'The current renderer aspect ratio.' } ];

	this.canvas = core.renderer.canvas;
};

E2.p.prototype.reset = function()
{
};

E2.p.prototype.update_output = function(slot)
{
	var c = this.canvas;

	// TODO: We've *got* to get rid of this. It locks up the UI thread badly.
	return c.width() / c.height();
};
<|endoftext|>


<commit_before>var tutorials = {
  'demo': {
    key: 'demo',
    title: 'Demo Tutorial',
    steps: [
      {
        key: 'anywhere',
        announce: 'The tutorial prompts will present themselves as a series of modals with \
annotations and prompts on how to progress. This, in fact, is an announcement-style tutorial step.\
\n\nFeel free to hide / show this modal at any point to attempt to break the flow of the tutorial. \
You should not be able to force the tutorial into any situtation it cannot recover from.',
        announceDismiss: "Okay, let's begin",
        activeWhen: [],
      },
      {
        key: 'beginning',
        highlight: '#colour',
        annotate: 'Step one: choose your favourite colour.\n\nNote that you can skip this step if \
your favourite colour was guessed correctly.',
        annotateIn: 'div.colour-input-group > div',
        annotateSkip: 'Skip',
        activeWhen: [
          {
            compare: 'checkpointComplete',
            checkpoint: 'demo_anywhere',
          },
        ],
      },
      {
        key: 'entering-name',
        highlight: '#name',
        annotate: 'Now we need to know your full name. This is mandatory, so start typing!',
        annotateIn: 'div.name-input-group > div',
        activeWhen: [
          {
            compare: 'checkpointComplete',
            checkpoint: 'demo_beginning',
          },
        ],
      },
      {
        key: 'optional-info',
        highlight: 'form div.form-details',
        highlightBack: '#fff',
        annotate: 'You can choose to enter more information at this point, and review the \
information you have already provided\n\nThe help overlay will remain open whilst you are typing.',
        annotateAfter: 'form div.form-details',
        annotateSkip: 'Okay I am done',
        editWhileOpen: true,
        activeWhen: [
          {
            compare: 'checkpointComplete',
            checkpoint: 'demo_anywhere',
          },
          {
            compare: 'inputNotVal',
            selector: '#name',
            value: '',
          },
        ],
      },
      {
        key: 'submission',
        highlight: 'form button[type="submit"]',
        annotate: 'Click "Submit" to submit the form and continue',
        annotateAfter: 'form button[type="submit"]',
        activeWhen: [
          {
            compare: 'inputNotVal',
            selector: '#name',
            value: '',
          },
          {
            compare: 'checkpointComplete',
            checkpoint: 'demo_optional-info',
          },
        ],
      },
      {
        key: 'new-page',
        announce: "The tutorial state can be inferred across pages, if you set your conditions \
wisely.\n\nIn this case, the url matching 'react-interactive-tutorials/demo-form' is used to \
recognise the fact that we have progressed.",
        announceDismiss: 'Okay, cool',
        activeWhen: [
          {
            compare: 'url',
            url: /^\/react-interactive-tutorials\/demo-form$/,
          },
        ],
      },
      {
        key: 'returning',
        highlight: '#return',
        annotate: "Let's return to the first page with the code",
        annotateAfter: '#return',
        activeWhen: [
          {
            compare: 'url',
            url: /^\/react-interactive-tutorials\/demo-form$/,
          },
          {
            compare: 'checkpointComplete',
            checkpoint: 'demo_new-page',
          },
        ],
      },
      {
        key: 'complete',
        announce: "Now we're back at the first page, but we know the user has acknowledged the \
announcements on the previous page.",
        announceDismiss: 'Okay',
        activeWhen: [
          {
            compare: 'url',
            url: /^\/react-interactive-tutorials\/$/,
          },
          {
            compare: 'checkpointComplete',
            checkpoint: 'demo_new-page',
          },
        ],
      },
    ],
    complete: {
      on: 'checkpointReached',
      checkpoint: 'complete',
      title: 'Demo Tutorial Complete!',
      message: 'And so concludes the demo tutorial.\n\nTake a look at the code for this tutorial \
below, and get started writing your own tutorials!',
    },
  },
};
interactiveTutorials.registerTutorials(tutorials);
<commit_msg>prompts prompts<commit_after>var tutorials = {
  'demo': {
    key: 'demo',
    title: 'Demo Tutorial',
    steps: [
      {
        key: 'anywhere',
        announce: 'The tutorial will present themselves as a series of modals with \
annotations and prompts on how to progress. This, in fact, is an announcement-style tutorial step.\
\n\nFeel free to hide / show this modal at any point to attempt to break the flow of the tutorial. \
You should not be able to force the tutorial into any situtation it cannot recover from.',
        announceDismiss: "Okay, let's begin",
        activeWhen: [],
      },
      {
        key: 'beginning',
        highlight: '#colour',
        annotate: 'Step one: choose your favourite colour.\n\nNote that you can skip this step if \
your favourite colour was guessed correctly.',
        annotateIn: 'div.colour-input-group > div',
        annotateSkip: 'Skip',
        activeWhen: [
          {
            compare: 'checkpointComplete',
            checkpoint: 'demo_anywhere',
          },
        ],
      },
      {
        key: 'entering-name',
        highlight: '#name',
        annotate: 'Now we need to know your full name. This is mandatory, so start typing!',
        annotateIn: 'div.name-input-group > div',
        activeWhen: [
          {
            compare: 'checkpointComplete',
            checkpoint: 'demo_beginning',
          },
        ],
      },
      {
        key: 'optional-info',
        highlight: 'form div.form-details',
        highlightBack: '#fff',
        annotate: 'You can choose to enter more information at this point, and review the \
information you have already provided\n\nThe help overlay will remain open whilst you are typing.',
        annotateAfter: 'form div.form-details',
        annotateSkip: 'Okay I am done',
        editWhileOpen: true,
        activeWhen: [
          {
            compare: 'checkpointComplete',
            checkpoint: 'demo_anywhere',
          },
          {
            compare: 'inputNotVal',
            selector: '#name',
            value: '',
          },
        ],
      },
      {
        key: 'submission',
        highlight: 'form button[type="submit"]',
        annotate: 'Click "Submit" to submit the form and continue',
        annotateAfter: 'form button[type="submit"]',
        activeWhen: [
          {
            compare: 'inputNotVal',
            selector: '#name',
            value: '',
          },
          {
            compare: 'checkpointComplete',
            checkpoint: 'demo_optional-info',
          },
        ],
      },
      {
        key: 'new-page',
        announce: "The tutorial state can be inferred across pages, if you set your conditions \
wisely.\n\nIn this case, the url matching 'react-interactive-tutorials/demo-form' is used to \
recognise the fact that we have progressed.",
        announceDismiss: 'Okay, cool',
        activeWhen: [
          {
            compare: 'url',
            url: /^\/react-interactive-tutorials\/demo-form$/,
          },
        ],
      },
      {
        key: 'returning',
        highlight: '#return',
        annotate: "Let's return to the first page with the code",
        annotateAfter: '#return',
        activeWhen: [
          {
            compare: 'url',
            url: /^\/react-interactive-tutorials\/demo-form$/,
          },
          {
            compare: 'checkpointComplete',
            checkpoint: 'demo_new-page',
          },
        ],
      },
      {
        key: 'complete',
        announce: "Now we're back at the first page, but we know the user has acknowledged the \
announcements on the previous page.",
        announceDismiss: 'Okay',
        activeWhen: [
          {
            compare: 'url',
            url: /^\/react-interactive-tutorials\/$/,
          },
          {
            compare: 'checkpointComplete',
            checkpoint: 'demo_new-page',
          },
        ],
      },
    ],
    complete: {
      on: 'checkpointReached',
      checkpoint: 'complete',
      title: 'Demo Tutorial Complete!',
      message: 'And so concludes the demo tutorial.\n\nTake a look at the code for this tutorial \
below, and get started writing your own tutorials!',
    },
  },
};
interactiveTutorials.registerTutorials(tutorials);
<|endoftext|>


<commit_before>(function() {

/*!
  * $script.js v1.3
  * https://github.com/ded/script.js
  * Copyright: @ded & @fat - Dustin Diaz, Jacob Thornton 2011
  * Follow our software http://twitter.com/dedfat
  * License: MIT
  */
!function(a,b,c){function t(a,c){var e=b.createElement("script"),f=j;e.onload=e.onerror=e[o]=function(){e[m]&&!/^c|loade/.test(e[m])||f||(e.onload=e[o]=null,f=1,c())},e.async=1,e.src=a,d.insertBefore(e,d.firstChild)}function q(a,b){p(a,function(a){return!b(a)})}var d=b.getElementsByTagName("head")[0],e={},f={},g={},h={},i="string",j=!1,k="push",l="DOMContentLoaded",m="readyState",n="addEventListener",o="onreadystatechange",p=function(a,b){for(var c=0,d=a.length;c<d;++c)if(!b(a[c]))return j;return 1};!b[m]&&b[n]&&(b[n](l,function r(){b.removeEventListener(l,r,j),b[m]="complete"},j),b[m]="loading");var s=function(a,b,d){function o(){if(!--m){e[l]=1,j&&j();for(var a in g)p(a.split("|"),n)&&!q(g[a],n)&&(g[a]=[])}}function n(a){return a.call?a():e[a]}a=a[k]?a:[a];var i=b&&b.call,j=i?b:d,l=i?a.join(""):b,m=a.length;c(function(){q(a,function(a){h[a]?(l&&(f[l]=1),o()):(h[a]=1,l&&(f[l]=1),t(s.path?s.path+a+".js":a,o))})},0);return s};s.get=t,s.ready=function(a,b,c){a=a[k]?a:[a];var d=[];!q(a,function(a){e[a]||d[k](a)})&&p(a,function(a){return e[a]})?b():!function(a){g[a]=g[a]||[],g[a][k](b),c&&c(d)}(a.join("|"));return s};var u=a.$script;s.noConflict=function(){a.$script=u;return this},typeof module!="undefined"&&module.exports?module.exports=s:a.$script=s}(this,document,setTimeout);

function loadScripts(base_url){
  var timestamp = '?' + (new Date()).getTime(),
      toLoad = [
          [
              base_url + '/build/jquery-1.6.1.js',
              base_url + '/build/easyXDM/easyXDM.js',
              base_url + '/build/underscore.js'
          ],
          [
              base_url + '/src/js/core.js' + timestamp
          ],
          [
              base_url + '/build/jquery.scrollTo-1.4.2.js',
              base_url + '/build/jquery.hoverintent.js',
              base_url + '/src/js/models/fact.js' + timestamp,
              base_url + '/src/js/views/ballooney_thingy.js' + timestamp,
              base_url + '/src/js/views/balloon.js' + timestamp,
              base_url + '/src/js/views/prepare.js' + timestamp,
              base_url + '/src/js/annotate.js' + timestamp
          ],
          [
              base_url + '/src/js/replace.js' + timestamp,
              base_url + '/src/js/scrollto.js' + timestamp,
              base_url + '/src/js/search.js' + timestamp,
              base_url + '/src/js/create.js' + timestamp,
              base_url + '/src/js/modal.js' + timestamp,
              base_url + '/src/js/lib/indicator.js' + timestamp
          ],
          [
              base_url + '/src/js/xdm.js' + timestamp
          ],
          [
              base_url + '/src/js/last.js' + timestamp
          ]
      ];

  // We use a self invoking anonymous function to load all the scripts
  // needed.
  (function(i){
      // Load the script
      $script(toLoad[i], i);

      // If there is more to load
      if ( toLoad[i+1] !== undefined ) {
          // Store the current function object (so we can call it from the
          // ready method of $script)
          var toCall = arguments.callee;

          // When $script is done loading the first batch, start loading
          // the next one
          $script.ready( i, function() {
              // Make a recursive call to make sure all scripts get loaded
              toCall(i+1);
          });
      } else {
          // Nothing to load anymore, call the ready method.
          $script.ready( i, function() {
            console.info( "Factlink library loaded" );
          });
      }
  })(0);
}

loadScripts(window.FactlinkConfig.lib)

})();<commit_msg>Reformated load_library.js and added highlight.js<commit_after>(function() {

/*!
  * $script.js v1.3
  * https://github.com/ded/script.js
  * Copyright: @ded & @fat - Dustin Diaz, Jacob Thornton 2011
  * Follow our software http://twitter.com/dedfat
  * License: MIT
  */
!function(a,b,c){function t(a,c){var e=b.createElement("script"),f=j;e.onload=e.onerror=e[o]=function(){e[m]&&!/^c|loade/.test(e[m])||f||(e.onload=e[o]=null,f=1,c())},e.async=1,e.src=a,d.insertBefore(e,d.firstChild)}function q(a,b){p(a,function(a){return!b(a)})}var d=b.getElementsByTagName("head")[0],e={},f={},g={},h={},i="string",j=!1,k="push",l="DOMContentLoaded",m="readyState",n="addEventListener",o="onreadystatechange",p=function(a,b){for(var c=0,d=a.length;c<d;++c)if(!b(a[c]))return j;return 1};!b[m]&&b[n]&&(b[n](l,function r(){b.removeEventListener(l,r,j),b[m]="complete"},j),b[m]="loading");var s=function(a,b,d){function o(){if(!--m){e[l]=1,j&&j();for(var a in g)p(a.split("|"),n)&&!q(g[a],n)&&(g[a]=[])}}function n(a){return a.call?a():e[a]}a=a[k]?a:[a];var i=b&&b.call,j=i?b:d,l=i?a.join(""):b,m=a.length;c(function(){q(a,function(a){h[a]?(l&&(f[l]=1),o()):(h[a]=1,l&&(f[l]=1),t(s.path?s.path+a+".js":a,o))})},0);return s};s.get=t,s.ready=function(a,b,c){a=a[k]?a:[a];var d=[];!q(a,function(a){e[a]||d[k](a)})&&p(a,function(a){return e[a]})?b():!function(a){g[a]=g[a]||[],g[a][k](b),c&&c(d)}(a.join("|"));return s};var u=a.$script;s.noConflict=function(){a.$script=u;return this},typeof module!="undefined"&&module.exports?module.exports=s:a.$script=s}(this,document,setTimeout);

function loadScripts(base_url){
  var timestamp = '?' + (new Date()).getTime(),
    toLoad = [
      [
        base_url + '/build/jquery-1.6.1.js',
        base_url + '/build/easyXDM/easyXDM.js',
        base_url + '/build/underscore.js'
      ],
      [
        base_url + '/src/js/core.js' + timestamp
      ],
      [
        base_url + '/build/jquery.scrollTo-1.4.2.js',
        base_url + '/build/jquery.hoverintent.js',
        base_url + '/src/js/models/fact.js' + timestamp,
        base_url + '/src/js/views/ballooney_thingy.js' + timestamp,
        base_url + '/src/js/views/balloon.js' + timestamp,
        base_url + '/src/js/views/prepare.js' + timestamp
      ],
      [
        base_url + '/src/js/replace.js' + timestamp,
        base_url + '/src/js/annotate.js' + timestamp,
        base_url + '/src/js/highlight.js' + timestamp,
        base_url + '/src/js/scrollto.js' + timestamp,
        base_url + '/src/js/search.js' + timestamp,
        base_url + '/src/js/create.js' + timestamp,
        base_url + '/src/js/modal.js' + timestamp,
        base_url + '/src/js/lib/indicator.js' + timestamp
      ],
      [
        base_url + '/src/js/xdm.js' + timestamp
      ],
      [
        base_url + '/src/js/last.js' + timestamp
      ]
    ];

  // We use a self invoking anonymous function to load all the scripts
  // needed.
  (function(i){
    // Load the script
    $script(toLoad[i], i);

    // If there is more to load
    if ( toLoad[i+1] !== undefined ) {
      // Store the current function object (so we can call it from the
      // ready method of $script)
      var toCall = arguments.callee;

      // When $script is done loading the first batch, start loading
      // the next one
      $script.ready( i, function() {
        // Make a recursive call to make sure all scripts get loaded
        toCall(i+1);
      });
    } else {
      // Nothing to load anymore, call the ready method.
      $script.ready( i, function() {
        console.info( "Factlink library loaded" );
      });
    }
  })(0);
}

loadScripts(window.FactlinkConfig.lib)

})();<|endoftext|>


<commit_before>/*!
 * Modal for the Viewer Layer
 * For both annotations and code/info
 *
 * Copyright (c) 2016 Dave Olsen, http://dmolsen.com
 * Licensed under the MIT license
 *
 * @requires url-handler.js
 * @requires data-saver.js
 *
 */

var modalViewer = {

	// set up some defaults
	active:        false,
	switchText:    true,
	template:      'info',
	patternData:   {},
	targetOrigin:  (window.location.protocol === 'file:') ? '*' : window.location.protocol+'//'+window.location.host,

  /**
  * initialize the modal window
  */
  onReady: function() {

    // make sure the listener for checkpanels is set-up
    Dispatcher.addListener('insertPanels', modalViewer.insert);

    // add the info/code panel onclick handler
    $('.pl-js-pattern-info-toggle').click(function(e) {
		modalViewer.toggle();
    });

    // make sure the close button handles the click
    $('#sg-modal-close-btn').on('click', function(e) {

      // hide any open annotations
      obj = JSON.stringify({ 'event': 'patternLab.annotationsHighlightHide' });
      document.getElementById('sg-viewport').contentWindow.postMessage(obj, modalViewer.targetOrigin);

      // hide the viewer
      modalViewer.close();

    });

    // see if the modal is already active, if so update attributes as appropriate
    if (DataSaver.findValue('modalActive') === 'true') {
      modalViewer.active = true;
      $('.pl-js-pattern-info-toggle').html("Hide Pattern Info");
    }

    // make sure the modal viewer is not viewable, it's alway hidden by default. the pageLoad event determines when it actually opens
    modalViewer.hide();

    // review the query strings in case there is something the modal viewer is supposed to handle by default
    var queryStringVars = urlHandler.getRequestVars();

    // show the modal if code view is called via query string
    if ((queryStringVars.view !== undefined) && ((queryStringVars.view === 'code') || (queryStringVars.view === 'c'))) {
      modalViewer.queryPattern();
    }

    // show the modal if the old annotations view is called via query string
    if ((queryStringVars.view !== undefined) && ((queryStringVars.view === 'annotations') || (queryStringVars.view === 'a'))) {
      modalViewer.queryPattern();
    }

	},

	/**
	 * toggle the modal window open and closed
	*/
	toggle: function() {
	if (modalViewer.active === false) {
		modalViewer.queryPattern();
	} else {
		obj = JSON.stringify({ 'event': 'patternLab.annotationsHighlightHide' });
		document.getElementById('sg-viewport').contentWindow.postMessage(obj, modalViewer.targetOrigin);
		modalViewer.close();
	}
	},

	/**
	 * open the modal window
	*/
	open: function() {

	// make sure the modal viewer and other options are off just in case
	modalViewer.close();

	// note it's turned on in the viewer
	DataSaver.updateValue('modalActive', 'true');
	modalViewer.active = true;

	// show the modal
	modalViewer.show();

	},

	/**
	 * close the modal window
	*/
	close: function() {

	var obj;

	// not that the modal viewer is no longer active
	DataSaver.updateValue('modalActive', 'false');
	modalViewer.active = false;

	//Remove active class to modal
	$('#sg-modal-container').removeClass('pl-is-active');

	// update the wording
	$('.pl-js-pattern-info-toggle').html("Show Pattern Info");

	// tell the styleguide to close
	obj = JSON.stringify({ 'event': 'patternLab.patternModalClose' });
	document.getElementById('sg-viewport').contentWindow.postMessage(obj, modalViewer.targetOrigin);

	},

	/**
	 * hide the modal window
	*/
	hide: function() {
	$('#sg-modal-container').removeClass('pl-is-active');
	},

	/**
	 * insert the copy for the modal window. if it's meant to be sent back to the iframe do do
	* @param  {String}       the rendered template that should be inserted
	* @param  {String}       the patternPartial that the rendered template is related to
	* @param  {Boolean}      if the refresh is of a view-all view and the content should be sent back
	* @param  {Boolean}      if the text in the dropdown should be switched
	*/
	insert: function(templateRendered, patternPartial, iframePassback, switchText) {

	if (iframePassback) {

		// send a message to the pattern
		var obj = JSON.stringify({ 'event': 'patternLab.patternModalInsert', 'patternPartial': patternPartial, 'modalContent': templateRendered.outerHTML });
		document.getElementById('sg-viewport').contentWindow.postMessage(obj, modalViewer.targetOrigin);

	} else {

		// insert the panels and open the viewer
		$('#sg-modal-content').html(templateRendered);
		modalViewer.open();

	}

	// update the wording unless this is a default viewall opening
	if (switchText === true) {
		$('.pl-js-pattern-info-toggle').html("Hide Pattern Info");
	}

	},

	/**
	 * refresh the modal if a new pattern is loaded and the modal is active
	* @param  {Object}       the patternData sent back from the query
	* @param  {Boolean}      if the refresh is of a view-all view and the content should be sent back
	* @param  {Boolean}      if the text in the dropdown should be switched
	*/
	refresh: function(patternData, iframePassback, switchText) {

	// if this is a styleguide view close the modal
	if (iframePassback) {
		modalViewer.hide();
	}

	// gather the data that will fill the modal window
	panelsViewer.gatherPanels(patternData, iframePassback, switchText);

	},

	/**
	 * slides the modal window into or out of view
	* @param  {Integer}      where the modal window should be slide to
	*/
	slide: function(pos) {
	$('#sg-modal-container').toggleClass('pl-is-active');
	},

	/**
	 * slides the modal window to a particular annotation
	* @param  {Integer}      the number for the element that should be highlighted
	*/
	slideToAnnotation: function(pos) {

	// remove active class
	els = document.querySelectorAll('#sg-annotations > .sg-annotations-list > li');
	for (i = 0; i < els.length; ++i) {
		els[i].classList.remove('active');
	}

	// add active class to called element and scroll to it
	for (i = 0; i < els.length; ++i) {
		if ((i+1) == pos) {
		els[i].classList.add('active');
		$('.pl-js-pattern-info').animate({scrollTop: els[i].offsetTop - 10}, 600);
		}
	}

	},

	/**
	 * Show modal
	 */
	show: function() {
	$('#sg-modal-container').addClass('pl-is-active');
	},

	/**
	 * ask the pattern for info so we can open the modal window and populate it
	 * @param  {Boolean}      if the dropdown text should be changed
	 */
	queryPattern: function(switchText) {

	// note that the modal is active and set switchText
	if ((switchText === undefined) || (switchText)) {
		switchText = true;
		DataSaver.updateValue('modalActive', 'true');
		modalViewer.active = true;
	}

	// send a message to the pattern
	var obj = JSON.stringify({ 'event': 'patternLab.patternQuery', 'switchText': switchText });
	document.getElementById('sg-viewport').contentWindow.postMessage(obj, modalViewer.targetOrigin);

	},

	/**
	 * toggle the comment pop-up based on a user clicking on the pattern
	* based on the great MDN docs at https://developer.mozilla.org/en-US/docs/Web/API/window.postMessage
	* @param  {Object}      event info
	*/
	receiveIframeMessage: function(event) {

	var els, i;

	// does the origin sending the message match the current host? if not dev/null the request
	if ((window.location.protocol !== 'file:') && (event.origin !== window.location.protocol+'//'+window.location.host)) {
		return;
	}

	var data = {};
	try {
		data = (typeof event.data !== 'string') ? event.data : JSON.parse(event.data);
	} catch(e) {}

	if ((data.event !== undefined) && (data.event == "patternLab.pageLoad")) {

		if ((modalViewer.active === false) && (data.patternpartial !== undefined) && (data.patternpartial.indexOf('viewall-') === 0) && (config.defaultShowPatternInfo !== undefined) && (config.defaultShowPatternInfo)) {
		modalViewer.queryPattern(false);
		} else if (modalViewer.active === true) {
		modalViewer.queryPattern();
		}

	} else if ((data.event !== undefined) && (data.event == 'patternLab.patternQueryInfo')) {

		// refresh the modal if a new pattern is loaded and the modal is active
		modalViewer.refresh(data.patternData, data.iframePassback, data.switchText);

	} else if ((data.event !== undefined) && (data.event == 'patternLab.annotationNumberClicked')) {

		// slide to a given annoation
		modalViewer.slideToAnnotation(data.displayNumber);

	}

	}

};

// when the document is ready make sure the modal is ready
$(document).ready(function() { modalViewer.onReady(); });
window.addEventListener("message", modalViewer.receiveIframeMessage, false);
<commit_msg>Clean up formatting<commit_after>/*!
 * Modal for the Viewer Layer
 * For both annotations and code/info
 *
 * Copyright (c) 2016 Dave Olsen, http://dmolsen.com
 * Licensed under the MIT license
 *
 * @requires url-handler.js
 * @requires data-saver.js
 *
 */

var modalViewer = {

	// set up some defaults
	active:        false,
	switchText:    true,
	template:      'info',
	patternData:   {},
	targetOrigin:  (window.location.protocol === 'file:') ? '*' : window.location.protocol+'//'+window.location.host,

  /**
  * initialize the modal window
  */
  onReady: function() {

    // make sure the listener for checkpanels is set-up
    Dispatcher.addListener('insertPanels', modalViewer.insert);

    // add the info/code panel onclick handler
    $('.pl-js-pattern-info-toggle').click(function(e) {
		modalViewer.toggle();
    });

    // make sure the close button handles the click
    $('#sg-modal-close-btn').on('click', function(e) {

      // hide any open annotations
      obj = JSON.stringify({ 'event': 'patternLab.annotationsHighlightHide' });
      document.getElementById('sg-viewport').contentWindow.postMessage(obj, modalViewer.targetOrigin);

      // hide the viewer
      modalViewer.close();

    });

    // see if the modal is already active, if so update attributes as appropriate
    if (DataSaver.findValue('modalActive') === 'true') {
      modalViewer.active = true;
      $('.pl-js-pattern-info-toggle').html("Hide Pattern Info");
    }

    // make sure the modal viewer is not viewable, it's alway hidden by default. the pageLoad event determines when it actually opens
    modalViewer.hide();

    // review the query strings in case there is something the modal viewer is supposed to handle by default
    var queryStringVars = urlHandler.getRequestVars();

    // show the modal if code view is called via query string
    if ((queryStringVars.view !== undefined) && ((queryStringVars.view === 'code') || (queryStringVars.view === 'c'))) {
      modalViewer.queryPattern();
    }

    // show the modal if the old annotations view is called via query string
    if ((queryStringVars.view !== undefined) && ((queryStringVars.view === 'annotations') || (queryStringVars.view === 'a'))) {
      modalViewer.queryPattern();
    }

	},

	/**
	 * toggle the modal window open and closed
	*/
	toggle: function() {
	if (modalViewer.active === false) {
		modalViewer.queryPattern();
	} else {
		obj = JSON.stringify({ 'event': 'patternLab.annotationsHighlightHide' });
		document.getElementById('sg-viewport').contentWindow.postMessage(obj, modalViewer.targetOrigin);
		modalViewer.close();
	}
	},

	/**
	 * open the modal window
	*/
	open: function() {

	// make sure the modal viewer and other options are off just in case
	modalViewer.close();

	// note it's turned on in the viewer
	DataSaver.updateValue('modalActive', 'true');
	modalViewer.active = true;

	// show the modal
	modalViewer.show();

	},

	/**
	 * close the modal window
	*/
	close: function() {

	var obj;

	// not that the modal viewer is no longer active
	DataSaver.updateValue('modalActive', 'false');
	modalViewer.active = false;

	//Remove active class to modal
	$('#sg-modal-container').removeClass('pl-is-active');

	// update the wording
	$('.pl-js-pattern-info-toggle').html("Show Pattern Info");

	// tell the styleguide to close
	obj = JSON.stringify({ 'event': 'patternLab.patternModalClose' });
	document.getElementById('sg-viewport').contentWindow.postMessage(obj, modalViewer.targetOrigin);

	},

	/**
	 * hide the modal window
	*/
	hide: function() {
	$('#sg-modal-container').removeClass('pl-is-active');
	},

	/**
	 * insert the copy for the modal window. if it's meant to be sent back to the iframe do do
	* @param  {String}       the rendered template that should be inserted
	* @param  {String}       the patternPartial that the rendered template is related to
	* @param  {Boolean}      if the refresh is of a view-all view and the content should be sent back
	* @param  {Boolean}      if the text in the dropdown should be switched
	*/
	insert: function(templateRendered, patternPartial, iframePassback, switchText) {

	if (iframePassback) {

		// send a message to the pattern
		var obj = JSON.stringify({ 'event': 'patternLab.patternModalInsert', 'patternPartial': patternPartial, 'modalContent': templateRendered.outerHTML });
		document.getElementById('sg-viewport').contentWindow.postMessage(obj, modalViewer.targetOrigin);

	} else {

		// insert the panels and open the viewer
		$('#sg-modal-content').html(templateRendered);
		modalViewer.open();

	}

	// update the wording unless this is a default viewall opening
	if (switchText === true) {
		$('.pl-js-pattern-info-toggle').html("Hide Pattern Info");
	}

	},

	/**
	 * refresh the modal if a new pattern is loaded and the modal is active
	* @param  {Object}       the patternData sent back from the query
	* @param  {Boolean}      if the refresh is of a view-all view and the content should be sent back
	* @param  {Boolean}      if the text in the dropdown should be switched
	*/
	refresh: function(patternData, iframePassback, switchText) {

	// if this is a styleguide view close the modal
	if (iframePassback) {
		modalViewer.hide();
	}

	// gather the data that will fill the modal window
	panelsViewer.gatherPanels(patternData, iframePassback, switchText);

	},

	/**
	 * slides the modal window into or out of view
	 * @param  {Integer}      where the modal window should be slide to
	 */
	slide: function(pos) {
		$('#sg-modal-container').toggleClass('pl-is-active');
	},

	/**
	 * slides the modal window to a particular annotation
	 * @param  {Integer}      the number for the element that should be highlighted
	 */
	slideToAnnotation: function(pos) {

	// remove active class
	els = document.querySelectorAll('#sg-annotations > .sg-annotations-list > li');
	for (i = 0; i < els.length; ++i) {
		els[i].classList.remove('active');
	}

	// add active class to called element and scroll to it
	for (i = 0; i < els.length; ++i) {
		if ((i+1) == pos) {
		els[i].classList.add('active');
		$('.pl-js-pattern-info').animate({scrollTop: els[i].offsetTop - 10}, 600);
		}
	}

	},

	/**
	 * Show modal
	 */
	show: function() {
	$('#sg-modal-container').addClass('pl-is-active');
	},

	/**
	 * ask the pattern for info so we can open the modal window and populate it
	 * @param  {Boolean}      if the dropdown text should be changed
	 */
	queryPattern: function(switchText) {

	// note that the modal is active and set switchText
	if ((switchText === undefined) || (switchText)) {
		switchText = true;
		DataSaver.updateValue('modalActive', 'true');
		modalViewer.active = true;
	}

	// send a message to the pattern
	var obj = JSON.stringify({ 'event': 'patternLab.patternQuery', 'switchText': switchText });
	document.getElementById('sg-viewport').contentWindow.postMessage(obj, modalViewer.targetOrigin);

	},

	/**
	 * toggle the comment pop-up based on a user clicking on the pattern
	 * based on the great MDN docs at https://developer.mozilla.org/en-US/docs/Web/API/window.postMessage
	 * @param  {Object}      event info
	 */
	receiveIframeMessage: function(event) {

		var els, i;

		// does the origin sending the message match the current host? if not dev/null the request
		if ((window.location.protocol !== 'file:') && (event.origin !== window.location.protocol+'//'+window.location.host)) {
			return;
		}

		var data = {};

		try {
			data = (typeof event.data !== 'string') ? event.data : JSON.parse(event.data);
		} catch(e) {}

		if ((data.event !== undefined) && (data.event == "patternLab.pageLoad")) {

			if ((modalViewer.active === false) && (data.patternpartial !== undefined) && (data.patternpartial.indexOf('viewall-') === 0) && (config.defaultShowPatternInfo !== undefined) && (config.defaultShowPatternInfo)) {
			modalViewer.queryPattern(false);
			} else if (modalViewer.active === true) {
			modalViewer.queryPattern();
			}

		} else if ((data.event !== undefined) && (data.event == 'patternLab.patternQueryInfo')) {

			// refresh the modal if a new pattern is loaded and the modal is active
			modalViewer.refresh(data.patternData, data.iframePassback, data.switchText);

		} else if ((data.event !== undefined) && (data.event == 'patternLab.annotationNumberClicked')) {

			// slide to a given annoation
			modalViewer.slideToAnnotation(data.displayNumber);
		}

	}

};

// when the document is ready make sure the modal is ready
$(document).ready(function() {
	modalViewer.onReady();
});

window.addEventListener("message", modalViewer.receiveIframeMessage, false);
<|endoftext|>


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

module.exports = {
  twitter: {
    api: {
      consumer_key:         process.env.TWITTER_CONSUMER_KEY,
      consumer_secret:      process.env.TWITTER_CONSUMER_SECRET,
      //access_token:         process.env.TWITTER_ACCESS_TOKEN,
      //access_token_secret:  process.env.TWITTER_ACCESS_TOKEN_SECRET
      app_only_auth:        true
    },
    controller: {
      url: util.format('mongodb://%s:%s@%s:%d/%s?authMechanism=SCRAM-SHA-1&authSource=admin',
        process.env.MONGO_USER,
        process.env.MONGO_PASSWD,
        process.env.MONGO_HOST,
        process.env.MONGO_PORT,
        process.env.MONGO_COLLECTION
      ),
    },
  },

  logger:{
    level: 'info',
    root: './',
  },
};
<commit_msg>fix url for authentication<commit_after>var util = require('util');

module.exports = {
  twitter: {
    api: {
      consumer_key:         process.env.TWITTER_CONSUMER_KEY,
      consumer_secret:      process.env.TWITTER_CONSUMER_SECRET,
      //access_token:         process.env.TWITTER_ACCESS_TOKEN,
      //access_token_secret:  process.env.TWITTER_ACCESS_TOKEN_SECRET
      app_only_auth:        true
    },
    controller: {
      url: util.format('mongodb://%s:%s@%s:%d/%s?authMechanism=SCRAM-SHA-1&authSource=%s',
        process.env.MONGO_USER,
        process.env.MONGO_PASSWD,
        process.env.MONGO_HOST,
        process.env.MONGO_PORT,
        process.env.MONGO_DATABASE,
        process.env.MONGO_DATABASE
      ),
    },
  },

  logger:{
    level: 'info',
    root: './',
  },
};
<|endoftext|>


<commit_before>// Packages
const chalk = require('chalk')

const DNS_VERIFICATION_ERROR = `Please make sure that your nameservers point to ${chalk.underline(
  'zeit.world'
)}.
> Examples: (full list at ${chalk.underline('https://zeit.world')})
> ${chalk.gray('-')} ${chalk.underline('california.zeit.world')}    ${chalk.dim(
  '173.255.215.107'
)}
> ${chalk.gray('-')} ${chalk.underline('newark.zeit.world')}        ${chalk.dim(
  '173.255.231.87'
)}
> ${chalk.gray('-')} ${chalk.underline('london.zeit.world')}        ${chalk.dim(
  '178.62.47.76'
)}
> ${chalk.gray('-')} ${chalk.underline('singapore.zeit.world')}     ${chalk.dim(
  '119.81.97.170'
)}`

const DOMAIN_VERIFICATION_ERROR =
  DNS_VERIFICATION_ERROR +
  `\n> Alternatively, ensure it resolves to ${chalk.underline(
    'alias.zeit.co'
  )} via ${chalk.dim('CNAME')} / ${chalk.dim('ALIAS')}.`

module.exports = {
  DNS_VERIFICATION_ERROR,
  DOMAIN_VERIFICATION_ERROR
}
<commit_msg>Fix zeit.world DNS examples list (#959)<commit_after>// Packages
const chalk = require('chalk')

const DNS_VERIFICATION_ERROR = `Please make sure that your nameservers point to ${chalk.underline(
  'zeit.world'
)}.
> For more details visit: ${chalk.underline('https://zeit.world')})
> ${chalk.gray('-')} ${chalk.underline('a.zeit.world')}
> ${chalk.gray('-')} ${chalk.underline('b.zeit.world')}
> ${chalk.gray('-')} ${chalk.underline('c.zeit.world')}
> ${chalk.gray('-')} ${chalk.underline('d.zeit.world')}
> ${chalk.gray('-')} ${chalk.underline('e.zeit.world')}
> ${chalk.gray('-')} ${chalk.underline('f.zeit.world')}
)}`

const DOMAIN_VERIFICATION_ERROR =
  DNS_VERIFICATION_ERROR +
  `\n> Alternatively, ensure it resolves to ${chalk.underline(
    'alias.zeit.co'
  )} via ${chalk.dim('CNAME')} / ${chalk.dim('ALIAS')}.`

module.exports = {
  DNS_VERIFICATION_ERROR,
  DOMAIN_VERIFICATION_ERROR
}
<|endoftext|>


<commit_before>/**
 * @preserve Copyright 2013 Martijn van de Rijdt
 *
 * 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.
 */

define( [ 'jquery', 'enketo-js/extend' ], function( $ ) {
    "use strict";

    var RESERVED_KEYS = [ '__settings', 'null', '__history', 'Firebug', 'undefined', '__bookmark', '__counter', '__current_server', '__loadLog', '__writetest', '__maxSize' ],
        localStorage = window.localStorage;

    // Could be replaced by Modernizr function if Modernizr remains used in final version
    function isSupported() {
        try {
            return 'localStorage' in window && window[ 'localStorage' ] !== null;
        } catch ( e ) {
            return false;
        }
    }

    function isWritable() {
        var result = setRecord( '__writetest', 'x', null, true );
        if ( result === 'success' ) {
            removeRecord( '__writetest' );
            return true;
        }
        return false;
    }

    //used for testing
    function getForbiddenKeys() {
        return RESERVED_KEYS;
    }

    /**
     * saves a data object in JSON format (string)
     * @param {string} newKey    [description]
     * @param {*} record     [description]
     * @param {boolean=} del [description] used to change name of existing record and delete old record
     * @param {boolean=} overwrite [description] overwrite is only used when there is *another* record with the same new name (not when simply updating current form)
     * @param {?string=} oldKey    [description]
     * @return {string}
     */
    function setRecord( newKey, record, del, overwrite, oldKey ) {
        var error;
        if ( !newKey || typeof newKey !== 'string' || newKey.length < 1 ) {
            //console.error( 'no key or empty key provided for record: ' + newKey );
            return 'require';
        }
        newKey = newKey.trim();
        oldKey = ( typeof oldKey === 'string' ) ? oldKey.trim() : null;
        overwrite = ( typeof overwrite !== 'undefined' && overwrite === true ) ? true : false;

        //using the knowledge that only survey data is provided as a "data" property (and is a string)
        if ( typeof record[ 'data' ] === 'string' && isReservedKey( newKey ) ) {
            return 'forbidden';
        }
        if ( typeof record[ 'data' ] === 'string' &&
            ( oldKey !== newKey && isExistingKey( newKey ) && overwrite !== true ) ||
            ( oldKey === newKey && overwrite !== true ) ) {
            return 'existing';
        }
        try {
            //add timestamp to survey data
            if ( typeof record[ 'data' ] === 'string' ) {
                record[ 'lastSaved' ] = ( new Date() ).getTime();
                //if (newKey == getCounterValue() ){
                localStorage.setItem( '__counter', JSON.stringify( {
                    'counter': getCounterValue()
                } ) );

                //}
            }
            localStorage.setItem( newKey, JSON.stringify( record ) );
            //console.debug( 'saved: ' + newKey + ', old key was: ' + oldKey );
            //if the record was loaded from the store (oldKey != null) and the key's value was changed during editing
            //delete the old record if del=true
            if ( oldKey !== null && oldKey !== '' && oldKey !== newKey ) {
                if ( del ) {
                    console.log( 'going to remove old record with key:' + oldKey );
                    removeRecord( oldKey );
                }
            }
            return 'success';
        } catch ( e ) {
            if ( e && e.code === 22 ) { //} (e.name==='QUOTA_EXCEEDED_ERR'){
                return 'full (or browser is set to not allow storage)';
            }
            console.log( 'error in store.setRecord:', e );
            error = ( e ) ? JSON.stringify( e ) : 'unknown';
            return 'error: ' + error;
        }
    }

    /**
     * Returns a form data record as an object. This is the only function that obtains records from the local storage.
     * @param  {string} key [description]
     * @return {?*}     [description]
     */
    function getRecord( key ) {
        var record;
        try {
            record = JSON.parse( localStorage.getItem( key ) );
            return record;
        } catch ( e ) {
            console.error( 'error with loading data from store: ' + e.message );
            return null;
        }
    }

    // removes a record
    function removeRecord( key ) {
        try {
            localStorage.removeItem( key );
            if ( !isReservedKey( key ) ) {
                //TODO remove this single jQuery dependency
                $( 'form.or' ).trigger( 'delete', JSON.stringify( getRecordList() ) );
            }
            return true;
        } catch ( e ) {
            console.log( 'error with removing data from store: ' + e.message );
            return false;
        }
    }

    /**
     * Returns a list of locally stored form names and properties for a provided server URL
     * @param  {string} serverURL
     * @return {Array.<{name: string, server: string, title: string, url: string}>}
     */
    function getFormList( serverURL ) {
        if ( typeof serverURL == 'undefined' ) {
            return null;
        }
        return /**@type {Array.<{name: string, server: string, title: string, url: string}>}*/ getRecord( '__server_' + serverURL );
    }

    /**
     * returns an ordered array of objects with record keys and final variables {{"key": "name1", "final": true},{"key": "name2", etc.
     * @return { Array.<Object.<string, (boolean|string)>>} [description]
     */
    function getRecordList() {
        var i, ready, record,
            formList = [],
            records = getSurveyRecords( false );
        //console.log('data received:'+JSON.stringify(data)); // DEBUG
        for ( i = 0; i < records.length; i++ ) {
            record = records[ i ];
            //record['ready'] = (record['ready']=== 'true' || record['ready'] === true) ? true : false;
            formList.push( {
                key: record[ 'key' ],
                'ready': record[ 'ready' ],
                'lastSaved': record[ 'lastSaved' ]
            } );
        }
        console.debug( 'formList returning ' + formList.length + ' items' ); //DEBUG
        //order formList by lastSaved timestamp
        formList.sort( function( a, b ) {
            return a[ 'lastSaved' ] - b[ 'lastSaved' ];
        } );
        return formList;
    }

    /**
     * retrieves all survey data
     * @param  {boolean=} finalOnly   [description]
     * @param  {?string=} excludeName [description]
     * @return {Array.<Object.<(string|number), (string|boolean)>>}             [description]
     */
    function getSurveyRecords( finalOnly, excludeName ) {
        var i, key,
            records = [],
            record = {};
        finalOnly = finalOnly || false;
        excludeName = excludeName || null;

        for ( i = 0; i < localStorage.length; i++ ) {
            key = localStorage.key( i );
            //console.debug('found record with with key:'+key);
            record = getRecord( key ); //localStorage.getItem(key);
            // get record - all non-reserved keys contain survey data
            if ( !isReservedKey( key ) ) {
                //console.debug('record with key: '+key+' is survey data');
                try {
                    /* although the key is also available as one of the record properties
            this should not be relied upon and the actual storage key should be used */
                    record.key = key;
                    //=== true comparison breaks in Google Closure compiler. Should probably be called with --output_wrapper to prevent this (but not possible in ANT?)
                    //alternatively, the complete code could perhaps be wrapped in an anonymous function (except declaration of globals?)
                    if ( key !== excludeName && ( !finalOnly || record[ 'ready' ] === 'true' || record[ 'ready' ] === true ) ) { //} && (record.key !== form.getKey()) ){
                        records.push( record );
                    }
                } catch ( e ) {
                    console.log( 'record found that was probably not in the correct JSON format' +
                        ' (e.g. Firebug settings or corrupt record) (error: ' + e.message + '), record was ignored' );
                }
            }
        }

        return records;
    }

    /**
     * [getSurveyDataArr description]
     * @param  {boolean=} finalOnly   [description]
     * @param  {?string=} excludeName the (currently open) record name to exclude from the returned data set
     * @return {Array.<{name: string, data: string}>}             [description]
     */
    function getSurveyDataArr( finalOnly, excludeName ) {
        var i, records,
            dataArr = [];
        finalOnly = finalOnly || true;
        records = getSurveyRecords( finalOnly, excludeName );
        //console.debug('getSurveyDataArr will build array from these records: '+JSON.stringify(records));
        for ( i = 0; i < records.length; i++ ) {
            dataArr.push( {
                name: records[ i ].key,
                data: records[ i ][ 'data' ]
            } ); //[records[i].key, records[i].data]
        }
        //console.debug('returning data array: '+JSON.stringify(dataArr));
        return dataArr;
    }

    /**
     * [getSurveyDataOnlyArr description]
     * @param  {boolean=} finalOnly [description]
     * @return {?Array.<string>}           [description]
     */
    function getSurveyDataOnlyArr( finalOnly ) {
        var i,
            dataObjArr = getSurveyDataArr( finalOnly ),
            dataOnlyArr = [];
        for ( i = 0; i < dataObjArr.length; i++ ) {
            dataOnlyArr.push( dataObjArr[ i ].data );
        }
        return ( dataOnlyArr.length > 0 ) ? dataOnlyArr : null;
    }

    /**
     * private function to check if key is forbidden
     * @param  {string}  k [description]
     * @return {boolean}   [description]
     */

    function isReservedKey( k ) {
        var i;
        for ( i = 0; i < RESERVED_KEYS.length; i++ ) {
            if ( k === RESERVED_KEYS[ i ] ) {
                return true;
            }
        }
        return false;
    }

    /**
     * private function to check if the key exists
     * @param  {string}  k [description]
     * @return {boolean}   [description]
     */

    function isExistingKey( k ) {
        if ( localStorage.getItem( k ) ) {
            //console.log('existing key');// DEBUG
            return true;
        }
        //console.log('not existing key');// DEBUG
        return false;
    }

    /**
     * Obtain a new counter string value that is one higher than the previous
     * @return {?(string|String)} [description]
     */
    function getCounterValue() {
        var record = getRecord( '__counter' ),
            number = ( record && record[ 'counter' ] && isNumber( record[ 'counter' ] ) ) ? Number( record[ 'counter' ] ) : 0,
            numberStr = ( number + 1 ).toString().pad( 4 );

        return numberStr;
    }

    function isNumber( n ) {
        return !isNaN( parseFloat( n ) ) && isFinite( n );
    }

    return {
        isSupported: isSupported,
        isWritable: isWritable,
        getForbiddenKeys: getForbiddenKeys,
        getRecord: getRecord,
        setRecord: setRecord,
        removeRecord: removeRecord,
        getFormList: getFormList,
        getRecordList: getRecordList,
        getSurveyRecords: getSurveyRecords,
        getSurveyDataArr: getSurveyDataArr,
        getSurveyDataOnlyArr: getSurveyDataOnlyArr,
        getCounterValue: getCounterValue
    };
} );
<commit_msg>added draft property to local records<commit_after>/**
 * @preserve Copyright 2013 Martijn van de Rijdt
 *
 * 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.
 */

define( [ 'jquery', 'enketo-js/extend' ], function( $ ) {
    "use strict";

    var RESERVED_KEYS = [ '__settings', 'null', '__history', 'Firebug', 'undefined', '__bookmark', '__counter', '__current_server', '__loadLog', '__writetest', '__maxSize' ],
        localStorage = window.localStorage;

    // Could be replaced by Modernizr function if Modernizr remains used in final version
    function isSupported() {
        try {
            return 'localStorage' in window && window[ 'localStorage' ] !== null;
        } catch ( e ) {
            return false;
        }
    }

    function isWritable() {
        var result = setRecord( '__writetest', 'x', null, true );
        if ( result === 'success' ) {
            removeRecord( '__writetest' );
            return true;
        }
        return false;
    }

    //used for testing
    function getForbiddenKeys() {
        return RESERVED_KEYS;
    }

    /**
     * saves a data object in JSON format (string)
     * @param {string} newKey    [description]
     * @param {*} record     [description]
     * @param {boolean=} del [description] used to change name of existing record and delete old record
     * @param {boolean=} overwrite [description] overwrite is only used when there is *another* record with the same new name (not when simply updating current form)
     * @param {?string=} oldKey    [description]
     * @return {string}
     */
    function setRecord( newKey, record, del, overwrite, oldKey ) {
        var error;
        if ( !newKey || typeof newKey !== 'string' || newKey.length < 1 ) {
            //console.error( 'no key or empty key provided for record: ' + newKey );
            return 'require';
        }
        newKey = newKey.trim();
        oldKey = ( typeof oldKey === 'string' ) ? oldKey.trim() : null;
        overwrite = ( typeof overwrite !== 'undefined' && overwrite === true ) ? true : false;

        //using the knowledge that only survey data is provided as a "data" property (and is a string)
        if ( typeof record[ 'data' ] === 'string' && isReservedKey( newKey ) ) {
            return 'forbidden';
        }
        if ( typeof record[ 'data' ] === 'string' &&
            ( oldKey !== newKey && isExistingKey( newKey ) && overwrite !== true ) ||
            ( oldKey === newKey && overwrite !== true ) ) {
            return 'existing';
        }
        try {
            //add timestamp to survey data
            if ( typeof record[ 'data' ] === 'string' ) {
                record[ 'lastSaved' ] = ( new Date() ).getTime();
                //if (newKey == getCounterValue() ){
                localStorage.setItem( '__counter', JSON.stringify( {
                    'counter': getCounterValue()
                } ) );

                //}
            }
            localStorage.setItem( newKey, JSON.stringify( record ) );
            //console.debug( 'saved: ' + newKey + ', old key was: ' + oldKey );
            //if the record was loaded from the store (oldKey != null) and the key's value was changed during editing
            //delete the old record if del=true
            if ( oldKey !== null && oldKey !== '' && oldKey !== newKey ) {
                if ( del ) {
                    console.log( 'going to remove old record with key:' + oldKey );
                    removeRecord( oldKey );
                }
            }
            return 'success';
        } catch ( e ) {
            if ( e && e.code === 22 ) { //} (e.name==='QUOTA_EXCEEDED_ERR'){
                return 'full (or browser is set to not allow storage)';
            }
            console.log( 'error in store.setRecord:', e );
            error = ( e ) ? JSON.stringify( e ) : 'unknown';
            return 'error: ' + error;
        }
    }

    /**
     * Returns a form data record as an object. This is the only function that obtains records from the local storage.
     * @param  {string} key [description]
     * @return {?*}     [description]
     */
    function getRecord( key ) {
        var record;
        try {
            record = JSON.parse( localStorage.getItem( key ) );
            return record;
        } catch ( e ) {
            console.error( 'error with loading data from store: ' + e.message );
            return null;
        }
    }

    // removes a record
    function removeRecord( key ) {
        try {
            localStorage.removeItem( key );
            if ( !isReservedKey( key ) ) {
                //TODO remove this single jQuery dependency
                $( 'form.or' ).trigger( 'delete', JSON.stringify( getRecordList() ) );
            }
            return true;
        } catch ( e ) {
            console.log( 'error with removing data from store: ' + e.message );
            return false;
        }
    }

    /**
     * Returns a list of locally stored form names and properties for a provided server URL
     * @param  {string} serverURL
     * @return {Array.<{name: string, server: string, title: string, url: string}>}
     */
    function getFormList( serverURL ) {
        if ( typeof serverURL == 'undefined' ) {
            return null;
        }
        return /**@type {Array.<{name: string, server: string, title: string, url: string}>}*/ getRecord( '__server_' + serverURL );
    }

    /**
     * returns an ordered array of objects with record keys and final variables {{"key": "name1", "draft": true},{"key": "name2", etc.
     * @return { Array.<Object.<string, (boolean|string)>>} [description]
     */
    function getRecordList() {
        var formList = [],
            records = getSurveyRecords( false );

        records.forEach( function( record ) {
            formList.push( {
                'key': record.key,
                'draft': record.draft,
                'lastSaved': record.lastSaved
            } );
        } );
        console.debug( 'formList returning:', formList );

        //order formList by lastSaved timestamp
        formList.sort( function( a, b ) {
            return a[ 'lastSaved' ] - b[ 'lastSaved' ];
        } );
        return formList;
    }

    /**
     * retrieves all survey data
     * @param  {boolean=} finalOnly   [description]
     * @param  {?string=} excludeName [description]
     * @return {Array.<Object.<(string|number), (string|boolean)>>}             [description]
     */
    function getSurveyRecords( finalOnly, excludeName ) {
        var i, key,
            records = [],
            record = {};
        finalOnly = finalOnly || false;
        excludeName = excludeName || null;
        console.log( 'finalOnly:', finalOnly );
        for ( i = 0; i < localStorage.length; i++ ) {
            key = localStorage.key( i );
            //console.debug('found record with with key:'+key);
            record = getRecord( key );
            // get record - all non-reserved keys contain survey data
            if ( !isReservedKey( key ) ) {
                //console.debug('record with key: '+key+' is survey data');
                try {
                    /* although the key is also available as one of the record properties
                        this should not be relied upon and the actual storage key should be used */
                    record.key = key;
                    console.log( 'record:', record, key, excludeName, !finalOnly, !record.draft );
                    //=== true comparison breaks in Google Closure compiler.
                    if ( key !== excludeName && ( !finalOnly || !record.draft ) ) {
                        records.push( record );
                    }
                } catch ( e ) {
                    console.log( 'record found that was probably not in the expected JSON format' +
                        ' (e.g. Firebug settings or corrupt record) (error: ' + e.message + '), record was ignored' );
                }
            }
        }

        return records;
    }

    /**
     * [getSurveyDataArr description]
     * @param  {boolean=} finalOnly   [description]
     * @param  {?string=} excludeName the (currently open) record name to exclude from the returned data set
     * @return {Array.<{name: string, data: string}>}             [description]
     */
    function getSurveyDataArr( finalOnly, excludeName ) {
        var i, records,
            dataArr = [];
        console.log( 'finalOnly:', finalOnly );
        finalOnly = finalOnly || true;
        excludeName = excludeName || null;
        records = getSurveyRecords( finalOnly, excludeName );
        //console.debug('getSurveyDataArr will build array from these records: '+JSON.stringify(records));
        for ( i = 0; i < records.length; i++ ) {
            dataArr.push( {
                name: records[ i ].key,
                data: records[ i ].data
            } ); //[records[i].key, records[i].data]
        }
        //console.debug('returning data array: '+JSON.stringify(dataArr));
        return dataArr;
    }

    /**
     * [getSurveyDataOnlyArr description]
     * @param  {boolean=} finalOnly [description]
     * @return {?Array.<string>}           [description]
     */
    function getSurveyDataOnlyArr( finalOnly ) {
        var i,
            dataObjArr = getSurveyDataArr( finalOnly ),
            dataOnlyArr = [];
        for ( i = 0; i < dataObjArr.length; i++ ) {
            dataOnlyArr.push( dataObjArr[ i ].data );
        }
        return ( dataOnlyArr.length > 0 ) ? dataOnlyArr : null;
    }

    /**
     * private function to check if key is forbidden
     * @param  {string}  k [description]
     * @return {boolean}   [description]
     */

    function isReservedKey( k ) {
        var i;
        for ( i = 0; i < RESERVED_KEYS.length; i++ ) {
            if ( k === RESERVED_KEYS[ i ] ) {
                return true;
            }
        }
        return false;
    }

    /**
     * private function to check if the key exists
     * @param  {string}  k [description]
     * @return {boolean}   [description]
     */

    function isExistingKey( k ) {
        if ( localStorage.getItem( k ) ) {
            //console.log('existing key');// DEBUG
            return true;
        }
        //console.log('not existing key');// DEBUG
        return false;
    }

    /**
     * Obtain a new counter string value that is one higher than the previous
     * @return {?(string|String)} [description]
     */
    function getCounterValue() {
        var record = getRecord( '__counter' ),
            number = ( record && record[ 'counter' ] && isNumber( record[ 'counter' ] ) ) ? Number( record[ 'counter' ] ) : 0,
            numberStr = ( number + 1 ).toString().pad( 4 );

        return numberStr;
    }

    function isNumber( n ) {
        return !isNaN( parseFloat( n ) ) && isFinite( n );
    }

    return {
        isSupported: isSupported,
        isWritable: isWritable,
        getForbiddenKeys: getForbiddenKeys,
        getRecord: getRecord,
        setRecord: setRecord,
        removeRecord: removeRecord,
        getFormList: getFormList,
        getRecordList: getRecordList,
        getSurveyRecords: getSurveyRecords,
        getSurveyDataArr: getSurveyDataArr,
        getSurveyDataOnlyArr: getSurveyDataOnlyArr,
        getCounterValue: getCounterValue
    };
} );
<|endoftext|>


<commit_before>/*
 *  awa-blogs -- Blogs and post
 *  Copyright (C) 2016, 2017 Stephane Carrez
 *  Written by Stephane Carrez (Stephane.Carrez@gmail.com)
 *
 *  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($, undefined) {
    $.widget("ui.blog_comment_list", $.ui.list, {
        currentNode: null,
        editInput: null,

        _create: function() {
            var self = this;

            $.ui.list.prototype._create.apply(this, arguments);
            if (self.options.selectAction === null) {
                self.options.selectAction = function(node, event) {
                    return self.selectAction(node, event);
                }
            }
        },
        getSelectedId: function(node) {
            while (node) {
                if ($(node).hasClass("awa-comment")) {
                    var id = $(node).attr('id');
                    return id == null ? null : id.substring(this.options.itemPrefix.length);
                }
                node = node.parentNode;
            }
            return null;
        },
        doPublish: function(node) {
            var id = this.getSelectedId(this.activeItem);

            return ASF.Post(this.activeItem, this.options.statusUrl, "id=" + id + "&status=COMMENT_PUBLISHED");
        },

        doSpam: function(node) {
            var id = this.getSelectedId(this.activeItem);

            return ASF.Post(this.activeItem, this.options.statusUrl, "id=" + id + "&status=COMMENT_SPAM");
        },

        doWait: function(node) {
            var id = this.getSelectedId(this.activeItem);

            return ASF.Post(this.activeItem, this.options.statusUrl, "id=" + id + "&status=COMMENT_WAITING");
        },

        editTask: function(node) {
            var list = this,
                id   = this.getSelectedId(this.activeItem),
                url  = this.options.editTaskUrl + "?id=" + id;

            ASF.Popup(node, 'vdo-edit-popup', url, {
                triggerHandler: function triggerHandler(action, node) {
                                    if (action == "open") {
                                        list.setMouseOver(false);
                                    } else {
                                        list.setMouseOver(true);
                                    }
                                },
                attachment: node
            });
            return false;
        },

        /**
         * Select the list item identified by <tt>node</tt> as the current selected item.
         *
         * @param node the list item to select
         */
        selectAction: function(node, event) {
            if ($(node).hasClass("comment-action-publish")) {
                return this.doPublish(node);
            } else if ($(node).hasClass("comment-action-spam")) {
                return this.doSpam(node);
            } else if ($(node).hasClass("comment-action-waiting")) {
                return this.doWait(node);
            } else if ($(node).hasClass("vdo-pause-task")) {
                return this.pauseTask(node);
            } else {
                var t = event.target;

                if ($(t).hasClass("time-day")) {
                    return this.editTime($(t));
                } else {
                    return this._super("selectAction", node);
                }
            }
        }
    });
    $.widget("ui.post_graph", {
        options: {
            url: "",
            barWidth: 1
        },
        _create: function() {
            var self = this;

            self.refresh();
        },
        plot: function(series) {
            var self = this;
            $.plot(this.element, series, {
                bars: { show: true, barWidth: self.options.barWidth * 86400 * 1000, align: "center" },
                xaxis: {
                    mode: "time",
                    minTickSize: [1, "day"]
                },
                yaxis: {
                    tickDecimals: 0
                },
                grid: {
                    hoverable: true
                }
            });
        },
        refresh: function() {
            var self = this;

            jQuery.ajax({
                url:  self.options.url,
                type: "GET",
                dataType: "json",
                success: function(data, status, jqXHDR) {
                    var i;

                    data = data.data;
                    data.pop();
                    if (data.length > 1) {
                       for (i = 0; i < data.length; i++) {
                          data[i][0] = new Date(data[i][0]).getTime();
                       }
                       self.plot([data]);
                    }
                }
            });
        }
    });

})(jQuery);

<commit_msg>Add action to delete a comment<commit_after>/*
 *  awa-blogs -- Blogs and post
 *  Copyright (C) 2016, 2017 Stephane Carrez
 *  Written by Stephane Carrez (Stephane.Carrez@gmail.com)
 *
 *  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($, undefined) {
    $.widget("ui.blog_comment_list", $.ui.list, {
        currentNode: null,
        editInput: null,

        _create: function() {
            var self = this;

            $.ui.list.prototype._create.apply(this, arguments);
            if (self.options.selectAction === null) {
                self.options.selectAction = function(node, event) {
                    return self.selectAction(node, event);
                }
            }
        },
        getSelectedId: function(node) {
            while (node) {
                if ($(node).hasClass("awa-comment")) {
                    var id = $(node).attr('id');
                    return id == null ? null : id.substring(this.options.itemPrefix.length);
                }
                node = node.parentNode;
            }
            return null;
        },
        doPublish: function(node) {
            var id = this.getSelectedId(this.activeItem);

            return ASF.Post(this.activeItem, this.options.statusUrl, "id=" + id + "&status=COMMENT_PUBLISHED");
        },

        doSpam: function(node) {
            var id = this.getSelectedId(this.activeItem);

            return ASF.Post(this.activeItem, this.options.statusUrl, "id=" + id + "&status=COMMENT_SPAM");
        },

        doWait: function(node) {
            var id = this.getSelectedId(this.activeItem);

            return ASF.Post(this.activeItem, this.options.statusUrl, "id=" + id + "&status=COMMENT_WAITING");
        },

        editTask: function(node) {
            var list = this,
                id   = this.getSelectedId(this.activeItem),
                url  = this.options.editTaskUrl + "?id=" + id;

            ASF.Popup(node, 'vdo-edit-popup', url, {
                triggerHandler: function triggerHandler(action, node) {
                                    if (action == "open") {
                                        list.setMouseOver(false);
                                    } else {
                                        list.setMouseOver(true);
                                    }
                                },
                attachment: node
            });
            return false;
        },

        /**
         * Select the list item identified by <tt>node</tt> as the current selected item.
         *
         * @param node the list item to select
         */
        selectAction: function(node, event) {
            if ($(node).hasClass("comment-action-publish")) {
                return this.doPublish(node);
            } else if ($(node).hasClass("comment-action-spam")) {
                return this.doSpam(node);
            } else if ($(node).hasClass("comment-action-waiting")) {
                return this.doWait(node);
            } else if ($(node).hasClass("comment-action-delete")) {
                return this.enterDelete(node);
            } else {
                var t = event.target;

                if ($(t).hasClass("time-day")) {
                    return this.editTime($(t));
                } else {
                    return this._super("selectAction", node);
                }
            }
        }
    });
    $.widget("ui.post_graph", {
        options: {
            url: "",
            barWidth: 1
        },
        _create: function() {
            var self = this;

            self.refresh();
        },
        plot: function(series) {
            var self = this;
            $.plot(this.element, series, {
                bars: { show: true, barWidth: self.options.barWidth * 86400 * 1000, align: "center" },
                xaxis: {
                    mode: "time",
                    minTickSize: [1, "day"]
                },
                yaxis: {
                    tickDecimals: 0
                },
                grid: {
                    hoverable: true
                }
            });
        },
        refresh: function() {
            var self = this;

            jQuery.ajax({
                url:  self.options.url,
                type: "GET",
                dataType: "json",
                success: function(data, status, jqXHDR) {
                    var i;

                    data = data.data;
                    data.pop();
                    if (data.length > 1) {
                       for (i = 0; i < data.length; i++) {
                          data[i][0] = new Date(data[i][0]).getTime();
                       }
                       self.plot([data]);
                    }
                }
            });
        }
    });

})(jQuery);

<|endoftext|>


<commit_before>// helper functions defined in helpers.js
var data = generateData(10);
var columns = getColumns(data);

describe("sensei-grid dom events", function () {

    var grid;
    var $el = $('
');

    // create dom element before each test
    beforeEach(function () {

        // suppress console.log statements from src files
        console.log = function () {};

        // create wrapper element
        $("body").append($el);

        // render grid
        grid = $el.grid(data, columns);
        grid.registerEditor(BasicEditor);
        grid.render();

    });

    // remove grid wrapper after each test
    afterEach(function () {
        grid.destroy();
        grid = null;
    });

    describe("click", function () {
        it("should set active cell", function () {
            var $cell = $(".sensei-grid>table>tbody>tr:first>td:eq(3)");
            $cell.trigger("click");
            expect($cell.hasClass("activeCell")).toBe(true);

            var $cell2 = $(".sensei-grid>table>tbody>tr:eq(4)>td:eq(1)");
            $cell2.trigger("click");
            expect($cell2.hasClass("activeCell")).toBe(true);
        });
        it("should only activate one cell", function () {
            var $cell = $(".sensei-grid>table>tbody>tr:first>td:eq(3)");
            $cell.trigger("click");
            expect($(".sensei-grid .activeCell").length).toBe(1);

            var $cell2 = $(".sensei-grid>table>tbody>tr:eq(4)>td:eq(1)");
            $cell2.trigger("click");
            expect($(".sensei-grid .activeCell").length).toBe(1);
        });
        it("outside of grid should remove active cell", function () {
            var $cell = $(".sensei-grid>table>tbody>tr:first>td:eq(3)");
            $cell.trigger("click");

            expect($(".sensei-grid .activeCell").length).toBe(1);

            $(document).trigger("click");
            expect($(".sensei-grid .activeCell").length).toBe(0);
        });
        it("outside of grid should close editor", function () {
            var $cell = $(".sensei-grid>table>tbody>tr:first>td:eq(3)");
            $cell.trigger("dblclick");
            expect($(".sensei-grid-editor").is(":visible")).toBe(true);
            expect($(".sensei-grid-editor").length).toBe(1);

            $(document).trigger("click");
            expect($(".sensei-grid .activeCell").length).toBe(0);
            expect($(".sensei-grid-editor").is(":visible")).toBe(false);
        });
    });
    describe("dblclick", function () {
        it("should open editor", function () {
            var $cell = $(".sensei-grid>table>tbody>tr:first>td:eq(3)");
            $cell.trigger("dblclick");
            expect($(".sensei-grid-editor").is(":visible")).toBe(true);
            expect($(".sensei-grid-editor").length).toBe(1);
        });
    });
    describe("cell shortcuts", function () {
        it("right arrow should move active cell", function () {
            var $cell = $(".sensei-grid>table>tbody>tr:first>td:eq(0)");
            $cell.trigger("click");
            expect($cell.hasClass("activeCell")).toBe(true);

            var e = $.Event("keydown");
            e.which = 39; // right

            // start position

            $(".sensei-grid>table").trigger(e);
            expect($cell.hasClass("activeCell")).toBe(false);
            expect($cell.next().hasClass("activeCell")).toBe(true);

            // end position

            $cell = $(".sensei-grid>table>tbody>tr:eq(9)>td:eq(4)");
            $cell.trigger("click");
            $(".sensei-grid>table").trigger(e);
            expect($cell.hasClass("activeCell")).toBe(true);
        });
        it("left arrow should move active cell", function () {
            var $cell = $(".sensei-grid>table>tbody>tr:first>td:eq(4)");
            $cell.trigger("click");
            expect($cell.hasClass("activeCell")).toBe(true);

            var e = $.Event("keydown");
            e.which = 37; // left

            // end position

            $(".sensei-grid>table").trigger(e);
            $cell = $(".sensei-grid>table>tbody>tr:eq(0)>td:eq(3)");
            expect($cell.hasClass("activeCell")).toBe(true);

            // start position

            $cell = $(".sensei-grid>table>tbody>tr:eq(0)>td:eq(0)");
            $cell.trigger("click");
            $(".sensei-grid>table").trigger(e);
            expect($cell.hasClass("activeCell")).toBe(true);
        });
        it("up arrow should move active cell", function () {
            var $cell = $(".sensei-grid>table>tbody>tr:eq(0)>td:eq(0)");
            $cell.trigger("click");
            expect($cell.hasClass("activeCell")).toBe(true);

            var e = $.Event("keydown");
            e.which = 38; // up

            // movement at start position

            $(".sensei-grid>table").trigger(e);
            $cell = $(".sensei-grid>table>tbody>tr:eq(0)>td:eq(0)");
            expect($cell.hasClass("activeCell")).toBe(true);

            // movement at end position

            $cell = $(".sensei-grid>table>tbody>tr:eq(1)>td:eq(0)");
            $cell.trigger("click");
            $(".sensei-grid>table").trigger(e);
            $cell = $(".sensei-grid>table>tbody>tr:eq(0)>td:eq(0)");
            expect($cell.hasClass("activeCell")).toBe(true);
        });
        it("down arrow should move active cell", function () {
            var $cell = $(".sensei-grid>table>tbody>tr:first>td:eq(0)");
            $cell.trigger("click");
            expect($cell.hasClass("activeCell")).toBe(true);

            var e = $.Event("keydown");
            e.which = 40; // down

            // movement at start position

            $(".sensei-grid>table").trigger(e);
            $cell = $(".sensei-grid>table>tbody>tr:eq(1)>td:eq(0)");
            expect($cell.hasClass("activeCell")).toBe(true);

            // movement at end position

            $cell = $(".sensei-grid>table>tbody>tr:eq(9)>td:eq(0)");
            $cell.trigger("click");
            $(".sensei-grid>table").trigger(e);
            expect($cell.hasClass("activeCell")).toBe(true);
        });
        it("backspace key should clear value of cell", function () {
            var $cell = $(".sensei-grid>table>tbody>tr:eq(1)>td:eq(0)");
            // activate cell
            $cell.trigger("click");
            expect($cell.hasClass("activeCell")).toBe(true);

            var e = $.Event("keydown");
            e.which = 27; // esc
            $(".sensei-grid").trigger(e);

            expect($cell.hasClass("activeCell")).toBe(false);
        });
    });
    describe("editor shortcuts", function () {
        it("tab key should move editor forward", function () {
            var $cell = $(".sensei-grid>table>tbody>tr:first>td:eq(0)");
            // open editor
            $cell.trigger("dblclick");
            expect($(".sensei-grid-editor").is(":visible")).toBe(true);
            expect($(".sensei-grid-editor:visible input").val()).toEqual($cell.text());

            var e = $.Event("keydown");
            e.which = 9; // tab
            $(".sensei-grid").trigger(e);

            expect($(".sensei-grid-editor:visible input").val()).toEqual($cell.next().text());
        });
        it("shift+tab key should move editor backward", function () {
            var $cell = $(".sensei-grid>table>tbody>tr:first>td:eq(1)");
            // open editor
            $cell.trigger("dblclick");
            expect($(".sensei-grid-editor").is(":visible")).toBe(true);
            expect($(".sensei-grid-editor:visible input").val()).toEqual($cell.text());

            var e = $.Event("keydown");
            e.which = 9; // tab
            e.shiftKey = true;
            $(".sensei-grid").trigger(e);

            expect($(".sensei-grid-editor:visible input").val()).toEqual($cell.prev().text());
        });
        it("enter key should save and close editor", function () {
            var $cell = $(".sensei-grid>table>tbody>tr:first>td:eq(1)");
            // open editor
            $cell.trigger("dblclick");
            expect($(".sensei-grid-editor").is(":visible")).toBe(true);
            expect($(".sensei-grid-editor:visible input").val()).toEqual($cell.text());

            var testVal = "i like simple grids and i cannot lie";
            $(".sensei-grid-editor input").val(testVal);

            var e = $.Event("keydown");
            e.which = 13; // enter
            $(".sensei-grid").trigger(e);

            expect($cell.text()).toEqual(testVal);
            expect($(".sensei-grid-editor").is(":visible")).toBe(false);
        });
        it("ctrl+enter key should move editor down", function () {
            var $cell = $(".sensei-grid>table>tbody>tr:first>td:eq(0)");
            // open editor
            $cell.trigger("dblclick");
            expect($(".sensei-grid-editor").is(":visible")).toBe(true);
            expect($(".sensei-grid-editor:visible input").val()).toEqual($cell.text());

            var e = $.Event("keydown");
            e.which = 13; // enter
            e.ctrlKey = true;
            $(".sensei-grid").trigger(e);

            $cell = $(".sensei-grid>table>tbody>tr:eq(1)>td:eq(0)");
            expect($(".sensei-grid-editor:visible input").val()).toEqual($cell.text());
        });
        it("shift+ctrl+enter key should move editor up", function () {
            var $cell = $(".sensei-grid>table>tbody>tr:eq(1)>td:eq(0)");
            // open editor
            $cell.trigger("dblclick");
            expect($(".sensei-grid-editor").is(":visible")).toBe(true);
            expect($(".sensei-grid-editor:visible input").val()).toEqual($cell.text());

            var e = $.Event("keydown");
            e.which = 13; // enter
            e.ctrlKey = true;
            e.shiftKey = true;
            $(".sensei-grid").trigger(e);

            $cell = $(".sensei-grid>table>tbody>tr:eq(0)>td:eq(0)");
            expect($(".sensei-grid-editor:visible input").val()).toEqual($cell.text());
        });
        it("esc key should close editor", function () {
            var $cell = $(".sensei-grid>table>tbody>tr:eq(1)>td:eq(0)");
            // open editor
            $cell.trigger("dblclick");
            expect($(".sensei-grid-editor").is(":visible")).toBe(true);
            expect($(".sensei-grid-editor:visible input").val()).toEqual($cell.text());

            var e = $.Event("keydown");
            e.which = 27; // esc
            $(".sensei-grid").trigger(e);

            expect($(".sensei-grid-editor").is(":visible")).toBe(false);
        });
    });
});<commit_msg>Fix backspace shortcut test.<commit_after>// helper functions defined in helpers.js
var data = generateData(10);
var columns = getColumns(data);

describe("sensei-grid dom events", function () {

    var grid;
    var $el = $('
');

    // create dom element before each test
    beforeEach(function () {

        // suppress console.log statements from src files
        console.log = function () {};

        // create wrapper element
        $("body").append($el);

        // render grid
        grid = $el.grid(data, columns);
        grid.registerEditor(BasicEditor);
        grid.render();

    });

    // remove grid wrapper after each test
    afterEach(function () {
        grid.destroy();
        grid = null;
    });

    describe("click", function () {
        it("should set active cell", function () {
            var $cell = $(".sensei-grid>table>tbody>tr:first>td:eq(3)");
            $cell.trigger("click");
            expect($cell.hasClass("activeCell")).toBe(true);

            var $cell2 = $(".sensei-grid>table>tbody>tr:eq(4)>td:eq(1)");
            $cell2.trigger("click");
            expect($cell2.hasClass("activeCell")).toBe(true);
        });
        it("should only activate one cell", function () {
            var $cell = $(".sensei-grid>table>tbody>tr:first>td:eq(3)");
            $cell.trigger("click");
            expect($(".sensei-grid .activeCell").length).toBe(1);

            var $cell2 = $(".sensei-grid>table>tbody>tr:eq(4)>td:eq(1)");
            $cell2.trigger("click");
            expect($(".sensei-grid .activeCell").length).toBe(1);
        });
        it("outside of grid should remove active cell", function () {
            var $cell = $(".sensei-grid>table>tbody>tr:first>td:eq(3)");
            $cell.trigger("click");

            expect($(".sensei-grid .activeCell").length).toBe(1);

            $(document).trigger("click");
            expect($(".sensei-grid .activeCell").length).toBe(0);
        });
        it("outside of grid should close editor", function () {
            var $cell = $(".sensei-grid>table>tbody>tr:first>td:eq(3)");
            $cell.trigger("dblclick");
            expect($(".sensei-grid-editor").is(":visible")).toBe(true);
            expect($(".sensei-grid-editor").length).toBe(1);

            $(document).trigger("click");
            expect($(".sensei-grid .activeCell").length).toBe(0);
            expect($(".sensei-grid-editor").is(":visible")).toBe(false);
        });
    });
    describe("dblclick", function () {
        it("should open editor", function () {
            var $cell = $(".sensei-grid>table>tbody>tr:first>td:eq(3)");
            $cell.trigger("dblclick");
            expect($(".sensei-grid-editor").is(":visible")).toBe(true);
            expect($(".sensei-grid-editor").length).toBe(1);
        });
    });
    describe("cell shortcuts", function () {
        it("right arrow should move active cell", function () {
            var $cell = $(".sensei-grid>table>tbody>tr:first>td:eq(0)");
            $cell.trigger("click");
            expect($cell.hasClass("activeCell")).toBe(true);

            var e = $.Event("keydown");
            e.which = 39; // right

            // start position

            $(".sensei-grid>table").trigger(e);
            expect($cell.hasClass("activeCell")).toBe(false);
            expect($cell.next().hasClass("activeCell")).toBe(true);

            // end position

            $cell = $(".sensei-grid>table>tbody>tr:eq(9)>td:eq(4)");
            $cell.trigger("click");
            $(".sensei-grid>table").trigger(e);
            expect($cell.hasClass("activeCell")).toBe(true);
        });
        it("left arrow should move active cell", function () {
            var $cell = $(".sensei-grid>table>tbody>tr:first>td:eq(4)");
            $cell.trigger("click");
            expect($cell.hasClass("activeCell")).toBe(true);

            var e = $.Event("keydown");
            e.which = 37; // left

            // end position

            $(".sensei-grid>table").trigger(e);
            $cell = $(".sensei-grid>table>tbody>tr:eq(0)>td:eq(3)");
            expect($cell.hasClass("activeCell")).toBe(true);

            // start position

            $cell = $(".sensei-grid>table>tbody>tr:eq(0)>td:eq(0)");
            $cell.trigger("click");
            $(".sensei-grid>table").trigger(e);
            expect($cell.hasClass("activeCell")).toBe(true);
        });
        it("up arrow should move active cell", function () {
            var $cell = $(".sensei-grid>table>tbody>tr:eq(0)>td:eq(0)");
            $cell.trigger("click");
            expect($cell.hasClass("activeCell")).toBe(true);

            var e = $.Event("keydown");
            e.which = 38; // up

            // movement at start position

            $(".sensei-grid>table").trigger(e);
            $cell = $(".sensei-grid>table>tbody>tr:eq(0)>td:eq(0)");
            expect($cell.hasClass("activeCell")).toBe(true);

            // movement at end position

            $cell = $(".sensei-grid>table>tbody>tr:eq(1)>td:eq(0)");
            $cell.trigger("click");
            $(".sensei-grid>table").trigger(e);
            $cell = $(".sensei-grid>table>tbody>tr:eq(0)>td:eq(0)");
            expect($cell.hasClass("activeCell")).toBe(true);
        });
        it("down arrow should move active cell", function () {
            var $cell = $(".sensei-grid>table>tbody>tr:first>td:eq(0)");
            $cell.trigger("click");
            expect($cell.hasClass("activeCell")).toBe(true);

            var e = $.Event("keydown");
            e.which = 40; // down

            // movement at start position

            $(".sensei-grid>table").trigger(e);
            $cell = $(".sensei-grid>table>tbody>tr:eq(1)>td:eq(0)");
            expect($cell.hasClass("activeCell")).toBe(true);

            // movement at end position

            $cell = $(".sensei-grid>table>tbody>tr:eq(9)>td:eq(0)");
            $cell.trigger("click");
            $(".sensei-grid>table").trigger(e);
            expect($cell.hasClass("activeCell")).toBe(true);
        });
        it("backspace key should clear value of cell", function () {
            var $cell = $(".sensei-grid>table>tbody>tr:eq(1)>td:eq(0)");
            // activate cell
            $cell.trigger("click");
            expect($cell.hasClass("activeCell")).toBe(true);

            var e = $.Event("keydown");
            e.which = 8; // backspace
            $(".sensei-grid").trigger(e);

            expect($cell.text()).toEqual("");
        });
    });
    describe("editor shortcuts", function () {
        it("tab key should move editor forward", function () {
            var $cell = $(".sensei-grid>table>tbody>tr:first>td:eq(0)");
            // open editor
            $cell.trigger("dblclick");
            expect($(".sensei-grid-editor").is(":visible")).toBe(true);
            expect($(".sensei-grid-editor:visible input").val()).toEqual($cell.text());

            var e = $.Event("keydown");
            e.which = 9; // tab
            $(".sensei-grid").trigger(e);

            expect($(".sensei-grid-editor:visible input").val()).toEqual($cell.next().text());
        });
        it("shift+tab key should move editor backward", function () {
            var $cell = $(".sensei-grid>table>tbody>tr:first>td:eq(1)");
            // open editor
            $cell.trigger("dblclick");
            expect($(".sensei-grid-editor").is(":visible")).toBe(true);
            expect($(".sensei-grid-editor:visible input").val()).toEqual($cell.text());

            var e = $.Event("keydown");
            e.which = 9; // tab
            e.shiftKey = true;
            $(".sensei-grid").trigger(e);

            expect($(".sensei-grid-editor:visible input").val()).toEqual($cell.prev().text());
        });
        it("enter key should save and close editor", function () {
            var $cell = $(".sensei-grid>table>tbody>tr:first>td:eq(1)");
            // open editor
            $cell.trigger("dblclick");
            expect($(".sensei-grid-editor").is(":visible")).toBe(true);
            expect($(".sensei-grid-editor:visible input").val()).toEqual($cell.text());

            var testVal = "i like simple grids and i cannot lie";
            $(".sensei-grid-editor input").val(testVal);

            var e = $.Event("keydown");
            e.which = 13; // enter
            $(".sensei-grid").trigger(e);

            expect($cell.text()).toEqual(testVal);
            expect($(".sensei-grid-editor").is(":visible")).toBe(false);
        });
        it("ctrl+enter key should move editor down", function () {
            var $cell = $(".sensei-grid>table>tbody>tr:first>td:eq(0)");
            // open editor
            $cell.trigger("dblclick");
            expect($(".sensei-grid-editor").is(":visible")).toBe(true);
            expect($(".sensei-grid-editor:visible input").val()).toEqual($cell.text());

            var e = $.Event("keydown");
            e.which = 13; // enter
            e.ctrlKey = true;
            $(".sensei-grid").trigger(e);

            $cell = $(".sensei-grid>table>tbody>tr:eq(1)>td:eq(0)");
            expect($(".sensei-grid-editor:visible input").val()).toEqual($cell.text());
        });
        it("shift+ctrl+enter key should move editor up", function () {
            var $cell = $(".sensei-grid>table>tbody>tr:eq(1)>td:eq(0)");
            // open editor
            $cell.trigger("dblclick");
            expect($(".sensei-grid-editor").is(":visible")).toBe(true);
            expect($(".sensei-grid-editor:visible input").val()).toEqual($cell.text());

            var e = $.Event("keydown");
            e.which = 13; // enter
            e.ctrlKey = true;
            e.shiftKey = true;
            $(".sensei-grid").trigger(e);

            $cell = $(".sensei-grid>table>tbody>tr:eq(0)>td:eq(0)");
            expect($(".sensei-grid-editor:visible input").val()).toEqual($cell.text());
        });
        it("esc key should close editor", function () {
            var $cell = $(".sensei-grid>table>tbody>tr:eq(1)>td:eq(0)");
            // open editor
            $cell.trigger("dblclick");
            expect($(".sensei-grid-editor").is(":visible")).toBe(true);
            expect($(".sensei-grid-editor:visible input").val()).toEqual($cell.text());

            var e = $.Event("keydown");
            e.which = 27; // esc
            $(".sensei-grid").trigger(e);

            expect($(".sensei-grid-editor").is(":visible")).toBe(false);
        });
    });
});<|endoftext|>