<commit_before> /*
 * testcalendar.js - test the calendar support per locale
 *
 * Copyright © 2019-2020, JEDLSoft
 *
 * 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.
 */

if (typeof(LocaleInfo) === "undefined") {
    var LocaleInfo = require("../../lib/LocaleInfo.js");
}

module.exports.testcalendar = {
    testDefaultCalendar_GregorianCaseAll: function(test) {
        test.expect(193);
        var localeList = ["ar-AE","ar-BH","ar-DJ","ar-DZ","ar-EG","ar-IQ","ar-JO","ar-KW","ar-LB","ar-LY","ar-MA","ar-MR",
        "ar-OM","ar-QA","ar-SA","ar-SD","ar-SY","ar-TN","ar-YE","as-IN","az-Latn-AZ","bg-BG","bn-IN","bs-Latn-BA,bs-Latn-ME",
        "cs-CZ","da-DK","de-AT","de-CH","de-DE","de-LU","et-EE","el-CY","el-GR","en-AM","en-AU","en-AZ","en-CA","en-GB","en-GH",
        "en-GM","en-HK","en-IE","en-IN","en-IS","en-JP","en-KE","en-KR","en-LK","en-LR","en-MM","en-MW","en-MY","en-NG","en-NZ",
        "en-PH","en-PK","en-PR","en-RW","en-SD","en-SG","en-SL","en-TW","en-TZ","en-UG","en-US","en-ZA","en-ZM","es-AR","es-BO",
        "es-CL","es-CO","es-CR","es-DO","es-EC","es-ES","es-GQ","es-GT","es-HN","es-MX","es-NI","es-PA","es-PE","es-PH","es-PR",
        "es-PY","es-SV","es-US","es-UY","es-VE","fi-FI","fr-BE","fr-BF","fr-BJ","fr-CA","fr-CD","fr-CF","fr-CG","fr-CH","fr-CI",
        "fr-CM","fr-GQ","fr-DJ","fr-DZ","fr-FR","fr-GA","fr-GN","fr-LB","fr-LU","fr-ML","fr-RW","fr-SN","fr-TG","ga-IE","gu-IN",
        "he-IL","hi-IN","hi-SG","hr-HR","hr-ME","hu-HU","id-ID","is-IS","it-CH","it-IT","ja-JP","ka-GE", "kk-Cyrl-KZ","km-KH","kn-IN",
        "ko-KR","ku-Arab-IQ","lt-LT","lv-LV","mk-MK","ml-IN","mn-Cyrl-MN","mr-IN","ms-MY","ms-SG","nb-NO","nl-BE","nl-NL","pa-IN",
        "pa-PK","pl-PL","pt-AO","pt-BR","pt-GQ","pt-CV","pt-PT","ro-RO","ru-BY","ru-GE","ru-KG","ru-KZ","ru-RU","ru-UA","si-LK",
        "sk-SK","sl-SI","sq-AL","sq-ME","sr-Latn-ME","sr-Latn-RS","sv-FI","sv-SE","sw-KE","ta-IN","ta-SG","te-IN","tr-AM","tr-AZ",
        "tr-CY","tr-TR","uk-UA","ur-IN","ur-PK","uz-Cyrl-UZ","uz-Latn-UZ","vi-VN","zh-Hans-CN","zh-Hans-SG","zh-Hant-HK",
        "zh-Hans-MY","zh-Hant-TW","af-ZA","ha-Latn-NG","or-IN","en-GE","en-CN","en-MX","en-TW","es-CA"];

        //console.log("localeList.length: ", localeList.length);
        for (var i=0; i < localeList.length;i++) {
            var info = new LocaleInfo(localeList[i]);
            test.equal(info.getCalendar(), "gregorian");
        }
        test.done();
    },
    testDefaultCalendar_fa_IR: function(test) {
        test.expect(2);
        var info = new LocaleInfo("fa-IR");
        test.ok(info !== null);
        test.equal(info.getCalendar(), "persian");

        test.done();
    },
    testDefaultCalendar_fa_AF: function(test) {
        test.expect(2);
        var info = new LocaleInfo("fa-AF");
        test.ok(info !== null);
        test.equal(info.getCalendar(), "persian");

        test.done();
    },
    testDefaultCalendar_en_ET: function(test) {
        test.expect(2);
        var info = new LocaleInfo("en-ET");
        test.ok(info !== null);
        test.equal(info.getCalendar(), "ethiopic");

        test.done();
    },
    testDefaultCalendar_am_ET: function(test) {
        test.expect(2);
        var info = new LocaleInfo("am-ET");
        test.ok(info !== null);
        test.equal(info.getCalendar(), "ethiopic");

        test.done();
    },
    testDefaultCalendar_th_TH: function(test) {
        test.expect(2);
        var info = new LocaleInfo("th-TH");
        test.ok(info !== null);
        test.equal(info.getCalendar(), "thaisolar");

        test.done();
    }
}
<commit_msg>Removed space<commit_after> /*
 * testcalendar.js - test the calendar support per locale
 *
 * Copyright © 2019-2020, JEDLSoft
 *
 * 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.
 */

if (typeof(LocaleInfo) === "undefined") {
    var LocaleInfo = require("../../lib/LocaleInfo.js");
}

module.exports.testcalendar = {
    testDefaultCalendar_GregorianCaseAll: function(test) {
        test.expect(193);
        var localeList = ["ar-AE","ar-BH","ar-DJ","ar-DZ","ar-EG","ar-IQ","ar-JO","ar-KW","ar-LB","ar-LY","ar-MA","ar-MR",
        "ar-OM","ar-QA","ar-SA","ar-SD","ar-SY","ar-TN","ar-YE","as-IN","az-Latn-AZ","bg-BG","bn-IN","bs-Latn-BA,bs-Latn-ME",
        "cs-CZ","da-DK","de-AT","de-CH","de-DE","de-LU","et-EE","el-CY","el-GR","en-AM","en-AU","en-AZ","en-CA","en-GB","en-GH",
        "en-GM","en-HK","en-IE","en-IN","en-IS","en-JP","en-KE","en-KR","en-LK","en-LR","en-MM","en-MW","en-MY","en-NG","en-NZ",
        "en-PH","en-PK","en-PR","en-RW","en-SD","en-SG","en-SL","en-TW","en-TZ","en-UG","en-US","en-ZA","en-ZM","es-AR","es-BO",
        "es-CL","es-CO","es-CR","es-DO","es-EC","es-ES","es-GQ","es-GT","es-HN","es-MX","es-NI","es-PA","es-PE","es-PH","es-PR",
        "es-PY","es-SV","es-US","es-UY","es-VE","fi-FI","fr-BE","fr-BF","fr-BJ","fr-CA","fr-CD","fr-CF","fr-CG","fr-CH","fr-CI",
        "fr-CM","fr-GQ","fr-DJ","fr-DZ","fr-FR","fr-GA","fr-GN","fr-LB","fr-LU","fr-ML","fr-RW","fr-SN","fr-TG","ga-IE","gu-IN",
        "he-IL","hi-IN","hi-SG","hr-HR","hr-ME","hu-HU","id-ID","is-IS","it-CH","it-IT","ja-JP","ka-GE","kk-Cyrl-KZ","km-KH","kn-IN",
        "ko-KR","ku-Arab-IQ","lt-LT","lv-LV","mk-MK","ml-IN","mn-Cyrl-MN","mr-IN","ms-MY","ms-SG","nb-NO","nl-BE","nl-NL","pa-IN",
        "pa-PK","pl-PL","pt-AO","pt-BR","pt-GQ","pt-CV","pt-PT","ro-RO","ru-BY","ru-GE","ru-KG","ru-KZ","ru-RU","ru-UA","si-LK",
        "sk-SK","sl-SI","sq-AL","sq-ME","sr-Latn-ME","sr-Latn-RS","sv-FI","sv-SE","sw-KE","ta-IN","ta-SG","te-IN","tr-AM","tr-AZ",
        "tr-CY","tr-TR","uk-UA","ur-IN","ur-PK","uz-Cyrl-UZ","uz-Latn-UZ","vi-VN","zh-Hans-CN","zh-Hans-SG","zh-Hant-HK",
        "zh-Hans-MY","zh-Hant-TW","af-ZA","ha-Latn-NG","or-IN","en-GE","en-CN","en-MX","en-TW","es-CA"];

        //console.log("localeList.length: ", localeList.length);
        for (var i=0; i < localeList.length;i++) {
            var info = new LocaleInfo(localeList[i]);
            test.equal(info.getCalendar(), "gregorian");
        }
        test.done();
    },
    testDefaultCalendar_fa_IR: function(test) {
        test.expect(2);
        var info = new LocaleInfo("fa-IR");
        test.ok(info !== null);
        test.equal(info.getCalendar(), "persian");

        test.done();
    },
    testDefaultCalendar_fa_AF: function(test) {
        test.expect(2);
        var info = new LocaleInfo("fa-AF");
        test.ok(info !== null);
        test.equal(info.getCalendar(), "persian");

        test.done();
    },
    testDefaultCalendar_en_ET: function(test) {
        test.expect(2);
        var info = new LocaleInfo("en-ET");
        test.ok(info !== null);
        test.equal(info.getCalendar(), "ethiopic");

        test.done();
    },
    testDefaultCalendar_am_ET: function(test) {
        test.expect(2);
        var info = new LocaleInfo("am-ET");
        test.ok(info !== null);
        test.equal(info.getCalendar(), "ethiopic");

        test.done();
    },
    testDefaultCalendar_th_TH: function(test) {
        test.expect(2);
        var info = new LocaleInfo("th-TH");
        test.ok(info !== null);
        test.equal(info.getCalendar(), "thaisolar");

        test.done();
    }
}
<|endoftext|>


<commit_before>//>>excludeStart("jqmBuildExclude", pragmas.jqmBuildExclude);
//>>description: Animated page change base constructor and logic
//>>label: Transition Core
//>>group: Transitions
//>>css.structure: ../css/structure/jquery.mobile.transition.css
//>>css.theme: ../css/themes/default/jquery.mobile.theme.css

