<commit_before>// Dependencies

const {checkIsNotNull} = require('focus-core').util.object;
const {builder, types} = require('focus-core').component;
const find = require('lodash/collection/find');
const {omit} = require('lodash/object');
const {isArray} = require('lodash/lang');
import {clone} from 'lodash/lang';
import {reduce} from 'lodash/collection';

// Mixins

const translationMixin = require('../../common/i18n').mixin;
const infiniteScrollMixin = require('../mixin/infinite-scroll').mixin;
const referenceMixin = require('../../common/mixin/reference-property');

// Components

const Button = require('../../common/button/action').component;

const listMixin = {
    /**
    * Display name.
    */
    displayName: 'selection-list',

    /**
    * Mixin dependancies.
    */
    mixins: [translationMixin, infiniteScrollMixin, referenceMixin],

    /**
    * Default properties for the list.
    * @returns {{isSelection: boolean}} the default properties
    */
    getDefaultProps: function getListDefaultProps(){
        return {
            data: [],
            isSelection: true,
            selectionStatus: 'partial',
            selectionData: [],
            isLoading: false,
            operationList: [],
            idField: 'id'
        };
    },

    /**
    * list property validation.
    * @type {Object}
    */
    propTypes: {
        LineComponent: types('func'),
        buttonComponent: types('func'),
        data: types('array'),
        idField: types('string'),
        isLoading: types('bool'),
        isSelection: types('bool'),
        loader: types('func'),
        onLineClick: types('func'),
        onSelection: types('func'),
        operationList: types(['array', 'object']),
        selectionData: types('array'),
        selectionStatus: types('string')
    },

    getInitialState() {
        return {
            selectedItems: null
        }
    },

    /**
    * Return selected items in the list.
    * @return {Array} selected items
    */
    getSelectedItems() {
        const {selectedItems} = this.state;
        if (selectedItems !== null) {
            const selectedItems = [];
            for (let [item, isSelected] of this.state.selectedItems) {
                if (isSelected) selectedItems.push(item);
            }
            return selectedItems;
        } else {
            return reduce(this.refs, (acc, ref) => {
                if (ref.getValue) {
                    const {item, isSelected} = ref.getValue();
                    if (isSelected) acc.push(item);
                }
                return acc;
            }, []);
        }
    },

    _handleLineSelection(data, isSelected) {
        const {selectedItems} = this.state;
        const newSelectedItems = new Map();
        if (selectedItems !== null) {
            for (let [key, value] of selectedItems) {
                newSelectedItems.set(key, value);
            }
        }
        newSelectedItems.set(data, isSelected);
        this.setState({selectedItems: newSelectedItems});
    },

    /**
    * Render lines of the list.
    * @returns {*} DOM for lines
    */
    _renderLines() {
        const {data, LineComponent: Line, selectionData, idField, selectionStatus, ...otherProps} = this.props;
        // LEGACY CODE
        const customLineComponent = otherProps.lineComponent;
        if (customLineComponent) {
            console.warn(`%c DEPRECATED : You are using the lineComponent prop in a list component, this will be removed in the next release of Focus Components. Please use LineComponent prop instead.`, `color: #FF9C00; font-weight: bold`);
        }
        const FinalLineComponent = customLineComponent || Line;
        // END OF LEGACY CODE
        if(!isArray(data)){
            console.error(
                'List: Lines: it seems data is not an array, please check the value in your store, it could also be related to your action in case of a load (have a look to shouldDumpStoreOnActionCall option).'
            );
        }
        return data.map((line, idx) => {
            let isSelected;
            const selection = find(selectionData, {[idField]: line[idField]});
            if (selection) {
                isSelected = selection.isSelected;
            } else {
                switch(selectionStatus){
                    case 'none':
                        isSelected = false;
                    break;
                    case 'selected':
                        isSelected = true;
                    break;
                    case 'partial':
                        isSelected = undefined;
                    break;
                    default:
                        isSelected = false;
                }
            }
            return (
                <FinalLineComponent
                    data={line}
                    isSelected={isSelected}
                    key={line[idField] || idx}
                    onSelection={this._handleLineSelection}
                    ref={`line${idx}`}
                    reference={this._getReference()}
                    {...otherProps}
                    />
            );
        });
    },
    /**
    * Render loading state
    * @return {HTML} the loading state
    */
    _renderLoading() {
        const {isLoading, loader} = this.props;
        if(isLoading){
            if(loader){
                return loader();
            }
            return (

{this.i18n('list.loading')} ...

            );
        }
    },
    /**
    * Render manual fetch state
    * @return {HTML} the rendered manual fetch state
    */
    _renderManualFetch() {
        const {isManualFetch, hasMoreData} = this.props;
        if(isManualFetch && hasMoreData){
            const style = {className: 'primary'};
            return (

                    <Button
                        handleOnClick={this.handleShowMore}
                        label='list.button.showMore'
                        style={style}
                        type='button'
                        />

            );
        }
    },

    /**
    * Render the list.
    * @returns {XML} DOM of the component
    */
    render() {
        return (

                {this._renderLines()}
                {this._renderLoading()}
                {this._renderManualFetch()}

        );
    }
};

module.exports = builder(listMixin);
<commit_msg>Wire up the onSelection prop on SelectionList<commit_after>// Dependencies

const {checkIsNotNull} = require('focus-core').util.object;
const {builder, types} = require('focus-core').component;
const find = require('lodash/collection/find');
const {omit} = require('lodash/object');
const {isArray} = require('lodash/lang');
import {clone} from 'lodash/lang';
import {reduce} from 'lodash/collection';

// Mixins

const translationMixin = require('../../common/i18n').mixin;
const infiniteScrollMixin = require('../mixin/infinite-scroll').mixin;
const referenceMixin = require('../../common/mixin/reference-property');

// Components

const Button = require('../../common/button/action').component;

const listMixin = {
    /**
    * Display name.
    */
    displayName: 'selection-list',

    /**
    * Mixin dependancies.
    */
    mixins: [translationMixin, infiniteScrollMixin, referenceMixin],

    /**
    * Default properties for the list.
    * @returns {{isSelection: boolean}} the default properties
    */
    getDefaultProps: function getListDefaultProps(){
        return {
            data: [],
            isSelection: true,
            selectionStatus: 'partial',
            selectionData: [],
            isLoading: false,
            operationList: [],
            idField: 'id'
        };
    },

    /**
    * list property validation.
    * @type {Object}
    */
    propTypes: {
        LineComponent: types('func'),
        buttonComponent: types('func'),
        data: types('array'),
        idField: types('string'),
        isLoading: types('bool'),
        isSelection: types('bool'),
        loader: types('func'),
        onLineClick: types('func'),
        onSelection: types('func'),
        operationList: types(['array', 'object']),
        selectionData: types('array'),
        selectionStatus: types('string')
    },

    getInitialState() {
        return {
            selectedItems: null
        }
    },

    /**
    * Return selected items in the list.
    * @return {Array} selected items
    */
    getSelectedItems() {
        const {selectedItems} = this.state;
        if (selectedItems !== null) {
            const selectedItems = [];
            for (let [item, isSelected] of this.state.selectedItems) {
                if (isSelected) selectedItems.push(item);
            }
            return selectedItems;
        } else {
            return reduce(this.refs, (acc, ref) => {
                if (ref.getValue) {
                    const {item, isSelected} = ref.getValue();
                    if (isSelected) acc.push(item);
                }
                return acc;
            }, []);
        }
    },

    _handleLineSelection(data, isSelected) {
        const {selectedItems} = this.state;
        const newSelectedItems = new Map();
        if (selectedItems !== null) {
            for (let [key, value] of selectedItems) {
                newSelectedItems.set(key, value);
            }
        }
        newSelectedItems.set(data, isSelected);

        if (this.props.onSelection) {
            this.props.onSelection(data, isSelected);
        }

        this.setState({selectedItems: newSelectedItems});
    },

    /**
    * Render lines of the list.
    * @returns {*} DOM for lines
    */
    _renderLines() {
        const {data, LineComponent: Line, selectionData, idField, selectionStatus, ...otherProps} = this.props;
        // LEGACY CODE
        const customLineComponent = otherProps.lineComponent;
        if (customLineComponent) {
            console.warn(`%c DEPRECATED : You are using the lineComponent prop in a list component, this will be removed in the next release of Focus Components. Please use LineComponent prop instead.`, `color: #FF9C00; font-weight: bold`);
        }
        const FinalLineComponent = customLineComponent || Line;
        // END OF LEGACY CODE
        if(!isArray(data)){
            console.error(
                'List: Lines: it seems data is not an array, please check the value in your store, it could also be related to your action in case of a load (have a look to shouldDumpStoreOnActionCall option).'
            );
        }
        return data.map((line, idx) => {
            let isSelected;
            const selection = find(selectionData, {[idField]: line[idField]});
            if (selection) {
                isSelected = selection.isSelected;
            } else {
                switch(selectionStatus){
                    case 'none':
                        isSelected = false;
                    break;
                    case 'selected':
                        isSelected = true;
                    break;
                    case 'partial':
                        isSelected = undefined;
                    break;
                    default:
                        isSelected = false;
                }
            }
            return (
                <FinalLineComponent
                    data={line}
                    isSelected={isSelected}
                    key={line[idField] || idx}
                    onSelection={this._handleLineSelection}
                    ref={`line${idx}`}
                    reference={this._getReference()}
                    {...otherProps}
                    />
            );
        });
    },
    /**
    * Render loading state
    * @return {HTML} the loading state
    */
    _renderLoading() {
        const {isLoading, loader} = this.props;
        if(isLoading){
            if(loader){
                return loader();
            }
            return (

{this.i18n('list.loading')} ...

            );
        }
    },
    /**
    * Render manual fetch state
    * @return {HTML} the rendered manual fetch state
    */
    _renderManualFetch() {
        const {isManualFetch, hasMoreData} = this.props;
        if(isManualFetch && hasMoreData){
            const style = {className: 'primary'};
            return (

                    <Button
                        handleOnClick={this.handleShowMore}
                        label='list.button.showMore'
                        style={style}
                        type='button'
                        />

            );
        }
    },

    /**
    * Render the list.
    * @returns {XML} DOM of the component
    */
    render() {
        return (

                {this._renderLines()}
                {this._renderLoading()}
                {this._renderManualFetch()}

        );
    }
};

module.exports = builder(listMixin);
<|endoftext|>


<commit_before>dojo.provide("dijit._Calendar");

dojo.require("dojo.cldr.supplemental");
dojo.require("dojo.date");
dojo.require("dojo.date.locale");

dojo.require("dijit._Widget");
dojo.require("dijit._Templated");

