<commit_before>'use strict';

define(['ol', 'toolbar', 'layermanager', 'geojson', 'sidebar', 'query', 'search', 'print', 'permalink', 'measure', 'geolocation', 'api', 'cesium', 'ows', 'datasource_selector', 'cesiumjs', 'bootstrap'],

    function(ol, toolbar, layermanager, geojson) {
        var module = angular.module('hs', [
            'hs.toolbar',
            'hs.layermanager',
            'hs.query',
            'hs.search', 'hs.print', 'hs.permalink',
            'hs.datasource_selector',
            'hs.geolocation',
            'hs.cesium',
            'hs.sidebar',
            'hs.ows'
        ]);

        module.directive('hs', ['hs.map.service', 'Core', '$compile', '$timeout', function(OlMap, Core, $compile, $timeout) {
            return {
                templateUrl: hsl_path + 'hslayers.html',
                link: function(scope, element) {
                    angular.element('.page-content', element).append($compile('

')(scope));
                    $timeout(function(){Core.fullScreenMap(element)}, 0);
                }
            };
        }]);

        function getHostname() {
            var url = window.location.href
            var urlArr = url.split("/");
            var domain = urlArr[2];
            return urlArr[0] + "//" + domain;
        };

        var kml_source = new ol.source.Vector({
            url: 'https://openlayers.org/en/v4.3.2/examples/data/kml/2012-02-10.kml',
            format: new ol.format.KML()
        });
        kml_source.set('clampToGround', true);

        module.value('config', {
            terrain_provider: 'https://assets.agi.com/stk-terrain/v1/tilesets/world/tiles',
            terrain_providers: [{
                title: 'EU-DEM',
                url: 'https://assets.agi.com/stk-terrain/v1/tilesets/world/tiles',
                active: true
            }],
            default_layers: [
                new ol.layer.Tile({
                    source: new ol.source.OSM(),
                    title: "OpenStreetMap",
                    base: true,
                    visible: false,
                    minimumTerrainLevel: 15
                }),
                new ol.layer.Vector({
                    title: "Test kml",
                    source: kml_source
                })
            ],
            project_name: 'erra/map',
            datasources: [
                {
                    title: "Datasets",
                    url: "http://otn-dev.intrasoft-intl.com/otnServices-1.0/platform/ckanservices/datasets",
                    language: 'eng',
                    type: "ckan",
                    download: true
                }, {
                    title: "Services",
                    url: "http://cat.ccss.cz/csw/",
                    language: 'eng',
                    type: "micka",
                    code_list_url: 'http://www.whatstheplan.eu/php/metadata/util/codelists.php?_dc=1440156028103&language=eng&page=1&start=0&limit=25&filter=%5B%7B%22property%22%3A%22label%22%7D%5D'
                }, {
                    title: "Hub layers",
                    url: "http://opentnet.eu/php/metadata/csw/",
                    language: 'eng',
                    type: "micka",
                    code_list_url: 'http://opentnet.eu/php/metadata/util/codelists.php?_dc=1440156028103&language=eng&page=1&start=0&limit=25&filter=%5B%7B%22property%22%3A%22label%22%7D%5D'
                }
            ],
            hostname: {
                "default": {
                    "title": "Default",
                    "type": "default",
                    "editable": false,
                    "url": getHostname()
                }
            },
            'catalogue_url': "/php/metadata/csw",
            'compositions_catalogue_url': "/php/metadata/csw",
            status_manager_url: '/wwwlibs/statusmanager2/index.php',
            default_view: new ol.View({
                center: [1208534.8815206578, 5761821.705531779],
                zoom: 16,
                units: "m"
            })
        });

        module.controller('Main', ['$scope', '$compile', '$element', 'Core', 'hs.map.service', 'config',
            function($scope, $compile, $element, Core, OlMap, config) {
                if (console) console.log("Main called");
                $scope.hsl_path = hsl_path; //Get this from hslayers.js file
                $scope.Core = Core;

                Core.singleDatasources = true;
                Core.panelEnabled('compositions', true);
                Core.panelEnabled('status_creator', false);
                $scope.Core.setDefaultPanel('layermanager');

                function createAboutDialog() {
                    var el = angular.element('

');
                    $("#hs-dialog-area").append(el);
                    $compile(el)($scope);
                }
                createAboutDialog();

                $scope.$on('infopanel.updated', function(event) {});
            }
        ]);

        return module;
    });
<commit_msg>Different default center and zoom for 3d-kml example<commit_after>'use strict';

define(['ol', 'toolbar', 'layermanager', 'geojson', 'sidebar', 'query', 'search', 'print', 'permalink', 'measure', 'geolocation', 'api', 'cesium', 'ows', 'datasource_selector', 'cesiumjs', 'bootstrap'],

    function(ol, toolbar, layermanager, geojson) {
        var module = angular.module('hs', [
            'hs.toolbar',
            'hs.layermanager',
            'hs.query',
            'hs.search', 'hs.print', 'hs.permalink',
            'hs.datasource_selector',
            'hs.geolocation',
            'hs.cesium',
            'hs.sidebar',
            'hs.ows'
        ]);

        module.directive('hs', ['hs.map.service', 'Core', '$compile', '$timeout', function(OlMap, Core, $compile, $timeout) {
            return {
                templateUrl: hsl_path + 'hslayers.html',
                link: function(scope, element) {
                    angular.element('.page-content', element).append($compile('

')(scope));
                    $timeout(function(){Core.fullScreenMap(element)}, 0);
                }
            };
        }]);

        function getHostname() {
            var url = window.location.href
            var urlArr = url.split("/");
            var domain = urlArr[2];
            return urlArr[0] + "//" + domain;
        };

        var kml_source = new ol.source.Vector({
            url: 'https://openlayers.org/en/v4.3.2/examples/data/kml/2012-02-10.kml',
            format: new ol.format.KML()
        });
        kml_source.set('clampToGround', true);

        module.value('config', {
            terrain_provider: 'https://assets.agi.com/stk-terrain/v1/tilesets/world/tiles',
            terrain_providers: [{
                title: 'EU-DEM',
                url: 'https://assets.agi.com/stk-terrain/v1/tilesets/world/tiles',
                active: true
            }],
            default_layers: [
                new ol.layer.Tile({
                    source: new ol.source.OSM(),
                    title: "OpenStreetMap",
                    base: true,
                    visible: false,
                    minimumTerrainLevel: 15
                }),
                new ol.layer.Vector({
                    title: "Test kml",
                    source: kml_source
                })
            ],
            project_name: 'erra/map',
            datasources: [
                {
                    title: "Datasets",
                    url: "http://otn-dev.intrasoft-intl.com/otnServices-1.0/platform/ckanservices/datasets",
                    language: 'eng',
                    type: "ckan",
                    download: true
                }, {
                    title: "Services",
                    url: "http://cat.ccss.cz/csw/",
                    language: 'eng',
                    type: "micka",
                    code_list_url: 'http://www.whatstheplan.eu/php/metadata/util/codelists.php?_dc=1440156028103&language=eng&page=1&start=0&limit=25&filter=%5B%7B%22property%22%3A%22label%22%7D%5D'
                }, {
                    title: "Hub layers",
                    url: "http://opentnet.eu/php/metadata/csw/",
                    language: 'eng',
                    type: "micka",
                    code_list_url: 'http://opentnet.eu/php/metadata/util/codelists.php?_dc=1440156028103&language=eng&page=1&start=0&limit=25&filter=%5B%7B%22property%22%3A%22label%22%7D%5D'
                }
            ],
            hostname: {
                "default": {
                    "title": "Default",
                    "type": "default",
                    "editable": false,
                    "url": getHostname()
                }
            },
            'catalogue_url': "/php/metadata/csw",
            'compositions_catalogue_url': "/php/metadata/csw",
            status_manager_url: '/wwwlibs/statusmanager2/index.php',
            default_view: new ol.View({
                center: [836003.5186791886, 5855420.235649515],
                zoom: 12,
                units: "m"
            })
        });

        module.controller('Main', ['$scope', '$compile', '$element', 'Core', 'hs.map.service', 'config',
            function($scope, $compile, $element, Core, OlMap, config) {
                if (console) console.log("Main called");
                $scope.hsl_path = hsl_path; //Get this from hslayers.js file
                $scope.Core = Core;

                Core.singleDatasources = true;
                Core.panelEnabled('compositions', true);
                Core.panelEnabled('status_creator', false);
                $scope.Core.setDefaultPanel('layermanager');

                function createAboutDialog() {
                    var el = angular.element('

');
                    $("#hs-dialog-area").append(el);
                    $compile(el)($scope);
                }
                createAboutDialog();

                $scope.$on('infopanel.updated', function(event) {});
            }
        ]);

        return module;
    });
<|endoftext|>


<commit_before>import * as yup from 'yup';
import get from 'lodash/get';
import includes from 'lodash/includes';
import keys from 'lodash/keys';
import map from 'lodash/map';
import countries from 'i18n-iso-countries';

import states from './validation/states';
import postalCodes from './validation/postalCodes';
import i18next from './language';
import { phoneRegex } from '../pages/prescription/prescriptionFormConstants';

const t = i18next.t.bind(i18next);

export const roles = [
  { value: 'clinic_manager', label: t('Clinic Manager') },
  { value: 'diabetes_educator', label: t('Diabetes Educator') },
  { value: 'endocrinologist', label: t('Endocrinologist') },
  { value: 'front_desk', label: t('Front Desk') },
  { value: 'information_technology', label: t('IT/Technology') },
  { value: 'medical_assistant', label: t('Medical Assistant') },
  { value: 'nurse', label: t('Nurse/Nurse Practitioner') },
  { value: 'primary_care_physician', label: t('Primary Care Physician') },
  { value: 'physician_assistant', label: t('Physician Assistant') },
  { value: 'pharmacist', label: t('Pharmacist') },
  { value: 'health_student', label: t('Health Professions Student') },
  { value: 'other', label: t('Other') },
];

export const clinicTypes = [
  { value: 'provider_practice', label: t('Provider Practice') },
  { value: 'healthcare_system', label: t('Healthcare System') },
  { value: 'veterinary_clinic', label: t('Veterinary Clinic') },
  { value: 'other', label: t('Other') },
];

export const clinicSizes = [
  { value: '0-249', label: t('0-249') },
  { value: '250-499', label: t('250-499') },
  { value: '500-999', label: t('500-999') },
  { value: '1000+', label: t('1000+') },
];

export const clinicValuesFromClinic = (clinic) => ({
  name: get(clinic, 'name', ''),
  address: get(clinic, 'address', ''),
  city: get(clinic, 'city', ''),
  state: get(clinic, 'state', ''),
  postalCode: get(clinic, 'postalCode', ''),
  country: get(clinic, 'country', 'US'),
  phoneNumbers: [
    {
      type: 'Office',
      number: get(clinic, 'phoneNumbers.0.number', ''),
    },
  ],
  clinicType: get(clinic, 'clinicType', ''),
  clinicSize: get(clinic, 'clinicSize', ''),
  website: get(clinic, 'website', ''),
});

export const validationSchema = yup.object().shape({
  name: yup.string().required(t('Please enter an organization name')),
  address: yup.string().required(t('Please enter an address')),
  city: yup.string().required(t('Please enter a city')),
  country: yup
    .string()
    .oneOf(keys(countries.getAlpha2Codes()))
    .required(t('Please enter a country')),
  state: yup
    .string()
    .required(t('Please enter a state'))
    .when('country', (country, schema) => !includes(keys(states), country)
      ? schema.required(t('Please enter a state'))
      : schema.oneOf(keys(states[country]), t('Please enter a valid state'))
    ),
  postalCode: yup
    .string()
    .required(t('Please enter a zip/postal code'))
    .when('country', (country, schema) => !includes(keys(postalCodes), country)
      ? schema.required(t('Please enter a zip/postal code'))
      : schema.matches(postalCodes[country], t('Please enter a valid zip/postal code'))
    ),
  phoneNumbers: yup.array().of(
    yup.object().shape({
      type: yup.string().required(),
      number: yup
        .string()
        .matches(phoneRegex, t('Please enter a valid phone number'))
        .required(t('Clinic phone number is required')),
    }),
  ),
  clinicType: yup
    .string()
    .oneOf(map(clinicTypes, 'value'))
    .required(t('Please select a clinic type')),
  clinicSize: yup
    .string()
    .oneOf(map(clinicSizes, 'value'))
    .required(t('Please select an organization size')),
  website: yup.string().url(t('Please enter a valid website address')),
});
<commit_msg>[WEB-1305] Update website validation to alert the user to the need for the protocol if missing<commit_after>import * as yup from 'yup';
import get from 'lodash/get';
import includes from 'lodash/includes';
import keys from 'lodash/keys';
import map from 'lodash/map';
import countries from 'i18n-iso-countries';

import states from './validation/states';
import postalCodes from './validation/postalCodes';
import i18next from './language';
import { phoneRegex } from '../pages/prescription/prescriptionFormConstants';

const t = i18next.t.bind(i18next);

export const roles = [
  { value: 'clinic_manager', label: t('Clinic Manager') },
  { value: 'diabetes_educator', label: t('Diabetes Educator') },
  { value: 'endocrinologist', label: t('Endocrinologist') },
  { value: 'front_desk', label: t('Front Desk') },
  { value: 'information_technology', label: t('IT/Technology') },
  { value: 'medical_assistant', label: t('Medical Assistant') },
  { value: 'nurse', label: t('Nurse/Nurse Practitioner') },
  { value: 'primary_care_physician', label: t('Primary Care Physician') },
  { value: 'physician_assistant', label: t('Physician Assistant') },
  { value: 'pharmacist', label: t('Pharmacist') },
  { value: 'health_student', label: t('Health Professions Student') },
  { value: 'other', label: t('Other') },
];

export const clinicTypes = [
  { value: 'provider_practice', label: t('Provider Practice') },
  { value: 'healthcare_system', label: t('Healthcare System') },
  { value: 'veterinary_clinic', label: t('Veterinary Clinic') },
  { value: 'other', label: t('Other') },
];

export const clinicSizes = [
  { value: '0-249', label: t('0-249') },
  { value: '250-499', label: t('250-499') },
  { value: '500-999', label: t('500-999') },
  { value: '1000+', label: t('1000+') },
];

export const clinicValuesFromClinic = (clinic) => ({
  name: get(clinic, 'name', ''),
  address: get(clinic, 'address', ''),
  city: get(clinic, 'city', ''),
  state: get(clinic, 'state', ''),
  postalCode: get(clinic, 'postalCode', ''),
  country: get(clinic, 'country', 'US'),
  phoneNumbers: [
    {
      type: 'Office',
      number: get(clinic, 'phoneNumbers.0.number', ''),
    },
  ],
  clinicType: get(clinic, 'clinicType', ''),
  clinicSize: get(clinic, 'clinicSize', ''),
  website: get(clinic, 'website', ''),
});

export const validationSchema = yup.object().shape({
  name: yup.string().required(t('Please enter an organization name')),
  address: yup.string().required(t('Please enter an address')),
  city: yup.string().required(t('Please enter a city')),
  country: yup
    .string()
    .oneOf(keys(countries.getAlpha2Codes()))
    .required(t('Please enter a country')),
  state: yup
    .string()
    .required(t('Please enter a state'))
    .when('country', (country, schema) => !includes(keys(states), country)
      ? schema.required(t('Please enter a state'))
      : schema.oneOf(keys(states[country]), t('Please enter a valid state'))
    ),
  postalCode: yup
    .string()
    .required(t('Please enter a zip/postal code'))
    .when('country', (country, schema) => !includes(keys(postalCodes), country)
      ? schema.required(t('Please enter a zip/postal code'))
      : schema.matches(postalCodes[country], t('Please enter a valid zip/postal code'))
    ),
  phoneNumbers: yup.array().of(
    yup.object().shape({
      type: yup.string().required(),
      number: yup
        .string()
        .matches(phoneRegex, t('Please enter a valid phone number'))
        .required(t('Clinic phone number is required')),
    }),
  ),
  clinicType: yup
    .string()
    .oneOf(map(clinicTypes, 'value'))
    .required(t('Please select a clinic type')),
  clinicSize: yup
    .string()
    .oneOf(map(clinicSizes, 'value'))
    .required(t('Please select an organization size')),
  website: yup
    .string()
    .url(({ value }) => /^https?:\/\//.test(value)
      ? t('Please enter a valid website address')
      : t('Please enter a valid website address with https:// at the beginning')
    ),
});
<|endoftext|>


<commit_before>var fs = require("fs");
var Module = require("module");

var moduleStack = [];
var defaultCompile = module.constructor.prototype._compile;

module.constructor.prototype._compile = function(content, filename){
    moduleStack.push(this);
    try {
        return defaultCompile.call(this, content, filename);
    }
    finally {
        moduleStack.pop();
    }
};

global.define = function (id, injects, factory) {

    // infere the module
    var currentModule = moduleStack[moduleStack.length-1];
    var mod = currentModule || module.parent || require.main;

    // parse arguments
    if (!factory) {
        var defaultInjects = ["require", "exports", "module"];
        // two or less arguments
        factory = injects;
        if (factory) {
            // two args
            if (typeof id === "string") {
                if (id !== mod.id) {
                    throw new Error("Can not assign module to a different id than the current file");
                }
                // default injects
                injects = defaultInjects;
            }
            else{
                // anonymous, deps included
                injects = id;
            }
        }
        else {
            // only one arg, just the factory
            factory = id;
            injects = defaultInjects;
        }
    }

    var req = function(module, relativeId, callback) {
        if (Array.isArray(relativeId)) {
            // async require
            return callback.apply(this, relativeId.map(req))
        }

        var chunks = relativeId.split("!");
        var prefix;
        if (chunks.length >= 2) {
            prefix = chunks[0];
            relativeId = chunks.slice(1).join("!");
        }

        var fileName = Module._resolveFilename(relativeId, module);
        if (Array.isArray(fileName))
            fileName = fileName[0];

        if (prefix && prefix.indexOf("text") !== -1) {
            return fs.readFileSync(fileName, "utf8");
        } else
            return require(fileName);
    }.bind(this, mod);

    id = mod.id;
    if (typeof factory !== "function") {
        // we can just provide a plain object
        return mod.exports = factory;
    }

    var returned = factory.apply(mod.exports, injects.map(function (injection) {
        switch (injection) {
            // check for CommonJS injection variables
            case "require": return req;
            case "exports": return mod.exports;
            case "module": return mod;
            default:
                // a module dependency
                return req(injection);
        }
    }));

    if (returned) {
        // since AMD encapsulates a function/callback, it can allow the factory to return the exports.
        mod.exports = returned;
    }
};<commit_msg>handle arguments of define same way as requirejs<commit_after>var fs = require("fs");
var Module = require("module");

var moduleStack = [];
var defaultCompile = module.constructor.prototype._compile;

module.constructor.prototype._compile = function(content, filename){
    moduleStack.push(this);
    try {
        return defaultCompile.call(this, content, filename);
    }
    finally {
        moduleStack.pop();
    }
};

global.define = function (id, deps, factory) {
    // Allow for anonymous modules
    if (typeof id !== "string") {
        factory = deps;
        deps = id;
        id = null;
    }
    // This module may not have dependencies
    if (deps && !Array.isArray(deps)) {
        factory = deps;
        deps = null;
    }
    if (!deps) {
        deps = ["require", "exports", "module"];
    }

    // infer the module
    var currentModule = moduleStack[moduleStack.length-1];
    var mod = currentModule || module.parent || require.main;

    if (typeof id === "string" && id !== mod.id) {
        throw new Error("Can not assign module to a different id than the current file");
    }

    var req = function(module, relativeId, callback) {
        if (Array.isArray(relativeId)) {
            // async require
            return callback.apply(this, relativeId.map(req))
        }

        var chunks = relativeId.split("!");
        var prefix;
        if (chunks.length >= 2) {
            prefix = chunks[0];
            relativeId = chunks.slice(1).join("!");
        }

        var fileName = Module._resolveFilename(relativeId, module);
        if (Array.isArray(fileName))
            fileName = fileName[0];

        if (prefix && prefix.indexOf("text") !== -1) {
            return fs.readFileSync(fileName, "utf8");
        } else
            return require(fileName);
    }.bind(this, mod);

    id = mod.id;
    if (typeof factory !== "function") {
        // we can just provide a plain object
        return mod.exports = factory;
    }

    var returned = factory.apply(mod.exports, deps.map(function (injection) {
        switch (injection) {
            // check for CommonJS injection variables
            case "require": return req;
            case "exports": return mod.exports;
            case "module": return mod;
            default:
                // a module dependency
                return req(injection);
        }
    }));

    if (returned) {
        // since AMD encapsulates a function/callback, it can allow the factory to return the exports.
        mod.exports = returned;
    }
};<|endoftext|>


<commit_before>// Constructor for FluidState
function FluidState(id, rule, deterministic, instance) {
    var self = this;

    self.meta = {};

    self.id = id;

    self.meta.id = self.parseId(self.id);

    self.name = self.meta.id.name;

    self.instance = instance;

    self.parent = null;

    self.state = {};

    self.states = [];

    self.triggers = [];

    self.trigger = null;

    self.active = false;

    self.deterministic = deterministic || false;

    self.transitions = {
        initial: false,
        accepting: false,
        acceptAny: false,
        from: [],
        to: []
    };

    self.rules = [];

    self.listeners = [];

    self.initialized = false;

    // Pre-Initialization Steps
    self.addRule(rule);
}

FluidState.prototype.initialize = function() {
    var self = this;

    // Add parent state
    // self.getParent();
    self.instance.getState(self.meta.id.parent).addState(self);

    self.initializeTransitions();

    self.initializeAutomaton();

    if (self.transitions.initial) self.activate();

    self.initialized = true;
}

FluidState.prototype.initializeAutomaton = function() {
    var self = this;

    if (self.deterministic) {
        if (self.transitions.acceptAny) {
            _.each(self.states, function(fluidState) {
                fluidState.accepting();
            });
        }
    }

    return self;
}

// Transitions
FluidState.prototype.initial = function(value) {
    var self = this;

    value = (value || !arguments.length) ? true : false;

    self.transitions.initial = value;

    return self;
}

FluidState.prototype.accepting = function(value) {
    var self = this;

    value = (value || !arguments.length) ? true : false;

    self.transitions.accepting = value;

    return self;
}

FluidState.prototype.acceptAny = function(value) {
    var self = this;

    value = (value || !arguments.length) ? true : false;

    self.transitions.acceptAny = value;

    return self;
}

FluidState.prototype.transition = function(direction, state) {
    var self = this;

    console.log("Adding state '%s' as transition %s '%s'", state.id, direction, self.id);

    self.transitions[direction].push(state);
    self.transitions[direction] = _.unique(self.transitions[direction]);

    return self;
}

FluidState.prototype.from = function(fromState, rule) {
    var self = this;

    if (rule) {
        self.instance.addRule(rule, self, fromState);
    }

    return self.transition('from', fromState);
}

FluidState.prototype.to = function(toState, rule) {
    var self = this;

    if (rule) {
        self.instance.addRule(rule, toState, self);
    }

    return self.transition('to', toState);
}

FluidState.prototype.hasTransition = function(direction, state) {
    var self = this;

    var transitionState;

    if (!(self.transitions.from.length || self.transitions.to.length)) {
        return true;
    }

    if (!self.transitions[direction].length) {
        return false;
    }

    transitionState = _.find(self.transitions[direction], function(currentState) {
        return currentState === state;
    });

    console.log("State '%s' does%s have a transition %s state '%s'", self.id, !!transitionState ? '' : ' NOT', direction, state.id);

    return !!transitionState;
}

FluidState.prototype.hasTransitionFrom = function(state) {
    var self = this;

    return self.hasTransition('from', state);
}

FluidState.prototype.hasTransitionTo = function(state) {
    var self = this;

    return self.hasTransition('to', state);
}

FluidState.prototype.initializeTransitions = function() {
    var self = this;

    var reverseDirection = {
        'from': 'to',
        'to': 'from'
    };

    _.each(reverseDirection, function(direction) {
        self.transitions[direction] = _.map(self.transitions[direction], function(currentState) {
            var fluidState = self.instance.getState(currentState);

            fluidState[reverseDirection[direction]](self);

            return fluidState;
        });
    });

    return self;
}

FluidState.prototype.getParent = function() {
    var self = this;

    if (!self.parent instanceof FluidState) {
        self.instance
            .getState(self.meta.id.parent)
            .addState(self);
    }

    return self.parent;
}

FluidState.prototype.addTrigger = function(property) {
    var self = this;

    if (_.isArray(property)) {
        _.each(property, function(currentProperty) {
            self.addTrigger(property);
        });
    } else {
        self.instance.addTrigger(property, self);
    }

    return self;
}

FluidState.prototype.parseId = function(id) {
    var idData = {
        id: id,
        parent: null,
        name: null,
        params: id.match(/([\.]?\w+)/g)
    };

    var tagMap = [
        {
            tag: '.',
            parent: false
        },
        {
            tag: '',
            parent: true
        }
    ];

    idData.parent = idData.params
        .splice(0, idData.params.length - 1)
        .join('') || null;

    idData.params = idData.params.map(function(idParam) {
        console.log(idParam);
        var tag = /[\:\.]?/.exec(idParam)[0];
        var param = /\w+/.exec(idParam)[0];

        var tagMapItem = tagMap.filter(function(tagMapItem) {
            return tagMapItem.tag == tag;
        })[0];

        return angular.extend({ param: param }, tagMapItem);
    });

    idData.name = idData.params.slice(-1)[0].param;

    return idData;
}

FluidState.prototype.addState = function(state) {
    var self = this;

    self.states.push(state);

    state.parent = this;

    return self;
}

FluidState.prototype.validate = function() {
    var self = this;

    console.log("Validating state '%s'", self.id);

    if (self.deterministic && self.states.length) {
        return self.determine();
    }

    var valid = true;

    if (!self.rules.length) {
        valid = _.some(self.states, {active: true});
    } else {
        valid = self.isValid();
    }

    if (valid) {
        this.activate();
    } else {
        this.deactivate();
    }
}

FluidState.prototype.isValid = function(fromState) {
    var self = this;

    var valid = true;

    var fluidRules;

    if (!fromState) {
        fluidRules = _.filter(self.rules, {fromState: self.instance});
    } else {
        fluidRules = _.filter(self.rules, function(fluidRule) {
            return fluidRule.fromState === self.instance
                || fluidRule.fromState === fromState;
        });
    }

    _.forEach(fluidRules, function(fluidRule) {
        valid = valid && fluidRule.validate();
    });

    return valid;
}

FluidState.prototype.activateTrigger = function() {
    var self = this;

    if (self.trigger) {
        self.trigger.activate();
    }

    return self;
}

FluidState.prototype.activate = function(active) {
    var self = this;

    active = arguments.length ? !!active : true;

    if (self.active !== active) {
        console.log("%sctivating state '%s'", active ? 'A' : 'Dea', self.id);

        self.active = active;

        self.instance.getStates();

        self.activateTrigger();
        self.notifyListeners();
        self.instance.refresh();
    }

    if (!self.deterministic) {
        _.each(self.states, function(state) {
            console.log("Validating child state '%s'", state.id);
            state.validate();
        });
    }

    return self;
}

FluidState.prototype.deactivate = function() {
    var self = this;

    self.activate(false);

    return self;
}

FluidState.prototype.determine = function(targetState) {
    var self = this;

    console.log("Determining state '%s'", self.id);

    var activeState = _.find(self.states, {active: true});

    var nextState;

    if (arguments.length && targetState instanceof FluidState) {
        nextState = targetState;
    } else {
        console.log('hereeeee');
        nextState = _.find(self.states, function(fluidState) {
            return fluidState.isValid(activeState)
                && fluidState.hasTransitionFrom(activeState);
            });
    }

    if (!activeState) {
        console.error("Deterministic parent state '%s' has no initial state.", self.id);
        return false;
    }

    if (!nextState) {
        if (activeState.isValid()) {
            return self;
        } else {
            console.error("Unable to transition from state '%s'; transitions may be incomplete.", activeState.id);
            return false;
        }
    } else {
        activeState.deactivate();

        nextState.activate();

        (nextState.transitions.accepting || self.transitions.acceptAny)
            ? self.activate()
            : self.deactivate();
    }

    return self;
}

FluidState.prototype.go = function() {
    var self = this;

    self.parent.determine(self);

    return self;
}

FluidState.prototype.addRule = function(rule, fromState) {
    var self = this;

    if (rule === undefined) return self;

    if (rule instanceof FluidRule) {
        self.instance.addRule(rule.validate, self, fromState);
    } else if (_.isString(rule) || _.isFunction(rule)) {
        self.instance.addRule(rule, self, fromState);
    } else {
        return (self.toggle(rule), self);
    }

    return self;
}

FluidState.prototype.pushRule = function(fluidRule) {
    var self = this;

    self.rules.push(fluidRule);

    return self;
}

FluidState.prototype.setTrigger = function(trigger) {
    var self = this;

    if (trigger instanceof FluidTrigger) {
        self.trigger = trigger;
    }

    return self;
}

FluidState.prototype.toggle = function(active) {
    var self = this;

    active = !!active;

    if (!arguments.length) {
        self[self.active ? 'deactivate' : 'activate']();
    } else {
        self[active ? 'activate' : 'deactivate']();
    }

    self.instance.refresh();

    return self;
}

FluidState.prototype.addListener = function(listener) {
    var self = this;

    self.listeners.push(listener);

    return self;
}

FluidState.prototype.notifyListeners = function() {
    var self = this;

    _.forEach(self.listeners, function(listener) {
        listener.notify(self.active);
    });

    return self;
}

FluidState.prototype.simplify = function() {
    var self = this;

    if (!self.states.length) return self.active;

    if (self.deterministic) {
        if (!self.active) {
            self.state = [];
        } else {
            self.state = {};
        }
    }

    if (_.every(self.states, {active: false})) return self.active;

    _.forEach(self.states, function(state) {
        self.state[state.name] = state.simplify();
    });

    return self.state;
}<commit_msg>Adding transition check between active and target states<commit_after>// Constructor for FluidState
function FluidState(id, rule, deterministic, instance) {
    var self = this;

    self.meta = {};

    self.id = id;

    self.meta.id = self.parseId(self.id);

    self.name = self.meta.id.name;

    self.instance = instance;

    self.parent = null;

    self.state = {};

    self.states = [];

    self.triggers = [];

    self.trigger = null;

    self.active = false;

    self.deterministic = deterministic || false;

    self.transitions = {
        initial: false,
        accepting: false,
        acceptAny: false,
        from: [],
        to: []
    };

    self.rules = [];

    self.listeners = [];

    self.initialized = false;

    // Pre-Initialization Steps
    self.addRule(rule);
}

FluidState.prototype.initialize = function() {
    var self = this;

    // Add parent state
    // self.getParent();
    self.instance.getState(self.meta.id.parent).addState(self);

    self.initializeTransitions();

    self.initializeAutomaton();

    if (self.transitions.initial) self.activate();

    self.initialized = true;
}

FluidState.prototype.initializeAutomaton = function() {
    var self = this;

    if (self.deterministic) {
        if (self.transitions.acceptAny) {
            _.each(self.states, function(fluidState) {
                fluidState.accepting();
            });
        }
    }

    return self;
}

// Transitions
FluidState.prototype.initial = function(value) {
    var self = this;

    value = (value || !arguments.length) ? true : false;

    self.transitions.initial = value;

    return self;
}

FluidState.prototype.accepting = function(value) {
    var self = this;

    value = (value || !arguments.length) ? true : false;

    self.transitions.accepting = value;

    return self;
}

FluidState.prototype.acceptAny = function(value) {
    var self = this;

    value = (value || !arguments.length) ? true : false;

    self.transitions.acceptAny = value;

    return self;
}

FluidState.prototype.transition = function(direction, state) {
    var self = this;

    console.log("Adding state '%s' as transition %s '%s'", state.id, direction, self.id);

    self.transitions[direction].push(state);
    self.transitions[direction] = _.unique(self.transitions[direction]);

    return self;
}

FluidState.prototype.from = function(fromState, rule) {
    var self = this;

    if (rule) {
        self.instance.addRule(rule, self, fromState);
    }

    return self.transition('from', fromState);
}

FluidState.prototype.to = function(toState, rule) {
    var self = this;

    if (rule) {
        self.instance.addRule(rule, toState, self);
    }

    return self.transition('to', toState);
}

FluidState.prototype.hasTransition = function(direction, state) {
    var self = this;

    var transitionState;

    if (!(self.transitions.from.length || self.transitions.to.length)) {
        return true;
    }

    if (!self.transitions[direction].length) {
        return false;
    }

    transitionState = _.find(self.transitions[direction], function(currentState) {
        return currentState === state;
    });

    console.log("State '%s' does%s have a transition %s state '%s'", self.id, !!transitionState ? '' : ' NOT', direction, state.id);

    return !!transitionState;
}

FluidState.prototype.hasTransitionFrom = function(state) {
    var self = this;

    return self.hasTransition('from', state);
}

FluidState.prototype.hasTransitionTo = function(state) {
    var self = this;

    return self.hasTransition('to', state);
}

FluidState.prototype.initializeTransitions = function() {
    var self = this;

    var reverseDirection = {
        'from': 'to',
        'to': 'from'
    };

    _.each(reverseDirection, function(direction) {
        self.transitions[direction] = _.map(self.transitions[direction], function(currentState) {
            var fluidState = self.instance.getState(currentState);

            fluidState[reverseDirection[direction]](self);

            return fluidState;
        });
    });

    return self;
}

FluidState.prototype.getParent = function() {
    var self = this;

    if (!self.parent instanceof FluidState) {
        self.instance
            .getState(self.meta.id.parent)
            .addState(self);
    }

    return self.parent;
}

FluidState.prototype.addTrigger = function(property) {
    var self = this;

    if (_.isArray(property)) {
        _.each(property, function(currentProperty) {
            self.addTrigger(property);
        });
    } else {
        self.instance.addTrigger(property, self);
    }

    return self;
}

FluidState.prototype.parseId = function(id) {
    var idData = {
        id: id,
        parent: null,
        name: null,
        params: id.match(/([\.]?\w+)/g)
    };

    var tagMap = [
        {
            tag: '.',
            parent: false
        },
        {
            tag: '',
            parent: true
        }
    ];

    idData.parent = idData.params
        .splice(0, idData.params.length - 1)
        .join('') || null;

    idData.params = idData.params.map(function(idParam) {
        console.log(idParam);
        var tag = /[\:\.]?/.exec(idParam)[0];
        var param = /\w+/.exec(idParam)[0];

        var tagMapItem = tagMap.filter(function(tagMapItem) {
            return tagMapItem.tag == tag;
        })[0];

        return angular.extend({ param: param }, tagMapItem);
    });

    idData.name = idData.params.slice(-1)[0].param;

    return idData;
}

FluidState.prototype.addState = function(state) {
    var self = this;

    self.states.push(state);

    state.parent = this;

    return self;
}

FluidState.prototype.validate = function() {
    var self = this;

    console.log("Validating state '%s'", self.id);

    if (self.deterministic && self.states.length) {
        return self.determine();
    }

    var valid = true;

    if (!self.rules.length) {
        valid = _.some(self.states, {active: true});
    } else {
        valid = self.isValid();
    }

    if (valid) {
        this.activate();
    } else {
        this.deactivate();
    }
}

FluidState.prototype.isValid = function(fromState) {
    var self = this;

    var valid = true;

    var fluidRules;

    if (!fromState) {
        fluidRules = _.filter(self.rules, {fromState: self.instance});
    } else {
        fluidRules = _.filter(self.rules, function(fluidRule) {
            return fluidRule.fromState === self.instance
                || fluidRule.fromState === fromState;
        });
    }

    _.forEach(fluidRules, function(fluidRule) {
        valid = valid && fluidRule.validate();
    });

    return valid;
}

FluidState.prototype.activateTrigger = function() {
    var self = this;

    if (self.trigger) {
        self.trigger.activate();
    }

    return self;
}

FluidState.prototype.activate = function(active) {
    var self = this;

    active = arguments.length ? !!active : true;

    if (self.active !== active) {
        console.log("%sctivating state '%s'", active ? 'A' : 'Dea', self.id);

        self.active = active;

        self.instance.getStates();

        self.activateTrigger();
        self.notifyListeners();
        self.instance.refresh();
    }

    if (!self.deterministic) {
        _.each(self.states, function(state) {
            console.log("Validating child state '%s'", state.id);
            state.validate();
        });
    }

    return self;
}

FluidState.prototype.deactivate = function() {
    var self = this;

    self.activate(false);

    return self;
}

FluidState.prototype.determine = function(targetState) {
    var self = this;

    console.log("Determining state '%s'", self.id);

    var activeState = _.find(self.states, {active: true});

    var nextState;

    if (!activeState) {
        console.error("Deterministic parent state '%s' has no initial state.", self.id);
        return false;
    }

    if (arguments.length && targetState instanceof FluidState) {
        nextState = targetState;
    } else {
        console.log('hereeeee');
        nextState = _.find(self.states, function(fluidState) {
            return fluidState.isValid(activeState)
                && fluidState.hasTransitionFrom(activeState);
            });
    }

    if (!nextState) {
        if (activeState.isValid()) {
            return self;
        } else {
            console.error("Unable to transition from state '%s'; transitions may be incomplete.", activeState.id);
            return false;
        }
    } else if (!activeState.hasTransitionTo(targetState)) {
        console.error("Active state '%s' has no transition to target state '%s'", activeState.id, targetState.id);
        return false;
    } else {
        activeState.deactivate();

        nextState.activate();

        (nextState.transitions.accepting || self.transitions.acceptAny)
            ? self.activate()
            : self.deactivate();
    }

    return self;
}

FluidState.prototype.go = function() {
    var self = this;

    self.parent.determine(self);

    return self;
}

FluidState.prototype.addRule = function(rule, fromState) {
    var self = this;

    if (rule === undefined) return self;

    if (rule instanceof FluidRule) {
        self.instance.addRule(rule.validate, self, fromState);
    } else if (_.isString(rule) || _.isFunction(rule)) {
        self.instance.addRule(rule, self, fromState);
    } else {
        return (self.toggle(rule), self);
    }

    return self;
}

FluidState.prototype.pushRule = function(fluidRule) {
    var self = this;

    self.rules.push(fluidRule);

    return self;
}

FluidState.prototype.setTrigger = function(trigger) {
    var self = this;

    if (trigger instanceof FluidTrigger) {
        self.trigger = trigger;
    }

    return self;
}

FluidState.prototype.toggle = function(active) {
    var self = this;

    active = !!active;

    if (!arguments.length) {
        self[self.active ? 'deactivate' : 'activate']();
    } else {
        self[active ? 'activate' : 'deactivate']();
    }

    self.instance.refresh();

    return self;
}

FluidState.prototype.addListener = function(listener) {
    var self = this;

    self.listeners.push(listener);

    return self;
}

FluidState.prototype.notifyListeners = function() {
    var self = this;

    _.forEach(self.listeners, function(listener) {
        listener.notify(self.active);
    });

    return self;
}

FluidState.prototype.simplify = function() {
    var self = this;

    if (!self.states.length) return self.active;

    if (self.deterministic) {
        if (!self.active) {
            self.state = [];
        } else {
            self.state = {};
        }
    }

    if (_.every(self.states, {active: false})) return self.active;

    _.forEach(self.states, function(state) {
        self.state[state.name] = state.simplify();
    });

    return self.state;
}<|endoftext|>


<commit_before>( function() {
	var thymolConfiguration = {
		// Please set the values of the following fields!
		thScriptName : "${thThymolSource}",
		thJQuerySource : "${thJQuerySource}",
		// These are defaults, change them if you wish..
		thDefaultPrefix : "th",
		thDefaultDataPrefix : "data",
		thDefaultPrecision : 10,
		thDefaultProtocol : "file:///",
		thDefaultLocale : "en",
		thDefaultPrecedence : 20000,
		thDefaultMessagePath : "",
		thDefaultMessagesBaseName : "Messages",
		thDefaultRelativeRootPath: "",  // Non-blank signifies use of thymol.js relative addressing
		thDefaultExtendedMapping: false
	};
	thymol = function( conf ) {
		conf.ready = function( func ) {
			if( typeof thymolDeferredFunctions === "undefined" || thymolDeferredFunctions === null ) {
				thymolDeferredFunctions = [];
			}
			thymolDeferredFunctions.push( func );
		};
		return conf;
	}( thymolConfiguration );
	var loadScript = function( script, params ) {
		var el = document.createElement( "script" );
		el.async = false;
		if( typeof script !== "undefined" && script !== null ) {
			el.src = script;
		}
		if( typeof params !== "undefined" && params !== null ) {
			el.src += params.charAt( 0 ) === "?" ? params : "?" + params;
		}
		el.type = "text/javascript";
		( document.getElementsByTagName( "HEAD" )[0] || document.body ).appendChild( el );
	};
	var scripts = document.getElementsByTagName( "script" );
	var script = document.currentScript || scripts[scripts.length - 1];
	var scriptSrc = script.getAttribute( "src" );
	var pathEnd = scriptSrc.lastIndexOf( "/" );
	if( pathEnd >= 0 ) {
		thymol.thLocation = scriptSrc.substring( 0, 1 + pathEnd );
	}
	var jquerySrc = script.getAttribute( "data-jquery-src" );
	if( !!jquerySrc || "" === jquerySrc ) {
		thymol.thJQuerySource = jquerySrc;
		if( "" !== thymol.thJQuerySource ) {
			loadScript( thymol.thJQuerySource );
		}
	}
	else if( typeof thymol.thJQuerySource !== "undefined" && thymol.thJQuerySource !== null && thymol.thJQuerySource.length > 0 ) {
		var hasProtocol = thymol.thJQuerySource.indexOf( ":/" ) >= 0;
		if( hasProtocol || thymol.thJQuerySource.charAt( 0 ) === "/" ) {
			if( !hasProtocol ) {
				loadScript( thymol.thDefaultProtocol + thymol.thJQuerySource );
			}
			else {
				loadScript( thymol.thJQuerySource );
			}
		}
		else {
			loadScript( thymol.thLocation + thymol.thJQuerySource );
		}
	}
	var thymolSrc = script.getAttribute( "data-thymol-src" );
	if( !!thymolSrc ) {
		thymol.thScriptName = thymolSrc;
	}
	var parameters = null;
	for( var i = 0, iLimit = scripts.length; i < iLimit; i++ ) {
		parameters = scripts[i].getAttribute( "data-thymol-parameters" );
		if( !!parameters ) {
			break;
		}
	}
	loadScript( thymol.thLocation + thymol.thScriptName, parameters );
} )();<commit_msg>Added thDefaultLocalMessages initialisation.<commit_after>( function() {
	var thymolConfiguration = {
		// Please set the values of the following fields!
		thScriptName : "${thThymolSource}",
		thJQuerySource : "${thJQuerySource}",
		// These are defaults, change them if you wish..
		thDefaultPrefix : "th",
		thDefaultDataPrefix : "data",
		thDefaultPrecision : 10,
		thDefaultProtocol : "file:///",
		thDefaultLocale : "en",
		thDefaultPrecedence : 20000,
		thDefaultMessagePath : "",
		thDefaultMessagesBaseName : "Messages",
		thDefaultRelativeRootPath: "",  // Non-blank signifies use of thymol.js relative addressing
		thDefaultExtendedMapping: false,
		thDefaultLocalMessages: true
	};
	thymol = function( conf ) {
		conf.ready = function( func ) {
			if( typeof thymolDeferredFunctions === "undefined" || thymolDeferredFunctions === null ) {
				thymolDeferredFunctions = [];
			}
			thymolDeferredFunctions.push( func );
		};
		return conf;
	}( thymolConfiguration );
	var loadScript = function( script, params ) {
		var el = document.createElement( "script" );
		el.async = false;
		if( typeof script !== "undefined" && script !== null ) {
			el.src = script;
		}
		if( typeof params !== "undefined" && params !== null ) {
			el.src += params.charAt( 0 ) === "?" ? params : "?" + params;
		}
		el.type = "text/javascript";
		( document.getElementsByTagName( "HEAD" )[0] || document.body ).appendChild( el );
	};
	var scripts = document.getElementsByTagName( "script" );
	var script = document.currentScript || scripts[scripts.length - 1];
	var scriptSrc = script.getAttribute( "src" );
	var pathEnd = scriptSrc.lastIndexOf( "/" );
	if( pathEnd >= 0 ) {
		thymol.thLocation = scriptSrc.substring( 0, 1 + pathEnd );
	}
	var jquerySrc = script.getAttribute( "data-jquery-src" );
	if( !!jquerySrc || "" === jquerySrc ) {
		thymol.thJQuerySource = jquerySrc;
		if( "" !== thymol.thJQuerySource ) {
			loadScript( thymol.thJQuerySource );
		}
	}
	else if( typeof thymol.thJQuerySource !== "undefined" && thymol.thJQuerySource !== null && thymol.thJQuerySource.length > 0 ) {
		var hasProtocol = thymol.thJQuerySource.indexOf( ":/" ) >= 0;
		if( hasProtocol || thymol.thJQuerySource.charAt( 0 ) === "/" ) {
			if( !hasProtocol ) {
				loadScript( thymol.thDefaultProtocol + thymol.thJQuerySource );
			}
			else {
				loadScript( thymol.thJQuerySource );
			}
		}
		else {
			loadScript( thymol.thLocation + thymol.thJQuerySource );
		}
	}
	var thymolSrc = script.getAttribute( "data-thymol-src" );
	if( !!thymolSrc ) {
		thymol.thScriptName = thymolSrc;
	}
	var parameters = null;
	for( var i = 0, iLimit = scripts.length; i < iLimit; i++ ) {
		parameters = scripts[i].getAttribute( "data-thymol-parameters" );
		if( !!parameters ) {
			break;
		}
	}
	loadScript( thymol.thLocation + thymol.thScriptName, parameters );
} )();<|endoftext|>


<commit_before>/**
 * Copyright 2015, Philipp Adrian, philippadrian.com
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 */

"use strict";
(function(module, require, window, document, undefined){

require = require || requireShim;
var React = window.React || require("react");
var ReactTransform = window.JSXTransformer ?
  window.JSXTransformer.transform :
  require("react-tools").transformWithDetails;
var objectKeys = Object.keys || objectKeysShim;
var selfClosingTags = ["area","base","br","col","command","embed","hr","img","input","keygen","link","meta","param","source","track","wbr"];
var preserveReactAttributes = ["onBeforeInput", "onBeforeInputCapture", "onCompositionEnd", "onCompositionEndCapture", "onCompositionStart", "onCompositionStartCapture", "onCompositionUpdate", "onCompositionUpdateCapture", "onChange", "onChangeCapture", "ResponderEventPlugin", "SimpleEventPlugin", "TapEventPlugin", "EnterLeaveEventPlugin", "ChangeEventPlugin", "SelectEventPlugin", "BeforeInputEventPlugin", "AnalyticsEventPlugin", "MobileSafariClickEventPlugin", "onMouseEnter", "onMouseLeave", "onSelect", "onSelectCapture", "onBlur", "onBlurCapture", "onClick", "onClickCapture", "onContextMenu", "onContextMenuCapture", "onCopy", "onCopyCapture", "onCut", "onCutCapture", "onDoubleClick", "onDoubleClickCapture", "onDrag", "onDragCapture", "onDragEnd", "onDragEndCapture", "onDragEnter", "onDragEnterCapture", "onDragExit", "onDragExitCapture", "onDragLeave", "onDragLeaveCapture", "onDragOver", "onDragOverCapture", "onDragStart", "onDragStartCapture", "onDrop", "onDropCapture", "onFocus", "onFocusCapture", "onInput", "onInputCapture", "onKeyDown", "onKeyDownCapture", "onKeyPress", "onKeyPressCapture", "onKeyUp", "onKeyUpCapture", "onLoad", "onLoadCapture", "onError", "onErrorCapture", "onMouseDown", "onMouseDownCapture", "onMouseMove", "onMouseMoveCapture", "onMouseOut", "onMouseOutCapture", "onMouseOver", "onMouseOverCapture", "onMouseUp", "onMouseUpCapture", "onPaste", "onPasteCapture", "onReset", "onResetCapture", "onScroll", "onScrollCapture", "onSubmit", "onSubmitCapture", "onTouchCancel", "onTouchCancelCapture", "onTouchEnd", "onTouchEndCapture", "onTouchMove", "onTouchMoveCapture", "onTouchStart", "onTouchStartCapture", "onWheel", "onWheelCapture", "className"];
///////////////////////////////////////////////////////////////////////////////
// Export / Attach / Public

module.exports = mount;

if(typeof window.React === "object")
  window.React.mount = mount;
if(typeof define === "function" && define.amd)
  define(function(){return mount});

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////

function getNodes(tags, context) {
  var keys = objectKeys(tags);
  var returns = [];

  // keys to uppercase to compare to nodeName
  for(var i=0; i<keys.length; i++) keys[i]=keys[i].toUpperCase();

  // if context is tag
  if(keys.indexOf(context.nodeName.toUpperCase()) >= 0) {
    return [context];
  };

  //Mount all top-level child tags within context
  var nodes, el, mount, n;
  for(var i=0; i<keys.length; i++) {
    nodes = context.getElementsByTagName(keys[i]);
    for(n=0; n<nodes.length; n++) {
      el = nodes[n];
      mount = true;
      while(el = el.parentNode) {
        if(keys.indexOf(el.nodeName.toUpperCase()) >= 0) {
          mount = false;
          break;
        }
        if(el === context) break;
      }
      if(mount) returns.push(nodes[n]);
    }
  }
  return returns;
}

///////////////////////////////////////////////////////////////////////////////

function htmlToComponent(str, tags, opts) {
  var keys = objectKeys(tags);
  var props = opts.props || {};
  var preserveAttributes = opts.preserveAttributes || [];
  var tagAttributes = [];
  var reactTags={};
  var reactKeys=[];
  var key;
  for(var i = 0; i<keys.length; i++) {
    key = "AB"+Math.random().toString(36).substring(2);
    if(typeof tags[keys[i]] !== "function") {
      if(typeof tags[keys[i]].slice !== "function") continue;
      tagAttributes = tags[keys[i]].slice(0,-1);
      reactTags[key] = tags[keys[i]].slice(-1)[0];
    }
    else
      reactTags[key] = tags[keys[i]];

    reactKeys.push(key);

    str = str
      .replace(new RegExp("(<\/?)"+keys[i]+"(?:[^>\"']|\".*\"|'.*')*>", "ig"), function(match, start){
        // find/replace spell-save attributes within tag to restore capitals
        if(start !== "</")
          for(var a=0; a<tagAttributes.length; a++)
            match = replaceAttribute(match, tagAttributes[a], tagAttributes[a]);

        // replace key
        return match
          .replace(new RegExp(start+keys[i]+"(\\s|>)", "i"), start+key+"$1");
      });
  }

  // remove/disable html comments
  str = str.replace(/<!--|-->/g,"")

  // find/replace global spell-save attributes to restore capitals
  var attributes = preserveReactAttributes.concat(preserveAttributes);
  for(var i=0; i<attributes.length; i++)
    str = replaceAttribute(str, attributes[i], attributes[i]);

  var jsx = htmlToJsx(str);

  // replace props variables {key} with corrected variables {props['key']}
  for(var key in props) {
    jsx = jsx
      .replace(new RegExp("(\{"+key+"\})","g"),"{props['"+key+"']}");
  }

  var component = ReactTransform(jsx).code;

  // replace component variables (ComponentName) with corrected variables (tags['ComponentName'])
  for(var i=0; i<reactKeys.length; i++) {
    component = component
      .replace(new RegExp(reactKeys[i],"g"), "reactTags['"+reactKeys[i]+"']");
  }

  return eval(component);
}

///////////////////////////////////////////////////////////////////////////////
// html to jsx (More info: https://facebook.github.io/react/docs/tags-and-attributes.html)

function htmlToJsx(str){

  // for attribute to htmlFor
  str = replaceAttribute(str, "for", "htmlFor");
  // class attribute to className
  str = replaceAttribute(str, "class", "className");

  // "selfclose" self closing tags: "…>" to "…/>"
  for(var k=0; k<selfClosingTags.length; k++) {
    str = str.replace(new RegExp("(<"+selfClosingTags[k]+"(?:[^>\"']|\".*\"|'.*')*)\/?>","ig"),"$1"+" />");
  }

  // Remove auto-quotes around {expressions} + Remove {expression}="" attachment
  str = str
    .replace(/<(?:[^>\"']|\".*\"|'.*')*=(?:[^>\"']|\".*\"|'.*')*>/g, function(match){
      return match.replace(/(?:"|')?(\{(?:[^\'"}]|".*"|'.*')*\})(?:"|')?(?:=""|='')?/g, "$1");
    });

  // Transform style attribute string ("color:red; background-image:url()") to object ({{color:'red', backgroundImage:'url()'}})
  str = str.replace(/(<(?:[^>"']|".*"|'.*')*\sstyle\s*=\s*)((?:"(?:[^"]|\s)*")|(?:'(?:[^']|\s)*'))((?:[^>"']|".*"|'.*')*>)/ig, function(match, start, style, end){
    var styles = "";
    style
      .slice(1,-1)
      .replace(/(&quot)|'/g,'"')
      .replace(/\s*([^:;]*)\s*:\s*((?:[^;"]|".*")*)\s*;?/g, function(match, key, value){

        // transform key to camelCase
        key = key.replace(/-([^-]*)/g, function(match, part){
          if(part === "ms") return part;
          return part.charAt(0).toUpperCase()+part.slice(1);
        });

        styles+=key+":'"+value+"',";

        return match;
      });

    return start+"{{"+styles.slice(0,-1)+"}}"+end;
  });

  return str;
}

///////////////////////////////////////////////////////////////////////////////

function mount(tags, opts){
  opts = opts || {};
  var component, wrapper;

  // Get HTML nodes that need to be mounted.
  var nodes = getNodes(tags, opts.context || document.body);

  for(var i=0; i<nodes.length; i++) {

    // create component to be mounted
    component = htmlToComponent(nodes[i].outerHTML, tags, opts);

    // get wrapper to mount into
    wrapper = typeof opts.wrapper === "object" && typeof opts.wrapper.cloneNode === "function"?
      opts.wrapper.cloneNode(false):
      document.createElement('div');

    wrapper.className += wrapper.className ? " react-mount":"react-mount";

    // Replace tag with wrapper
    nodes[i].parentNode.replaceChild(wrapper, nodes[i]);

    // Render component into wrapper.
    React.render(component, wrapper);
  }
}

///////////////////////////////////////////////////////////////////////////////

function objectKeysShim(o){
  var keys = [];
  for(key in o) keys.push(key);
  return keys;
}

///////////////////////////////////////////////////////////////////////////////

function replaceAttribute(str, search, replace){
  return str
    .replace(new RegExp("(<(?:[^>\"']|\".*\"|'.*')*\\s)"+search+"(\s*=(?:[^>\"']|\".*\"|'.*')*>)", "ig"), "$1"+replace+"$2");
}

///////////////////////////////////////////////////////////////////////////////

function requireShim(required){
  throw "react-mount: Error - React and JSXTransformer/react-tools are required for react-mount to work";
}

///////////////////////////////////////////////////////////////////////////////

})(typeof module === "object" ? module : {}, typeof require === "function" ? require : undefined, window, document);
<commit_msg>Webpack support! #1<commit_after>/**
 * Copyright 2015, Philipp Adrian, philippadrian.com
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 */

"use strict";
(function(module, require, window, document, undefined){

var React = window.React || require("react");
var ReactTransform = window.JSXTransformer ?
  window.JSXTransformer.transform :
  require("react-tools").transformWithDetails;
var objectKeys = Object.keys || objectKeysShim;
var selfClosingTags = ["area","base","br","col","command","embed","hr","img","input","keygen","link","meta","param","source","track","wbr"];
var preserveReactAttributes = ["onBeforeInput", "onBeforeInputCapture", "onCompositionEnd", "onCompositionEndCapture", "onCompositionStart", "onCompositionStartCapture", "onCompositionUpdate", "onCompositionUpdateCapture", "onChange", "onChangeCapture", "ResponderEventPlugin", "SimpleEventPlugin", "TapEventPlugin", "EnterLeaveEventPlugin", "ChangeEventPlugin", "SelectEventPlugin", "BeforeInputEventPlugin", "AnalyticsEventPlugin", "MobileSafariClickEventPlugin", "onMouseEnter", "onMouseLeave", "onSelect", "onSelectCapture", "onBlur", "onBlurCapture", "onClick", "onClickCapture", "onContextMenu", "onContextMenuCapture", "onCopy", "onCopyCapture", "onCut", "onCutCapture", "onDoubleClick", "onDoubleClickCapture", "onDrag", "onDragCapture", "onDragEnd", "onDragEndCapture", "onDragEnter", "onDragEnterCapture", "onDragExit", "onDragExitCapture", "onDragLeave", "onDragLeaveCapture", "onDragOver", "onDragOverCapture", "onDragStart", "onDragStartCapture", "onDrop", "onDropCapture", "onFocus", "onFocusCapture", "onInput", "onInputCapture", "onKeyDown", "onKeyDownCapture", "onKeyPress", "onKeyPressCapture", "onKeyUp", "onKeyUpCapture", "onLoad", "onLoadCapture", "onError", "onErrorCapture", "onMouseDown", "onMouseDownCapture", "onMouseMove", "onMouseMoveCapture", "onMouseOut", "onMouseOutCapture", "onMouseOver", "onMouseOverCapture", "onMouseUp", "onMouseUpCapture", "onPaste", "onPasteCapture", "onReset", "onResetCapture", "onScroll", "onScrollCapture", "onSubmit", "onSubmitCapture", "onTouchCancel", "onTouchCancelCapture", "onTouchEnd", "onTouchEndCapture", "onTouchMove", "onTouchMoveCapture", "onTouchStart", "onTouchStartCapture", "onWheel", "onWheelCapture", "className"];
///////////////////////////////////////////////////////////////////////////////
// Export / Attach / Public

module.exports = mount;

if(typeof window.React === "object")
  window.React.mount = mount;
if(typeof define === "function" && define.amd)
  define(function(){return mount});

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////

function getNodes(tags, context) {
  var keys = objectKeys(tags);
  var returns = [];

  // keys to uppercase to compare to nodeName
  for(var i=0; i<keys.length; i++) keys[i]=keys[i].toUpperCase();

  // if context is tag
  if(keys.indexOf(context.nodeName.toUpperCase()) >= 0) {
    return [context];
  };

  //Mount all top-level child tags within context
  var nodes, el, mount, n;
  for(var i=0; i<keys.length; i++) {
    nodes = context.getElementsByTagName(keys[i]);
    for(n=0; n<nodes.length; n++) {
      el = nodes[n];
      mount = true;
      while(el = el.parentNode) {
        if(keys.indexOf(el.nodeName.toUpperCase()) >= 0) {
          mount = false;
          break;
        }
        if(el === context) break;
      }
      if(mount) returns.push(nodes[n]);
    }
  }
  return returns;
}

///////////////////////////////////////////////////////////////////////////////

function htmlToComponent(str, tags, opts) {
  var keys = objectKeys(tags);
  var props = opts.props || {};
  var preserveAttributes = opts.preserveAttributes || [];
  var tagAttributes = [];
  var reactTags={};
  var reactKeys=[];
  var key;
  for(var i = 0; i<keys.length; i++) {
    key = "AB"+Math.random().toString(36).substring(2);
    if(typeof tags[keys[i]] !== "function") {
      if(typeof tags[keys[i]].slice !== "function") continue;
      tagAttributes = tags[keys[i]].slice(0,-1);
      reactTags[key] = tags[keys[i]].slice(-1)[0];
    }
    else
      reactTags[key] = tags[keys[i]];

    reactKeys.push(key);

    str = str
      .replace(new RegExp("(<\/?)"+keys[i]+"(?:[^>\"']|\".*\"|'.*')*>", "ig"), function(match, start){
        // find/replace spell-save attributes within tag to restore capitals
        if(start !== "</")
          for(var a=0; a<tagAttributes.length; a++)
            match = replaceAttribute(match, tagAttributes[a], tagAttributes[a]);

        // replace key
        return match
          .replace(new RegExp(start+keys[i]+"(\\s|>)", "i"), start+key+"$1");
      });
  }

  // remove/disable html comments
  str = str.replace(/<!--|-->/g,"")

  // find/replace global spell-save attributes to restore capitals
  var attributes = preserveReactAttributes.concat(preserveAttributes);
  for(var i=0; i<attributes.length; i++)
    str = replaceAttribute(str, attributes[i], attributes[i]);

  var jsx = htmlToJsx(str);

  // replace props variables {key} with corrected variables {props['key']}
  for(var key in props) {
    jsx = jsx
      .replace(new RegExp("(\{"+key+"\})","g"),"{props['"+key+"']}");
  }

  var component = ReactTransform(jsx).code;

  // replace component variables (ComponentName) with corrected variables (tags['ComponentName'])
  for(var i=0; i<reactKeys.length; i++) {
    component = component
      .replace(new RegExp(reactKeys[i],"g"), "reactTags['"+reactKeys[i]+"']");
  }

  return eval(component);
}

///////////////////////////////////////////////////////////////////////////////
// html to jsx (More info: https://facebook.github.io/react/docs/tags-and-attributes.html)

function htmlToJsx(str){

  // for attribute to htmlFor
  str = replaceAttribute(str, "for", "htmlFor");
  // class attribute to className
  str = replaceAttribute(str, "class", "className");

  // "selfclose" self closing tags: "…>" to "…/>"
  for(var k=0; k<selfClosingTags.length; k++) {
    str = str.replace(new RegExp("(<"+selfClosingTags[k]+"(?:[^>\"']|\".*\"|'.*')*)\/?>","ig"),"$1"+" />");
  }

  // Remove auto-quotes around {expressions} + Remove {expression}="" attachment
  str = str
    .replace(/<(?:[^>\"']|\".*\"|'.*')*=(?:[^>\"']|\".*\"|'.*')*>/g, function(match){
      return match.replace(/(?:"|')?(\{(?:[^\'"}]|".*"|'.*')*\})(?:"|')?(?:=""|='')?/g, "$1");
    });

  // Transform style attribute string ("color:red; background-image:url()") to object ({{color:'red', backgroundImage:'url()'}})
  str = str.replace(/(<(?:[^>"']|".*"|'.*')*\sstyle\s*=\s*)((?:"(?:[^"]|\s)*")|(?:'(?:[^']|\s)*'))((?:[^>"']|".*"|'.*')*>)/ig, function(match, start, style, end){
    var styles = "";
    style
      .slice(1,-1)
      .replace(/(&quot)|'/g,'"')
      .replace(/\s*([^:;]*)\s*:\s*((?:[^;"]|".*")*)\s*;?/g, function(match, key, value){

        // transform key to camelCase
        key = key.replace(/-([^-]*)/g, function(match, part){
          if(part === "ms") return part;
          return part.charAt(0).toUpperCase()+part.slice(1);
        });

        styles+=key+":'"+value+"',";

        return match;
      });

    return start+"{{"+styles.slice(0,-1)+"}}"+end;
  });

  return str;
}

///////////////////////////////////////////////////////////////////////////////

function mount(tags, opts){
  opts = opts || {};
  var component, wrapper;

  // Get HTML nodes that need to be mounted.
  var nodes = getNodes(tags, opts.context || document.body);

  for(var i=0; i<nodes.length; i++) {

    // create component to be mounted
    component = htmlToComponent(nodes[i].outerHTML, tags, opts);

    // get wrapper to mount into
    wrapper = typeof opts.wrapper === "object" && typeof opts.wrapper.cloneNode === "function"?
      opts.wrapper.cloneNode(false):
      document.createElement('div');

    wrapper.className += wrapper.className ? " react-mount":"react-mount";

    // Replace tag with wrapper
    nodes[i].parentNode.replaceChild(wrapper, nodes[i]);

    // Render component into wrapper.
    React.render(component, wrapper);
  }
}

///////////////////////////////////////////////////////////////////////////////

function objectKeysShim(o){
  var keys = [];
  for(key in o) keys.push(key);
  return keys;
}

///////////////////////////////////////////////////////////////////////////////

function replaceAttribute(str, search, replace){
  return str
    .replace(new RegExp("(<(?:[^>\"']|\".*\"|'.*')*\\s)"+search+"(\s*=(?:[^>\"']|\".*\"|'.*')*>)", "ig"), "$1"+replace+"$2");
}

///////////////////////////////////////////////////////////////////////////////

})(
typeof module === "object" ?
  module : {},
typeof require === "function" ?
  require :
  function (required){
    throw "react-mount: Error - React and JSXTransformer/react-tools are required for react-mount to work";
  },
window,
document);<|endoftext|>


<commit_before>import { extend } from '../core/util';
import Browser from '../core/Browser';
import Point from '../geo/Point';
import ImageGLRenderable from '../renderer/layer/ImageGLRenderable';
import CanvasRenderer from '../renderer/layer/CanvasRenderer';
import { ResourceCache } from '../renderer/layer/CanvasRenderer';
import Extent from '../geo/Extent';
import Layer from './Layer';

/**
 * @property {Object}              options                     - ImageLayer's options
 * @property {String}              [options.crossOrigin=null]    - image's corssOrigin
 * @property {String}              [options.renderer=gl]         - ImageLayer's renderer, canvas or gl. gl tiles requires image CORS that canvas doesn't. canvas tiles can't pitch.
 * @memberOf ImageLayer
 * @instance
 */
const options = {
    renderer: Browser.webgl ? 'gl' : 'canvas',
    crossOrigin: null
};

const TEMP_POINT = new Point(0, 0);

/**
 * @classdesc
 * A layer used to display images, you can specify each image's geographic extent and opacity
 * @category layer
 * @extends Layer
 * @param {String|Number} id - tile layer's id
 * @param {Object[]} [images=null] - images
 * @param {Object} [options=null] - options defined in [ImageLayer]{@link ImageLayer#options}
 * @example
 * new ImageLayer("images", [{
        url : 'http://example.com/foo.png',
        extent: [xmin, ymin, xmax, ymax],
        opacity : 1
    }])
 */
class ImageLayer extends Layer {

    constructor(id, images, options) {
        if (images && !Array.isArray(images) && !images.url) {
            options = images;
            images = null;
        }
        super(id, options);
        this._images = images;
    }

    onAdd() {
        this._prepareImages(this._images);
    }

    /**
     * Set images and redraw
     * @param {Object[]} images - new images
     * @return {ImageLayer} this
     */
    setImages(images) {
        this._images = images;
        this._prepareImages(images);
        return this;
    }

    /**
     * Get images
     * @return {Object[]}
     */
    getImages() {
        return this._images;
    }

    _prepareImages(images) {
        images = images || [];
        if (!Array.isArray(images)) {
            images = [images];
        }
        const map = this.getMap();
        this._imageData = images.map(img => {
            const extent = new Extent(img.extent);
            return extend({}, img, {
                extent: extent,
                extent2d: extent.convertTo(c => map.coordToPoint(c, map.getGLZoom()))
            });
        });
        this._images = images;
        const renderer = this.getRenderer();
        if (renderer) {
            renderer.refreshImages();
        }
    }
}

ImageLayer.mergeOptions(options);

const EMPTY_ARRAY = [];

export class ImageLayerCanvasRenderer extends CanvasRenderer {
    isDrawable() {
        if (this.getMap().getPitch()) {
            if (console) {
                console.warn('ImageLayer with canvas renderer can\'t be pitched, use gl renderer (\'renderer\' : \'gl\') instead.');
            }
            return false;
        }
        return true;
    }

    checkResources() {
        if (this._imageLoaded) {
            return EMPTY_ARRAY;
        }
        const layer = this.layer;
        let urls = layer._imageData.map(img => [img.url, null, null]);
        if (this.resources) {
            const unloaded = [];
            const resources = new ResourceCache();
            urls.forEach(url => {
                if (this.resources.isResourceLoaded(url)) {
                    const img = this.resources.getImage(url);
                    resources.addResource(url, img);
                } else {
                    unloaded.push(url);
                }
            });
            this.resources.forEach((url, res) => {
                if (!resources.isResourceLoaded(url)) {
                    this.retireImage(res.image);
                }
            });
            this.resources = resources;
            urls = unloaded;
        }
        this._imageLoaded = true;
        return urls;
    }

    retireImage(/* image */) {

    }

    refreshImages() {
        this._imageLoaded = false;
        this.setToRedraw();
    }

    needToRedraw() {
        const map = this.getMap();
        // don't redraw when map is zooming without pitch and layer doesn't have any point symbolizer.
        if (map.isZooming() && !map.getPitch()) {
            return false;
        }
        return super.needToRedraw();
    }

    draw() {
        if (!this.isDrawable()) {
            return;
        }
        this.prepareCanvas();
        this._painted = false;
        this._drawImages();
        this.completeRender();
    }

    _drawImages() {
        const imgData = this.layer._imageData;
        const map = this.getMap();
        const mapExtent = map._get2DExtent(map.getGLZoom());
        if (imgData && imgData.length) {
            for (let i = 0; i < imgData.length; i++) {
                const extent = imgData[i].extent2d;
                const image = this.resources && this.resources.getImage(imgData[i].url);
                if (image && mapExtent.intersects(extent)) {
                    this._painted = true;
                    this._drawImage(image, extent, imgData[i].opacity || 1);
                }
            }
        }
    }

    _drawImage(image, extent, opacity) {
        let globalAlpha = 0;
        const ctx = this.context;
        if (opacity < 1) {
            globalAlpha = ctx.globalAlpha;
            ctx.globalAlpha = opacity;
        }
        const map = this.getMap();
        const nw = TEMP_POINT.set(extent.xmin, extent.ymax);
        const point = map._pointToContainerPoint(nw, map.getGLZoom());
        let x = point.x, y = point.y;
        const bearing = map.getBearing();
        if (bearing) {
            ctx.save();
            ctx.translate(x, y);
            if (bearing) {
                ctx.rotate(-bearing * Math.PI / 180);
            }
            x = y = 0;
        }
        const scale = map.getGLScale();
        ctx.drawImage(image, x, y, extent.getWidth() / scale, extent.getHeight() / scale);
        if (bearing) {
            ctx.restore();
        }
        if (globalAlpha) {
            ctx.globalAlpha = globalAlpha;
        }
    }

    drawOnInteracting() {
        this.draw();
    }
}

export class ImageLayerGLRenderer extends ImageGLRenderable(ImageLayerCanvasRenderer) {

    //override to set to always drawable
    isDrawable() {
        return true;
    }

    _drawImage(image, extent, opacity) {
        this.drawGLImage(image, extent.xmin, extent.ymax, extent.getWidth(), extent.getHeight(), 1, opacity);
    }

    createContext() {
        this.createGLContext();
    }

    resizeCanvas(canvasSize) {
        if (!this.canvas) {
            return;
        }
        super.resizeCanvas(canvasSize);
        this.resizeGLCanvas();
    }

    clearCanvas() {
        if (!this.canvas) {
            return;
        }
        super.clearCanvas();
        this.clearGLCanvas();
    }

    retireImage(image) {
        this.disposeImage(image);
    }

    onRemove() {
        this.removeGLCanvas();
        super.onRemove();
    }
}

ImageLayer.registerRenderer('canvas', ImageLayerCanvasRenderer);
ImageLayer.registerRenderer('gl', ImageLayerGLRenderer);

export default ImageLayer;
<commit_msg>remove ImageLayer.needToRedraw, fix #1308 (#1410)<commit_after>import { extend } from '../core/util';
import Browser from '../core/Browser';
import Point from '../geo/Point';
import ImageGLRenderable from '../renderer/layer/ImageGLRenderable';
import CanvasRenderer from '../renderer/layer/CanvasRenderer';
import { ResourceCache } from '../renderer/layer/CanvasRenderer';
import Extent from '../geo/Extent';
import Layer from './Layer';

/**
 * @property {Object}              options                     - ImageLayer's options
 * @property {String}              [options.crossOrigin=null]    - image's corssOrigin
 * @property {String}              [options.renderer=gl]         - ImageLayer's renderer, canvas or gl. gl tiles requires image CORS that canvas doesn't. canvas tiles can't pitch.
 * @memberOf ImageLayer
 * @instance
 */
const options = {
    renderer: Browser.webgl ? 'gl' : 'canvas',
    crossOrigin: null
};

const TEMP_POINT = new Point(0, 0);

/**
 * @classdesc
 * A layer used to display images, you can specify each image's geographic extent and opacity
 * @category layer
 * @extends Layer
 * @param {String|Number} id - tile layer's id
 * @param {Object[]} [images=null] - images
 * @param {Object} [options=null] - options defined in [ImageLayer]{@link ImageLayer#options}
 * @example
 * new ImageLayer("images", [{
        url : 'http://example.com/foo.png',
        extent: [xmin, ymin, xmax, ymax],
        opacity : 1
    }])
 */
class ImageLayer extends Layer {

    constructor(id, images, options) {
        if (images && !Array.isArray(images) && !images.url) {
            options = images;
            images = null;
        }
        super(id, options);
        this._images = images;
    }

    onAdd() {
        this._prepareImages(this._images);
    }

    /**
     * Set images and redraw
     * @param {Object[]} images - new images
     * @return {ImageLayer} this
     */
    setImages(images) {
        this._images = images;
        this._prepareImages(images);
        return this;
    }

    /**
     * Get images
     * @return {Object[]}
     */
    getImages() {
        return this._images;
    }

    _prepareImages(images) {
        images = images || [];
        if (!Array.isArray(images)) {
            images = [images];
        }
        const map = this.getMap();
        this._imageData = images.map(img => {
            const extent = new Extent(img.extent);
            return extend({}, img, {
                extent: extent,
                extent2d: extent.convertTo(c => map.coordToPoint(c, map.getGLZoom()))
            });
        });
        this._images = images;
        const renderer = this.getRenderer();
        if (renderer) {
            renderer.refreshImages();
        }
    }
}

ImageLayer.mergeOptions(options);

const EMPTY_ARRAY = [];

export class ImageLayerCanvasRenderer extends CanvasRenderer {
    isDrawable() {
        if (this.getMap().getPitch()) {
            if (console) {
                console.warn('ImageLayer with canvas renderer can\'t be pitched, use gl renderer (\'renderer\' : \'gl\') instead.');
            }
            return false;
        }
        return true;
    }

    checkResources() {
        if (this._imageLoaded) {
            return EMPTY_ARRAY;
        }
        const layer = this.layer;
        let urls = layer._imageData.map(img => [img.url, null, null]);
        if (this.resources) {
            const unloaded = [];
            const resources = new ResourceCache();
            urls.forEach(url => {
                if (this.resources.isResourceLoaded(url)) {
                    const img = this.resources.getImage(url);
                    resources.addResource(url, img);
                } else {
                    unloaded.push(url);
                }
            });
            this.resources.forEach((url, res) => {
                if (!resources.isResourceLoaded(url)) {
                    this.retireImage(res.image);
                }
            });
            this.resources = resources;
            urls = unloaded;
        }
        this._imageLoaded = true;
        return urls;
    }

    retireImage(/* image */) {

    }

    refreshImages() {
        this._imageLoaded = false;
        this.setToRedraw();
    }

    draw() {
        if (!this.isDrawable()) {
            return;
        }
        this.prepareCanvas();
        this._painted = false;
        this._drawImages();
        this.completeRender();
    }

    _drawImages() {
        const imgData = this.layer._imageData;
        const map = this.getMap();
        const mapExtent = map._get2DExtent(map.getGLZoom());
        if (imgData && imgData.length) {
            for (let i = 0; i < imgData.length; i++) {
                const extent = imgData[i].extent2d;
                const image = this.resources && this.resources.getImage(imgData[i].url);
                if (image && mapExtent.intersects(extent)) {
                    this._painted = true;
                    this._drawImage(image, extent, imgData[i].opacity || 1);
                }
            }
        }
    }

    _drawImage(image, extent, opacity) {
        let globalAlpha = 0;
        const ctx = this.context;
        if (opacity < 1) {
            globalAlpha = ctx.globalAlpha;
            ctx.globalAlpha = opacity;
        }
        const map = this.getMap();
        const nw = TEMP_POINT.set(extent.xmin, extent.ymax);
        const point = map._pointToContainerPoint(nw, map.getGLZoom());
        let x = point.x, y = point.y;
        const bearing = map.getBearing();
        if (bearing) {
            ctx.save();
            ctx.translate(x, y);
            if (bearing) {
                ctx.rotate(-bearing * Math.PI / 180);
            }
            x = y = 0;
        }
        const scale = map.getGLScale();
        ctx.drawImage(image, x, y, extent.getWidth() / scale, extent.getHeight() / scale);
        if (bearing) {
            ctx.restore();
        }
        if (globalAlpha) {
            ctx.globalAlpha = globalAlpha;
        }
    }

    drawOnInteracting() {
        this.draw();
    }
}

export class ImageLayerGLRenderer extends ImageGLRenderable(ImageLayerCanvasRenderer) {

    //override to set to always drawable
    isDrawable() {
        return true;
    }

    _drawImage(image, extent, opacity) {
        this.drawGLImage(image, extent.xmin, extent.ymax, extent.getWidth(), extent.getHeight(), 1, opacity);
    }

    createContext() {
        this.createGLContext();
    }

    resizeCanvas(canvasSize) {
        if (!this.canvas) {
            return;
        }
        super.resizeCanvas(canvasSize);
        this.resizeGLCanvas();
    }

    clearCanvas() {
        if (!this.canvas) {
            return;
        }
        super.clearCanvas();
        this.clearGLCanvas();
    }

    retireImage(image) {
        this.disposeImage(image);
    }

    onRemove() {
        this.removeGLCanvas();
        super.onRemove();
    }
}

ImageLayer.registerRenderer('canvas', ImageLayerCanvasRenderer);
ImageLayer.registerRenderer('gl', ImageLayerGLRenderer);

export default ImageLayer;
<|endoftext|>


<commit_before>const ecs = new Ecs();
const groups = {
  MODEL: 'MODEL',
  GRAPHICS: 'GRAPHICS',
};
const comps = {
  POSITION: 'position',
  VELOCITY: 'velocity',
  RECTANGLE: 'rectangle',
  INPUT: 'input',
  PLAYER_CONTROLLED: 'playerControlled',
  AI_CONTROLLED: 'aiControlled',
  COLOR: 'color',
};
const keyCodeToName = {//translate keyCode to key string
  "32": "SPACE",
  "38": "UP",
  "40": "DOWN",
  "37": "LEFT",
  "39": "RIGHT"
};
const view = {
  canvas: document.querySelector('canvas'),
  ctx: document.querySelector('canvas').getContext("2d"),
};

//components
ecs.registerComponent(comps.POSITION, function(x = 0, y = 0) {
  this.x = x;
  this.y = y;
});

ecs.registerComponent(comps.VELOCITY, function(x = 0, y = 0) {
  this.x = x;
  this.y = y;
});

ecs.registerComponent(comps.RECTANGLE, function(width = 5, height = 5) {
  this.width = width;
  this.height = height;
});

ecs.registerComponent(comps.INPUT, function() {
  this.UP = false;
  this.DOWN = false;
  this.LEFT = false;
  this.RIGHT = false;
  this.SPACE = false;
});

ecs.registerComponent(comps.PLAYER_CONTROLLED);

ecs.registerComponent(comps.COLOR);

ecs.registerComponent(comps.HIDDEN);

ecs.registerComponent(comps.AI_CONTROLLED);

//systems
ecs.registerSystem({//move entities with velocity
  group: groups.MODEL,
  has: [comps.POSITION, comps.VELOCITY],
  pre(dt) {

  },
  forEach(entity, dt){//iterates all entities with position and velocity component
    const { position, velocity } = entity;
    position.x += velocity.x * dt;
    position.y += velocity.y * dt;
  }
});

ecs.registerSystem({
  group: groups.GRAPHICS,
  has: [comps.POSITION, comps.RECTANGLE, comps.COLOR],
  not: [comps.HIDDEN],
  pre(view) {
    view.canvas.width = view.canvas.width;
  },
  forEach(entity, view) {
    const { x, y } = entity.position;
    const { width, height } = entity.rectangle;
    const { ctx } = view;
    ctx.fillStyle = entity.color.value;
    ctx.fillRect(x, y, width, height);
  }
})

ecs.registerSystem({
  group: groups.MODEL,
  has: [comps.INPUT, comps.PLAYER_CONTROLLED],
  mounted() {//called once system is created
    document.addEventListener("keydown", e => {//keydown event
      const key = keyCodeToName[e.keyCode];
      //TODO: DO something
    });

    document.addEventListener("keyup",function (e) {//keyup event

    });
  }
});

function createMeteorite() {
  ecs.createEntity()
    .add(comps.POSITION, Math.random() * view.canvas.width, 0)
    .add(comps.VELOCITY, 50, 50)
    .add(comps.RECTANGLE, 20, 20)
    .add(comps.COLOR, "orange");
}

function createSnowFlake() {
  ecs.createEntity()
    .add(comps.POSITION, Math.random() * view.canvas.width * 2 - view.canvas.width, 0)
    .add(comps.VELOCITY, 0, 5)
    .add(comps.RECTANGLE, 1, 2)
    .add(comps.COLOR, "white");
}

function loop() {
  createSnowFlake()
  Math.random() > 0.9 && createMeteorite()
  const dt = 0.016;
  ecs.runGroup(groups.MODEL, dt);
  ecs.runGroup(groups.GRAPHICS, view);
  requestAnimationFrame(loop);
}

loop();
<commit_msg>Update example<commit_after>const ecs = new Ecs();
const groups = {
  MODEL: 'MODEL',
  GRAPHICS: 'GRAPHICS',
};
const comps = {
  POSITION: 'position',
  VELOCITY: 'velocity',
  RECTANGLE: 'rectangle',
  INPUT: 'input',
  PLAYER_CONTROLLED: 'playerControlled',
  AI_CONTROLLED: 'aiControlled',
  COLOR: 'color',
};
const keyCodeToName = {//translate keyCode to key string
  "32": "SPACE",
  "38": "UP",
  "40": "DOWN",
  "37": "LEFT",
  "39": "RIGHT"
};
const view = {
  canvas: document.querySelector('canvas'),
  ctx: document.querySelector('canvas').getContext("2d"),
};

window.onload = loop;

//components
ecs.registerComponent(comps.POSITION, function(x = 0, y = 0) {
  this.x = x;
  this.y = y;
});

ecs.registerComponent(comps.VELOCITY, function(x = 0, y = 0) {
  this.x = x;
  this.y = y;
});

ecs.registerComponent(comps.RECTANGLE, function(width = 5, height = 5) {
  this.width = width;
  this.height = height;
});

ecs.registerComponent(comps.INPUT, function() {
  this.UP = false;
  this.DOWN = false;
  this.LEFT = false;
  this.RIGHT = false;
  this.SPACE = false;
});

ecs.registerComponent(comps.PLAYER_CONTROLLED);

ecs.registerComponent(comps.COLOR);

ecs.registerComponent(comps.HIDDEN);

ecs.registerComponent(comps.AI_CONTROLLED);

//systems
ecs.registerSystem({//move entities with velocity
  group: groups.MODEL,
  has: [comps.POSITION, comps.VELOCITY],
  pre(dt) {

  },
  forEach({ position, velocity }, dt){//iterates all entities with position and velocity component
    position.x += velocity.x * dt;
    position.y += velocity.y * dt;
  }
});

ecs.registerSystem({
  group: groups.GRAPHICS,
  has: [comps.POSITION, comps.RECTANGLE, comps.COLOR],
  not: [comps.HIDDEN],
  pre({ canvas }) {
    canvas.width = canvas.width;
  },
  forEach({ position, rectangle, color }, { ctx }) {
    const { x, y } = position;
    const { width, height } = rectangle;
    ctx.fillStyle = color.value;
    ctx.fillRect(x, y, width, height);
  }
})

function createMeteorite() {
  ecs.createEntity()
    .add(comps.POSITION, Math.random() * view.canvas.width, 0)
    .add(comps.VELOCITY, 50, 50)
    .add(comps.RECTANGLE, 20, 20)
    .add(comps.COLOR, "orange");
}

function createSnowFlake() {
  ecs.createEntity()
    .add(comps.POSITION, Math.random() * view.canvas.width * 2 - view.canvas.width, 0)
    .add(comps.VELOCITY, 0, 5)
    .add(comps.RECTANGLE, 1, 2)
    .add(comps.COLOR, "white");
}

function loop() {
  const dt = 0.016;
  createSnowFlake();
  Math.random() > 0.9 && createMeteorite();
  ecs.runGroup(groups.MODEL, dt);
  ecs.runGroup(groups.GRAPHICS, view);
  requestAnimationFrame(loop);
}
<|endoftext|>