define( [ "jquery",
		  "../jquery.mobile.core",

		  // TODO event.special.scrollstart
		  "../events/touch",

		  // TODO $.mobile.focusPage reference
		  "../jquery.mobile.navigation" ], function( jQuery ) {
//>>excludeEnd("jqmBuildExclude");

(function( $, window, undefined ) {

	// TODO remove direct references to $.mobile and properties, we should
	//      favor injection with params to the constructor
	$.mobile.Transition = function() {
		this.init.apply(this, arguments);
	};

	$.extend($.mobile.Transition.prototype, {
		toPreClass: " ui-page-pre-in",

		init: function( name, reverse, $to, $from ) {
			$.extend(this, {
				name: name,
				reverse: reverse,
				$to: $to,
				$from: $from,
				deferred: new $.Deferred()
			});
		},

		cleanFrom: function() {
			this.$from
				.removeClass( $.mobile.activePageClass + " out in reverse " + this.name )
				.height( "" );
		},

		// NOTE overridden by child object prototypes, noop'd here as defaults
		beforeDoneIn: function() {},
		beforeDoneOut: function() {},
		beforeStartOut: function() {},

		doneIn: function() {
			this.beforeDoneIn();

			this.$to.removeClass( "out in reverse " + this.name ).height( "" );

			this.toggleViewportClass();

			// In some browsers (iOS5), 3D transitions block the ability to scroll to the desired location during transition
			// This ensures we jump to that spot after the fact, if we aren't there already.
			if ( $.mobile.window.scrollTop() !== this.toScroll ) {
				this.scrollPage();
			}

			this.deferred.resolve( this.name, this.reverse, this.$to, this.$from, true );
		},

		doneOut: function( screenHeight, reverseClass, none ) {
			this.beforeDoneOut();
			this.startIn( screenHeight, reverseClass, none );
		},

		hideIn: function( callback ) {
			// Prevent flickering in phonegap container: see comments at #4024 regarding iOS
			this.$to.css( "z-index", -10 );
			callback.call(this);
			this.$to.css( "z-index", "" );
		},

		scrollPage: function() {
			// By using scrollTo instead of silentScroll, we can keep things better in order
			// Just to be precautios, disable scrollstart listening like silentScroll would
			$.event.special.scrollstart.enabled = false;

			if( $.mobile.hideUrlBar ) {
				window.scrollTo( 0, this.toScroll );
			}

			// reenable scrollstart listening like silentScroll would
			setTimeout( function() {
				$.event.special.scrollstart.enabled = true;
			}, 150 );
		},

		startIn: function( screenHeight, reverseClass, none ) {
			this.hideIn(function() {
				this.$to.addClass( $.mobile.activePageClass + this.toPreClass );

				// Send focus to page as it is now display: block
				$.mobile.focusPage( this.$to );

				// Set to page height
				this.$to.height( screenHeight + this.toScroll );

                if ( !none ) {
                    this.scrollPage();
                }
			});

			if ( !none ) {
				this.$to.animationComplete( $.proxy(function() {
					this.doneIn();
				}, this));
			}

			this.$to
				.removeClass( this.toPreClass )
				.addClass( this.name + " in " + reverseClass );

			if ( none ) {
				this.doneIn();
			}

		},

		startOut: function( screenHeight, reverseClass, none ) {
			this.beforeStartOut( screenHeight, reverseClass, none );

			// Set the from page's height and start it transitioning out
			// Note: setting an explicit height helps eliminate tiling in the transitions
			this.$from
				.height( screenHeight + $.mobile.window.scrollTop() )
				.addClass( this.name + " out" + reverseClass );
		},

		toggleViewportClass: function() {
			$.mobile.pageContainer.toggleClass( "ui-mobile-viewport-transitioning viewport-" + this.name );
		},

		transition: function() {
			// NOTE many of these could be calculated/recorded in the constructor, it's my
			//      opinion that binding them as late as possible has value with regards to
			//      better transitions with fewer bugs. Ie, it's not guaranteed that the
			//      object will be created and transition will be run immediately after as
			//      it is today. So we wait until transition is invoked to gather the following
			var reverseClass = this.reverse ? " reverse" : "",
				screenHeight = $.mobile.getScreenHeight(),
				maxTransitionOverride = $.mobile.maxTransitionWidth !== false && $.mobile.window.width() > $.mobile.maxTransitionWidth,
				none = !$.support.cssTransitions || maxTransitionOverride || !this.name || this.name === "none" || Math.max( $.mobile.window.scrollTop(), this.toScroll ) > $.mobile.getMaxScrollForTransition();

			this.toScroll = $.mobile.urlHistory.getActive().lastScroll || $.mobile.defaultHomeScroll;
			this.toggleViewportClass();

			if ( this.$from && !none ) {
				this.startOut( screenHeight, reverseClass, none );
			} else {
				this.doneOut( screenHeight, reverseClass, none );
			}

			return this.deferred.promise();
		}
	});
})( jQuery, this );
//>>excludeStart("jqmBuildExclude", pragmas.jqmBuildExclude);
});
//>>excludeEnd("jqmBuildExclude");
<commit_msg>Transitions: check to see if there is a stored scroll position when url bar hiding is disabled<commit_after>//>>excludeStart("jqmBuildExclude", pragmas.jqmBuildExclude);
//>>description: Animated page change base constructor and logic
//>>label: Transition Core
//>>group: Transitions
//>>css.structure: ../css/structure/jquery.mobile.transition.css
//>>css.theme: ../css/themes/default/jquery.mobile.theme.css

define( [ "jquery",
		  "../jquery.mobile.core",

		  // TODO event.special.scrollstart
		  "../events/touch",

		  // TODO $.mobile.focusPage reference
		  "../jquery.mobile.navigation" ], function( jQuery ) {
//>>excludeEnd("jqmBuildExclude");

(function( $, window, undefined ) {

	// TODO remove direct references to $.mobile and properties, we should
	//      favor injection with params to the constructor
	$.mobile.Transition = function() {
		this.init.apply(this, arguments);
	};

	$.extend($.mobile.Transition.prototype, {
		toPreClass: " ui-page-pre-in",

		init: function( name, reverse, $to, $from ) {
			$.extend(this, {
				name: name,
				reverse: reverse,
				$to: $to,
				$from: $from,
				deferred: new $.Deferred()
			});
		},

		cleanFrom: function() {
			this.$from
				.removeClass( $.mobile.activePageClass + " out in reverse " + this.name )
				.height( "" );
		},

		// NOTE overridden by child object prototypes, noop'd here as defaults
		beforeDoneIn: function() {},
		beforeDoneOut: function() {},
		beforeStartOut: function() {},

		doneIn: function() {
			this.beforeDoneIn();

			this.$to.removeClass( "out in reverse " + this.name ).height( "" );

			this.toggleViewportClass();

			// In some browsers (iOS5), 3D transitions block the ability to scroll to the desired location during transition
			// This ensures we jump to that spot after the fact, if we aren't there already.
			if ( $.mobile.window.scrollTop() !== this.toScroll ) {
				this.scrollPage();
			}

			this.deferred.resolve( this.name, this.reverse, this.$to, this.$from, true );
		},

		doneOut: function( screenHeight, reverseClass, none ) {
			this.beforeDoneOut();
			this.startIn( screenHeight, reverseClass, none );
		},

		hideIn: function( callback ) {
			// Prevent flickering in phonegap container: see comments at #4024 regarding iOS
			this.$to.css( "z-index", -10 );
			callback.call(this);
			this.$to.css( "z-index", "" );
		},

		scrollPage: function() {
			// By using scrollTo instead of silentScroll, we can keep things better in order
			// Just to be precautios, disable scrollstart listening like silentScroll would
			$.event.special.scrollstart.enabled = false;
			if( $.mobile.hideUrlBar || this.toScroll !== $.mobile.defaultHomeScroll ) {
				window.scrollTo( 0, this.toScroll );
			}

			// reenable scrollstart listening like silentScroll would
			setTimeout( function() {
				$.event.special.scrollstart.enabled = true;
			}, 150 );
		},

		startIn: function( screenHeight, reverseClass, none ) {
			this.hideIn(function() {
				this.$to.addClass( $.mobile.activePageClass + this.toPreClass );

				// Send focus to page as it is now display: block
				$.mobile.focusPage( this.$to );

				// Set to page height
				this.$to.height( screenHeight + this.toScroll );

                if ( !none ) {
                    this.scrollPage();
                }
			});

			if ( !none ) {
				this.$to.animationComplete( $.proxy(function() {
					this.doneIn();
				}, this));
			}

			this.$to
				.removeClass( this.toPreClass )
				.addClass( this.name + " in " + reverseClass );

			if ( none ) {
				this.doneIn();
			}

		},

		startOut: function( screenHeight, reverseClass, none ) {
			this.beforeStartOut( screenHeight, reverseClass, none );

			// Set the from page's height and start it transitioning out
			// Note: setting an explicit height helps eliminate tiling in the transitions
			this.$from
				.height( screenHeight + $.mobile.window.scrollTop() )
				.addClass( this.name + " out" + reverseClass );
		},

		toggleViewportClass: function() {
			$.mobile.pageContainer.toggleClass( "ui-mobile-viewport-transitioning viewport-" + this.name );
		},

		transition: function() {
			// NOTE many of these could be calculated/recorded in the constructor, it's my
			//      opinion that binding them as late as possible has value with regards to
			//      better transitions with fewer bugs. Ie, it's not guaranteed that the
			//      object will be created and transition will be run immediately after as
			//      it is today. So we wait until transition is invoked to gather the following
			var reverseClass = this.reverse ? " reverse" : "",
				screenHeight = $.mobile.getScreenHeight(),
				maxTransitionOverride = $.mobile.maxTransitionWidth !== false && $.mobile.window.width() > $.mobile.maxTransitionWidth,
				none = !$.support.cssTransitions || maxTransitionOverride || !this.name || this.name === "none" || Math.max( $.mobile.window.scrollTop(), this.toScroll ) > $.mobile.getMaxScrollForTransition();

			this.toScroll = $.mobile.urlHistory.getActive().lastScroll || $.mobile.defaultHomeScroll;
			this.toggleViewportClass();

			if ( this.$from && !none ) {
				this.startOut( screenHeight, reverseClass, none );
			} else {
				this.doneOut( screenHeight, reverseClass, none );
			}

			return this.deferred.promise();
		}
	});
})( jQuery, this );
//>>excludeStart("jqmBuildExclude", pragmas.jqmBuildExclude);
});
//>>excludeEnd("jqmBuildExclude");
<|endoftext|>


<commit_before>/*global FormData XMLHttpRequest*/
import ko from "knockout";

import api from "../api";
import makeSource from "../typeaheadsource";
import store from "../store";
import Document from "./document";

export default class TranscriptMigration {
  constructor() {
    this.selectedLectures = [];
    this.selectedExaminants = [];
    this.similar = [];
    this.date = '';
    this.doctype = 'oral';
    this.name = "(Migration)";
    this.file = null;
    this.status = undefined; /* undefined | 'success' | 'error' | 'waiting' */
    this.errorlabel = '';
    this.submissionEnabled = true;
    this.proxyCnt = 0;
    this.dateFieldHasFocus = true;
    ko.track(this);

    ko.getObservable(this, 'selectedLectures').subscribe(this.getSimilar.bind(this));
    ko.getObservable(this, 'selectedExaminants').subscribe(this.getSimilar.bind(this));
    ko.getObservable(this, 'date').subscribe(this.getSimilar.bind(this));
  }

  getFullDate() {
    if (this.date.length == 4)
      return this.date + '-01-01';
    if (this.date.length == 7)
      return this.date + '-01';
    return this.date;
  }

  getSimilar() {
    let job = {
      department: 'mathematics',
      student_name: "",
      date: this.getFullDate(),
      document_type: this.doctype,
      lectures: this.selectedLectures,
      examinants: this.selectedExaminants,
    };
    api.post('similar', job).done(data => {
      if (data.data !== undefined)
        this.similar = data.data.map(e => new Document(e));
    });
  }