dojo.declare(
	"dijit._Calendar",
	[dijit._Widget, dijit._Templated],
	{
		/*
		summary:
			A simple GUI for choosing a date in the context of a monthly calendar.

		description:
			This widget is used internally by other widgets and is not accessible
			as a standalone widget.
			This widget can't be used in a form because it doesn't serialize the date to an
			<input> field.  For a form element, use DateTextbox instead.

			Note that the parser takes all dates attributes passed in the `RFC 3339` format:
			http://www.faqs.org/rfcs/rfc3339.html (2005-06-30T08:05:00-07:00)
			so that they are serializable and locale-independent.

		usage:
			var calendar = new dijit._Calendar({}, dojo.byId("calendarNode"));
		 	-or-

		*/
		templatePath: dojo.moduleUrl("dijit", "templates/Calendar.html"),

		// value: Date
		// the currently selected Date
		value: new Date(),

		// dayWidth: String
		// How to represent the days of the week in the calendar header. See dojo.date.locale
		dayWidth: "narrow",

		setValue: function(/*Date*/ value){
			// summary: set the current date and update the UI.  If the date is disabled, the selection will
			//	not change, but the display will change to the corresponding month.
			if(!this.value || dojo.date.compare(value, this.value)){
				value = new Date(value);
				this.displayMonth = new Date(value);
				if(!this.isDisabledDate(value, this.lang)){
					this.value = value;
					this.value.setHours(0,0,0,0);
					this.onChange(this.value);
				}
				this._populateGrid();
			}
		},

		_setText: function(node, text){
			while(node.firstChild){
				node.removeChild(node.firstChild);
			}
			node.appendChild(document.createTextNode(text));
		},

		_populateGrid: function(){
			var month = this.displayMonth;
			month.setDate(1);
			var firstDay = month.getDay();
			var daysInMonth = dojo.date.getDaysInMonth(month);
			var daysInPreviousMonth = dojo.date.getDaysInMonth(dojo.date.add(month, "month", -1));
			var today = new Date();
			var selected = this.value;

			var dayOffset = dojo.cldr.supplemental.getFirstDayOfWeek(this.lang);
			if(dayOffset > firstDay){ dayOffset -= 7; }

			// Iterate through dates in the calendar and fill in date numbers and style info
			dojo.query(".calendarDateTemplate", this.domNode).forEach(function(template, i){
				i += dayOffset;
				var date = new Date(month);
				var number, clazz, adj = 0;

				if(i < firstDay){
					number = daysInPreviousMonth - firstDay + i + 1;
					adj = -1;
					clazz = "calendarPrevious";
				}else if(i >= (firstDay + daysInMonth)){
					number = i - firstDay - daysInMonth + 1;
					adj = 1;
					clazz = "calendarNext";
				}else{
					number = i - firstDay + 1;
					clazz = "calendarCurrent";
				}

				if(adj){
					date = dojo.date.add(date, "month", adj);
				}
				date.setDate(number);

				if(!dojo.date.compare(date, today, "date")){
					clazz = "calendarCurrentDate " + clazz;
				}

				if(!dojo.date.compare(date, selected, "date")){
					clazz = "calendarSelectedDate " + clazz;
				}

				if(this.isDisabledDate(date, this.lang)){
					clazz = "calendarDisabledDate " + clazz;
				}

				template.className =  clazz + "Month calendarDateTemplate";
				template.dijitDateValue = date.valueOf();
				var label = dojo.query(".calendarDateLabel", template)[0];
				this._setText(label, date.getDate());
			}, this);

			// Fill in localized month name
			var monthNames = dojo.date.locale.getNames('months', 'wide', 'standAlone', this.lang);
			this._setText(this.monthLabelNode, monthNames[month.getMonth()]);

			// Fill in localized prev/current/next years
			var y = month.getFullYear() - 1;
			dojo.forEach(["previous", "current", "next"], function(name){
				this._setText(this[name+"YearLabelNode"],
					dojo.date.locale.format(new Date(y++, 0), {selector:'year', locale:this.lang}));
			}, this);
		},

		postCreate: function(){
			dijit._Calendar.superclass.postCreate.apply(this);

			var cloneClass = dojo.hitch(this, function(clazz, n){
				var template = dojo.query(clazz, this.domNode)[0];
	 			for(var i=0; i<n; i++){
					template.parentNode.appendChild(template.cloneNode(true));
				}
			});

			// clone the day label and calendar day templates 6 times to make 7 columns
			cloneClass(".calendarDayLabelTemplate", 6);
			cloneClass(".calendarDateTemplate", 6);

			// now make 6 week rows
			cloneClass(".calendarWeekTemplate", 5);

			// insert localized day names in the header
			var dayNames = dojo.date.locale.getNames('days', this.dayWidth, 'standAlone', this.lang);
			var dayOffset = dojo.cldr.supplemental.getFirstDayOfWeek(this.lang);
			dojo.query(".calendarDayLabel", this.domNode).forEach(function(label, i){
				this._setText(label, dayNames[(i + dayOffset) % 7]);
			}, this);

			// Fill in spacer element with all the month names (invisible) so that the maximum width will affect layout
			var monthNames = dojo.date.locale.getNames('months', 'wide', 'standAlone', this.lang);
			dojo.forEach(monthNames, function(name){
				var monthSpacer = dojo.doc.createElement("div");
				this._setText(monthSpacer, name);
				this.monthLabelSpacer.appendChild(monthSpacer);
			}, this);

			this.value = null;
			this.setValue(new Date());

			if(!this.isLeftToRight()){
				var temp = this.decreaseArrowNode.innerHTML;
				this.decreaseArrowNode.innerHTML = this.increaseArrowNode.innerHTML;
				this.increaseArrowNode.innerHTML = temp;
			}
		},

		_adjustDate: function(/*String*/part, /*int*/amount){
			this.displayMonth = dojo.date.add(this.displayMonth, part, amount);
			this._populateGrid();
		},

		_onIncrementMonth: function(/*Event*/evt){
			// summary: handler for increment month event
			evt.stopPropagation();
			this._adjustDate("month", 1);
		},

		_onDecrementMonth: function(/*Event*/evt){
			// summary: handler for increment month event
			evt.stopPropagation();
			this._adjustDate("month", -1);
		},

		_onIncrementYear: function(/*Event*/evt){
			// summary: handler for increment year event
			evt.stopPropagation();
			this._adjustDate("year", 1);
		},

		_onDecrementYear: function(/*Event*/evt){
			// summary: handler for increment year event
			evt.stopPropagation();
			this._adjustDate("year", -1);
		},

		_onDayClick: function(/*Event*/evt){
			var node = evt.target;
			dojo.stopEvent(evt);
			while(!node.dijitDateValue){
				node = node.parentNode;
			}
			if(!dojo.hasClass(node, "calendarDisabledDate")){
				this.setValue(node.dijitDateValue);
				this.onValueSelected(this.value);
			}
		},

		onValueSelected: function(/*Date*/date){
			//summary: a date cell was selected.  It may be the same as the previous value.
		},

		onChange: function(/*Date*/date){
			//summary: called only when the selected date has changed
		},

		isDisabledDate: function(/*Date*/dateObject, /*String?*/locale){
			// summary:
			//	May be overridden to disable certain dates in the calendar e.g. isDisabledDate=dojo.date.locale.isWeekend
			return false; // Boolean
		}
	}
);
<commit_msg>Missed a checkin. Prefix calendar classes with 'dijit'. Refs #3872<commit_after>dojo.provide("dijit._Calendar");

dojo.require("dojo.cldr.supplemental");
dojo.require("dojo.date");
dojo.require("dojo.date.locale");

dojo.require("dijit._Widget");
dojo.require("dijit._Templated");

dojo.declare(
	"dijit._Calendar",
	[dijit._Widget, dijit._Templated],
	{
		/*
		summary:
			A simple GUI for choosing a date in the context of a monthly calendar.

		description:
			This widget is used internally by other widgets and is not accessible
			as a standalone widget.
			This widget can't be used in a form because it doesn't serialize the date to an
			<input> field.  For a form element, use DateTextbox instead.

			Note that the parser takes all dates attributes passed in the `RFC 3339` format:
			http://www.faqs.org/rfcs/rfc3339.html (2005-06-30T08:05:00-07:00)
			so that they are serializable and locale-independent.

		usage:
			var calendar = new dijit._Calendar({}, dojo.byId("calendarNode"));
		 	-or-

		*/
		templatePath: dojo.moduleUrl("dijit", "templates/Calendar.html"),

		// value: Date
		// the currently selected Date
		value: new Date(),

		// dayWidth: String
		// How to represent the days of the week in the calendar header. See dojo.date.locale
		dayWidth: "narrow",

		setValue: function(/*Date*/ value){
			// summary: set the current date and update the UI.  If the date is disabled, the selection will
			//	not change, but the display will change to the corresponding month.
			if(!this.value || dojo.date.compare(value, this.value)){
				value = new Date(value);
				this.displayMonth = new Date(value);
				if(!this.isDisabledDate(value, this.lang)){
					this.value = value;
					this.value.setHours(0,0,0,0);
					this.onChange(this.value);
				}
				this._populateGrid();
			}
		},

		_setText: function(node, text){
			while(node.firstChild){
				node.removeChild(node.firstChild);
			}
			node.appendChild(document.createTextNode(text));
		},

		_populateGrid: function(){
			var month = this.displayMonth;
			month.setDate(1);
			var firstDay = month.getDay();
			var daysInMonth = dojo.date.getDaysInMonth(month);
			var daysInPreviousMonth = dojo.date.getDaysInMonth(dojo.date.add(month, "month", -1));
			var today = new Date();
			var selected = this.value;

			var dayOffset = dojo.cldr.supplemental.getFirstDayOfWeek(this.lang);
			if(dayOffset > firstDay){ dayOffset -= 7; }

			// Iterate through dates in the calendar and fill in date numbers and style info
			dojo.query(".dijitCalendarDateTemplate", this.domNode).forEach(function(template, i){
				i += dayOffset;
				var date = new Date(month);
				var number, clazz = "dijitCalendar", adj = 0;

				if(i < firstDay){
					number = daysInPreviousMonth - firstDay + i + 1;
					adj = -1;
					clazz += "Previous";
				}else if(i >= (firstDay + daysInMonth)){
					number = i - firstDay - daysInMonth + 1;
					adj = 1;
					clazz += "Next";
				}else{
					number = i - firstDay + 1;
					clazz += "Current";
				}

				if(adj){
					date = dojo.date.add(date, "month", adj);
				}
				date.setDate(number);

				if(!dojo.date.compare(date, today, "date")){
					clazz = "dijitCalendarCurrentDate " + clazz;
				}

				if(!dojo.date.compare(date, selected, "date")){
					clazz = "dijitCalendarSelectedDate " + clazz;
				}

				if(this.isDisabledDate(date, this.lang)){
					clazz = "dijitCalendarDisabledDate " + clazz;
				}

				template.className =  clazz + "Month dijitCalendarDateTemplate";
				template.dijitDateValue = date.valueOf();
				var label = dojo.query(".dijitCalendarDateLabel", template)[0];
				this._setText(label, date.getDate());
			}, this);

			// Fill in localized month name
			var monthNames = dojo.date.locale.getNames('months', 'wide', 'standAlone', this.lang);
			this._setText(this.monthLabelNode, monthNames[month.getMonth()]);

			// Fill in localized prev/current/next years
			var y = month.getFullYear() - 1;
			dojo.forEach(["previous", "current", "next"], function(name){
				this._setText(this[name+"YearLabelNode"],
					dojo.date.locale.format(new Date(y++, 0), {selector:'year', locale:this.lang}));
			}, this);
		},

		postCreate: function(){
			dijit._Calendar.superclass.postCreate.apply(this);

			var cloneClass = dojo.hitch(this, function(clazz, n){
				var template = dojo.query(clazz, this.domNode)[0];
	 			for(var i=0; i<n; i++){
					template.parentNode.appendChild(template.cloneNode(true));
				}
			});

			// clone the day label and calendar day templates 6 times to make 7 columns
			cloneClass(".dijitCalendarDayLabelTemplate", 6);
			cloneClass(".dijitCalendarDateTemplate", 6);

			// now make 6 week rows
			cloneClass(".dijitCalendarWeekTemplate", 5);

			// insert localized day names in the header
			var dayNames = dojo.date.locale.getNames('days', this.dayWidth, 'standAlone', this.lang);
			var dayOffset = dojo.cldr.supplemental.getFirstDayOfWeek(this.lang);
			dojo.query(".dijitCalendarDayLabel", this.domNode).forEach(function(label, i){
				this._setText(label, dayNames[(i + dayOffset) % 7]);
			}, this);

			// Fill in spacer element with all the month names (invisible) so that the maximum width will affect layout
			var monthNames = dojo.date.locale.getNames('months', 'wide', 'standAlone', this.lang);
			dojo.forEach(monthNames, function(name){
				var monthSpacer = dojo.doc.createElement("div");
				this._setText(monthSpacer, name);
				this.monthLabelSpacer.appendChild(monthSpacer);
			}, this);

			this.value = null;
			this.setValue(new Date());

			if(!this.isLeftToRight()){
				var temp = this.decreaseArrowNode.innerHTML;
				this.decreaseArrowNode.innerHTML = this.increaseArrowNode.innerHTML;
				this.increaseArrowNode.innerHTML = temp;
			}
		},

		_adjustDate: function(/*String*/part, /*int*/amount){
			this.displayMonth = dojo.date.add(this.displayMonth, part, amount);
			this._populateGrid();
		},

		_onIncrementMonth: function(/*Event*/evt){
			// summary: handler for increment month event
			evt.stopPropagation();
			this._adjustDate("month", 1);
		},

		_onDecrementMonth: function(/*Event*/evt){
			// summary: handler for increment month event
			evt.stopPropagation();
			this._adjustDate("month", -1);
		},

		_onIncrementYear: function(/*Event*/evt){
			// summary: handler for increment year event
			evt.stopPropagation();
			this._adjustDate("year", 1);
		},

		_onDecrementYear: function(/*Event*/evt){
			// summary: handler for increment year event
			evt.stopPropagation();
			this._adjustDate("year", -1);
		},

		_onDayClick: function(/*Event*/evt){
			var node = evt.target;
			dojo.stopEvent(evt);
			while(!node.dijitDateValue){
				node = node.parentNode;
			}
			if(!dojo.hasClass(node, "dijitCalendarDisabledDate")){
				this.setValue(node.dijitDateValue);
				this.onValueSelected(this.value);
			}
		},

		onValueSelected: function(/*Date*/date){
			//summary: a date cell was selected.  It may be the same as the previous value.
		},

		onChange: function(/*Date*/date){
			//summary: called only when the selected date has changed
		},

		isDisabledDate: function(/*Date*/dateObject, /*String?*/locale){
			// summary:
			//	May be overridden to disable certain dates in the calendar e.g. isDisabledDate=dojo.date.locale.isWeekend
			return false; // Boolean
		}
	}
);
<|endoftext|>