  typeaheadDataset(type) {
    return {
      source: makeSource(store[type].map(e => e.name)),
      templates: {
        suggestion: l => `<a href="#" onclick="return false;">${l}</a>`,
      },
    };
  }

  submit() {
    /* input validation */
    if (this.selectedLectures.length === 0) {
      this.status = 'error';
      this.errorlabel = "Bitte gib die in der Prüfung geprüften Vorlesungen an.";
      return;
    }
    if (this.selectedExaminants.length === 0) {
      this.status = 'error';
      this.errorlabel = "Bitte gib die in der Prüfung anwesenden PrüferInnen an.";
      return;
    }
    // even though we set the input field to only accept pdfs, Chrome allows any file to be selected
    if (!this.file || !this.file.name.toLowerCase().endsWith('.pdf')) {
      this.status = 'error';
      this.errorlabel = "Bitte gib eine Pdf-Datei zum Hochladen an.";
      return;
    }
    if (new Date() < Date.parse(this.getFullDate())) {
      this.status = 'error';
      // ERROR: HACKING TOO MUCH TIME
      this.errorlabel = "Bitte verletze nicht die Kausalität.";
      return;
    }

    let fd = new FormData();
    fd.append('json', JSON.stringify({
      lectures: this.selectedLectures,
      examinants: this.selectedExaminants,
      date: this.getFullDate(),
      document_type: this.doctype,
      student_name: '(Migration)',
      department: 'mathematics',
    }));
    fd.append('file', this.file);
    let req = new XMLHttpRequest();
    req.withCredentials = true;
    req.open('POST', api.baseUrl + 'documents_migration');
    req.onerror = (e) => {
      this.status = 'error';
      this.errorlabel = e;
      this.submissionEnabled = true;
    };
    req.onreadystatechange = () => {
      if (req.readyState === 4) {
        switch (req.status) {
          case 200:
            this.status = 'success';
            this.errorlabel = '';
            this.submissionEnabled = true;
            // Clear inputs. Note: The file input field cannot be cleared since we can obviously not write its value.
            this.selectedLectures = [];
            this.selectedExaminants = [];
            this.similar = [];
            this.date = '';
            this.doctype = 'oral';
            this.dateFieldHasFocus = true;
            break;
          case 400:
            req.onerror("Ungültige Eingabe. Bitte überprüfe noch einmal alle Felder.");
            break;
          default:
            req.onerror(req.requestText);
        }
      }
    };
    this.status = 'waiting';
    this.errorlabel = '';
    this.submissionEnabled = false;
    req.send(fd);
  }
}
<commit_msg>Add X-CSRF-Header to document submission requests<commit_after>/*global FormData XMLHttpRequest*/
import ko from "knockout";

import api from "../api";
import makeSource from "../typeaheadsource";
import store from "../store";
import Document from "./document";

export default class TranscriptMigration {
  constructor() {
    this.selectedLectures = [];
    this.selectedExaminants = [];
    this.similar = [];
    this.date = '';
    this.doctype = 'oral';
    this.name = "(Migration)";
    this.file = null;
    this.status = undefined; /* undefined | 'success' | 'error' | 'waiting' */
    this.errorlabel = '';
    this.submissionEnabled = true;
    this.proxyCnt = 0;
    this.dateFieldHasFocus = true;
    ko.track(this);

    ko.getObservable(this, 'selectedLectures').subscribe(this.getSimilar.bind(this));
    ko.getObservable(this, 'selectedExaminants').subscribe(this.getSimilar.bind(this));
    ko.getObservable(this, 'date').subscribe(this.getSimilar.bind(this));
  }

  getFullDate() {
    if (this.date.length == 4)
      return this.date + '-01-01';
    if (this.date.length == 7)
      return this.date + '-01';
    return this.date;
  }

  getSimilar() {
    let job = {
      department: 'mathematics',
      student_name: "",
      date: this.getFullDate(),
      document_type: this.doctype,
      lectures: this.selectedLectures,
      examinants: this.selectedExaminants,
    };
    api.post('similar', job).done(data => {
      if (data.data !== undefined)
        this.similar = data.data.map(e => new Document(e));
    });
  }

  typeaheadDataset(type) {
    return {
      source: makeSource(store[type].map(e => e.name)),
      templates: {
        suggestion: l => `<a href="#" onclick="return false;">${l}</a>`,
      },
    };
  }

  submit() {
    /* input validation */
    if (this.selectedLectures.length === 0) {
      this.status = 'error';
      this.errorlabel = "Bitte gib die in der Prüfung geprüften Vorlesungen an.";
      return;
    }
    if (this.selectedExaminants.length === 0) {
      this.status = 'error';
      this.errorlabel = "Bitte gib die in der Prüfung anwesenden PrüferInnen an.";
      return;
    }
    // even though we set the input field to only accept pdfs, Chrome allows any file to be selected
    if (!this.file || !this.file.name.toLowerCase().endsWith('.pdf')) {
      this.status = 'error';
      this.errorlabel = "Bitte gib eine Pdf-Datei zum Hochladen an.";
      return;
    }
    if (new Date() < Date.parse(this.getFullDate())) {
      this.status = 'error';
      // ERROR: HACKING TOO MUCH TIME
      this.errorlabel = "Bitte verletze nicht die Kausalität.";
      return;
    }

    let fd = new FormData();
    fd.append('json', JSON.stringify({
      lectures: this.selectedLectures,
      examinants: this.selectedExaminants,
      date: this.getFullDate(),
      document_type: this.doctype,
      student_name: '(Migration)',
      department: 'mathematics',
    }));
    fd.append('file', this.file);
    let req = new XMLHttpRequest();
    req.withCredentials = true;
    req.setRequestHeader('X-CSRF', api.token);
    req.open('POST', api.baseUrl + 'documents_migration');
    req.onerror = (e) => {
      this.status = 'error';
      this.errorlabel = e;
      this.submissionEnabled = true;
    };
    req.onreadystatechange = () => {
      if (req.readyState === 4) {
        switch (req.status) {
          case 200:
            this.status = 'success';
            this.errorlabel = '';
            this.submissionEnabled = true;
            // Clear inputs. Note: The file input field cannot be cleared since we can obviously not write its value.
            this.selectedLectures = [];
            this.selectedExaminants = [];
            this.similar = [];
            this.date = '';
            this.doctype = 'oral';
            this.dateFieldHasFocus = true;
            break;
          case 400:
            req.onerror("Ungültige Eingabe. Bitte überprüfe noch einmal alle Felder.");
            break;
          default:
            req.onerror(req.requestText);
        }
      }
    };
    this.status = 'waiting';
    this.errorlabel = '';
    this.submissionEnabled = false;
    req.send(fd);
  }
}
<|endoftext|>


<commit_before>/**
 * eslint rule that ensures every require()'d and imported package is declared
 * in package.json. It is based on import/no-extraneous-dependencies, but has
 * been extended to understand `symlinkDependencies`.
 */

const path = require('path');
const readPkgUp = require('read-pkg-up');
const minimatch = require('minimatch');

const importType = require('eslint-plugin-import/lib/core/importType').default;
const isStaticRequire = require('eslint-plugin-import/lib/core/staticRequire').default;

function getPackageContent(filename) {
  try {
    return readPkgUp.sync({cwd: filename, normalize: false}).pkg;
  } catch (e) {
    return null;
  }
}

const globalPkg = getPackageContent(path.join(__dirname, '../../'));

function getDependencies(packageContent) {
  return {
    dependencies: packageContent.dependencies || {},
    devDependencies: packageContent.devDependencies || {},
    optionalDependencies: packageContent.optionalDependencies || {},
    peerDependencies: packageContent.peerDependencies || {},
    symlinkDependencies: packageContent.symlinkDependencies || {},
  };
}

function findPackageInDependencies(packageName, packageContent) {
  const deps = getDependencies(packageContent);
  return [
    'dependencies',
    'devDependencies',
    'optionalDependencies',
    'peerDependencies',
    'symlinkDependencies',
  ].filter((depsName) => packageName in deps[depsName])[0];
}

function reportIfMissing(context, pkg, depsOptions, node, name) {
  if (importType(name, context) !== 'external') {
    return;
  }
  const splitName = name.split('/');
  const packageName = splitName[0][0] === '@'
    ? splitName.slice(0, 2).join('/')
    : splitName[0];
  const isSelf = packageName === pkg.name;

  const inWhichDeps = findPackageInDependencies(packageName, pkg);
  const deps = getDependencies(pkg);
  const isInDeps = deps.dependencies[packageName] !== undefined;
  const isInDevDeps = deps.devDependencies[packageName] !== undefined;
  const isInOptDeps = deps.optionalDependencies[packageName] !== undefined;
  const isInPeerDeps = deps.peerDependencies[packageName] !== undefined;
  const isInSymlinkDeps = deps.symlinkDependencies[packageName] !== undefined;

  if (isInDeps ||
    (depsOptions.allowSelf && isSelf) ||
    (depsOptions.allowDevDeps && inWhichDeps === 'devDependencies') ||
    (depsOptions.allowPeerDeps && inWhichDeps === 'peerDependencies') ||
    (depsOptions.allowSymlinkDeps && inWhichDeps === 'symlinkDependencies') ||
    (depsOptions.allowOptDeps && inWhichDeps === 'optionalDependencies')
  ) {
    return;
  }

  let destination = 'dependencies';
  if (globalPkg) {
    destination = findPackageInDependencies(packageName, globalPkg) || destination;
  }

  if (inWhichDeps === 'devDependencies' && !depsOptions.allowDevDeps) {
    context.report({
      node,
      message:
        `'${packageName}' should be listed in the project's ${destination}, ` +
        `not devDependencies.`,
    });
    return;
  }

  if (inWhichDeps === 'optionalDependencies' && !depsOptions.allowOptDeps) {
    context.report({
      node,
      message:
        `'${packageName}' should be listed in the project's ${destination}, ` +
        `not optionalDependencies.`,
    });
    return;
  }

  if (inWhichDeps === 'symlinkDependencies' && !depsOptions.allowSymlinkDeps) {
    context.report({
      node,
      message:
        `'${packageName}' should be listed in the project's ${destination}, ` +
        `not symlinkDependencies.`,
    });
    return;
  }

  context.report({
    node,
    message:
      `'${packageName}' should be listed in the project's ${destination}.`,
  });
}

function testConfig(config, filename) {
  // Simplest configuration first, either a boolean or nothing.
  if (typeof config === 'boolean' || typeof config === 'undefined') {
    return config;
  }
  // Array of globs.
  return config.some(c => (
    minimatch(filename, c) ||
    minimatch(filename, path.join(process.cwd(), c))
  ));
}

module.exports = {
  meta: {
    docs: {},

    schema: [
      {
        'type': 'object',
        'properties': {
          'allowSelf': { 'type': 'boolean' },
          'devDependencies': { 'type': ['boolean', 'array'] },
          'optionalDependencies': { 'type': ['boolean', 'array'] },
          'peerDependencies': { 'type': ['boolean', 'array'] },
          'symlinkDependencies': { 'type': ['boolean', 'array'] },
        },
        'additionalProperties': false,
      },
    ],
  },

  create(context) {
    const options = context.options[0] || {};
    const filename = context.getFilename();
    const pkg = getPackageContent(filename);

    if (!pkg) {
      return {};
    }

    const depsOptions = {
      allowSelf: !!options.allowSelf,
      allowDevDeps: testConfig(options.devDependencies, filename) !== false,
      allowOptDeps: testConfig(options.optionalDependencies, filename) !== false,
      allowPeerDeps: testConfig(options.peerDependencies, filename) !== false,
      allowSymlinkDeps: testConfig(options.symlinkDependencies, filename) !== false,
    };

    // todo: use module visitor from module-utils core
    return {
      ImportDeclaration: function (node) {
        reportIfMissing(context, pkg, depsOptions, node, node.source.value);
      },
      CallExpression: function handleRequires(node) {
        if (isStaticRequire(node)) {
          reportIfMissing(context, pkg, depsOptions, node, node.arguments[0].value);
        }
      },
    };
  },
};
<commit_msg>eslint-plugin-silk: add --fix support to no-extraneous-dependencies based on global package.json<commit_after>/**
 * eslint rule that ensures every require()'d and imported package is declared
 * in package.json. It is based on import/no-extraneous-dependencies, but has
 * been extended to understand `symlinkDependencies`.
 */

const fs = require('fs');
const path = require('path');
const readPkgUp = require('read-pkg-up');
const minimatch = require('minimatch');

const importType = require('eslint-plugin-import/lib/core/importType').default;
const isStaticRequire = require('eslint-plugin-import/lib/core/staticRequire').default;

function getPkg(cwd) {
  try {
    return readPkgUp.sync({cwd, normalize: false});
  } catch (e) {
    return null;
  }
}

const globalPkg = getPkg(path.join(__dirname, '../../'));

function getDependencies(packageContent) {
  return {
    dependencies: packageContent.dependencies || {},
    devDependencies: packageContent.devDependencies || {},
    optionalDependencies: packageContent.optionalDependencies || {},
    peerDependencies: packageContent.peerDependencies || {},
    symlinkDependencies: packageContent.symlinkDependencies || {},
  };
}

function findPackageInDependencies(packageName, packageContent) {
  const deps = getDependencies(packageContent);
  return [
    'dependencies',
    'devDependencies',
    'optionalDependencies',
    'peerDependencies',
    'symlinkDependencies',
  ].filter((depsName) => packageName in deps[depsName])[0];
}

function reportIfMissing(context, pkg, depsOptions, node, name) {
  if (importType(name, context) !== 'external') {
    return;
  }
  const splitName = name.split('/');
  const packageName = splitName[0][0] === '@'
    ? splitName.slice(0, 2).join('/')
    : splitName[0];
  const isSelf = packageName === pkg.pkg.name;

  const inWhichDeps = findPackageInDependencies(packageName, pkg.pkg);
  const deps = getDependencies(pkg.pkg);
  const isInDeps = deps.dependencies[packageName] !== undefined;
  const isInDevDeps = deps.devDependencies[packageName] !== undefined;
  const isInOptDeps = deps.optionalDependencies[packageName] !== undefined;
  const isInPeerDeps = deps.peerDependencies[packageName] !== undefined;
  const isInSymlinkDeps = deps.symlinkDependencies[packageName] !== undefined;

  if (isInDeps ||
    (depsOptions.allowSelf && isSelf) ||
    (depsOptions.allowDevDeps && inWhichDeps === 'devDependencies') ||
    (depsOptions.allowPeerDeps && inWhichDeps === 'peerDependencies') ||
    (depsOptions.allowSymlinkDeps && inWhichDeps === 'symlinkDependencies') ||
    (depsOptions.allowOptDeps && inWhichDeps === 'optionalDependencies')
  ) {
    return;
  }

  let destination = 'dependencies';
  if (globalPkg) {
    destination = findPackageInDependencies(packageName, globalPkg.pkg) || destination;
  }

  if (inWhichDeps === 'devDependencies' && !depsOptions.allowDevDeps) {
    context.report({
      node,
      message:
        `'${packageName}' should be listed in the project's ${destination}, ` +
        `not devDependencies.`,
    });
    return;
  }

  if (inWhichDeps === 'optionalDependencies' && !depsOptions.allowOptDeps) {
    context.report({
      node,
      message:
        `'${packageName}' should be listed in the project's ${destination}, ` +
        `not optionalDependencies.`,
    });
    return;
  }

  if (inWhichDeps === 'symlinkDependencies' && !depsOptions.allowSymlinkDeps) {
    context.report({
      node,
      message:
        `'${packageName}' should be listed in the project's ${destination}, ` +
        `not symlinkDependencies.`,
    });
    return;
  }

  // HACK: eslint fix() functions are *always* called, regardless of whether
  // `--fix` is enabled or not, and they express a fix in terms of AST changes
  // (which eslint then choses to apply or not based on `--fix`.) Our fixes
  // here don't work that way, however, so skip the whole error reporting flow
  // if we can fix the problem.
  if (process.argv.indexOf('--fix') !== -1 && globalPkg) {
    const globalDeps = getDependencies(globalPkg.pkg);
    if (packageName in globalDeps[destination]) {
      const version = globalDeps[destination][packageName];
      const dest = pkg.pkg[destination] || {};
      dest[packageName] = version;
      pkg.pkg[destination] = dest;
      fs.writeFileSync(pkg.path, JSON.stringify(pkg.pkg, null, 2));
      return;
    }
  }

  context.report({
    node,
    message:
      `'${packageName}' should be listed in the project's ${destination}.`,
  });
}

function testConfig(config, filename) {
  // Simplest configuration first, either a boolean or nothing.
  if (typeof config === 'boolean' || typeof config === 'undefined') {
    return config;
  }
  // Array of globs.
  return config.some(c => (
    minimatch(filename, c) ||
    minimatch(filename, path.join(process.cwd(), c))
  ));
}

module.exports = {
  meta: {
    docs: {},

    schema: [
      {
        'type': 'object',
        'properties': {
          'allowSelf': { 'type': 'boolean' },
          'devDependencies': { 'type': ['boolean', 'array'] },
          'optionalDependencies': { 'type': ['boolean', 'array'] },
          'peerDependencies': { 'type': ['boolean', 'array'] },
          'symlinkDependencies': { 'type': ['boolean', 'array'] },
        },
        'additionalProperties': false,
      },
    ],
  },

  create(context) {
    const options = context.options[0] || {};
    const filename = context.getFilename();
    const pkg = getPkg(filename);

    if (!pkg) {
      return {};
    }

    const depsOptions = {
      allowSelf: !!options.allowSelf,
      allowDevDeps: testConfig(options.devDependencies, filename) !== false,
      allowOptDeps: testConfig(options.optionalDependencies, filename) !== false,
      allowPeerDeps: testConfig(options.peerDependencies, filename) !== false,
      allowSymlinkDeps: testConfig(options.symlinkDependencies, filename) !== false,
    };

    // todo: use module visitor from module-utils core
    return {
      ImportDeclaration: function (node) {
        reportIfMissing(context, pkg, depsOptions, node, node.source.value);
      },
      CallExpression: function handleRequires(node) {
        if (isStaticRequire(node)) {
          reportIfMissing(context, pkg, depsOptions, node, node.arguments[0].value);
        }
      },
    };
  },
};
<|endoftext|>


<commit_before>'use strict';

module.exports = function appVariables(app, config){

    return function $isAuthenticated(req, res, next){
        console.log('Is authenticated');
        if(req.isAuthenticated()) next();
        else {
            req.session.returnTo = req.path;
            //TODO: we need to get this from config...
            res.redirect('/login');
        }
    };
};
<commit_msg>example: remove cruft<commit_after>'use strict';

module.exports = function appVariables(app, config){

    return function $isAuthenticated(req, res, next){

        if(req.isAuthenticated()) next();
        else {
            req.session.returnTo = req.path;
            //TODO: we need to get this from config...
            res.redirect('/login');
        }
    };
};
<|endoftext|>


<commit_before>const mapLimit = require('map-limit')
const isStream = require('is-stream')
const eos = require('end-of-stream')
const through = require('through2')
const falafel = require('falafel')
const resolve = require('resolve')
const assert = require('assert')
const mkdirp = require('mkdirp')
const xtend = require('xtend')
const path = require('path')
const fs = require('fs')

const sheetify = require('./index')

module.exports = transform

// inline sheetify transform for browserify
// 1. walk AST
// 2. replace sheetify references with prefix id's
// 3. aggregate all transform calls
// 3. asynchronously either replace sheetify calls
//    with CSS injection or extract CSS to callback
// 4. flush transform
// obj -> (str, opts) -> str
function transform (filename, opts) {
  const bufs = []
  const nodes = []
  var mname = null

  opts.basedir = opts.basedir || process.cwd()
  opts = xtend(opts)

  // argv parsing
  if (opts.o) opts.out = opts.o
  if (opts.out) {
    if (typeof opts.out === 'string') opts.out = path.resolve(opts.out)
    else assert.ok(isStream(opts.out), 'opts.out must be a path or a stream')
  }

  const transformStream = through(write, end)
  return transformStream

  // aggregate all AST nodes
  // (buf, str, fn) -> null
  function write (buf, enc, next) {
    bufs.push(buf)
    next()
  }

  // parse and push AST nodes
  // null -> null
  function end () {
    const self = this
    const src = Buffer.concat(bufs).toString('utf8')
    const ast = falafel(src, { ecmaVersion: 6 }, walk)

    // transform all detected nodes and
    // close stream when done
    mapLimit(nodes, Infinity, iterate, function (err) {
      if (err) return self.emit('error', err)
      self.push(ast.toString())
      self.push(null)
    })

    // find sheetify call
    // - read from file, read from inline or resolve npm package
    // - detect if should be prefixed or not
    function iterate (args, done) {
      const transformFn = args[0]
      const node = args[1]
      transformFn(function (err, css, prefix) {
        if (err) return done(err)
        if (opts.out) {
          // exorcise to external file
          if (typeof opts.out === 'string') {
            const dirname = path.dirname(opts.out)
            mkdirp(dirname, function (err) {
              if (err) return done(err)
              const ws = fs.createWriteStream(opts.out)
              eos(ws, done)
              node.update('0')
              ws.end(css)
            })
          } else {
            // exorcise to stream
            const ws = opts.out
            eos(ws, done)
            node.update('0')
            ws.write(css)
            done()
          }
        } else {
          // inject CSS inline
          const str = [
            "((require('insert-css')(" + JSON.stringify(css) + ')',
            ' || true) && ' + JSON.stringify(prefix) + ')'
          ].join('')
          node.update(str)
          done()
        }
      })
    }
  }

  // transform an AST node
  // obj -> null
  function walk (node) {
    // transform require calls
    if (node.type === 'CallExpression' &&
    node.callee && node.callee.name === 'require' &&
    node.arguments.length === 1 &&
    node.arguments[0].value === 'sheetify') {
      node.update('0')
      mname = node.parent.id.name
      return
    }

    // transform template strings
    // modify node value to prefix, and push css for transform
    if (node.type === 'TemplateLiteral' &&
    node.parent && node.parent.tag &&
    node.parent.tag.name === mname) {
      const tmplCss = [ node.quasis.map(cooked) ]
        .concat(node.expressions.map(expr)).join('').trim()

      sheetify(tmplCss, filename, opts, function (tf) {
        nodes.push([ tf, node.parent ])
      })

      return
    }

    // transform call references into files read from disk
    // modify value node to prefix, and push css for transform
    if (node.type === 'CallExpression' &&
    node.callee && node.callee.type === 'Identifier' &&
    node.callee.name === mname) {
      // determine path
      // - check if module import
      // - don't prefix by default if module import
      // - check if local file
      const resolvePath = cssResolve(node.arguments[0].value, opts.basedir)
      const fnp = resolvePath ||
        path.join(path.dirname(filename), node.arguments[0].value)
      if (resolvePath) opts.global = true
      else transformStream.emit('file', fnp)
      const fnCss = fs.readFileSync(fnp, 'utf8').trim()

      // read optional arguments passed in to node
      // e.g. { global: false }
      if (node.arguments[1] && node.arguments[1].properties) {
        const props = node.arguments[1].properties
        props.forEach(function (prop) {
          opts[prop.key.name] = prop.value.value
        })
      }

      sheetify(fnCss, fnp, opts, function (tf) {
        nodes.push([ tf, node ])
      })

      return
    }
  }
}