<commit_before>import { expect } from 'chai'
import resolve from '../resolve'

describe('resolve', () => {
  const route1 = { foo: 'foo' }
  const route2 = { bar: 'bar' }

  it('returns the last matched route', () => {
    const routes = [route1, route2]
    expect(resolve(routes)).to.eql(route2)
  })

  it('yields route resolution to a `resolve` method', () => {
    const routes = [{ ...route1, resolve: () => route2 }]
    expect(resolve(routes)).to.eql(route2)
  })

  it('supports async `resolve` methods', async () => {
    const routes = [{
      ...route1,
      resolve: async route => (
        await new Promise(done => setTimeout(() => done(route), 10))
      ),
    }]
    expect(await resolve(routes)).to.eql(route1)
  })

  it('provides `resolve` methods with a context', () => {
    const routes = [{
      ...route1,
      resolve: (_, ctx = {}) => ctx.foo,
    }]
    expect(resolve(routes, { foo: 'foo' })).to.eql('foo')
  })

  it('yields child route resolution to parent routes via `next` function', () => {
    const routes = [{
      resolve: (_, { next }) => ({
        ...next(),
        ...route1,
      }),
    }, {
      ...route2,
    }]
    expect(resolve(routes)).to.eql({ ...route1, ...route2 })
  })
})
<commit_msg>add negative match test<commit_after>import { expect } from 'chai'
import resolve from '../resolve'

describe('resolve', () => {
  const route1 = { foo: 'foo' }
  const route2 = { bar: 'bar' }

  it('returns undefined when given empty array', () => {
    const routes = []
    expect(resolve(routes)).to.equal(undefined)
  })

  it('returns the last matched route', () => {
    const routes = [route1, route2]
    expect(resolve(routes)).to.eql(route2)
  })

  it('yields route resolution to a `resolve` method', () => {
    const routes = [{ ...route1, resolve: () => route2 }]
    expect(resolve(routes)).to.eql(route2)
  })

  it('supports async `resolve` methods', async () => {
    const routes = [{
      ...route1,
      resolve: async route => (
        await new Promise(done => setTimeout(() => done(route), 10))
      ),
    }]
    expect(await resolve(routes)).to.eql(route1)
  })

  it('provides `resolve` methods with a context', () => {
    const routes = [{
      ...route1,
      resolve: (_, ctx = {}) => ctx.foo,
    }]
    expect(resolve(routes, { foo: 'foo' })).to.eql('foo')
  })

  it('yields child route resolution to parent routes via `next` function', () => {
    const routes = [{
      resolve: (_, { next }) => ({
        ...next(),
        ...route1,
      }),
    }, {
      ...route2,
    }]
    expect(resolve(routes)).to.eql({ ...route1, ...route2 })
  })
})
<|endoftext|>


<commit_before>require('app');
var angular = require('angular');
<commit_msg>Clean up<commit_after>require('app');<|endoftext|>


<commit_before>/**
* ML template class.
*
* @class FM.MlTemplate
* @memberOf FM
* @extends FM.LmObject
* @param {FM.AppObject} app application object
* @param {object} [attrs] DOM node attributes
* @param {DOMnode} node DOM node
*
*
*/
FM.MlTemplate = FM.defineClass('MlTemplate',FM.LmObject);

// methods
FM.MlTemplate.prototype._init = function(app,attrs,node) {
    this._super("_init",app,attrs);
    this.objectSubClass = "Template";
    this.node = node;
    this.lastTemplateName = '';

    // two way binding
    this.node.fmmlTemplate = this;
    this.getApp().addListener(this);
    this.addListener(this.getApp());
}

FM.MlTemplate.prototype.dispose = function() {
    FM.MlHost.disposeChildNodes(this.getNode());
    this._super("dispose");
}

FM.MlTemplate.prototype.getNode = function() {
    return this.node;
}

FM.MlTemplate.prototype._applyTemplate = function() {
    var me = this;

    // t. args from node attributes
    var args = FM.UtTemplate.getTemplateArgs(this.getAttr());

    // add global arguments (from url query str)
    if(this.getAttr('data-fmml-use-global-args','false') == 'true') {
        var globalArgs = FM.getArgs();
        FM.forEach(globalArgs, function(n,v) {
            if(!FM.isset(args,n)) {
                args[n]=v;
            }
            return true;
        });
    }

    // eval values
    var app = this.getApp();
    var oObj = this.getDmObject();
    FM.forEach(args, function(n,v) {
        if(FM.isString(v) && FM.startsWith(v,'@')) {
            args[n] = FM.resolveAttrValue(null,"-",v,{
                A: app,
                D: oObj,
                T: me
            });
        }
        return true;
    });

    // template name
    var tname = this.getAttr('data-fmml-template','');
    tname = FM.applyTemplate(args, tname, false, false);
    if(tname != this.lastTemplateName) {
        FM.UtTemplate.getTemplate(app,args,tname,function(isok,templ) {
            if(isok) {
                me.lastTemplateName = tname;
                var tmplnode = $(templ);
                var replaced = me.getAttr('data-fmml-template-replace','') == "true";
                if(replaced) {
                    $(me.getNode()).replaceWith(tmplnode);
                    me.node = tmplnode;
                    me.node.fmmlTemplate = me;
                } else {
                    $(me.getNode()).html(templ);
                }
                FM.MlHost.initChildNodes(me.getApp(),me.getNode(),oObj,!replaced);
            }
        });
    }
}

FM.MlTemplate.prototype.run = function(dmObj) {
    this._super("run");
    this.setDmObject(dmObj);

    this._applyTemplate();

}

FM.MlTemplate.prototype.onUrlHashChange = function(sender,hash) {
    if(sender == this.getApp() && this.getAttr('data-fmml-template-type') == 'route') {
        this._applyTemplate();
    }
}

FM.MlTemplate.newTemplate = function(app,attrs,node,oObj) {
    var obj = new FM.MlTemplate(app,attrs,node);
    if(obj && obj.getAttr('data-fmml-run-on-init','true') != 'false') {
        obj.run(oObj);
    }
    return obj;
}
<commit_msg>template apidoc<commit_after>/**
 * -----------------------------------------------------------------------------
 *
 * @review isipka
 *
 * -----------------------------------------------------------------------------
 */
/**
* Generic ML template class.
*
* @class FM.MlTemplate
* @memberOf FM
* @extends FM.LmObject
* @param {FM.AppObject} app Application object.
* @param {object} [attrs] DOM node attributes.
* @param {node} node DOM node.
 * List of DOM attributes (check inherited attributes too):
 *

 *

 *

 *    Name	description	Default
 *

 *

 *

 *

 *    data-fmml-template-type
 *    Template type (only "route" is currently supported)
 *    [...], route
 *

 *

 *    data-fmml-template
 *    Template name
 *    -
 *

 *

 *    data-fmml-template-replace
 *
 *      Replace DOM node instead of his content.
 *
 *    [false], true
 *

 *

 *    data-fmml-run-on-init
 *
 *      Run template after creation.
 *
 *    [true], false
 *

 *

 *

 */
FM.MlTemplate = FM.defineClass('MlTemplate',FM.LmObject);

// methods
FM.MlTemplate.prototype._init = function(app,attrs,node) {
    this._super("_init",app,attrs);
    this.objectSubClass = "Template";
    this.node = node;
    this.lastTemplateName = '';

    // two way binding
    this.node.fmmlTemplate = this;
    this.getApp().addListener(this);
    this.addListener(this.getApp());
}

/**
 * Dispose template.
 *
 * @public
 * @function
 */
FM.MlTemplate.prototype.dispose = function() {
    FM.MlHost.disposeChildNodes(this.getNode());
    this._super("dispose");
}

/**
 * Returns template DOM node.
 *
 * @public
 * @function
 * @returns {node}
 */
FM.MlTemplate.prototype.getNode = function() {
    return this.node;
}