function cooked (node) { return node.value.cooked }
function expr (ex) { return { _expr: ex.source() } }

// find a file in CSS with either a {style} field
// or main with `.css` in it
// (str, str) -> str
function cssResolve (pkgname, basedir) {
  try {
    const res = resolve.sync(pkgname, {
      basedir: pkgname,
      packageFilter: packageFilter
    })

    if (path.extname(res) !== '.css') {
      throw new Error('path ' + res + ' is not a CSS file')
    }

    return res
  } catch (e) {
    return
  }

  function packageFilter (pkg, path) {
    if (pkg.style) pkg.main = pkg.style
    return pkg
  }
}
<commit_msg>default opts to empty object<commit_after>const mapLimit = require('map-limit')
const isStream = require('is-stream')
const eos = require('end-of-stream')
const through = require('through2')
const falafel = require('falafel')
const resolve = require('resolve')
const assert = require('assert')
const mkdirp = require('mkdirp')
const xtend = require('xtend')
const path = require('path')
const fs = require('fs')

const sheetify = require('./index')

module.exports = transform

// inline sheetify transform for browserify
// 1. walk AST
// 2. replace sheetify references with prefix id's
// 3. aggregate all transform calls
// 3. asynchronously either replace sheetify calls
//    with CSS injection or extract CSS to callback
// 4. flush transform
// obj -> (str, opts) -> str
function transform (filename, opts) {
  const bufs = []
  const nodes = []
  var mname = null

  opts = opts || {}
  opts.basedir = opts.basedir || process.cwd()
  opts = xtend(opts)

  // argv parsing
  if (opts.o) opts.out = opts.o
  if (opts.out) {
    if (typeof opts.out === 'string') opts.out = path.resolve(opts.out)
    else assert.ok(isStream(opts.out), 'opts.out must be a path or a stream')
  }

  const transformStream = through(write, end)
  return transformStream

  // aggregate all AST nodes
  // (buf, str, fn) -> null
  function write (buf, enc, next) {
    bufs.push(buf)
    next()
  }

  // parse and push AST nodes
  // null -> null
  function end () {
    const self = this
    const src = Buffer.concat(bufs).toString('utf8')
    const ast = falafel(src, { ecmaVersion: 6 }, walk)

    // transform all detected nodes and
    // close stream when done
    mapLimit(nodes, Infinity, iterate, function (err) {
      if (err) return self.emit('error', err)
      self.push(ast.toString())
      self.push(null)
    })

    // find sheetify call
    // - read from file, read from inline or resolve npm package
    // - detect if should be prefixed or not
    function iterate (args, done) {
      const transformFn = args[0]
      const node = args[1]
      transformFn(function (err, css, prefix) {
        if (err) return done(err)
        if (opts.out) {
          // exorcise to external file
          if (typeof opts.out === 'string') {
            const dirname = path.dirname(opts.out)
            mkdirp(dirname, function (err) {
              if (err) return done(err)
              const ws = fs.createWriteStream(opts.out)
              eos(ws, done)
              node.update('0')
              ws.end(css)
            })
          } else {
            // exorcise to stream
            const ws = opts.out
            eos(ws, done)
            node.update('0')
            ws.write(css)
            done()
          }
        } else {
          // inject CSS inline
          const str = [
            "((require('insert-css')(" + JSON.stringify(css) + ')',
            ' || true) && ' + JSON.stringify(prefix) + ')'
          ].join('')
          node.update(str)
          done()
        }
      })
    }
  }

  // transform an AST node
  // obj -> null
  function walk (node) {
    // transform require calls
    if (node.type === 'CallExpression' &&
    node.callee && node.callee.name === 'require' &&
    node.arguments.length === 1 &&
    node.arguments[0].value === 'sheetify') {
      node.update('0')
      mname = node.parent.id.name
      return
    }

    // transform template strings
    // modify node value to prefix, and push css for transform
    if (node.type === 'TemplateLiteral' &&
    node.parent && node.parent.tag &&
    node.parent.tag.name === mname) {
      const tmplCss = [ node.quasis.map(cooked) ]
        .concat(node.expressions.map(expr)).join('').trim()

      sheetify(tmplCss, filename, opts, function (tf) {
        nodes.push([ tf, node.parent ])
      })

      return
    }

    // transform call references into files read from disk
    // modify value node to prefix, and push css for transform
    if (node.type === 'CallExpression' &&
    node.callee && node.callee.type === 'Identifier' &&
    node.callee.name === mname) {
      // determine path
      // - check if module import
      // - don't prefix by default if module import
      // - check if local file
      const resolvePath = cssResolve(node.arguments[0].value, opts.basedir)
      const fnp = resolvePath ||
        path.join(path.dirname(filename), node.arguments[0].value)
      if (resolvePath) opts.global = true
      else transformStream.emit('file', fnp)
      const fnCss = fs.readFileSync(fnp, 'utf8').trim()

      // read optional arguments passed in to node
      // e.g. { global: false }
      if (node.arguments[1] && node.arguments[1].properties) {
        const props = node.arguments[1].properties
        props.forEach(function (prop) {
          opts[prop.key.name] = prop.value.value
        })
      }

      sheetify(fnCss, fnp, opts, function (tf) {
        nodes.push([ tf, node ])
      })

      return
    }
  }
}

function cooked (node) { return node.value.cooked }
function expr (ex) { return { _expr: ex.source() } }

// find a file in CSS with either a {style} field
// or main with `.css` in it
// (str, str) -> str
function cssResolve (pkgname, basedir) {
  try {
    const res = resolve.sync(pkgname, {
      basedir: pkgname,
      packageFilter: packageFilter
    })

    if (path.extname(res) !== '.css') {
      throw new Error('path ' + res + ' is not a CSS file')
    }

    return res
  } catch (e) {
    return
  }

  function packageFilter (pkg, path) {
    if (pkg.style) pkg.main = pkg.style
    return pkg
  }
}
<|endoftext|>


<commit_before>(function() {
	'use strict';
	// Got this from MDN:
	// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/toLocaleString#Example:_Checking_for_support_for_locales_and_options_arguments
	function toLocaleStringSupportsLocales() {
		var number = 0;
		try {
			number.toLocaleString("i");
		} catch(e) {
			return e.name === "RangeError";
		}
		return false;
	}
	var replaceSeparators = function(sNum, separators) {
		var sNumParts = sNum.split('.');
		if(separators && separators.thousands) {
			sNumParts[0] = sNumParts[0].replace(/(\d)(?=(\d\d\d)+(?!\d))/g, "$1" + separators.thousands);
		} else if(separators && separators.hundreds) {
			sNumParts[0] = sNumParts[0].replace(/(\d)(?=(\d\d)+(?!\d))/g, "$1" + separators.hundreds);
		}
		sNum = sNumParts.join(separators.decimal);
		return sNum;
	};
	var getLast3Digits = function(sNum) {
		var sNumParts = sNum.split('.');
		switch(sNumParts[0].length) {
			case 0:
				sNumParts[0] = '000';
				break;
			case 1:
				sNumParts[0] = '00' + sNumParts[0];
				break;
			case 2:
				sNumParts[0] = '0' + sNumParts[0];
				break;
		}
		sNum = sNumParts.join('.');
		return sNum;
	};
	var renderFormat = function(template, props) {
		for(var prop in props) {
			template = template.replace("{{" + prop + "}}", props[prop]);
		}
		return template;
	};
	var mapMatch = function(map, locale) {
		var match = locale;
		var language = locale && locale.toLowerCase().match(/^\w+/);
		if(!map.hasOwnProperty(locale)) {
			if(map.hasOwnProperty(language)) {
				match = language;
			} else {
				match = "en";
			}
		}
		return map[match];
	};
	var dotThousCommaDec = function(sNum) {
		var separators = {
			decimal: ',',
			thousands: '.'
		};
		return replaceSeparators(sNum, separators);
	};
	var commaThousDotDec = function(sNum) {
		var separators = {
			decimal: '.',
			thousands: ','
		};
		return replaceSeparators(sNum, separators);
	};
	var spaceThousCommaDec = function(sNum) {
		var seperators = {
			decimal: ',',
			thousands: '\u00A0'
		};
		return replaceSeparators(sNum, seperators);
	};
	var spaceHundredsCommaThousCommaDec = function(sNum) {
		var hundredSeperators = {
				decimal: '.',
				hundreds: ','
			},
			thoudandSeperators = {
				decimal: '.',
				thousands: ','
			};
		sNum = +sNum;
		if(sNum >= 1000) {
			return replaceSeparators(Math.round(sNum / 1000) + '', hundredSeperators) + ',' + getLast3Digits((sNum % 1000) + '');
		} else {
			return replaceSeparators(sNum + '', thoudandSeperators);
		}
	};
	var apostrophThousDotDec = function(sNum) {
		var seperators = {
			decimal: '.',
			thousands: '\u0027'
		};
		return replaceSeparators(sNum, seperators);
	};
	var transformForLocale = {
		en: commaThousDotDec,
		it: dotThousCommaDec,
		fr: spaceThousCommaDec,
		de: dotThousCommaDec,
		"de-DE": dotThousCommaDec,
		"de-AT": dotThousCommaDec,
		"de-CH": apostrophThousDotDec,
		"de-LI": apostrophThousDotDec,
		"de-BE": dotThousCommaDec,
		"hi-IN": spaceHundredsCommaThousCommaDec,
		"en-IN": spaceHundredsCommaThousCommaDec,
		ro: dotThousCommaDec,
		"ro-RO": dotThousCommaDec,
		hu: spaceThousCommaDec,
		"hu-HU": spaceThousCommaDec,
		"da-DK": dotThousCommaDec,
		"nb-NO": spaceThousCommaDec
	};
	var currencyFormatMap = {
		en: "pre",
		it: "post",
		fr: "post",
		de: "post",
		"de-DE": "post",
		"de-AT": "prespace",
		"de-CH": "prespace",
		"de-LI": "post",
		"de-BE": "post",
		ro: "post",
		"ro-RO": "post",
		hu: "post",
		"hu-HU": "post",
		"da-DK": "post",
		"nb-NO": "post"
	};
	var currencySymbols = {
		"afn": "؋",
		"ars": "$",
		"awg": "ƒ",
		"aud": "$",
		"azn": "₼",
		"bsd": "$",
		"bbd": "$",
		"byr": "p.",
		"bzd": "BZ$",
		"bmd": "$",
		"bob": "Bs.",
		"bam": "KM",
		"bwp": "P",
		"bgn": "лв",
		"brl": "R$",
		"bnd": "$",
		"khr": "៛",
		"cad": "$",
		"kyd": "$",
		"clp": "$",
		"cny": "¥",
		"cop": "$",
		"crc": "₡",
		"hrk": "kn",
		"cup": "₱",
		"czk": "Kč",
		"dkk": "kr",
		"dop": "RD$",
		"xcd": "$",
		"egp": "£",
		"svc": "$",
		"eek": "kr",
		"eur": "€",
		"fkp": "£",
		"fjd": "$",
		"ghc": "¢",
		"gip": "£",
		"gtq": "Q",
		"ggp": "£",
		"gyd": "$",
		"hnl": "L",
		"hkd": "$",
		"huf": "Ft",
		"isk": "kr",
		"inr": "₹",
		"idr": "Rp",
		"irr": "﷼",
		"imp": "£",
		"ils": "₪",
		"jmd": "J$",
		"jpy": "¥",
		"jep": "£",
		"kes": "KSh",
		"kzt": "лв",
		"kpw": "₩",
		"krw": "₩",
		"kgs": "лв",
		"lak": "₭",
		"lvl": "Ls",
		"lbp": "£",
		"lrd": "$",
		"ltl": "Lt",
		"mkd": "ден",
		"myr": "RM",
		"mur": "₨",
		"mxn": "$",
		"mnt": "₮",
		"mzn": "MT",
		"nad": "$",
		"npr": "₨",
		"ang": "ƒ",
		"nzd": "$",
		"nio": "C$",
		"ngn": "₦",
		"nok": "kr",
		"omr": "﷼",
		"pkr": "₨",
		"pab": "B/.",
		"pyg": "Gs",
		"pen": "S/.",
		"php": "₱",
		"pln": "zł",
		"qar": "﷼",
		"ron": "lei",
		"rub": "₽",
		"shp": "£",
		"sar": "﷼",
		"rsd": "Дин.",
		"scr": "₨",
		"sgd": "$",
		"sbd": "$",
		"sos": "S",
		"zar": "R",
		"lkr": "₨",
		"sek": "kr",
		"chf": "CHF",
		"srd": "$",
		"syp": "£",
		"tzs": "TSh",
		"twd": "NT$",
		"thb": "฿",
		"ttd": "TT$",
		"try": "",
		"trl": "₤",
		"tvd": "$",
		"ugx": "USh",
		"uah": "₴",
		"gbp": "£",
		"usd": "$",
		"uyu": "$U",
		"uzs": "лв",
		"vef": "Bs",
		"vnd": "₫",
		"yer": "﷼",
		"zwd": "Z$"
	};
	var currencyFormats = {
		pre: "{{code}}{{num}}",
		post: "{{num}} {{code}}",
		prespace: "{{code}} {{num}}"
	};
	Number.prototype.toLocaleString = function(locale, options) {
		if(locale && locale.length < 2) throw new RangeError("Invalid language tag: " + locale);
		var sNum;
		if(options && options.minimumFractionDigits) {
			sNum = this.toFixed(options.minimumFractionDigits);
		} else {
			sNum = this.toString();
		}
		sNum = mapMatch(transformForLocale, locale)(sNum, options);
		if(options && options.currency && options.style === "currency") {
			var format = currencyFormats[mapMatch(currencyFormatMap, locale)];
			if(options.currencyDisplay === "code") {
				sNum = renderFormat(format, {
					num: sNum,
					code: options.currency.toUpperCase()
				});
			} else {
				sNum = renderFormat(format, {
					num: sNum,
					code: currencySymbols[options.currency.toLowerCase()]
				});
			}
		}
		return sNum;
	};
}());

<commit_msg>Add files via upload<commit_after>(function() {
	'use strict';
	// Got this from MDN:
	// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/toLocaleString#Example:_Checking_for_support_for_locales_and_options_arguments
	function toLocaleStringSupportsLocales() {
		var number = 0;
		try {
			number.toLocaleString("i");
		} catch(e) {
			return e.name === "RangeError";
		}
		return false;
	}
	var replaceSeparators = function(sNum, separators) {
		var sNumParts = sNum.split('.');
		if(separators && separators.thousands) {
			sNumParts[0] = sNumParts[0].replace(/(\d)(?=(\d\d\d)+(?!\d))/g, "$1" + separators.thousands);
		} else if(separators && separators.hundreds) {
			sNumParts[0] = sNumParts[0].replace(/(\d)(?=(\d\d)+(?!\d))/g, "$1" + separators.hundreds);
		}
		sNum = sNumParts.join(separators.decimal);
		return sNum;
	};
	var getLast3Digits = function(sNum) {
		var sNumParts = sNum.split('.');
		switch(sNumParts[0].length) {
			case 0:
				sNumParts[0] = '000';
				break;
			case 1:
				sNumParts[0] = '00' + sNumParts[0];
				break;
			case 2:
				sNumParts[0] = '0' + sNumParts[0];
				break;
		}
		sNum = sNumParts.join('.');
		return sNum;
	};
	var renderFormat = function(template, props) {
		for(var prop in props) {
			template = template.replace("{{" + prop + "}}", props[prop]);
		}
		return template;
	};
	var mapMatch = function(map, locale) {
		var match = locale;
		var language = locale && locale.toLowerCase().match(/^\w+/);
		if(!map.hasOwnProperty(locale)) {
			if(map.hasOwnProperty(language)) {
				match = language;
			} else {
				match = "en";
			}
		}
		return map[match];
	};
	var dotThousCommaDec = function(sNum) {
		var separators = {
			decimal: ',',
			thousands: '.'
		};
		return replaceSeparators(sNum, separators);
	};
	var commaThousDotDec = function(sNum) {
		var separators = {
			decimal: '.',
			thousands: ','
		};
		return replaceSeparators(sNum, separators);
	};
	var spaceThousCommaDec = function(sNum) {
		var seperators = {
			decimal: ',',
			thousands: '\u00A0'
		};
		return replaceSeparators(sNum, seperators);
	};
	var spaceHundredsCommaThousCommaDec = function(sNum) {
		var hundredSeperators = {
				decimal: '.',
				hundreds: ','
			},
			thoudandSeperators = {
				decimal: '.',
				thousands: ','
			};
		sNum = +sNum;
		if(sNum >= 1000) {
			return replaceSeparators(Math.floor(sNum / 1000) + '', hundredSeperators) + ',' + getLast3Digits((sNum % 1000) + '');
		} else {
			return replaceSeparators(sNum + '', thoudandSeperators);
		}
	};
	var apostrophThousDotDec = function(sNum) {
		var seperators = {
			decimal: '.',
			thousands: '\u0027'
		};
		return replaceSeparators(sNum, seperators);
	};
	var transformForLocale = {
		en: commaThousDotDec,
		it: dotThousCommaDec,
		fr: spaceThousCommaDec,
		de: dotThousCommaDec,
		"de-DE": dotThousCommaDec,
		"de-AT": dotThousCommaDec,
		"de-CH": apostrophThousDotDec,
		"de-LI": apostrophThousDotDec,
		"de-BE": dotThousCommaDec,
		"hi-IN": spaceHundredsCommaThousCommaDec,
		"en-IN": spaceHundredsCommaThousCommaDec,
		ro: dotThousCommaDec,
		"ro-RO": dotThousCommaDec,
		hu: spaceThousCommaDec,
		"hu-HU": spaceThousCommaDec,
		"da-DK": dotThousCommaDec,
		"nb-NO": spaceThousCommaDec
	};
	var currencyFormatMap = {
		en: "pre",
		it: "post",
		fr: "post",
		de: "post",
		"de-DE": "post",
		"de-AT": "prespace",
		"de-CH": "prespace",
		"de-LI": "post",
		"de-BE": "post",
		ro: "post",
		"ro-RO": "post",
		hu: "post",
		"hu-HU": "post",
		"da-DK": "post",
		"nb-NO": "post"
	};
	var currencySymbols = {
		"afn": "؋",
		"ars": "$",
		"awg": "ƒ",
		"aud": "$",
		"azn": "₼",
		"bsd": "$",
		"bbd": "$",
		"byr": "p.",
		"bzd": "BZ$",
		"bmd": "$",
		"bob": "Bs.",
		"bam": "KM",
		"bwp": "P",
		"bgn": "лв",
		"brl": "R$",
		"bnd": "$",
		"khr": "៛",
		"cad": "$",
		"kyd": "$",
		"clp": "$",
		"cny": "¥",
		"cop": "$",
		"crc": "₡",
		"hrk": "kn",
		"cup": "₱",
		"czk": "Kč",
		"dkk": "kr",
		"dop": "RD$",
		"xcd": "$",
		"egp": "£",
		"svc": "$",
		"eek": "kr",
		"eur": "€",
		"fkp": "£",
		"fjd": "$",
		"ghc": "¢",
		"gip": "£",
		"gtq": "Q",
		"ggp": "£",
		"gyd": "$",
		"hnl": "L",
		"hkd": "$",
		"huf": "Ft",
		"isk": "kr",
		"inr": "₹",
		"idr": "Rp",
		"irr": "﷼",
		"imp": "£",
		"ils": "₪",
		"jmd": "J$",
		"jpy": "¥",
		"jep": "£",
		"kes": "KSh",
		"kzt": "лв",
		"kpw": "₩",
		"krw": "₩",
		"kgs": "лв",
		"lak": "₭",
		"lvl": "Ls",
		"lbp": "£",
		"lrd": "$",
		"ltl": "Lt",
		"mkd": "ден",
		"myr": "RM",
		"mur": "₨",
		"mxn": "$",
		"mnt": "₮",
		"mzn": "MT",
		"nad": "$",
		"npr": "₨",
		"ang": "ƒ",
		"nzd": "$",
		"nio": "C$",
		"ngn": "₦",
		"nok": "kr",
		"omr": "﷼",
		"pkr": "₨",
		"pab": "B/.",
		"pyg": "Gs",
		"pen": "S/.",
		"php": "₱",
		"pln": "zł",
		"qar": "﷼",
		"ron": "lei",
		"rub": "₽",
		"shp": "£",
		"sar": "﷼",
		"rsd": "Дин.",
		"scr": "₨",
		"sgd": "$",
		"sbd": "$",
		"sos": "S",
		"zar": "R",
		"lkr": "₨",
		"sek": "kr",
		"chf": "CHF",
		"srd": "$",
		"syp": "£",
		"tzs": "TSh",
		"twd": "NT$",
		"thb": "฿",
		"ttd": "TT$",
		"try": "",
		"trl": "₤",
		"tvd": "$",
		"ugx": "USh",
		"uah": "₴",
		"gbp": "£",
		"usd": "$",
		"uyu": "$U",
		"uzs": "лв",
		"vef": "Bs",
		"vnd": "₫",
		"yer": "﷼",
		"zwd": "Z$"
	};
	var currencyFormats = {
		pre: "{{code}}{{num}}",
		post: "{{num}} {{code}}",
		prespace: "{{code}} {{num}}"
	};
	Number.prototype.toLocaleString = function(locale, options) {
		if(locale && locale.length < 2) throw new RangeError("Invalid language tag: " + locale);
		var sNum;
		if(options && options.minimumFractionDigits) {
			sNum = this.toFixed(options.minimumFractionDigits);
		} else {
			sNum = this.toString();
		}
		sNum = mapMatch(transformForLocale, locale)(sNum, options);
		if(options && options.currency && options.style === "currency") {
			var format = currencyFormats[mapMatch(currencyFormatMap, locale)];
			if(options.currencyDisplay === "code") {
				sNum = renderFormat(format, {
					num: sNum,
					code: options.currency.toUpperCase()
				});
			} else {
				sNum = renderFormat(format, {
					num: sNum,
					code: currencySymbols[options.currency.toLowerCase()]
				});
			}
		}
		return sNum;
	};
}());
<|endoftext|>