/**
 *
 * @ignore
 */
FM.MlTemplate.prototype._applyTemplate = function() {
    var me = this;

    // t. args from node attributes
    var args = FM.UtTemplate.getTemplateArgs(this.getAttr());

    // add global arguments (from url query str)
    if(this.getAttr('data-fmml-use-global-args','false') == 'true') {
        var globalArgs = FM.getArgs();
        FM.forEach(globalArgs, function(n,v) {
            if(!FM.isset(args,n)) {
                args[n]=v;
            }
            return true;
        });
    }

    // eval values
    var app = this.getApp();
    var oObj = this.getDmObject();
    FM.forEach(args, function(n,v) {
        if(FM.isString(v) && FM.startsWith(v,'@')) {
            args[n] = FM.resolveAttrValue(null,"-",v,{
                A: app,
                D: oObj,
                T: me
            });
        }
        return true;
    });

    // template name
    var tname = this.getAttr('data-fmml-template','');
    tname = FM.applyTemplate(args, tname, false, false);
    if(tname != this.lastTemplateName) {
        FM.UtTemplate.getTemplate(app,args,tname,function(isok,templ) {
            if(isok) {
                me.lastTemplateName = tname;
                var tmplnode = $(templ);
                var replaced = me.getAttr('data-fmml-template-replace','') == "true";
                if(replaced) {
                    $(me.getNode()).replaceWith(tmplnode);
                    me.node = tmplnode;
                    me.node.fmmlTemplate = me;
                } else {
                    $(me.getNode()).html(templ);
                }
                FM.MlHost.initChildNodes(me.getApp(),me.getNode(),oObj,!replaced);
            }
        });
    }
}

/**
 * Run template.
 *
 * @public
 * @function
 * @param {FM.DmObject} [dmObj] Template DM object.
 */
FM.MlTemplate.prototype.run = function(dmObj) {
    this._super("run");
    this.setDmObject(dmObj);

    this._applyTemplate();

}

/**
 * Fired when change on hash of window.location object attributes occurs.
 * If template type is route template will be applyed again.
 *
 * @public
 * @event
 * @param {FM.AppObject} sender This event is sent from application.
 * @param {string} hash New location hash.
 */
FM.MlTemplate.prototype.onUrlHashChange = function(sender,hash) {
    if(sender == this.getApp() && this.getAttr('data-fmml-template-type') == 'route') {
        this._applyTemplate();
    }
}

/**
* Returns new instance of template.
*
* @static
* @public
* @function
* @param {FM.AppObject} app Current application.
* @param {object} attrs Template attributes.
* @param {node} attrs Template node.
* @param {FM.DmObject} [oObj=null] DM object to run template with.
*
* @return {FM.MlTemplate} New template instance.
*/
FM.MlTemplate.newTemplate = function(app,attrs,node,oObj) {
    var obj = new FM.MlTemplate(app,attrs,node);
    if(obj && obj.getAttr('data-fmml-run-on-init','true') != 'false') {
        obj.run(oObj);
    }
    return obj;
}
<|endoftext|>


<commit_before>THREE.TRKLoader = function() {};