<commit_before><commit_msg>Fixed some of the issues<commit_after><|endoftext|>


<commit_before>var express = require('express');
var monk = require('monk');
var bodyParser = require('body-parser');

var dbAPI = require('api/db.js');
var common = require('api/routing.js');

var Item = require('api/Item.js');
var Reservation = require('api/Reservation.js');

var router = express.Router();
router.use(bodyParser.json());

/* Method handlers: */

/* Return a listing of all inventory items. */
router.get('/inventory', function(req, res) {
    dbAPI.inventory.find({}, {}).then(
        (docs) => {
            promises = docs.map(
                (doc) => {
                    item = new Item(doc._id);
                    return item.summary();
                }
            );

            return Promise.all(promises);
        }
    ).then(common.jsonSuccess(res)).catch(common.apiErrorHandler(req, res));
});

/*
 Add a new inventory item.

 Send parameters as JSON:
  - 'name': name of item type
  - 'count': initial inventory count
 */
router.post('/inventory', function(req, res) {
    if(!checkRequestParameter(req, res, 'name') || !checkRequestParameter(req, res, 'count')) {
        return;
    }

    dbAPI.inventory.count( { name: req.body.name } ).then(
        (count) => {
            if(count > 0) {
                return Promise.reject("Item already exists.");
            } else {
                item = new Item(req.body.name, req.body.count);
                return item.save();
            }
        }
    ).then(common.sendJSON(res, 201)).catch(common.apiErrorHandler(req, res));
});

/* Get information on one inventory item. */
router.get('/inventory/:id', function(req, res) {
    var item = new Item(monk.id(req.params.id));

    item.exists().then(
        (exists) => {
            if(exists) {
                return item.summary();
            } else {
                return Promise.reject("Item does not exist.");
            }
        }
    ).then(common.jsonSuccess(res)).catch(common.apiErrorHandler(req, res));
});

router.delete('/inventory/:id', function(req, res) {
    item = new Item(monk.id(req.params.id));

    item.delete().then(common.emptySuccess(res)).catch(common.apiErrorHandler(req, res));
});

/* Update an inventory item. */
router.put('/inventory/:id', function(req, res) {
    if(!checkRequestParameter(req, res, 'name')) { return; }
    if(!checkRequestParameter(req, res, 'count')) { return; }

    var item = new Item(monk.id(req.params.id));

    common.checkRequestParameters(req, 'name', 'count').then(
        () => { return item.reserved(); }
    ).then(
        (rsvp_count) => {
            if(rsvp_count > req.body.count)
                return Promise.reject("Cannot satisfy reservations with lowered inventory count.");

            this.name(req.body.name);
            this.count(parseInt(req.body.count));

            return this.save();
        }
    ).then(common.jsonSuccess(res)).catch(common.apiErrorHandler(req, res));
});

/* Get info on part reservations. */
router.get('/inventory/:id/reservations', (req, res) => {
    var item = new Item(monk.id(req.params.id));

    item.reservations().then(
        (ids) => {
            /* Convert all RSVPs to (promises for) summaries */
            return Promise.all(ids.map(
                (id) => {
                    rsvp = new Reservation(id);
                    return rsvp.summary();
                }
            ));
        }
    ).then(common.jsonSuccess(res)).catch(common.apiErrorHandler(req, res));
});

/* Redirect all part-specific reservation requests to the reservation route */
router.all('/inventory/:id/reservations/:rid*', (req, res) => {
    // find subroute:
    subroute = req.path.split('/inventory/'+req.params.id+'/reservations/'+req.params.rid);

    if(subroute.length > 1) {
        res.redirect(307, req.baseUrl+'/reservations/'+req.params.rid+subroute[1]);
    } else {
        res.status(404).send("Could not split path.");
    }
});
router.post('/inventory/:id/reservations', (req, res) => {
    res.redirect(307, req.baseUrl+'/reservations');
});
router.put('/inventory/:id/reservations', (req, res) => {
    res.redirect(307, req.baseUrl+'/reservations');
});
router.delete('/inventory/:id/reservations', (req, res) => {
    res.redirect(307, req.baseUrl+'/reservations');
});

module.exports = router;
<commit_msg>Fix error with inventory POST and PUT endpoints<commit_after>var express = require('express');
var monk = require('monk');
var bodyParser = require('body-parser');

var dbAPI = require('api/db.js');
var common = require('api/routing.js');

var Item = require('api/Item.js');
var Reservation = require('api/Reservation.js');

var router = express.Router();
router.use(bodyParser.json());

/* Method handlers: */

/* Return a listing of all inventory items. */
router.get('/inventory', function(req, res) {
    dbAPI.inventory.find({}, {}).then(
        (docs) => {
            promises = docs.map(
                (doc) => {
                    item = new Item(doc._id);
                    return item.summary();
                }
            );

            return Promise.all(promises);
        }
    ).then(common.jsonSuccess(res)).catch(common.apiErrorHandler(req, res));
});

/*
 Add a new inventory item.

 Send parameters as JSON:
  - 'name': name of item type
  - 'count': initial inventory count
 */
router.post('/inventory', function(req, res) {
    common.checkRequestParameters(req, 'name', 'count').then(
        () => { return dbAPI.inventory.count( { name: req.body.name } ); }
    ).then(
        (count) => {
            if(count > 0) {
                return Promise.reject("Item already exists.");
            } else {
                item = new Item(req.body.name, req.body.count);
                return item.save();
            }
        }
    ).then(common.sendJSON(res, 201)).catch(common.apiErrorHandler(req, res));
});

/* Get information on one inventory item. */
router.get('/inventory/:id', function(req, res) {
    var item = new Item(monk.id(req.params.id));

    item.exists().then(
        (exists) => {
            if(exists) {
                return item.summary();
            } else {
                return Promise.reject("Item does not exist.");
            }
        }
    ).then(common.jsonSuccess(res)).catch(common.apiErrorHandler(req, res));
});

router.delete('/inventory/:id', function(req, res) {
    item = new Item(monk.id(req.params.id));

    item.delete().then(common.emptySuccess(res)).catch(common.apiErrorHandler(req, res));
});

/* Update an inventory item. */
router.put('/inventory/:id', function(req, res) {
    var item = new Item(monk.id(req.params.id));

    common.checkRequestParameters(req, 'name', 'count').then(
        () => { return item.reserved(); }
    ).then(
        (rsvp_count) => {
            if(rsvp_count > req.body.count)
                return Promise.reject("Cannot satisfy reservations with lowered inventory count.");

            this.name(req.body.name);
            this.count(parseInt(req.body.count));

            return this.save();
        }
    ).then(common.jsonSuccess(res)).catch(common.apiErrorHandler(req, res));
});

/* Get info on part reservations. */
router.get('/inventory/:id/reservations', (req, res) => {
    var item = new Item(monk.id(req.params.id));

    item.reservations().then(
        (ids) => {
            /* Convert all RSVPs to (promises for) summaries */
            return Promise.all(ids.map(
                (id) => {
                    rsvp = new Reservation(id);
                    return rsvp.summary();
                }
            ));
        }
    ).then(common.jsonSuccess(res)).catch(common.apiErrorHandler(req, res));
});

/* Redirect all part-specific reservation requests to the reservation route */
router.all('/inventory/:id/reservations/:rid*', (req, res) => {
    // find subroute:
    subroute = req.path.split('/inventory/'+req.params.id+'/reservations/'+req.params.rid);

    if(subroute.length > 1) {
        res.redirect(307, req.baseUrl+'/reservations/'+req.params.rid+subroute[1]);
    } else {
        res.status(404).send("Could not split path.");
    }
});
router.post('/inventory/:id/reservations', (req, res) => {
    res.redirect(307, req.baseUrl+'/reservations');
});
router.put('/inventory/:id/reservations', (req, res) => {
    res.redirect(307, req.baseUrl+'/reservations');
});
router.delete('/inventory/:id/reservations', (req, res) => {
    res.redirect(307, req.baseUrl+'/reservations');
});

module.exports = router;
<|endoftext|>


<commit_before>var fakeData = [
    { "src": "http://scout-app.io/_img/scout-app-logo.svg",     "alt": "Scout-App 2 Logo featuring Scout the Puppy."  },
    { "src": "http://scout-app.io/_img/logo-win.svg",           "alt": "Windows"                                      },
    { "src": "http://scout-app.io/_img/logo-ubuntu.svg",        "alt": "Ubuntu"                                       },
    { "src": "http://scout-app.io/_img/logo-zorin.svg",         "alt": "Zorin"                                        },
    { "src": "http://scout-app.io/_img/logo-osx.svg",           "alt": "OSX"                                          },
    { "src": "http://scout-app.io/_img/screenshots/win/01.png", "alt": "First Time User Experience (Windows 7)"       },
    { "src": "http://scout-app.io/_img/screenshots/win/02.png", "alt": "Project view (Windows 7)"                     },
    { "src": "http://scout-app.io/_img/screenshots/win/25.png", "alt": "Multi-Project Import (Windows 7)"             },
    { "src": "",                                                "alt": "Status of All Projects (Windows 7)"           },
    { "src": "",                                                "alt": "Dev Tools are always accessible (Windows 7)"  },
    { "src": "",                                                "alt": "Windows 10"                                   },
    { "src": "http://scout-app.io/_img/logo-win.svg",           "alt": "Windows"                                      },
    { "src": "http://scout-app.io/_img/logo-ubuntu.svg",        "alt": "Ubuntu"                                       },
    { "src": "http://scout-app.io/_img/logo-zorin.svg",         "alt": "Zorin"                                        },
    { "src": "http://scout-app.io/_img/logo-osx.svg",           "alt": "OSX"                                          },
    { "src": "http://scout-app.io/_img/screenshots/win/02.png", "alt": "English (Windows 7)"                          },
    { "src": "http://scout-app.io/_img/screenshots/win/03.png", "alt": "Dutch (Windows 7)"                            },
    { "src": "http://scout-app.io/_img/screenshots/win/04.png", "alt": "French (Windows 7)"                           },
    { "src": "",                                                "alt": "Russian (Windows 7)"                          },
    { "src": "http://scout-app.io/_img/logo-win.svg",           "alt": "Windows"                                      },
    { "src": "http://scout-app.io/_img/logo-ubuntu.svg",        "alt": "Ubuntu"                                       },
    { "src": "http://scout-app.io/_img/logo-zorin.svg",         "alt": "Zorin"                                        },
    { "src": "http://scout-app.io/_img/logo-osx.svg",           "alt": "OSX"                                          },
    { "src": "http://scout-app.io/_img/screenshots/win/02.png", "alt": "Simplex (Windows 7)"                          },
    { "src": "http://scout-app.io/_img/screenshots/win/06.png", "alt": "Cerulean (Windows 7)"                         },
    { "src": "http://scout-app.io/_img/screenshots/win/07.png", "alt": "Classic (Windows 7)"                          },
    { "src": "",                                                "alt": "Cosmo (Windows 7)"                            },
    { "src": "",                                                "alt": "W3suli.com (Windows 7)"                       },
    { "src": "",                                                "alt": "Yeti (Windows 7)"                             },
    { "src": "http://scout-app.io/_img/logo-nodesass.svg",      "alt": "The Node-Sass engine."                        },
    { "src": "http://scout-app.io/_img/logo-ugui.png",          "alt": "The Universal GUI Library/Framework"          },
    { "src": "http://scout-app.io/_img/logo-nwjs.png",          "alt": "The NW.js Cross-Platform Runtime Environment" },
    { "src": "http://scout-app.io/_img/devswag.png",            "alt": "DevSwag Logo"                                 },
    { "src": "http://scout-app.io/_img/big-sticker.png",        "alt": "Scout-App logo as a sticker"                  },
    { "src": "data:image/gif;base64,R0lGODlhEAAQAMQAAORHHOVSKudfOulrSOp3WOyDZu6QdvCchPGolfO0o/XBs/fNwfjZ0frl3/zy7////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAkAABAALAAAAAAQABAAAAVVICSOZGlCQAosJ6mu7fiyZeKqNKToQGDsM8hBADgUXoGAiqhSvp5QAnQKGIgUhwFUYLCVDFCrKUE1lBavAViFIDlTImbKC5Gm2hB0SlBCBMQiB0UjIQA7",
                                                                "alt": "Data URI Test"                                }
];

/**
 * Process an array of objects, each containing the src and alt data for images.
 * @param  {array} data Array of objects. Each object has a "src" and "alt" for an image.
 */
function processAltsScript (data) {
    var fs = require('fs-extra');
    var path = require('path');
    var nw = require('nw.gui');
    var http = require('http');
    var https = require('https');
    var appData = nw.App.dataPath;
    var i = 0;

    function rmrf (location) {
        location = path.normalize(location);
        while (fs.existsSync(location)) {
            if (process.platform == 'win32') {
                require('child_process').execSync('rd /S /Q ' + location);
            } else {
                fs.removeSync(location);
            }
        }
    }

    rmrf(path.join(appData, 'temp'));
    fs.mkdirSync(path.join(appData, 'temp'));

    function downloadComplete (response, newFile) {
        response.pipe(newFile);
        if (i < data.length) {
            i = i + 1;
            downloadImage();
        }
    }

    function downloadImage () {
        var image = data[i];
        if (image.src.length > 1 && image.alt.length > 1) {
            var ext = path.extname(image.src);
            var newFile = path.join(appData, 'temp', i + ext);
            var protocol = image.src.split('://')[0];

            if (protocol == 'http') {
                http.get(image.src, function (response) {
                    console.log(response);
                    downloadComplete(response, newFile);
                });
            } else if (protocol == 'https') {
                https.get(image.src, function (response) {
                    downloadComplete(response, newFile);
                });
            }
        } else if (i < data.length) {
            i = i + 1;
            downloadImage();
        } else {
            console.log('done');
        }
    }

    downloadImage();
}

processAltsScript(fakeData);

/*

var http = require('http');
var fs = require('fs');

function getImage (url, filename) {
    http.get(url, function (response) {
        if (response.statusCode == 200) {
            response.pipe(fs.createWriteStream(filename));
        } else {
            console.log(response.statusCode);
        }
    })
}

getImage('http://scout-app.io/_img/logo-ubuntu.svg', '01.svg');

*/
<commit_msg>First part done<commit_after>var fakeData = [
    { "src": "http://scout-app.io/_img/scout-app-logo.svg",     "alt": "Scout-App 2 Logo featuring Scout the Puppy."  },
    { "src": "http://scout-app.io/_img/logo-win.svg",           "alt": "Windows"                                      },
    { "src": "http://scout-app.io/_img/logo-ubuntu.svg",        "alt": "Ubuntu"                                       },
    { "src": "http://scout-app.io/_img/logo-zorin.svg",         "alt": "Zorin"                                        },
    { "src": "http://scout-app.io/_img/logo-osx.svg",           "alt": "OSX"                                          },
    { "src": "http://scout-app.io/_img/screenshots/win/01.png", "alt": "First Time User Experience (Windows 7)"       },
    { "src": "http://scout-app.io/_img/screenshots/win/02.png", "alt": "Project view (Windows 7)"                     },
    { "src": "http://scout-app.io/_img/screenshots/win/25.png", "alt": "Multi-Project Import (Windows 7)"             },
    { "src": "",                                                "alt": "Status of All Projects (Windows 7)"           },
    { "src": "",                                                "alt": "Dev Tools are always accessible (Windows 7)"  },
    { "src": "",                                                "alt": "Windows 10"                                   },
    { "src": "http://scout-app.io/_img/logo-win.svg",           "alt": "Windows"                                      },
    { "src": "http://scout-app.io/_img/logo-ubuntu.svg",        "alt": "Ubuntu"                                       },
    { "src": "http://scout-app.io/_img/logo-zorin.svg",         "alt": "Zorin"                                        },
    { "src": "http://scout-app.io/_img/logo-osx.svg",           "alt": "OSX"                                          },
    { "src": "http://scout-app.io/_img/screenshots/win/02.png", "alt": "English (Windows 7)"                          },
    { "src": "http://scout-app.io/_img/screenshots/win/03.png", "alt": "Dutch (Windows 7)"                            },
    { "src": "http://scout-app.io/_img/screenshots/win/04.png", "alt": "French (Windows 7)"                           },
    { "src": "",                                                "alt": "Russian (Windows 7)"                          },
    { "src": "http://scout-app.io/_img/logo-win.svg",           "alt": "Windows"                                      },
    { "src": "http://scout-app.io/_img/logo-ubuntu.svg",        "alt": "Ubuntu"                                       },
    { "src": "http://scout-app.io/_img/logo-zorin.svg",         "alt": "Zorin"                                        },
    { "src": "http://scout-app.io/_img/logo-osx.svg",           "alt": "OSX"                                          },
    { "src": "http://scout-app.io/_img/screenshots/win/02.png", "alt": "Simplex (Windows 7)"                          },
    { "src": "http://scout-app.io/_img/screenshots/win/06.png", "alt": "Cerulean (Windows 7)"                         },
    { "src": "http://scout-app.io/_img/screenshots/win/07.png", "alt": "Classic (Windows 7)"                          },
    { "src": "",                                                "alt": "Cosmo (Windows 7)"                            },
    { "src": "",                                                "alt": "W3suli.com (Windows 7)"                       },
    { "src": "",                                                "alt": "Yeti (Windows 7)"                             },
    { "src": "http://scout-app.io/_img/logo-nodesass.svg",      "alt": "The Node-Sass engine."                        },
    { "src": "http://scout-app.io/_img/logo-ugui.png",          "alt": "The Universal GUI Library/Framework"          },
    { "src": "http://scout-app.io/_img/logo-nwjs.png",          "alt": "The NW.js Cross-Platform Runtime Environment" },
    { "src": "http://scout-app.io/_img/devswag.png",            "alt": "DevSwag Logo"                                 },
    { "src": "http://scout-app.io/_img/big-sticker.png",        "alt": "Scout-App logo as a sticker"                  },
    { "src": "data:image/gif;base64,R0lGODlhEAAQAMQAAORHHOVSKudfOulrSOp3WOyDZu6QdvCchPGolfO0o/XBs/fNwfjZ0frl3/zy7////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAkAABAALAAAAAAQABAAAAVVICSOZGlCQAosJ6mu7fiyZeKqNKToQGDsM8hBADgUXoGAiqhSvp5QAnQKGIgUhwFUYLCVDFCrKUE1lBavAViFIDlTImbKC5Gm2hB0SlBCBMQiB0UjIQA7",
                                                                "alt": "Data URI Test"                                }
];

/**
 * Process an array of objects, each containing the src and alt data for images.
 * @param  {array} data Array of objects. Each object has a "src" and "alt" for an image.
 */
function processAltsScript (data) {
    var fs = require('fs-extra');
    var path = require('path');
    var nw = require('nw.gui');
    var http = require('http');
    var https = require('https');
    var appData = nw.App.dataPath;
    var i = 0;

    function rmrf (location) {
        location = path.normalize(location);
        while (fs.existsSync(location)) {
            if (process.platform == 'win32') {
                require('child_process').execSync('rd /S /Q ' + location);
            } else {
                fs.removeSync(location);
            }
        }
    }

    rmrf(path.join(appData, 'temp'));
    fs.mkdirSync(path.join(appData, 'temp'));

    function downloadComplete (response, newFile) {

        if (response.statusCode == 200) {
            response.pipe(fs.createWriteStream(newFile));
            if (i < data.length) {
                i = i + 1;
                downloadImage();
            }
        } else {
            console.log(response.statusCode);
        }
    }

    function downloadImage () {
        var image = data[i];
        if (image.src.length > 1 && image.alt.length > 1) {
            var ext = path.extname(image.src);
            var newFile = path.join(appData, 'temp', i + ext);
            var protocol = image.src.split('://')[0];

            if (protocol == 'http') {
                http.get(image.src, function (response) {
                    downloadComplete(response, newFile);
                });
            } else if (protocol == 'https') {
                https.get(image.src, function (response) {
                    downloadComplete(response, newFile);
                });
            }
        } else if (i < data.length) {
            i = i + 1;
            downloadImage();
        } else {
            console.log('done');
        }
    }

    downloadImage();
}

// LEFT TO DO:
// Create a UI to accept the new array of objects
// Pass that into the stuff above
// process all the data and produce stats on an object
// Run Pa11y and then prepend stuff to the output file.
<|endoftext|>