Object.assign( THREE.TRKLoader.prototype, THREE.EventDispatcher.prototype, {

    load: function(url, onLoad, onProgress, onError) {
        window.console.log(url, onLoad, onProgress, onError);

        var scope = this;
        var xhr = new XMLHttpRequest();

        function onloaded(event) {
            if (event.target.status === 200 || event.target.status === 0) {
                var geometry = scope.parse(event.target.response || event.target.responseText);
                scope.dispatchEvent({
                    type: 'load',
                    content: geometry,
                });
                if (onLoad) {
                    onLoad(geometry);
                }
            } else {
                scope.dispatchEvent({
                    type: 'error',
                    message: 'Couldn\'t load URL [' + url + ']',
                    response: event.target.statusText,
                });
            }
        }

        xhr.addEventListener('load', onloaded, false);

        xhr.addEventListener('progress', function(event) {
            scope.dispatchEvent({
                type: 'progress',
                loaded: event.loaded,
                total: event.total,
            });
        }, false);

        xhr.addEventListener('error', function() {
            scope.dispatchEvent({
                type: 'error',
                message: 'Couldn\'t load URL [' + url + ']',
            });
        }, false);

        if (xhr.overrideMimeType) {
            xhr.overrideMimeType('text/plain; charset=x-user-defined');
        }

        xhr.open('GET', url, true);

        xhr.responseType = 'arraybuffer';

        xhr.send(null);
    },

    littleEndian: function() {
        var buffer = new ArrayBuffer(2);
        new DataView(buffer).setInt16(0, 256, true);

        return new Int16Array(buffer)[0] === 256;
    },

    scan: function(type, chunks, offset, data) {
        window.console.log(type, chunks, offset, data);
    },

    parse: function(data) {
        var littleEndian = this.littleEndian();
        var reader = new DataView(data);

        // String.fromCharCode
        // str.charCodeAt(position)

        // ////////////////////////////////////////////
        //
        // parse all trk header
        // http://msdn.microsoft.com/en-us/library/s3f49ktz.aspx
        //
        // ////////////////////////////////////////////

        var offset = 0;
        var header = {};

        // id_string[6]
        // char
        // 6
        // ID string for track file. The first 5 characters must be "TRACK".
        header.ID_STRING = [];
        for (var i = 0; i < 6; i++) {
            header.ID_STRING.push(String.fromCharCode(reader.getUint8(offset)));
            offset++;
        }

        // dim[3]
        // short int
        // 6
        // Dimension of the image volume.
        header.dim = [];
        for (var q = 0; q < 3; q++) {
            header.dim.push(reader.getInt16(offset, littleEndian));
            offset += 2;
        }

        // voxel_size[3]
        // float
        // 12
        // Voxel size of the image volume.
        header.VOXEL_SIZE = [];
        for (var r = 0; r < 3; r++) {
            header.VOXEL_SIZE.push(reader.getFloat32(offset, littleEndian));
            offset += 4;
        }
        // origin[3]
        // float
        // 12
        // Origin of the image volume. This field is not yet being used by TrackVis. That means the origin is always (0, 0, 0).
        header.origin = [];
        for (var s = 0; s < 3; s++) {
            header.origin.push(reader.getFloat32(offset, littleEndian));
            offset += 4;
        }

        // n_scalars
        // short int
        // 2
        // Number of scalars saved at each track point (besides x, y and z coordinates).
        header.N_SCALARS = [];
        for (var t = 0; t < 1; t++) {
            header.N_SCALARS.push(reader.getInt16(offset, littleEndian));
            offset += 2;
        }

        //  scalar_name[10][20]
        //  char
        //  200
        //  Name of each scalar. Can not be longer than 20 characters each. Can only store up to 10 names.
        header.SCALAR_NAME = [];
        for (var u = 0; u < 10; u++) {
            header.SCALAR_NAME.push([]);
            for (var v = 0; v < 20; v++) {
                header.SCALAR_NAME[u].push(String.fromCharCode(reader.getUint8(offset)));
                offset++;
            }
        }

        // n_propertiess
        // short int
        // 2
        // Number of properties saved at each track.
        header.N_PROPERTIES = [];
        for (var x = 0; x < 1; x++) {
            header.N_PROPERTIES.push(reader.getInt16(offset, littleEndian));
            offset += 2;
        }

        //  scalar_name[10][20]
        //  char
        //  200
        //  Name of each scalar. Can not be longer than 20 characters each. Can only store up to 10 names.
        header.PROPERTY_NAME = [];
        for (var y = 0; y < 10; y++) {
            header.PROPERTY_NAME.push([]);
            for (var z = 0; z < 20; z++) {
                header.PROPERTY_NAME[y].push(String.fromCharCode(reader.getUint8(offset)));
                offset++;
            }
        }

        // vox_to_ras[4][4]
        // float
        // 64
        // 4x4 matrix for voxel to RAS (crs to xyz) transformation. If vox_to_ras[3][3] is 0, it means the matrix is not recorded. This field is added from version 2.
        header.VOX_TO_RAS = [];
        for (var a = 0; a < 4; a++) {
            header.VOX_TO_RAS.push([]);
            for (var b = 0; b < 4; b++) {
                header.VOX_TO_RAS[a].push(reader.getFloat32(offset));
                offset += 4;
            }
        }

        // reserved[444]
        // char
        // 444
        // Reserved space for future version.
        offset += 444;

        // voxel_order[4]
        // char
        // 4
        // Storing order of the original image data.
        header.VOXEL_ORDER = [];
        for (var c = 0; c < 4; c++) {
            header.VOXEL_ORDER.push(String.fromCharCode(reader.getUint8(offset)));
            offset++;
        }

        // pad2[4]
        // char
        // 4
        // Paddings.
        header.pad2 = [];
        for (var d = 0; d < 4; d++) {
            header.pad2.push(String.fromCharCode(reader.getUint8(offset)));
            offset++;
        }

        // image_orientation_patient[6]
        // float
        // 24
        // Image orientation of the original image. As defined in the DICOM header.
        header.IMAGE_ORIENTATION_PATIENT = [];
        for (var e = 0; e < 6; e++) {
            header.IMAGE_ORIENTATION_PATIENT.push(reader.getFloat32(offset, littleEndian));
            offset += 4;
        }

        // pad1[2]
        // char
        // 2
        // Paddings.
        header.pad1 = [];
        for (var f = 0; f < 2; f++) {
            header.pad2.push(String.fromCharCode(reader.getUint8(offset)));
            offset++;
        }

        // invert_x, invert_y, invert_z, swap_xy, swap_yz, swap_zx
        // unsigned_char
        // 1
        // Inversion/rotation flags used to generate this track file. For internal use only.
        header.INVERT_X = [];
        for (var g = 0; g < 1; g++) {
            header.INVERT_X.push(String.fromCharCode(reader.getUint8(offset)));
            offset++;
        }
        header.INVERT_Y = [];
        for (var h = 0; h < 1; h++) {
            header.INVERT_Y.push(String.fromCharCode(reader.getUint8(offset)));
            offset++;
        }
        header.INVERT_Z = [];
        for (var ii = 0; ii < 1; ii++) {
            header.INVERT_Z.push(String.fromCharCode(reader.getUint8(offset)));
            offset++;
        }
        header.SWAP_XY = [];
        for (var ij = 0; ij < 1; ij++) {
            header.SWAP_XY.push(String.fromCharCode(reader.getUint8(offset)));
            offset++;
        }
        header.SWAP_YZ = [];
        for (var ik = 0; ik < 1; ik++) {
            header.SWAP_YZ.push(String.fromCharCode(reader.getUint8(offset)));
            offset++;
        }
        header.SWAP_ZX = [];
        for (var il = 0; il < 1; il++) {
            header.SWAP_ZX.push(String.fromCharCode(reader.getUint8(offset)));
            offset++;
        }

        // n_count
        // int
        // 4
        // Number of tracks stored in this track file. 0 means the number was NOT stored.
        header.N_COUNT = [];
        for (var im = 0; im < 1; im++) {
            header.N_COUNT.push(reader.getUint32(offset, littleEndian));
            offset += 4;
        }

        // version
        // int
        // 4
        // Version number. Current version is 2.
        header.version = [];
        for (var io = 0; io < 1; io++) {
            header.version.push(reader.getUint32(offset, littleEndian));
            offset += 4;
        }

        // hdr_size
        // int
        // 4
        // Size of the header. Used to determine byte swap. Should be 1000.
        header.HDR_SIZE = [];
        for (var ip = 0; ip < 1; ip++) {
            header.HDR_SIZE.push(reader.getUint32(offset, littleEndian));
            offset += 4;
        }

        window.console.log(header);

        // /////////////////////////////////////
        //
        // parse the tracts now...!
        //
        // ////////////////////////////////////

        // we should also store each track length

        // get the number of points in this track
        var tracks = [];

        while (offset < reader.byteLength) {
            var nbPoints = -1;
            nbPoints = reader.getUint32(offset, littleEndian);
            offset += 4;

            var track = {
                'points': [],
                'scalars': [],
                'properties': [],
                'geometry': new THREE.Geometry(),
                'xProperties': {},
            };

            var length = 0;

            for (var k = 0; k < nbPoints; k++) {
                // first 3 floats are the coordinates
                track.points[k] = [];
                track.points[k].push(reader.getFloat32(offset, littleEndian));
                offset += 4;
                track.points[k].push(reader.getFloat32(offset, littleEndian));
                offset += 4;
                track.points[k].push(reader.getFloat32(offset, littleEndian));
                offset += 4;

                // add geometry
                //
                track.geometry.vertices.push(new THREE.Vector3(track.points[k][0], track.points[k][1], track.points[k][2]));

                // then the scalars
                track.scalars[k] = [];
                for (var l = 0; l < header.N_SCALARS[0]; l++) {
                    track.scalars[k][l] = [];
                    track.scalars[k][l].push(reader.getFloat32(offset, littleEndian));
                    offset += 4;
                    track.scalars[k][l].push(reader.getFloat32(offset, littleEndian));
                    offset += 4;
                    track.scalars[k][l].push(reader.getFloat32(offset, littleEndian));
                    offset += 4;
                }

                if (k !== 0) {
                    // get previous and current points
                    var prev = track.points[k - 1];
                    var cur = track.points[k];
                    var xDist = cur[0] - prev[0];
                    var yDist = cur[1] - prev[1];
                    var zDist = cur[2] - prev[2];
                    // get distance
                    var distance = Math.sqrt(Math.pow(xDist, 2) + Math.pow(yDist, 2) + Math.pow(zDist, 2));
                    // add add to length
                    length += distance;
                }
            }

            track.xProperties.length = length;

            for (var p = 0; p < nbPoints; p++) {
                // get previous point if any
                var first = track.points[0];
                if (p > 1) {
                    first = track.points[p - 1];
                }

                // get next point if any
                var last = track.points[nbPoints - 1];
                if (p < nbPoints - 2) {
                    last = track.points[p + 1];
                }

                var diff = [Math.abs(last[0] - first[0]),
                    Math.abs(last[1] - first[1]),
                    Math.abs(last[2] - first[2]),
                ];

                var colordistance = Math.sqrt(diff[0] * diff[0] + diff[1] * diff[1] + diff[2] * diff[2]);
                diff[0] /= colordistance;
                diff[1] /= colordistance;
                diff[2] /= colordistance;

                track.geometry.colors.push(new THREE.Color(diff[0], diff[1], diff[2]));
            }

            // get the property of this track
            for (var o = 0; o < header.N_PROPERTIES[0]; o++) {
                track.properties[o] = [];
                track.properties[o].push(reader.getFloat32(offset, littleEndian));
                offset += 4;
                track.properties[o].push(reader.getFloat32(offset, littleEndian));
                offset += 4;
                track.properties[o].push(reader.getFloat32(offset, littleEndian));
                offset += 4;
            }

            tracks.push(track);
        }

        return tracks;
    },

};
<commit_msg>Update loaders.trk.js<commit_after>THREE.TRKLoader = function() {};

Object.assign( THREE.TRKLoader.prototype, THREE.EventDispatcher.prototype, {

    load: function(url, onLoad, onProgress, onError) {
        window.console.log(url, onLoad, onProgress, onError);

        var scope = this;
        var xhr = new XMLHttpRequest();

        function onloaded(event) {
            if (event.target.status === 200 || event.target.status === 0) {
                var geometry = scope.parse(event.target.response || event.target.responseText);
                scope.dispatchEvent({
                    type: 'load',
                    content: geometry,
                });
                if (onLoad) {
                    onLoad(geometry);
                }
            } else {
                scope.dispatchEvent({
                    type: 'error',
                    message: 'Couldn\'t load URL [' + url + ']',
                    response: event.target.statusText,
                });
            }
        }

        xhr.addEventListener('load', onloaded, false);

        xhr.addEventListener('progress', function(event) {
            scope.dispatchEvent({
                type: 'progress',
                loaded: event.loaded,
                total: event.total,
            });
        }, false);

        xhr.addEventListener('error', function() {
            scope.dispatchEvent({
                type: 'error',
                message: 'Couldn\'t load URL [' + url + ']',
            });
        }, false);

        if (xhr.overrideMimeType) {
            xhr.overrideMimeType('text/plain; charset=x-user-defined');
        }

        xhr.open('GET', url, true);

        xhr.responseType = 'arraybuffer';

        xhr.send(null);
    },

    littleEndian: function() {
        var buffer = new ArrayBuffer(2);
        new DataView(buffer).setInt16(0, 256, true);

        return new Int16Array(buffer)[0] === 256;
    },

    scan: function(type, chunks, offset, data) {
        window.console.log(type, chunks, offset, data);
    },

    parse: function(data) {
        var littleEndian = this.littleEndian();
        var reader = new DataView(data);

        // String.fromCharCode
        // str.charCodeAt(position)

        // ////////////////////////////////////////////
        //
        // parse all trk header
        // http://msdn.microsoft.com/en-us/library/s3f49ktz.aspx
        //
        // ////////////////////////////////////////////

        var offset = 0;
        var header = {};

        // id_string[6]
        // char
        // 6
        // ID string for track file. The first 5 characters must be "TRACK".
        header.ID_STRING = [];
        for (var i = 0; i < 6; i++) {
            header.ID_STRING.push(String.fromCharCode(reader.getUint8(offset)));
            offset++;
        }

        // dim[3]
        // short int
        // 6
        // Dimension of the image volume.
        header.dim = [];
        for (var q = 0; q < 3; q++) {
            header.dim.push(reader.getInt16(offset, littleEndian));
            offset += 2;
        }

        // voxel_size[3]
        // float
        // 12
        // Voxel size of the image volume.
        header.VOXEL_SIZE = [];
        for (var r = 0; r < 3; r++) {
            header.VOXEL_SIZE.push(reader.getFloat32(offset, littleEndian));
            offset += 4;
        }
        // origin[3]
        // float
        // 12
        // Origin of the image volume. This field is not yet being used by TrackVis. That means the origin is always (0, 0, 0).
        header.origin = [];
        for (var s = 0; s < 3; s++) {
            header.origin.push(reader.getFloat32(offset, littleEndian));
            offset += 4;
        }

        // n_scalars
        // short int
        // 2
        // Number of scalars saved at each track point (besides x, y and z coordinates).
        header.N_SCALARS = [];
        for (var t = 0; t < 1; t++) {
            header.N_SCALARS.push(reader.getInt16(offset, littleEndian));
            offset += 2;
        }

        //  scalar_name[10][20]
        //  char
        //  200
        //  Name of each scalar. Can not be longer than 20 characters each. Can only store up to 10 names.
        header.SCALAR_NAME = [];
        for (var u = 0; u < 10; u++) {
            header.SCALAR_NAME.push([]);
            for (var v = 0; v < 20; v++) {
                header.SCALAR_NAME[u].push(String.fromCharCode(reader.getUint8(offset)));
                offset++;
            }
        }

        // n_propertiess
        // short int
        // 2
        // Number of properties saved at each track.
        header.N_PROPERTIES = [];
        for (var x = 0; x < 1; x++) {
            header.N_PROPERTIES.push(reader.getInt16(offset, littleEndian));
            offset += 2;
        }

        //  scalar_name[10][20]
        //  char
        //  200
        //  Name of each scalar. Can not be longer than 20 characters each. Can only store up to 10 names.
        header.PROPERTY_NAME = [];
        for (var y = 0; y < 10; y++) {
            header.PROPERTY_NAME.push([]);
            for (var z = 0; z < 20; z++) {
                header.PROPERTY_NAME[y].push(String.fromCharCode(reader.getUint8(offset)));
                offset++;
            }
        }

        // vox_to_ras[4][4]
        // float
        // 64
        // 4x4 matrix for voxel to RAS (crs to xyz) transformation. If vox_to_ras[3][3] is 0, it means the matrix is not recorded. This field is added from version 2.
        header.VOX_TO_RAS = [];
        for (var a = 0; a < 4; a++) {
            header.VOX_TO_RAS.push([]);
            for (var b = 0; b < 4; b++) {
                header.VOX_TO_RAS[a].push(reader.getFloat32(offset));
                offset += 4;
            }
        }

        // reserved[444]
        // char
        // 444
        // Reserved space for future version.
        offset += 444;

        // voxel_order[4]
        // char
        // 4
        // Storing order of the original image data.
        header.VOXEL_ORDER = [];
        for (var c = 0; c < 4; c++) {
            header.VOXEL_ORDER.push(String.fromCharCode(reader.getUint8(offset)));
            offset++;
        }

        // pad2[4]
        // char
        // 4
        // Paddings.
        header.pad2 = [];
        for (var d = 0; d < 4; d++) {
            header.pad2.push(String.fromCharCode(reader.getUint8(offset)));
            offset++;
        }

        // image_orientation_patient[6]
        // float
        // 24
        // Image orientation of the original image. As defined in the DICOM header.
        header.IMAGE_ORIENTATION_PATIENT = [];
        for (var e = 0; e < 6; e++) {
            header.IMAGE_ORIENTATION_PATIENT.push(reader.getFloat32(offset, littleEndian));
            offset += 4;
        }

        // pad1[2]
        // char
        // 2
        // Paddings.
        header.pad1 = [];
        for (var f = 0; f < 2; f++) {
            header.pad2.push(String.fromCharCode(reader.getUint8(offset)));
            offset++;
        }

        // invert_x, invert_y, invert_z, swap_xy, swap_yz, swap_zx
        // unsigned_char
        // 1
        // Inversion/rotation flags used to generate this track file. For internal use only.
        header.INVERT_X = [];
        for (var g = 0; g < 1; g++) {
            header.INVERT_X.push(String.fromCharCode(reader.getUint8(offset)));
            offset++;
        }
        header.INVERT_Y = [];
        for (var h = 0; h < 1; h++) {
            header.INVERT_Y.push(String.fromCharCode(reader.getUint8(offset)));
            offset++;
        }
        header.INVERT_Z = [];
        for (var ii = 0; ii < 1; ii++) {
            header.INVERT_Z.push(String.fromCharCode(reader.getUint8(offset)));
            offset++;
        }
        header.SWAP_XY = [];
        for (var ij = 0; ij < 1; ij++) {
            header.SWAP_XY.push(String.fromCharCode(reader.getUint8(offset)));
            offset++;
        }
        header.SWAP_YZ = [];
        for (var ik = 0; ik < 1; ik++) {
            header.SWAP_YZ.push(String.fromCharCode(reader.getUint8(offset)));
            offset++;
        }
        header.SWAP_ZX = [];
        for (var il = 0; il < 1; il++) {
            header.SWAP_ZX.push(String.fromCharCode(reader.getUint8(offset)));
            offset++;
        }

        // n_count
        // int
        // 4
        // Number of tracks stored in this track file. 0 means the number was NOT stored.
        header.N_COUNT = [];
        for (var im = 0; im < 1; im++) {
            header.N_COUNT.push(reader.getUint32(offset, littleEndian));
            offset += 4;
        }

        // version
        // int
        // 4
        // Version number. Current version is 2.
        header.version = [];
        for (var io = 0; io < 1; io++) {
            header.version.push(reader.getUint32(offset, littleEndian));
            offset += 4;
        }

        // hdr_size
        // int
        // 4
        // Size of the header. Used to determine byte swap. Should be 1000.
        header.HDR_SIZE = [];
        for (var ip = 0; ip < 1; ip++) {
            header.HDR_SIZE.push(reader.getUint32(offset, littleEndian));
            offset += 4;
        }

        window.console.log(header);

        // /////////////////////////////////////
        //
        // parse the tracts now...!
        //
        // ////////////////////////////////////

        // we should also store each track length

        // get the number of points in this track
        var tracks = [];

        while (offset < reader.byteLength) {
            var nbPoints = -1;
            nbPoints = reader.getUint32(offset, littleEndian);
            offset += 4;

            var track = {
                'points': [],
                'scalars': [],
                'properties': [],
                'geometry': new THREE.Geometry(),
                'xProperties': {},
            };

            var length = 0;

            for (var k = 0; k < nbPoints; k++) {
                // first 3 floats are the coordinates
                track.points[k] = [];
                track.points[k].push(reader.getFloat32(offset, littleEndian));
                offset += 4;
                track.points[k].push(reader.getFloat32(offset, littleEndian));
                offset += 4;
                track.points[k].push(reader.getFloat32(offset, littleEndian));
                offset += 4;

                // add geometry
                //
                track.geometry.vertices.push(new THREE.Vector3(track.points[k][0], track.points[k][1], track.points[k][2]));

                // then the scalars
                track.scalars[k] = [];
                for (var l = 0; l < header.N_SCALARS[0]; l++) {
                    track.scalars[k][l] = [];
                    track.scalars[k][l].push(reader.getFloat32(offset, littleEndian));
                    offset += 4;
                    track.scalars[k][l].push(reader.getFloat32(offset, littleEndian));
                    offset += 4;
                    track.scalars[k][l].push(reader.getFloat32(offset, littleEndian));
                    offset += 4;
                }

                if (k !== 0) {
                    // get previous and current points
                    var prev = track.points[k - 1];
                    var cur = track.points[k];
                    var xDist = cur[0] - prev[0];
                    var yDist = cur[1] - prev[1];
                    var zDist = cur[2] - prev[2];
                    // get distance
                    var distance = Math.sqrt(Math.pow(xDist, 2) + Math.pow(yDist, 2) + Math.pow(zDist, 2));
                    // add add to length
                    length += distance;
                }
            }

            track.xProperties.length = length;

            for (var p = 0; p < nbPoints; p++) {
                // get previous point if any
                var first = track.points[0];
                if (p > 1) {
                    first = track.points[p - 1];
                }

                // get next point if any
                var last = track.points[nbPoints - 1];
                if (p < nbPoints - 2) {
                    last = track.points[p + 1];
                }

                var diff = [Math.abs(last[0] - first[0]),
                    Math.abs(last[1] - first[1]),
                    Math.abs(last[2] - first[2]),
                ];

                var colordistance = Math.sqrt(diff[0] * diff[0] + diff[1] * diff[1] + diff[2] * diff[2]);
                diff[0] /= colordistance;
                diff[1] /= colordistance;
                diff[2] /= colordistance;

                track.geometry.colors.push(new THREE.Color(diff[0], diff[1], diff[2]));
            }

            // get the property of this track
            for (var o = 0; o < header.N_PROPERTIES[0]; o++) {
                track.properties[o] = [];
                track.properties[o].push(reader.getFloat32(offset, littleEndian));
                offset += 4;
                track.properties[o].push(reader.getFloat32(offset, littleEndian));
                offset += 4;
                track.properties[o].push(reader.getFloat32(offset, littleEndian));
                offset += 4;
            }

            tracks.push(track);
        }

        return tracks;
    }
};
<|endoftext|>


<commit_before>// Unit test for a.model (plugin)

module('plugin/model.js', {
    setup: function() {

    },
    teardown: function() {
        a.modelManager.clear();
    }
});

// Test nullable properties
test('a.model.property-nullable', function() {
    var unittest = a.model('unittest-nullable', {
        testnullable: {
            nullable: true,
            init: 'ok'
        },
        testnotnullable: {
            nullable: false,
            init: 'ok'
        }
    });
    var unit = new unittest();

    // Test changing data for null
    unit.set('testnullable', null);
    unit.set('testnotnullable', null);

    strictEqual(unit.get('testnullable'), null, 'Test nullable');
    strictEqual(unit.get('testnotnullable'), 'ok', 'Test not nullable');
});

// Test init properties
test('a.model.property-init', function() {
    var unittest = a.model('unittest-prop-init', {
        testinit: {
            init: 'ok'
        }
    });

    var unit = new unittest();

    // Test changing data
    strictEqual(unit.get('testinit'), 'ok', 'Test init');

    unit.set('testinit', 'something');
    strictEqual(unit.get('testinit'), 'something', 'Test erase init');

    unit.init();

    strictEqual(unit.get('testinit'), 'ok', 'Test clear init');
});

// Test property needed
test('a.model.property-needed', function() {
    var unittest = a.model('unittest-needed', {
        need: {
            needed: true,
            init: 'ok'
        },
        notneeded: {
            needed: false,
            init: 'ok'
        }
    });

    var unit = new unittest();

    unit.takeSnapshot();
    var snapshot = unit.differenceSnapshot(true);

    // Test outputted value
    strictEqual(snapshot.needed, undefined);
    strictEqual(snapshot.need, 'ok');
});

// Test property check
test('a.model.property-check', function() {
    var unittest = a.model('unittest-check', {
        testcheck: {
            init: 'ok',
            check: 'String'
        }
    });

    var unit = new unittest();

    strictEqual(unit.get('testcheck'), 'ok', 'Test init value');

    unit.set('testcheck', 'get');
    strictEqual(unit.get('testcheck'), 'get', 'Test second value');

    unit.get('testcheck', 12);
    strictEqual(unit.get('testcheck'), 'get', 'Test thrid value not setted');
});

// Test property check, for a model (a model include a model)
test('a.model.property-check-model', function() {
    var child = a.model('unittest-check-child', {
        test: {
            init: 'ok',
            check: 'String',
            validate: function(value) {
                strictEqual(value, 'piou');
            }
        }
    });

    var parent = a.model('unittest-check-parent', {
        sub: {
            check: 'unittest-check-child'
        }
    });

    // We create a new parent, and check validation is raised on child
    // element
    var c = new parent(),
        d = new child();

    c.set('sub', d);

    // Set element raise the validate method
    c.get('sub').set('test', 'piou');
});

// Test property check, for a list of values
test('a.model.property-check-array', function() {
    var unittest = a.model('unittest-check-array', {
        testcheck: {
            init: 'ok',
            check: ['a', 'yeah', 'okay']
        }
    });

    var unit = new unittest();

    strictEqual(unit.get('testcheck'), 'ok', 'Test init value');

    unit.set('testcheck', 'get');
    strictEqual(unit.get('testcheck'), 'ok', 'Test still init value');

    unit.set('testcheck', 'yeah');
    strictEqual(unit.get('testcheck'), 'yeah', 'Test second value');

    unit.set('testcheck', 'a');
    strictEqual(unit.get('testcheck'), 'a', 'Test thrid value');

    unit.set('testcheck', 'yup');
    strictEqual(unit.get('testcheck'), 'a', 'Test still thrid value');

    unit.set('testcheck', 'okay');
    strictEqual(unit.get('testcheck'), 'okay', 'Test fourth value');
});

// Test property check, for a list of values
test('a.model.property-check-object', function() {
    var unittest = a.model('unittest-check-object', {
        testcheck: {
            init: 'ok',
            check: {
                'a': 'something great',
                'yeah': 'another',
                'okay': 'still good'
            }
        }
    });

    var unit = new unittest();

    strictEqual(unit.get('testcheck'), 'ok', 'Test init value');

    unit.set('testcheck', 'get');
    strictEqual(unit.get('testcheck'), 'ok', 'Test still init value');

    unit.set('testcheck', 'yeah');
    strictEqual(unit.get('testcheck'), 'yeah', 'Test second value');

    unit.set('testcheck', 'a');
    strictEqual(unit.get('testcheck'), 'a', 'Test thrid value');

    unit.set('testcheck', 'yup');
    strictEqual(unit.get('testcheck'), 'a', 'Test still thrid value');

    unit.set('testcheck', 'okay');
    strictEqual(unit.get('testcheck'), 'okay', 'Test fourth value');
});

// Test property validate
test('a.model.property-validate', function() {
    var unittest = a.model('unittest-validate', {
        testvalidate: {
            init: 'ok',
            validate: function(value, old) {
                if(value == 'something') {
                    return true;
                }
            }
        }
    });

    var unit = new unittest();

    strictEqual(unit.get('testvalidate'), 'ok', 'Test init value');

    unit.set('testvalidate', 'another');
    strictEqual(unit.get('testvalidate'), 'ok', 'Test still init value');

    unit.set('testvalidate', 'something');
    strictEqual(unit.get('testvalidate'), 'something', 'Test accepted');
});

// Test property pattern
test('a.model.property-pattern', function() {
    var test = a.model('unittest-pattern', {
        name: {
            init: 'hello',
            check: 'string',
            pattern: '^[a-zA-Z0-9]+$'
        }
    });

    var instance = new test();

    strictEqual(instance.get('name'), 'hello');

    instance.set('name', '__');
    // Refused by pattern
    strictEqual(instance.get('name'), 'hello');

    instance.set('name', 'abcd09');
    // Allowed by pattern
    strictEqual(instance.get('name'), 'abcd09');

    instance.set('name', 'abcd09-');
    // Refused by pattern
    strictEqual(instance.get('name'), 'abcd09');
});

// Test property transform
test('a.model.property-transform', function() {
    var unittest = a.model('unittest-transform', {
        testtransform: {
            init: 'ok',
            transform: function piou(value, old) {
                return '' + old + value;
            }
        }
    });

    var unit = new unittest();

    strictEqual(unit.get('testtransform'), 'ok', 'Test init value');

    unit.set('testtransform', 'something');
    strictEqual(unit.get('testtransform'), 'oksomething', 'Test concat');

    unit.set('testtransform', 'another');
    strictEqual(unit.get('testtransform'), 'oksomethinganother', 'Second');
});

// Test property event
asyncTest('a.model.property-event', function() {
    expect(2);

    var unittest = a.model('unittest-event', {
        evt: {
            init: 'another',
            event: 'super'
        }
    });

    var unit = new unittest();

    function eventMatcher(data) {
        if(data.value == 'something') {
            strictEqual(data.value, 'something', 'Test something value');
        } else {
            strictEqual(data.value, 'ok', 'Test ok value');
            start();
        }
    };

    unit.bind('super', eventMatcher);

    unit.set('evt', 'something');

    setTimeout(function() {
        unit.set('evt', 'ok');
    }, 150);
});

// Test property apply
asyncTest('a.model.property-apply', function() {
    expect(1);

    var unittest = a.model('unittest-apply', {
        app: {
            init: 'another',
            apply: function(value, old) {
                strictEqual(value, 'ok');
                start();
            }
        }
    });

    var unit = new unittest();

    unit.set('app', 'ok');
});

// Test list function
test('a.model.list', function() {
    var unittest = a.model('unittest-list', {
        A: {
            init: 'ok'
        },
        B: {
            init: 'something'
        }
    });

    var unit = new unittest();
    var list = unit.list();

    strictEqual(list.join(','), 'A,B');
});

// Test has function
test('a.model.has', function() {
    var unittest = a.model('unittest-has', {
        A: {
            init: 'ok'
        },
        B: {
            init: 'something'
        }
    });

    var unit = new unittest();

    strictEqual(unit.has('A'), true);
    strictEqual(unit.has('B'), true);
    strictEqual(unit.has('C'), false);
});

// Test init function
test('a.model.init', function() {
    var unittest = a.model('unittest-init', {
        testA: {
            init: 'ok'
        },
        testB: {
            init: 'something'
        },
        testC: {
            // Value will be erased on first loading
            value: 'notok'
        }
    });

    var unit = new unittest();

    // First init
    strictEqual(unit.get('testA'), 'ok', 'Test init1');
    strictEqual(unit.get('testB'), 'something', 'Test init2');
    strictEqual(unit.get('testC'), null, 'Test init3');

    // Change init
    unit.set('testA', 'another');
    unit.set('testB', 'stuff');
    unit.set('testC', 'great');

    strictEqual(unit.get('testA'), 'another', 'Test change init1');
    strictEqual(unit.get('testB'), 'stuff', 'Test change init2');
    strictEqual(unit.get('testC'), 'great', 'Test change init3');

    // Rollback init
    unit.init();

    // Second init
    strictEqual(unit.get('testA'), 'ok', 'Test rollback init1');
    strictEqual(unit.get('testB'), 'something', 'Test rollback init2');
    strictEqual(unit.get('testC'), null, 'Test rollback init3');
});

// Test jsons function
test('a.model.json', function() {
    var unittest = a.model('unittest-json', {
        testA: {
            init: 'something'
        },
        testB: {
            init: 'great'
        }
    });

    var unit = new unittest();
    unit.set('testA', 'another');
    var json = unit.toJSON();

    strictEqual(json, '{"testA":"another","testB":"great"}', 'Test JSON');

    var second = new unittest();
    second.fromJSON(json);

    var alternative = second.toJSON();

    strictEqual(alternative, '{"testA":"another","testB":"great"}', 'Test second');
});

// Test Object output
test('a.model.object', function() {
    var unittest = a.model('unittest-object', {
        testA: {
            init: 'something'
        },
        testB: {
            init: 'great'
        }
    });

    var unit = new unittest();
    unit.set('testA', 'another');
    var obj1 = unit.toObject();

    strictEqual(obj1.testA, 'another', 'Test first Object');
    strictEqual(obj1.testB, 'great', 'Test first Object');

    var second = new unittest();
    second.fromObject(obj1);

    var obj2 = second.toObject();

    strictEqual(obj2.testA, 'another', 'Test second Object');
    strictEqual(obj2.testB, 'great', 'Test second Object');
});

// Test snapshot function
test('a.model.snapshot', function() {
    var unittest = a.model('unittest-snapshot', {
        snap: {
            needed: true,
            init: 'ok'
        },
        nosnap: {
            init: 'notok'
        },
        so: {
            init: 'something'
        }
    });

    var unit = new unittest();
    // Taking snapshot
    unit.takeSnapshot();

    var firstSimpleSnapshot  = a.parser.json.stringify(
                    unit.differenceSnapshot(true)
        ),
        firstComplexSnapshot = a.parser.json.stringify(
                    unit.differenceSnapshot(false)
        );

    strictEqual(firstSimpleSnapshot, '{"snap":"ok"}');
    strictEqual(firstComplexSnapshot, '{"snap":{"value":"ok","old":"ok"}}')
});

// Test model manager
test('a.modelManager', function() {
    var model = a.model('modelmanagertest', {}, null);

    var instance1 = new model(),
        instance2 = new model();

    var storedInstance1 = a.modelManager.get(instance1.uid),
        storedInstance2 = a.modelManager.get(instance2.uid);

    strictEqual(storedInstance1.uid, instance1.uid);
    strictEqual(storedInstance2.uid, instance2.uid);

    var list = a.modelManager.getByName('modelmanagertest');

    // We test the list element before removing everything inside
    strictEqual(list.length, 2);
    if(list[0].uid == instance1.uid) {
        strictEqual(list[0].uid, instance1.uid);
        strictEqual(list[1].uid, instance2.uid);
    } else {
        strictEqual(list[1].uid, instance1.uid);
        strictEqual(list[0].uid, instance2.uid);
    }

    a.modelManager.remove(storedInstance1.uid);
    strictEqual(a.modelManager.get(instance1.uid), null);
    strictEqual(a.modelManager.get(instance2.uid).uid, instance2.uid);

    a.modelManager.remove(storedInstance2.uid);
});

// Unit test multiple model management
asyncTest('a.model.model-multiple', function() {
    expect(4);

    var unittest = a.model('unittest-multiple', {
        id: {
            init: 0,
            event: 'yatta'
        }
    });

    var unittest1 = new unittest(),
        unittest2 = new unittest();

    unittest1.bind('yatta', function(data) {
        strictEqual(data.value, 5, 'Testing data update 1');
        strictEqual(unittest1.get('id'), 5, 'Testing model update 1');
    });
    unittest2.bind('yatta', function(data) {
        strictEqual(data.value, 6, 'Testing data update 2');
        strictEqual(unittest2.get('id'), 6, 'Testing model update 2');
        start();
    });

    unittest1.set('id', 5);
    unittest2.set('id', 6);
});

// Test modelManager searchInstance function
test('a.model.searchInstance', function() {
    var unittest = a.model('unittest-searchInstance', {
        id: {
            check: 'number'
        },
        name: {
            init: 'piou'
        },
        val: {
            init: 5
        }
    });

    var test1 = new unittest(),
        test2 = new unittest();

    test1.set('id', 3);
    test1.set('name', 'ok');

    test2.set('id', 20);
    test2.set('val', 12);
    test2.set('name', 'something');

    var getTest1 = a.model({
            model: 'unittest-searchInstance',
            name: 'ok'
        }),
        getTest2 = a.model({
            model: 'unittest-searchInstance',
            name: 'something',
            val: 12
        });

    strictEqual(getTest1.get('id'), 3);
    strictEqual(getTest2.get('id'), 20);
});

test('a.model.validates', function() {
    ok(1==1);
});

test('a.model.requests', function() {
    ok(1==1);
});<commit_msg>Adding unit test for new clone function.<commit_after>// Unit test for a.model (plugin)

module('plugin/model.js', {
    setup: function() {

    },
    teardown: function() {
        a.modelManager.clear();
    }
});

// Test nullable properties
test('a.model.property-nullable', function() {
    var unittest = a.model('unittest-nullable', {
        testnullable: {
            nullable: true,
            init: 'ok'
        },
        testnotnullable: {
            nullable: false,
            init: 'ok'
        }
    });
    var unit = new unittest();

    // Test changing data for null
    unit.set('testnullable', null);
    unit.set('testnotnullable', null);

    strictEqual(unit.get('testnullable'), null, 'Test nullable');
    strictEqual(unit.get('testnotnullable'), 'ok', 'Test not nullable');
});

// Test init properties
test('a.model.property-init', function() {
    var unittest = a.model('unittest-prop-init', {
        testinit: {
            init: 'ok'
        }
    });

    var unit = new unittest();

    // Test changing data
    strictEqual(unit.get('testinit'), 'ok', 'Test init');

    unit.set('testinit', 'something');
    strictEqual(unit.get('testinit'), 'something', 'Test erase init');

    unit.init();

    strictEqual(unit.get('testinit'), 'ok', 'Test clear init');
});

// Test property needed
test('a.model.property-needed', function() {
    var unittest = a.model('unittest-needed', {
        need: {
            needed: true,
            init: 'ok'
        },
        notneeded: {
            needed: false,
            init: 'ok'
        }
    });

    var unit = new unittest();

    unit.takeSnapshot();
    var snapshot = unit.differenceSnapshot(true);

    // Test outputted value
    strictEqual(snapshot.needed, undefined);
    strictEqual(snapshot.need, 'ok');
});

// Test property check
test('a.model.property-check', function() {
    var unittest = a.model('unittest-check', {
        testcheck: {
            init: 'ok',
            check: 'String'
        }
    });

    var unit = new unittest();

    strictEqual(unit.get('testcheck'), 'ok', 'Test init value');

    unit.set('testcheck', 'get');
    strictEqual(unit.get('testcheck'), 'get', 'Test second value');

    unit.get('testcheck', 12);
    strictEqual(unit.get('testcheck'), 'get', 'Test thrid value not setted');
});

// Test property check, for a model (a model include a model)
test('a.model.property-check-model', function() {
    var child = a.model('unittest-check-child', {
        test: {
            init: 'ok',
            check: 'String',
            validate: function(value) {
                strictEqual(value, 'piou');
            }
        }
    });

    var parent = a.model('unittest-check-parent', {
        sub: {
            check: 'unittest-check-child'
        }
    });

    // We create a new parent, and check validation is raised on child
    // element
    var c = new parent(),
        d = new child();

    c.set('sub', d);

    // Set element raise the validate method
    c.get('sub').set('test', 'piou');
});

// Test property check, for a list of values
test('a.model.property-check-array', function() {
    var unittest = a.model('unittest-check-array', {
        testcheck: {
            init: 'ok',
            check: ['a', 'yeah', 'okay']
        }
    });

    var unit = new unittest();

    strictEqual(unit.get('testcheck'), 'ok', 'Test init value');

    unit.set('testcheck', 'get');
    strictEqual(unit.get('testcheck'), 'ok', 'Test still init value');

    unit.set('testcheck', 'yeah');
    strictEqual(unit.get('testcheck'), 'yeah', 'Test second value');

    unit.set('testcheck', 'a');
    strictEqual(unit.get('testcheck'), 'a', 'Test thrid value');

    unit.set('testcheck', 'yup');
    strictEqual(unit.get('testcheck'), 'a', 'Test still thrid value');

    unit.set('testcheck', 'okay');
    strictEqual(unit.get('testcheck'), 'okay', 'Test fourth value');
});

// Test property check, for a list of values
test('a.model.property-check-object', function() {
    var unittest = a.model('unittest-check-object', {
        testcheck: {
            init: 'ok',
            check: {
                'a': 'something great',
                'yeah': 'another',
                'okay': 'still good'
            }
        }
    });

    var unit = new unittest();

    strictEqual(unit.get('testcheck'), 'ok', 'Test init value');

    unit.set('testcheck', 'get');
    strictEqual(unit.get('testcheck'), 'ok', 'Test still init value');

    unit.set('testcheck', 'yeah');
    strictEqual(unit.get('testcheck'), 'yeah', 'Test second value');

    unit.set('testcheck', 'a');
    strictEqual(unit.get('testcheck'), 'a', 'Test thrid value');

    unit.set('testcheck', 'yup');
    strictEqual(unit.get('testcheck'), 'a', 'Test still thrid value');

    unit.set('testcheck', 'okay');
    strictEqual(unit.get('testcheck'), 'okay', 'Test fourth value');
});

// Test property validate
test('a.model.property-validate', function() {
    var unittest = a.model('unittest-validate', {
        testvalidate: {
            init: 'ok',
            validate: function(value, old) {
                if(value == 'something') {
                    return true;
                }
            }
        }
    });

    var unit = new unittest();

    strictEqual(unit.get('testvalidate'), 'ok', 'Test init value');

    unit.set('testvalidate', 'another');
    strictEqual(unit.get('testvalidate'), 'ok', 'Test still init value');

    unit.set('testvalidate', 'something');
    strictEqual(unit.get('testvalidate'), 'something', 'Test accepted');
});

// Test property pattern
test('a.model.property-pattern', function() {
    var test = a.model('unittest-pattern', {
        name: {
            init: 'hello',
            check: 'string',
            pattern: '^[a-zA-Z0-9]+$'
        }
    });

    var instance = new test();

    strictEqual(instance.get('name'), 'hello');

    instance.set('name', '__');
    // Refused by pattern
    strictEqual(instance.get('name'), 'hello');

    instance.set('name', 'abcd09');
    // Allowed by pattern
    strictEqual(instance.get('name'), 'abcd09');

    instance.set('name', 'abcd09-');
    // Refused by pattern
    strictEqual(instance.get('name'), 'abcd09');
});

// Test property transform
test('a.model.property-transform', function() {
    var unittest = a.model('unittest-transform', {
        testtransform: {
            init: 'ok',
            transform: function piou(value, old) {
                return '' + old + value;
            }
        }
    });

    var unit = new unittest();

    strictEqual(unit.get('testtransform'), 'ok', 'Test init value');

    unit.set('testtransform', 'something');
    strictEqual(unit.get('testtransform'), 'oksomething', 'Test concat');

    unit.set('testtransform', 'another');
    strictEqual(unit.get('testtransform'), 'oksomethinganother', 'Second');
});

// Test property event
asyncTest('a.model.property-event', function() {
    expect(2);

    var unittest = a.model('unittest-event', {
        evt: {
            init: 'another',
            event: 'super'
        }
    });

    var unit = new unittest();

    function eventMatcher(data) {
        if(data.value == 'something') {
            strictEqual(data.value, 'something', 'Test something value');
        } else {
            strictEqual(data.value, 'ok', 'Test ok value');
            start();
        }
    };

    unit.bind('super', eventMatcher);

    unit.set('evt', 'something');

    setTimeout(function() {
        unit.set('evt', 'ok');
    }, 150);
});

// Test property apply
asyncTest('a.model.property-apply', function() {
    expect(1);

    var unittest = a.model('unittest-apply', {
        app: {
            init: 'another',
            apply: function(value, old) {
                strictEqual(value, 'ok');
                start();
            }
        }
    });

    var unit = new unittest();

    unit.set('app', 'ok');
});

// Test list function
test('a.model.list', function() {
    var unittest = a.model('unittest-list', {
        A: {
            init: 'ok'
        },
        B: {
            init: 'something'
        }
    });

    var unit = new unittest();
    var list = unit.list();

    strictEqual(list.join(','), 'A,B');
});

// Test has function
test('a.model.has', function() {
    var unittest = a.model('unittest-has', {
        A: {
            init: 'ok'
        },
        B: {
            init: 'something'
        }
    });

    var unit = new unittest();

    strictEqual(unit.has('A'), true);
    strictEqual(unit.has('B'), true);
    strictEqual(unit.has('C'), false);
});

// Test init function
test('a.model.init', function() {
    var unittest = a.model('unittest-init', {
        testA: {
            init: 'ok'
        },
        testB: {
            init: 'something'
        },
        testC: {
            // Value will be erased on first loading
            value: 'notok'
        }
    });

    var unit = new unittest();

    // First init
    strictEqual(unit.get('testA'), 'ok', 'Test init1');
    strictEqual(unit.get('testB'), 'something', 'Test init2');
    strictEqual(unit.get('testC'), null, 'Test init3');

    // Change init
    unit.set('testA', 'another');
    unit.set('testB', 'stuff');
    unit.set('testC', 'great');

    strictEqual(unit.get('testA'), 'another', 'Test change init1');
    strictEqual(unit.get('testB'), 'stuff', 'Test change init2');
    strictEqual(unit.get('testC'), 'great', 'Test change init3');

    // Rollback init
    unit.init();

    // Second init
    strictEqual(unit.get('testA'), 'ok', 'Test rollback init1');
    strictEqual(unit.get('testB'), 'something', 'Test rollback init2');
    strictEqual(unit.get('testC'), null, 'Test rollback init3');
});

// Test jsons function
test('a.model.json', function() {
    var unittest = a.model('unittest-json', {
        testA: {
            init: 'something'
        },
        testB: {
            init: 'great'
        }
    });

    var unit = new unittest();
    unit.set('testA', 'another');
    var json = unit.toJSON();

    strictEqual(json, '{"testA":"another","testB":"great"}', 'Test JSON');

    var second = new unittest();
    second.fromJSON(json);

    var alternative = second.toJSON();

    strictEqual(alternative, '{"testA":"another","testB":"great"}', 'Test second');
});

// Test Object output
test('a.model.object', function() {
    var unittest = a.model('unittest-object', {
        testA: {
            init: 'something'
        },
        testB: {
            init: 'great'
        }
    });

    var unit = new unittest();
    unit.set('testA', 'another');
    var obj1 = unit.toObject();

    strictEqual(obj1.testA, 'another', 'Test first Object');
    strictEqual(obj1.testB, 'great', 'Test first Object');

    var second = new unittest();
    second.fromObject(obj1);

    var obj2 = second.toObject();

    strictEqual(obj2.testA, 'another', 'Test second Object');
    strictEqual(obj2.testB, 'great', 'Test second Object');
});

// Test model clone
test('a.model.clone', function() {
    var unittest = a.model('unittest-clone', {
        za: {
            init: 'ok'
        },
        bigObject: {
            init: {
                'hello': 'yeah'
            }
        }
    });

    var test1 = new unittest(),
        test2 = test1.clone();

    test2.get('bigObject').hello = 'something';

    strictEqual(test1.get('za'), test2.get('za'));
    strictEqual(test1.get('za'), 'ok');
    test2.set('za', 'you');
    strictEqual(test1.get('za'), 'ok');
    strictEqual(test2.get('za'), 'you');
    strictEqual(test1.get('bigObject').hello, 'yeah');
    strictEqual(test2.get('bigObject').hello, 'something');
});

// Test snapshot function
test('a.model.snapshot', function() {
    var unittest = a.model('unittest-snapshot', {
        snap: {
            needed: true,
            init: 'ok'
        },
        nosnap: {
            init: 'notok'
        },
        so: {
            init: 'something'
        }
    });

    var unit = new unittest();
    // Taking snapshot
    unit.takeSnapshot();

    var firstSimpleSnapshot  = a.parser.json.stringify(
                    unit.differenceSnapshot(true)
        ),
        firstComplexSnapshot = a.parser.json.stringify(
                    unit.differenceSnapshot(false)
        );

    strictEqual(firstSimpleSnapshot, '{"snap":"ok"}');
    strictEqual(firstComplexSnapshot, '{"snap":{"value":"ok","old":"ok"}}')
});

// Test model manager
test('a.modelManager', function() {
    var model = a.model('modelmanagertest', {}, null);

    var instance1 = new model(),
        instance2 = new model();

    var storedInstance1 = a.modelManager.get(instance1.uid),
        storedInstance2 = a.modelManager.get(instance2.uid);

    strictEqual(storedInstance1.uid, instance1.uid);
    strictEqual(storedInstance2.uid, instance2.uid);

    var list = a.modelManager.getByName('modelmanagertest');

    // We test the list element before removing everything inside
    strictEqual(list.length, 2);
    if(list[0].uid == instance1.uid) {
        strictEqual(list[0].uid, instance1.uid);
        strictEqual(list[1].uid, instance2.uid);
    } else {
        strictEqual(list[1].uid, instance1.uid);
        strictEqual(list[0].uid, instance2.uid);
    }

    a.modelManager.remove(storedInstance1.uid);
    strictEqual(a.modelManager.get(instance1.uid), null);
    strictEqual(a.modelManager.get(instance2.uid).uid, instance2.uid);

    a.modelManager.remove(storedInstance2.uid);
});

// Unit test multiple model management
asyncTest('a.model.model-multiple', function() {
    expect(4);

    var unittest = a.model('unittest-multiple', {
        id: {
            init: 0,
            event: 'yatta'
        }
    });

    var unittest1 = new unittest(),
        unittest2 = new unittest();

    unittest1.bind('yatta', function(data) {
        strictEqual(data.value, 5, 'Testing data update 1');
        strictEqual(unittest1.get('id'), 5, 'Testing model update 1');
    });
    unittest2.bind('yatta', function(data) {
        strictEqual(data.value, 6, 'Testing data update 2');
        strictEqual(unittest2.get('id'), 6, 'Testing model update 2');
        start();
    });

    unittest1.set('id', 5);
    unittest2.set('id', 6);
});

// Test modelManager searchInstance function
test('a.model.searchInstance', function() {
    var unittest = a.model('unittest-searchInstance', {
        id: {
            check: 'number'
        },
        name: {
            init: 'piou'
        },
        val: {
            init: 5
        }
    });

    var test1 = new unittest(),
        test2 = new unittest();

    test1.set('id', 3);
    test1.set('name', 'ok');

    test2.set('id', 20);
    test2.set('val', 12);
    test2.set('name', 'something');

    var getTest1 = a.model({
            model: 'unittest-searchInstance',
            name: 'ok'
        }),
        getTest2 = a.model({
            model: 'unittest-searchInstance',
            name: 'something',
            val: 12
        });

    strictEqual(getTest1.get('id'), 3);
    strictEqual(getTest2.get('id'), 20);
});

test('a.model.validates', function() {
    ok(1==1);
});

test('a.model.requests', function() {
    ok(1==1);
});<|endoftext|>


<commit_before>'use strict';

var init = function() {
  // Intialize module
};

module.exports = init;

<commit_msg>Update header.js<commit_after>'use strict';

export default class Header {
  constructor() {
    console.log('Header module');
  }
}
<|endoftext|>