<commit_before>export default {
  el: {
    colorpicker: {
      confirm: 'OK',
      clear: 'Tyhjennä'
    },
    datepicker: {
      now: 'Nyt',
      today: 'Tänään',
      cancel: 'Peruuta',
      clear: 'Tyhjennä',
      confirm: 'OK',
      selectDate: 'Valitse päivä',
      selectTime: 'Valitse aika',
      startDate: 'Aloituspäivä',
      startTime: 'Aloitusaika',
      endDate: 'Lopetuspäivä',
      endTime: 'Lopetusaika',
      prevYear: 'Previous Year', // to be translated
      nextYear: 'Next Year', // to be translated
      prevMonth: 'Previous Month', // to be translated
      nextMonth: 'Next Month', // to be translated
      year: '',
      month1: 'tammikuu',
      month2: 'helmikuu',
      month3: 'maaliskuu',
      month4: 'huhtikuu',
      month5: 'toukokuu',
      month6: 'kesäkuu',
      month7: 'heinäkuu',
      month8: 'elokuu',
      month9: 'syyskuu',
      month10: 'lokakuu',
      month11: 'marraskuu',
      month12: 'joulukuu',
      // week: 'week',
      weeks: {
        sun: 'su',
        mon: 'ma',
        tue: 'ti',
        wed: 'ke',
        thu: 'to',
        fri: 'pe',
        sat: 'la'
      },
      months: {
        jan: 'tam',
        feb: 'hel',
        mar: 'maa',
        apr: 'huh',
        may: 'tou',
        jun: 'kes',
        jul: 'hei',
        aug: 'elo',
        sep: 'syy',
        oct: 'lok',
        nov: 'mar',
        dec: 'jou'
      }
    },
    select: {
      loading: 'Lataa',
      noMatch: 'Ei vastaavia tietoja',
      noData: 'Ei tietoja',
      placeholder: 'Valitse'
    },
    cascader: {
      noMatch: 'Ei vastaavia tietoja',
      loading: 'Lataa',
      placeholder: 'Valitse'
    },
    pagination: {
      goto: 'Mene',
      pagesize: '/sivu',
      total: 'Yhteensä {total}',
      pageClassifier: ''
    },
    messagebox: {
      title: 'Viesti',
      confirm: 'OK',
      cancel: 'Peruuta',
      error: 'Virheellinen syöte'
    },
    upload: {
      deleteTip: 'press delete to remove', // to be translated
      delete: 'Poista',
      preview: 'Esikatsele',
      continue: 'Jatka'
    },
    table: {
      emptyText: 'Ei tietoja',
      confirmFilter: 'Vahvista',
      resetFilter: 'Tyhjennä',
      clearFilter: 'Kaikki',
      sumText: 'Sum' // to be translated
    },
    tree: {
      emptyText: 'Ei tietoja'
    },
    transfer: {
      noMatch: 'Ei vastaavia tietoja',
      noData: 'Ei tietoja',
      titles: ['List 1', 'List 2'], // to be translated
      filterPlaceholder: 'Enter keyword', // to be translated
      noCheckedFormat: '{total} items', // to be translated
      hasCheckedFormat: '{checked}/{total} checked' // to be translated
    }
  }
};
<commit_msg>i18n: add missing Finnish translations (#13233)<commit_after>export default {
  el: {
    colorpicker: {
      confirm: 'OK',
      clear: 'Tyhjennä'
    },
    datepicker: {
      now: 'Nyt',
      today: 'Tänään',
      cancel: 'Peruuta',
      clear: 'Tyhjennä',
      confirm: 'OK',
      selectDate: 'Valitse päivä',
      selectTime: 'Valitse aika',
      startDate: 'Aloituspäivä',
      startTime: 'Aloitusaika',
      endDate: 'Lopetuspäivä',
      endTime: 'Lopetusaika',
      prevYear: 'Edellinen Vuosi',
      nextYear: 'Seuraava Vuosi',
      prevMonth: 'Edellinen Kuukausi',
      nextMonth: 'Seuraava Kuukausi',
      year: '',
      month1: 'tammikuu',
      month2: 'helmikuu',
      month3: 'maaliskuu',
      month4: 'huhtikuu',
      month5: 'toukokuu',
      month6: 'kesäkuu',
      month7: 'heinäkuu',
      month8: 'elokuu',
      month9: 'syyskuu',
      month10: 'lokakuu',
      month11: 'marraskuu',
      month12: 'joulukuu',
      // week: 'week',
      weeks: {
        sun: 'su',
        mon: 'ma',
        tue: 'ti',
        wed: 'ke',
        thu: 'to',
        fri: 'pe',
        sat: 'la'
      },
      months: {
        jan: 'tam',
        feb: 'hel',
        mar: 'maa',
        apr: 'huh',
        may: 'tou',
        jun: 'kes',
        jul: 'hei',
        aug: 'elo',
        sep: 'syy',
        oct: 'lok',
        nov: 'mar',
        dec: 'jou'
      }
    },
    select: {
      loading: 'Lataa',
      noMatch: 'Ei vastaavia tietoja',
      noData: 'Ei tietoja',
      placeholder: 'Valitse'
    },
    cascader: {
      noMatch: 'Ei vastaavia tietoja',
      loading: 'Lataa',
      placeholder: 'Valitse'
    },
    pagination: {
      goto: 'Mene',
      pagesize: '/sivu',
      total: 'Yhteensä {total}',
      pageClassifier: ''
    },
    messagebox: {
      title: 'Viesti',
      confirm: 'OK',
      cancel: 'Peruuta',
      error: 'Virheellinen syöte'
    },
    upload: {
      deleteTip: 'Lehdistö Poista että poistaa',
      delete: 'Poista',
      preview: 'Esikatsele',
      continue: 'Jatka'
    },
    table: {
      emptyText: 'Ei tietoja',
      confirmFilter: 'Vahvista',
      resetFilter: 'Tyhjennä',
      clearFilter: 'Kaikki',
      sumText: 'Summa'
    },
    tree: {
      emptyText: 'Ei tietoja'
    },
    transfer: {
      noMatch: 'Ei vastaavia tietoja',
      noData: 'Ei tietoja',
      titles: ['Luettelo 1', 'Luettelo 2'],
      filterPlaceholder: 'Kirjoita avainsana',
      noCheckedFormat: '{total} kohdetta',
      hasCheckedFormat: '{checked}/{total} valittu'
    }
  }
};
<|endoftext|>


<commit_before>export default {
  el: {
    colorpicker: {
      confirm: 'Sawa',
      clear: 'Futa'
    },
    datepicker: {
      now: 'Hivi Punde',
      today: 'Leo',
      cancel: 'Katisha',
      clear: 'Futa',
      confirm: 'Sawa',
      selectDate: 'Chagua tarehe',
      selectTime: 'Chagua Muda',
      startDate: 'Kuanzia tarehe',
      startTime: 'Kuanzia saa',
      endDate: 'Mpaka Tarehe',
      endTime: 'Mpaka Saa',
      prevYear: 'Mwaka uliopita',
      nextYear: 'Mwaka ujao',
      prevMonth: 'Mwezi uliopita',
      nextMonth: 'Mwezi ujao',
      year: '',
      month1: 'Januari',
      month2: 'Februari',
      month3: 'Machi',
      month4: 'Aprili',
      month5: 'Mei',
      month6: 'Juni',
      month7: 'Jalai',
      month8: 'Agosti',
      month9: 'Septemba',
      month10: 'Oktoba',
      month11: 'Novemba',
      month12: 'Disemba',
      week: 'wili',
      weeks: {
        sun: 'J2',
        mon: 'J3',
        tue: 'J4',
        wed: 'J5',
        thu: 'Alhamis',
        fri: 'Ijumaa',
        sat: 'J1'
      },
      months: {
        jan: 'Jan',
        feb: 'Feb',
        mar: 'Mar',
        apr: 'Apr',
        may: 'Mei',
        jun: 'Jun',
        jul: 'Jul',
        aug: 'Ago',
        sep: 'Sep',
        oct: 'Okt',
        nov: 'Nov',
        dec: 'Dec'
      }
    },
    select: {
      loading: 'Inapakia',
      noMatch: 'Hakuna Matokeo yaliyofanana',
      noData: 'Hakuna Matokeo',
      placeholder: 'Chagua'
    },
    cascader: {
      noMatch: 'Hakuna Matokeo yaliyofanana',
      loading: 'Inapakia',
      placeholder: 'Chagua',
      noData: 'Hakuna Matokeo'
    },
    pagination: {
      goto: 'Nenda',
      pagesize: '/page',
      total: 'Jumla {total}',
      pageClassifier: ''
    },
    messagebox: {
      title: 'Ujumbe',
      confirm: 'Sawa',
      cancel: 'Katisha',
      error: 'Maingizo yasiyo sahihi'
    },
    upload: {
      deleteTip: 'bonyeza futa kuondoa',
      delete: 'Futa',
      preview: 'Onyesha',
      continue: 'Endelea'
    },
    table: {
      emptyText: 'Hakuna Data',
      confirmFilter: 'Hakikisha',
      resetFilter: 'Ondoa Kichujio',
      clearFilter: 'Zote',
      sumText: 'Jumla'
    },
    tree: {
      emptyText: 'Hakuna Data'
    },
    transfer: {
      noMatch: 'Hakuna Matokeo yaliyofanana',
      noData: 'Hakuna Data',
      titles: ['List 1', 'List 2'], // to be translated
      filterPlaceholder: 'Enter keyword', // to be translated
      noCheckedFormat: '{total} ya zote', // to be translated
      hasCheckedFormat: '{checked}/{total} zilizochaguliwa' // to be translated
    },
    image: {
      error: 'IMEFELI'
    },
    pageHeader: {
      title: 'Nyuma' // to be translated
    },
    popconfirm: {
      confirmButtonText: 'Ndio',
      cancelButtonText: 'Hapana'
    },
    empty: {
      description: 'Hakuna Data'
    }
  }
};<commit_msg>i18n: Format optimization<commit_after>export default {
  el: {
    colorpicker: {
      confirm: 'Sawa',
      clear: 'Futa'
    },
    datepicker: {
      now: 'Hivi Punde',
      today: 'Leo',
      cancel: 'Katisha',
      clear: 'Futa',
      confirm: 'Sawa',
      selectDate: 'Chagua tarehe',
      selectTime: 'Chagua Muda',
      startDate: 'Kuanzia tarehe',
      startTime: 'Kuanzia saa',
      endDate: 'Mpaka Tarehe',
      endTime: 'Mpaka Saa',
      prevYear: 'Mwaka uliopita',
      nextYear: 'Mwaka ujao',
      prevMonth: 'Mwezi uliopita',
      nextMonth: 'Mwezi ujao',
      year: '',
      month1: 'Januari',
      month2: 'Februari',
      month3: 'Machi',
      month4: 'Aprili',
      month5: 'Mei',
      month6: 'Juni',
      month7: 'Jalai',
      month8: 'Agosti',
      month9: 'Septemba',
      month10: 'Oktoba',
      month11: 'Novemba',
      month12: 'Disemba',
      week: 'wili',
      weeks: {
        sun: 'J2',
        mon: 'J3',
        tue: 'J4',
        wed: 'J5',
        thu: 'Alhamis',
        fri: 'Ijumaa',
        sat: 'J1'
      },
      months: {
        jan: 'Jan',
        feb: 'Feb',
        mar: 'Mar',
        apr: 'Apr',
        may: 'Mei',
        jun: 'Jun',
        jul: 'Jul',
        aug: 'Ago',
        sep: 'Sep',
        oct: 'Okt',
        nov: 'Nov',
        dec: 'Dec'
      }
    },
    select: {
      loading: 'Inapakia',
      noMatch: 'Hakuna Matokeo yaliyofanana',
      noData: 'Hakuna Matokeo',
      placeholder: 'Chagua'
    },
    cascader: {
      noMatch: 'Hakuna Matokeo yaliyofanana',
      loading: 'Inapakia',
      placeholder: 'Chagua',
      noData: 'Hakuna Matokeo'
    },
    pagination: {
      goto: 'Nenda',
      pagesize: '/page',
      total: 'Jumla {total}',
      pageClassifier: ''
    },
    messagebox: {
      title: 'Ujumbe',
      confirm: 'Sawa',
      cancel: 'Katisha',
      error: 'Maingizo yasiyo sahihi'
    },
    upload: {
      deleteTip: 'bonyeza futa kuondoa',
      delete: 'Futa',
      preview: 'Onyesha',
      continue: 'Endelea'
    },
    table: {
      emptyText: 'Hakuna Data',
      confirmFilter: 'Hakikisha',
      resetFilter: 'Ondoa Kichujio',
      clearFilter: 'Zote',
      sumText: 'Jumla'
    },
    tree: {
      emptyText: 'Hakuna Data'
    },
    transfer: {
      noMatch: 'Hakuna Matokeo yaliyofanana',
      noData: 'Hakuna Data',
      titles: ['List 1', 'List 2'], // to be translated
      filterPlaceholder: 'Enter keyword', // to be translated
      noCheckedFormat: '{total} ya zote', // to be translated
      hasCheckedFormat: '{checked}/{total} zilizochaguliwa' // to be translated
    },
    image: {
      error: 'IMEFELI'
    },
    pageHeader: {
      title: 'Nyuma' // to be translated
    },
    popconfirm: {
      confirmButtonText: 'Ndio',
      cancelButtonText: 'Hapana'
    },
    empty: {
      description: 'Hakuna Data'
    }
  }
};
<|endoftext|>


<commit_before>/*
 * Paper.js
 *
 * This file is part of Paper.js, a JavaScript Vector Graphics Library,
 * based on Scriptographer.org and designed to be largely API compatible.
 * http://paperjs.org/
 * http://scriptographer.org/
 *
 * Copyright (c) 2011, Juerg Lehni & Jonathan Puckey
 * http://lehni.org/ & http://jonathanpuckey.com/
 *
 * Distributed under the MIT license. See LICENSE file for details.
 *
 * All rights reserved.
 */

/**
 * @name PaperScopeItem
 *
 * @class A private base class for all classes that have lists and references in
 * the {@link PaperScope} ({@link Project}, {@link View}, {@link Tool}), so
 * functionality can be shared.
 *
 * @private
 */
var PaperScopeItem = Base.extend(/** @lends PaperScopeItem# */{

	/**
	 * Creates a PaperScopeItem object.
	 */
	initialize: function(activate) {
		// Store reference to the currently active global paper scope:
		this._scope = paper;
		// Push it onto this._scope.projects and set index:
		this._index = this._scope[this._list].push(this) - 1;
		// If the project has no active reference, activate this one
		if (activate || !this._scope[this._reference])
			this.activate();
	},

	activate: function() {
		if (!this._scope)
			return false;
		this._scope[this._reference] = this;
		return true;
	},

	remove: function() {
		if (this._index == null)
			return false;
		Base.splice(this._scope[this._list], null, this._index, 1);
		// Clear the active tool reference if it was pointint to this.
		if (this._scope[this._reference] == this)
			this._scope[this._reference] = null;
		this._scope = null;
		return true;
	}
});
<commit_msg>Define #isActive() for PaperScopeItems.<commit_after>/*
 * Paper.js
 *
 * This file is part of Paper.js, a JavaScript Vector Graphics Library,
 * based on Scriptographer.org and designed to be largely API compatible.
 * http://paperjs.org/
 * http://scriptographer.org/
 *
 * Copyright (c) 2011, Juerg Lehni & Jonathan Puckey
 * http://lehni.org/ & http://jonathanpuckey.com/
 *
 * Distributed under the MIT license. See LICENSE file for details.
 *
 * All rights reserved.
 */

/**
 * @name PaperScopeItem
 *
 * @class A private base class for all classes that have lists and references in
 * the {@link PaperScope} ({@link Project}, {@link View}, {@link Tool}), so
 * functionality can be shared.
 *
 * @private
 */
var PaperScopeItem = Base.extend(/** @lends PaperScopeItem# */{

	/**
	 * Creates a PaperScopeItem object.
	 */
	initialize: function(activate) {
		// Store reference to the currently active global paper scope:
		this._scope = paper;
		// Push it onto this._scope.projects and set index:
		this._index = this._scope[this._list].push(this) - 1;
		// If the project has no active reference, activate this one
		if (activate || !this._scope[this._reference])
			this.activate();
	},

	activate: function() {
		if (!this._scope)
			return false;
		this._scope[this._reference] = this;
		return true;
	},

	isActive: function() {
		return this._scope[this._reference] === this;
	},

	remove: function() {
		if (this._index == null)
			return false;
		Base.splice(this._scope[this._list], null, this._index, 1);
		// Clear the active tool reference if it was pointint to this.
		if (this._scope[this._reference] == this)
			this._scope[this._reference] = null;
		this._scope = null;
		return true;
	}
});
<|endoftext|>


<commit_before>define([], function() {
	"use strict";
	if(typeof window == 'undefined') {
		return;
	}

	var s_classList = 'classList',
		nsReg = /\.(.+)/,
		allEvents = {},
		nodeIndex = 0,
		fn = [];

	function $b(s, context) {
		return new $b.i(s, context);
	}

	$b.i = function(s, context) {
		var result,
			l, i;

		if(s) {
			if(s.nodeType || s == window) {
				result = [s];
			} else if(typeof s == 'string') {
				if(/</.test(s)) {
					result = $b.parseHTML(s);
				} else {
					if(context) {
						if(context = $b(context)[0]) {
							result = context.querySelectorAll(s);
						}
					} else {
						result = document.querySelectorAll(s);
					}
				}
			} else if(s instanceof Function) { // typeof s == 'function' doesn't work correctly in Phantom
				if(document.readyState == 'loading') {
					document.addEventListener('DOMContentLoaded', s);
				} else {
					s();
				}
			} else {
				result = s;
			}
		}

		l = result && result.length;

		if(l) {
			for(i = 0; i < l; i++) {
				this.push(result[i]);
			}
		}
	};

	$b.fn = $b.i.fn = $b.i.prototype = fn;

	$b.extend = function(obj) {
		var k = arguments,
			i, j, l;
		for (i = 1; i < k.length; i++) {
			if (l = k[i]) {
				for (j in l) {
					obj[j] = l[j];
				}
			}
		}

		return obj;
	};

	$b.extend(fn, {
		is: function(s) {
			var node = this[0];
			return node ? (node.matches
					|| node.webkitMatchesSelector
					|| node.mozMatchesSelector
					|| node.msMatchesSelector
					|| node.oMatchesSelector).call(node, s) : false;
		},
		on: function(names, selector, handler) {
			var _this = this,
				delegate,
				name,
				namespace,
				node,
				nodeID,
				events,
				event,
				exist,
				i, j, k;

			if(typeof selector == 'function') {
				handler = selector;
				selector = null;
			}

			if(selector) {
				delegate = function(evt) {
					var randomID = 'x' + String(Math.random()).split('.')[1],
						node = this,
						is;

					node.setAttribute(randomID, randomID);

					is = '[' + randomID + '="' + randomID + '"] ' + selector;

					if ($b(evt.target).is(is + ',' + is + ' *')) {
						handler.call(node, evt);
					}

					node.removeAttribute(randomID);
				};

				//delegate._callback = handler;
				//handler = delegate;
			}

			names = names.split(/\s/);

			for(i = 0; i < names.length; i++) {
				name = names[i].split(nsReg);
				namespace = name[1];
				name = name[0];

				for(j = 0; j < _this.length; j++) {
					node = _this[j];

					nodeID = node.b$ = node.b$ || ++nodeIndex,
					events = allEvents[name + nodeID] = allEvents[name + nodeID] || [],
					exist = false;

					for(k = 0; k < events.length; k++) {
						event = events[k];

						if(handler == event.handler && (!selector || selector == event.selector)) {
							exist = true;
							break;
						}
					}

					if(!exist) {
						events.push({
							delegate: delegate,
							handler: handler,
							namespace: namespace,
							selector: selector
						});

						node.addEventListener(name, delegate || handler, false);
					}
				}
			}

			return _this;
		},
		off: function(names, selector, handler) {
			var _this = this,
				name,
				namespace,
				node,
				events,
				event,
				i, j, k;

			if(typeof selector == 'function') {
				handler = selector;
				selector = null;
			}

			names = names.split(/\s/);

			for(i = 0; i < names.length; i++) {
				name = names[i].split(nsReg);
				namespace = name[1];
				name = name[0];

				for(j = 0; j < _this.length; j++) {
					node = _this[j];

					events = allEvents[name + node.b$];

					if (events) {
						for(k = 0; k < events.length; k++) {
							event = events[k];
							if((!handler || handler == event.handler || handler == event.delegate)
									&& (!namespace || namespace == event.namespace)
									&& (!selector || selector == event.selector)) {
								node.removeEventListener(name, event.delegate || event.handler);
								events.splice(k--, 1);
							}
						}
					} else {
						if(!namespace && !selector) {
							node.removeEventListener(name, handler);
						}
					}
				}
			}

			return _this;
		},
		hasClass: function(className) {
			return !!this[0] && this[0][s_classList].contains(className);
		},
		addClass: function(className) {
			this.forEach(function(item) {
				var classList = item[s_classList];
				classList.add.apply(classList, className.split(/\s/));
			});
			return this;
		},
		removeClass: function(className) {
			this.forEach(function(item) {
				var classList = item[s_classList];
				classList.remove.apply(classList, className.split(/\s/));
			});
			return this;
		},
		toggleClass: function(className, b) {
			this.forEach(function(item) {
				var classList = item[s_classList];
				if (typeof b !== 'boolean') {
					b = !classList.contains(className);
				}
				classList[b ? 'add' : 'remove'].apply(classList, className.split(/\s/));
			});
			return this;
		},
		add: function(s) {
			var result = $b(this),
				map = {},
				nodeID,
				node,
				i;

			s = $b(s);

			for(i = 0; i < result.length; i++) {
				node = result[i];
				nodeID = node.b$ = node.b$ || ++nodeIndex;
				map[nodeID] = 1;
			}

			for(i = 0; i < s.length; i++) {
				node = s[i];
				nodeID = node.b$ = node.b$ || ++nodeIndex;
				if(!map[nodeID]) {
					map[nodeID] = 1;
					result.push(node);
				}
			}

			return result;
		},
		not: function(s) {
			var result = $b(this),
				index,
				i;

			s = $b(s);

			for (i = 0; i < s.length; i++) {
				if (~(index = result.indexOf(s[i]))) {
					result.splice(index, 1);
				}
			}

			return result;
		},
		find: function(s) {
			var result = $b();
			this.forEach(function(item) {
				result = result.add($b(s, item));
			});
			return result;
		}
	});

	// simple html parser
	$b.parseHTML = function(html) {
		var node = document.createElement('div'),
			// wrapMap is taken from jQuery
			wrapMap = {
				option: [1, "<select multiple='multiple'>", "</select>"],
				legend: [1, "<fieldset>", "</fieldset>"],
				thead: [1, "
", "
"],
				tr: [2, "

", "

"],
				td: [3, "

", "

"],
				col: [2, "

<colgroup>", "</colgroup>
"],
				area: [1, "<map>", "</map>"],
				_: [0, "", ""]
			},
			wrapper,
			i,
			ex;

		html = html.replace(/^\s+|\s+$/g, '');

		wrapMap.optgroup = wrapMap.option;
		wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;
		wrapMap.th = wrapMap.td;

		ex = /<([\w:]+)/.exec(html);

		wrapper = ex && wrapMap[ex[1]] || wrapMap._;

		node.innerHTML = wrapper[1] + html + wrapper[2];

		i = wrapper[0];

		while (i--) {
			node = node.children[0];
		}

		return $b(node.childNodes);
	};

	$b.create = function create(tagName, props) {
		var el, i, j, prop;

		if (typeof tagName == 'object') {
			props = tagName;
			tagName = props.tagName;
		}

		el = document.createElement(tagName);

		if (props)
			for (i in props) {
				prop = props[i];
				if (i == 'attributes' && typeof prop == 'object') {
					for (j in prop)
						if (prop.hasOwnProperty(j)) {
							el.setAttribute(j, prop[j]);
						}
				} else if (i == 'tagName') {
					continue;
				} else if (i == 'children' && prop) {
					for (j = 0; j < prop.length; j++) {
						el.appendChild(create(prop[j]));
					}
				} else if (typeof el[i] == 'object' && el[i] !== null && typeof props == 'object') {
					for (j in prop)
						if (prop.hasOwnProperty(j)) {
							el[i][j] = prop[j];
						}
				} else {
					el[i] = prop;
				}
			}
		return el;
	};

	$b.one = function(s, context) {
		return $b(s, context)[0] || null;
	};

	return $b;
});
<commit_msg>get rid of some undocumented methods from bQuery: addClass, removeClass, toggleClass, hasClass<commit_after>define([], function() {
	"use strict";

	/* istanbul ignore if  */
	if(typeof window == 'undefined') {
		return;
	}

	var s_classList = 'classList',
		nsReg = /\.(.+)/,
		allEvents = {},
		nodeIndex = 0,
		fn = [];

	function $b(s, context) {
		return new $b.i(s, context);
	}

	$b.i = function(s, context) {
		var result,
			l, i;

		if(s) {
			if(s.nodeType || s == window) {
				result = [s];
			} else if(typeof s == 'string') {
				if(/</.test(s)) {
					result = $b.parseHTML(s);
				} else {
					if(context) {
						if(context = $b(context)[0]) {
							result = context.querySelectorAll(s);
						}
					} else {
						result = document.querySelectorAll(s);
					}
				}
			} else if(typeof s == 'function') {
				if(document.readyState == 'loading') {
					document.addEventListener('DOMContentLoaded', s);
				} else {
					s();
				}
			} else {
				result = s;
			}
		}

		l = result && result.length;

		if(l) {
			for(i = 0; i < l; i++) {
				this.push(result[i]);
			}
		}
	};

	$b.fn = $b.i.fn = $b.i.prototype = fn;

	$b.extend = function(obj) {
		var k = arguments,
			i, j, l;
		for (i = 1; i < k.length; i++) {
			if (l = k[i]) {
				for (j in l) {
					obj[j] = l[j];
				}
			}
		}

		return obj;
	};

	$b.extend(fn, {
		is: function(s) {
			var node = this[0];
			return node ? (node.matches
					|| node.webkitMatchesSelector
					|| node.mozMatchesSelector
					|| node.msMatchesSelector
					|| node.oMatchesSelector).call(node, s) : false;
		},
		on: function(names, selector, handler) {
			var _this = this,
				delegate,
				name,
				namespace,
				node,
				nodeID,
				events,
				event,
				exist,
				i, j, k;

			if(typeof selector == 'function') {
				handler = selector;
				selector = null;
			}

			if(selector) {
				delegate = function(evt) {
					var randomID = 'x' + String(Math.random()).split('.')[1],
						node = this,
						is;

					node.setAttribute(randomID, randomID);

					is = '[' + randomID + '="' + randomID + '"] ' + selector;

					if ($b(evt.target).is(is + ',' + is + ' *')) {
						handler.call(node, evt);
					}

					node.removeAttribute(randomID);
				};

				//delegate._callback = handler;
				//handler = delegate;
			}

			names = names.split(/\s/);

			for(i = 0; i < names.length; i++) {
				name = names[i].split(nsReg);
				namespace = name[1];
				name = name[0];

				for(j = 0; j < _this.length; j++) {
					node = _this[j];

					nodeID = node.b$ = node.b$ || ++nodeIndex,
					events = allEvents[name + nodeID] = allEvents[name + nodeID] || [],
					exist = false;

					for(k = 0; k < events.length; k++) {
						event = events[k];

						if(handler == event.handler && (!selector || selector == event.selector)) {
							exist = true;
							break;
						}
					}

					if(!exist) {
						events.push({
							delegate: delegate,
							handler: handler,
							namespace: namespace,
							selector: selector
						});

						node.addEventListener(name, delegate || handler, false);
					}
				}
			}

			return _this;
		},
		off: function(names, selector, handler) {
			var _this = this,
				name,
				namespace,
				node,
				events,
				event,
				i, j, k;

			if(typeof selector == 'function') {
				handler = selector;
				selector = null;
			}

			names = names.split(/\s/);

			for(i = 0; i < names.length; i++) {
				name = names[i].split(nsReg);
				namespace = name[1];
				name = name[0];

				for(j = 0; j < _this.length; j++) {
					node = _this[j];

					events = allEvents[name + node.b$];

					if (events) {
						for(k = 0; k < events.length; k++) {
							event = events[k];
							if((!handler || handler == event.handler || handler == event.delegate)
									&& (!namespace || namespace == event.namespace)
									&& (!selector || selector == event.selector)) {
								node.removeEventListener(name, event.delegate || event.handler);
								events.splice(k--, 1);
							}
						}
					} else {
						if(!namespace && !selector) {
							node.removeEventListener(name, handler);
						}
					}
				}
			}

			return _this;
		},
		add: function(s) {
			var result = $b(this),
				map = {},
				nodeID,
				node,
				i;

			s = $b(s);

			for(i = 0; i < result.length; i++) {
				node = result[i];
				nodeID = node.b$ = node.b$ || ++nodeIndex;
				map[nodeID] = 1;
			}

			for(i = 0; i < s.length; i++) {
				node = s[i];
				nodeID = node.b$ = node.b$ || ++nodeIndex;
				if(!map[nodeID]) {
					map[nodeID] = 1;
					result.push(node);
				}
			}

			return result;
		},
		not: function(s) {
			var result = $b(this),
				index,
				i;

			s = $b(s);

			for (i = 0; i < s.length; i++) {
				if (~(index = result.indexOf(s[i]))) {
					result.splice(index, 1);
				}
			}

			return result;
		},
		find: function(s) {
			var result = $b();
			this.forEach(function(item) {
				result = result.add($b(s, item));
			});
			return result;
		}
	});

	// simple html parser
	$b.parseHTML = function(html) {
		var node = document.createElement('div'),
			// wrapMap is taken from jQuery
			wrapMap = {
				option: [1, "<select multiple='multiple'>", "</select>"],
				legend: [1, "<fieldset>", "</fieldset>"],
				thead: [1, "
", "
"],
				tr: [2, "

", "

"],
				td: [3, "

", "

"],
				col: [2, "

<colgroup>", "</colgroup>
"],
				area: [1, "<map>", "</map>"],
				_: [0, "", ""]
			},
			wrapper,
			i,
			ex;

		html = html.replace(/^\s+|\s+$/g, '');

		wrapMap.optgroup = wrapMap.option;
		wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;
		wrapMap.th = wrapMap.td;

		ex = /<([\w:]+)/.exec(html);

		wrapper = ex && wrapMap[ex[1]] || wrapMap._;

		node.innerHTML = wrapper[1] + html + wrapper[2];

		i = wrapper[0];

		while (i--) {
			node = node.children[0];
		}

		return $b(node.childNodes);
	};

	$b.create = function create(tagName, props) {
		var el, i, j, prop;

		if (typeof tagName == 'object') {
			props = tagName;
			tagName = props.tagName;
		}

		el = document.createElement(tagName);

		if (props)
			for (i in props) {
				prop = props[i];
				if (i == 'attributes' && typeof prop == 'object') {
					for (j in prop)
						if (prop.hasOwnProperty(j)) {
							el.setAttribute(j, prop[j]);
						}
				} else if (i == 'tagName') {
					continue;
				} else if (i == 'children' && prop) {
					for (j = 0; j < prop.length; j++) {
						el.appendChild(create(prop[j]));
					}
				} else if (typeof el[i] == 'object' && el[i] !== null && typeof props == 'object') {
					for (j in prop)
						if (prop.hasOwnProperty(j)) {
							el[i][j] = prop[j];
						}
				} else {
					el[i] = prop;
				}
			}
		return el;
	};

	$b.one = function(s, context) {
		return $b(s, context)[0] || null;
	};

	return $b;
});
<|endoftext|>


<commit_before>(function(angular) {
    'use strict';

    angular.module('esri.core').factory('esriLayerUtils', function(esriLoader) {

        // parse array of visible layer ids from a string
        function parseVisibleLayers(val) {
            var visibleLayers;
            if (typeof val === 'string') {
                visibleLayers = [];
                val.split(',').forEach(function(layerId) {
                    var n = parseInt(layerId);
                    if (!isNaN(n)) {
                        visibleLayers.push(n);
                    }
                });
            }
            return visibleLayers;
        }

        // layerOptions.infoTemplate expects one of the following:
        //  1. [title <String | Function>, content <String | Function>]
        //  2. {title: <String | Function>, content: <String | Function>}
        //  3. a valid Esri JSAPI InfoTemplate
        function objectToInfoTemplate(infoTemplate, InfoTemplate) {
            // only attempt to construct if a valid InfoTemplate wasn't already passed in
            if (infoTemplate.declaredClass === 'esri.InfoTemplate') {
                return infoTemplate;
            } else {
                // construct infoTemplate from object, using 2 args style:
                //  https://developers.arcgis.com/javascript/jsapi/infotemplate-amd.html#infotemplate2
                if (angular.isArray(infoTemplate) && infoTemplate.length === 2) {
                    return new InfoTemplate(infoTemplate[0], infoTemplate[1]);
                } else {
                    return new InfoTemplate(infoTemplate.title, infoTemplate.content);
                }
            }
        }

        // stateless utility service
        var service = {};

        // create a feature layer
        service.createFeatureLayer = function(url, layerOptions) {
            return esriLoader.require(['esri/layers/FeatureLayer', 'esri/InfoTemplate']).then(function(esriModules) {
                var FeatureLayer = esriModules[0];
                var InfoTemplate = esriModules[1];

                if (layerOptions) {
                    // normalize info template defined in layerOptions.infoTemplate
                    // or nested esriLayerOption directive to be instance of esri/InfoTemplate
                    // and pass to layer constructor in layerOptions
                    if (layerOptions.infoTemplate) {
                        layerOptions.infoTemplate = objectToInfoTemplate(layerOptions.infoTemplate, InfoTemplate);
                    }

                    // layerOptions.mode expects a FeatureLayer constant name as a <String>
                    // https://developers.arcgis.com/javascript/jsapi/featurelayer-amd.html#constants
                    if (layerOptions.hasOwnProperty('mode')) {
                        // look up and convert to the appropriate <Number> value
                        layerOptions.mode = FeatureLayer[layerOptions.mode];
                    }
                }
                return new FeatureLayer(url, layerOptions);
            });
        };

        // create a dynamic service layer
        service.createDynamicMapServiceLayer = function(url, layerOptions, visibleLayers) {
            return esriLoader.require(['esri/layers/ArcGISDynamicMapServiceLayer', 'esri/InfoTemplate', 'esri/layers/ImageParameters']).then(function(esriModules) {
                var ArcGISDynamicMapServiceLayer = esriModules[0];
                var InfoTemplate = esriModules[1];
                var ImageParameters = esriModules[2];
                var layer;

                if (layerOptions) {
                    // normalize info templates defined in layerOptions.infoTemplates
                    // or nested esriLayerOption directives to be instances of esri/InfoTemplate
                    // and pass to layer constructor in layerOptions
                    if (layerOptions.infoTemplates) {
                        for (var layerId in layerOptions.infoTemplates) {
                            if (layerOptions.infoTemplates.hasOwnProperty(layerId)) {
                                layerOptions.infoTemplates[layerId].infoTemplate = objectToInfoTemplate(layerOptions.infoTemplates[layerId].infoTemplate, InfoTemplate);
                            }
                        }
                    }

                    // check for imageParameters property and
                    // convert into ImageParameters() if needed
                    if (angular.isObject(layerOptions.imageParameters)) {
                        if (layerOptions.imageParameters.declaredClass !== 'esri.layers.ImageParameters') {
                            var imageParameters = new ImageParameters();
                            for (var key in layerOptions.imageParameters) {
                                if (layerOptions.imageParameters.hasOwnProperty(key)) {
                                    // TODO: may want to convert timeExent to new TimeExtent()
                                    // also not handling conversion for bbox, imageSpatialReference, nor layerTimeOptions
                                    imageParameters[key] = layerOptions.imageParameters[key];
                                }
                            }
                            layerOptions.imageParameters = imageParameters;
                        }
                    }
                }

                // create the layer object
                layer = new ArcGISDynamicMapServiceLayer(url, layerOptions);

                // set visible layers if passed as attribute
                if (visibleLayers) {
                    layer.setVisibleLayers(parseVisibleLayers(visibleLayers));
                }

                return layer;
            });
        };

        // create an InfoTemplate object from JSON
        service.createInfoTemplate = function(infoTemplate) {
            return esriLoader.require('esri/InfoTemplate').then(function(InfoTemplate) {
                return objectToInfoTemplate(infoTemplate, InfoTemplate);
            });
        };

        return service;
    });

})(angular);
<commit_msg>added ngdoc for esriLayerUtils<commit_after>(function(angular) {
    'use strict';

    /**
     * @ngdoc service
     * @name esri.core.factory:esriLayerUtils
     *
     * @description
     * Functions to create instances of layers and related classes (such as InfoTemplate).
     *
     * @requires esri.core.factory:esriLoader
     */
    angular.module('esri.core').factory('esriLayerUtils', function(esriLoader) {

        // parse array of visible layer ids from a string
        function parseVisibleLayers(val) {
            var visibleLayers;
            if (typeof val === 'string') {
                visibleLayers = [];
                val.split(',').forEach(function(layerId) {
                    var n = parseInt(layerId);
                    if (!isNaN(n)) {
                        visibleLayers.push(n);
                    }
                });
            }
            return visibleLayers;
        }

        // layerOptions.infoTemplate expects one of the following:
        //  1. [title <String | Function>, content <String | Function>]
        //  2. {title: <String | Function>, content: <String | Function>}
        //  3. a valid Esri JSAPI InfoTemplate
        function objectToInfoTemplate(infoTemplate, InfoTemplate) {
            // only attempt to construct if a valid InfoTemplate wasn't already passed in
            if (infoTemplate.declaredClass === 'esri.InfoTemplate') {
                return infoTemplate;
            } else {
                // construct infoTemplate from object, using 2 args style:
                //  https://developers.arcgis.com/javascript/jsapi/infotemplate-amd.html#infotemplate2
                if (angular.isArray(infoTemplate) && infoTemplate.length === 2) {
                    return new InfoTemplate(infoTemplate[0], infoTemplate[1]);
                } else {
                    return new InfoTemplate(infoTemplate.title, infoTemplate.content);
                }
            }
        }

        // stateless utility service
        var service = {};

        /**
         * @ngdoc function
         * @name createFeatureLayer
         * @methodOf esri.core.factory:esriLayerUtils
         * @param {String} url The url of the map or feature service layer
         * @param {Object=} options FeatureLayer options
         * @returns {Promise} Returns a $q style promise resolved with an instance of {@link https://developers.arcgis.com/javascript/jsapi/featurelayer-amd.html#featurelayer1 FeatureLayer}
         */
        service.createFeatureLayer = function(url, layerOptions) {
            return esriLoader.require(['esri/layers/FeatureLayer', 'esri/InfoTemplate']).then(function(esriModules) {
                var FeatureLayer = esriModules[0];
                var InfoTemplate = esriModules[1];

                if (layerOptions) {
                    // normalize info template defined in layerOptions.infoTemplate
                    // or nested esriLayerOption directive to be instance of esri/InfoTemplate
                    // and pass to layer constructor in layerOptions
                    if (layerOptions.infoTemplate) {
                        layerOptions.infoTemplate = objectToInfoTemplate(layerOptions.infoTemplate, InfoTemplate);
                    }

                    // layerOptions.mode expects a FeatureLayer constant name as a <String>
                    // https://developers.arcgis.com/javascript/jsapi/featurelayer-amd.html#constants
                    if (layerOptions.hasOwnProperty('mode')) {
                        // look up and convert to the appropriate <Number> value
                        layerOptions.mode = FeatureLayer[layerOptions.mode];
                    }
                }
                return new FeatureLayer(url, layerOptions);
            });
        };

        /**
         * @ngdoc function
         * @name createDynamicMapServiceLayer
         * @methodOf esri.core.factory:esriLayerUtils
         * @param {String} url The url of the map service
         * @param {Object=} options ArcGISDynamicMapServiceLayer options
         * @returns {Promise} Returns a $q style promise resolved with an instance of {@link https://developers.arcgis.com/javascript/jsapi/arcgisdynamicmapservicelayer-amd.html#arcgisdynamicmapservicelayer1 ArcGISDynamicMapServiceLayer}
         */
        service.createDynamicMapServiceLayer = function(url, layerOptions, visibleLayers) {
            return esriLoader.require(['esri/layers/ArcGISDynamicMapServiceLayer', 'esri/InfoTemplate', 'esri/layers/ImageParameters']).then(function(esriModules) {
                var ArcGISDynamicMapServiceLayer = esriModules[0];
                var InfoTemplate = esriModules[1];
                var ImageParameters = esriModules[2];
                var layer;

                if (layerOptions) {
                    // normalize info templates defined in layerOptions.infoTemplates
                    // or nested esriLayerOption directives to be instances of esri/InfoTemplate
                    // and pass to layer constructor in layerOptions
                    if (layerOptions.infoTemplates) {
                        for (var layerId in layerOptions.infoTemplates) {
                            if (layerOptions.infoTemplates.hasOwnProperty(layerId)) {
                                layerOptions.infoTemplates[layerId].infoTemplate = objectToInfoTemplate(layerOptions.infoTemplates[layerId].infoTemplate, InfoTemplate);
                            }
                        }
                    }

                    // check for imageParameters property and
                    // convert into ImageParameters() if needed
                    if (angular.isObject(layerOptions.imageParameters)) {
                        if (layerOptions.imageParameters.declaredClass !== 'esri.layers.ImageParameters') {
                            var imageParameters = new ImageParameters();
                            for (var key in layerOptions.imageParameters) {
                                if (layerOptions.imageParameters.hasOwnProperty(key)) {
                                    // TODO: may want to convert timeExent to new TimeExtent()
                                    // also not handling conversion for bbox, imageSpatialReference, nor layerTimeOptions
                                    imageParameters[key] = layerOptions.imageParameters[key];
                                }
                            }
                            layerOptions.imageParameters = imageParameters;
                        }
                    }
                }

                // create the layer object
                layer = new ArcGISDynamicMapServiceLayer(url, layerOptions);

                // set visible layers if passed as attribute
                if (visibleLayers) {
                    layer.setVisibleLayers(parseVisibleLayers(visibleLayers));
                }

                return layer;
            });
        };

        // create an InfoTemplate object from JSON
        /**
         * @ngdoc function
         * @name createInfoTemplate
         * @methodOf esri.core.factory:esriLayerUtils
         * @param {Object|Array} infoTemplate Either an array with `['title', 'content']` or an object with `{title: 'title', content: 'content'}`
         * @returns {Promise} Returns a $q style promise resolved with an instance of {@link https://developers.arcgis.com/javascript/jsapi/infotemplate-amd.html InfoTemplate}
         */
        service.createInfoTemplate = function(infoTemplate) {
            return esriLoader.require('esri/InfoTemplate').then(function(InfoTemplate) {
                return objectToInfoTemplate(infoTemplate, InfoTemplate);
            });
        };

        return service;
    });

})(angular);
<|endoftext|>


<commit_before>var math = require('../math'),
    Texture = require('../textures/Texture'),
    Container = require('../display/Container'),
    utils = require('../utils'),
    CONST = require('../const'),
    tempPoint = new math.Point();

/**
 * The Sprite object is the base for all textured objects that are rendered to the screen
 *
 * A sprite can be created directly from an image like this:
 *
 * ```js
 * var sprite = new PIXI.Sprite.fromImage('assets/image.png');
 * ```
 *
 * @class
 * @extends PIXI.Container
 * @memberof PIXI
 * @param texture {PIXI.Texture} The texture for this sprite
 */
function Sprite(texture)
{
    Container.call(this);

    /**
     * The anchor sets the origin point of the texture.
     * The default is 0,0 this means the texture's origin is the top left
     * Setting the anchor to 0.5,0.5 means the texture's origin is centered
     * Setting the anchor to 1,1 would mean the texture's origin point will be the bottom right corner
     *
     * @member {PIXI.Point}
     */
    this.anchor = new math.Point();

    /**
     * The texture that the sprite is using
     *
     * @member {PIXI.Texture}
     * @private
     */
    this._texture = null;

    /**
     * The width of the sprite (this is initially set by the texture)
     *
     * @member {number}
     * @private
     */
    this._width = 0;

    /**
     * The height of the sprite (this is initially set by the texture)
     *
     * @member {number}
     * @private
     */
    this._height = 0;

    /**
     * The tint applied to the sprite. This is a hex value. A value of 0xFFFFFF will remove any tint effect.
     *
     * @member {number}
     * @default 0xFFFFFF
     */
    this.tint = 0xFFFFFF;

    /**
     * The blend mode to be applied to the sprite. Apply a value of `PIXI.BLEND_MODES.NORMAL` to reset the blend mode.
     *
     * @member {number}
     * @default PIXI.BLEND_MODES.NORMAL
     * @see PIXI.BLEND_MODES
     */
    this.blendMode = CONST.BLEND_MODES.NORMAL;

    /**
     * The shader that will be used to render the sprite. Set to null to remove a current shader.
     *
     * @member {PIXI.AbstractFilter|PIXI.Shader}
     */
    this.shader = null;

    /**
     * An internal cached value of the tint.
     *
     * @member {number}
     * @default 0xFFFFFF
     */
    this.cachedTint = 0xFFFFFF;

    // call texture setter
    this.texture = texture || Texture.EMPTY;
    this.textureDirty = true;
    this.vertexData = new Float32Array(16);
}

// constructor
Sprite.prototype = Object.create(Container.prototype);
Sprite.prototype.constructor = Sprite;
module.exports = Sprite;

Object.defineProperties(Sprite.prototype, {
    /**
     * The width of the sprite, setting this will actually modify the scale to achieve the value set
     *
     * @member {number}
     * @memberof PIXI.Sprite#
     */
    width: {
        get: function ()
        {
            return Math.abs(this.scale.x) * this.texture.orig.width;
        },
        set: function (value)
        {
            var sign = utils.sign(this.scale.x) || 1;
            this.scale.x = sign * value / this.texture.orig.width;
            this._width = value;
        }
    },

    /**
     * The height of the sprite, setting this will actually modify the scale to achieve the value set
     *
     * @member {number}
     * @memberof PIXI.Sprite#
     */
    height: {
        get: function ()
        {
            return  Math.abs(this.scale.y) * this.texture.orig.height;
        },
        set: function (value)
        {
            var sign = utils.sign(this.scale.y) || 1;
            this.scale.y = sign * value / this.texture.orig.height;
            this._height = value;
        }
    },

    /**
     * The texture that the sprite is using
     *
     * @member {PIXI.Texture}
     * @memberof PIXI.Sprite#
     */
    texture: {
        get: function ()
        {
            return  this._texture;
        },
        set: function (value)
        {
            if (this._texture === value)
            {
                return;
            }

            this._texture = value;
            this.cachedTint = 0xFFFFFF;

            this.textureDirty = true;

            if (value)
            {
                // wait for the texture to load
                if (value.baseTexture.hasLoaded)
                {
                    this._onTextureUpdate();
                }
                else
                {
                    value.once('update', this._onTextureUpdate, this);
                }
            }
        }
    }
});

/**
 * When the texture is updated, this event will fire to update the scale and frame
 *
 * @private
 */
Sprite.prototype._onTextureUpdate = function ()
{
    this.textureDirty = true;

    // so if _width is 0 then width was not set..
    if (this._width)
    {
        this.scale.x = utils.sign(this.scale.x) * this._width / this.texture.orig.width;
    }

    if (this._height)
    {
        this.scale.y = utils.sign(this.scale.y) * this._height / this.texture.orig.height;
    }
};

/**
 * calculates worldTransform * vertices, store it in vertexData
 */
Sprite.prototype.calculateVertices = function ()
{
    var texture = this._texture,
        wt = this.transform.worldTransform,
        a = wt.a, b = wt.b, c = wt.c, d = wt.d, tx = wt.tx, ty = wt.ty,
        vertexData = this.vertexData,
        w0, w1, h0, h1,
        trim = texture.trim,
        orig = texture.orig;

    if (trim)
    {
        // if the sprite is trimmed and is not a tilingsprite then we need to add the extra space before transforming the sprite coords..
        w1 = trim.x - this.anchor.x * orig.width;
        w0 = w1 + trim.width;

        h1 = trim.y - this.anchor.y * orig.height;
        h0 = h1 + trim.height;

    }
    else
    {
        w0 = (orig.width ) * (1-this.anchor.x);
        w1 = (orig.width ) * -this.anchor.x;

        h0 = orig.height * (1-this.anchor.y);
        h1 = orig.height * -this.anchor.y;
    }

    // xy
    vertexData[0] = a * w1 + c * h1 + tx;
    vertexData[1] = d * h1 + b * w1 + ty;

    // xy
    vertexData[2] = a * w0 + c * h1 + tx;
    vertexData[3] = d * h1 + b * w0 + ty;

     // xy
    vertexData[4] = a * w0 + c * h0 + tx;
    vertexData[5] = d * h0 + b * w0 + ty;

    // xy
    vertexData[6] = a * w1 + c * h0 + tx;
    vertexData[7] = d * h0 + b * w1 + ty;
};

/**
 * we need this method to be compatible with pixiv3. v3 does calculate bounds of original texture are, not trimmed one
 */
Sprite.prototype.calculateBoundsVertices = function ()
{
    var texture = this._texture,
        trim = texture.trim,
        vertexData = this.vertexData,
        orig = texture.orig;

    if (!trim || trim.width == orig.width && trim.height == orig.height) {
        vertexData[8] = vertexData[0];
        vertexData[9] = vertexData[1];
        vertexData[10] = vertexData[2];
        vertexData[11] = vertexData[3];
        vertexData[12] = vertexData[4];
        vertexData[13] = vertexData[5];
        vertexData[14] = vertexData[6];
        vertexData[15] = vertexData[7];
        return;
    }

    var wt = this.transform.worldTransform,
        a = wt.a, b = wt.b, c = wt.c, d = wt.d, tx = wt.tx, ty = wt.ty,
        w0, w1, h0, h1;

    w0 = (orig.width ) * (1-this.anchor.x);
    w1 = (orig.width ) * -this.anchor.x;

    h0 = orig.height * (1-this.anchor.y);
    h1 = orig.height * -this.anchor.y;

    // xy
    vertexData[8] = a * w1 + c * h1 + tx;
    vertexData[9] = d * h1 + b * w1 + ty;

    // xy
    vertexData[10] = a * w0 + c * h1 + tx;
    vertexData[11] = d * h1 + b * w0 + ty;

    // xy
    vertexData[12] = a * w0 + c * h0 + tx;
    vertexData[13] = d * h0 + b * w0 + ty;

    // xy
    vertexData[14] = a * w1 + c * h0 + tx;
    vertexData[15] = d * h0 + b * w1 + ty;
};

/**
*
* Renders the object using the WebGL renderer
*
* @param renderer {PIXI.WebGLRenderer}
* @private
*/
Sprite.prototype._renderWebGL = function (renderer)
{
    if(this.transform.updated || this.textureDirty)
    {
        this.textureDirty = false;
        // set the vertex data
        this.calculateVertices();
    }

    renderer.setObjectRenderer(renderer.plugins.sprite);
    renderer.plugins.sprite.render(this);
};

/**
* Renders the object using the Canvas renderer
*
* @param renderer {PIXI.CanvasRenderer} The renderer
* @private
*/
Sprite.prototype._renderCanvas = function (renderer)
{
    renderer.plugins.sprite.render(this);
};

/**
 * Returns the bounds of the Sprite as a rectangle. The bounds calculation takes the worldTransform into account.
 *
 * @return {PIXI.Rectangle} the framing rectangle
 */
Sprite.prototype.getBounds = function ()
{
    //TODO lookinto caching..
    if(!this._currentBounds)
    {
       // if(this.vertexDirty)
        {
            this.vertexDirty = false;

            // set the vertex data
            this.calculateBoundsVertices();

        }

        var minX, maxX, minY, maxY,
            w0, w1, h0, h1,
            vertexData = this.vertexData;

        var x1 = vertexData[8];
        var y1 = vertexData[9];

        var x2 = vertexData[10];
        var y2 = vertexData[11];

        var x3 = vertexData[12];
        var y3 = vertexData[13];

        var x4 = vertexData[14];
        var y4 = vertexData[15];

        minX = x1;
        minX = x2 < minX ? x2 : minX;
        minX = x3 < minX ? x3 : minX;
        minX = x4 < minX ? x4 : minX;

        minY = y1;
        minY = y2 < minY ? y2 : minY;
        minY = y3 < minY ? y3 : minY;
        minY = y4 < minY ? y4 : minY;

        maxX = x1;
        maxX = x2 > maxX ? x2 : maxX;
        maxX = x3 > maxX ? x3 : maxX;
        maxX = x4 > maxX ? x4 : maxX;

        maxY = y1;
        maxY = y2 > maxY ? y2 : maxY;
        maxY = y3 > maxY ? y3 : maxY;
        maxY = y4 > maxY ? y4 : maxY;

        // check for children
        if(this.children.length)
        {
            var childBounds = this.containerGetBounds();

            w0 = childBounds.x;
            w1 = childBounds.x + childBounds.width;
            h0 = childBounds.y;
            h1 = childBounds.y + childBounds.height;

            minX = (minX < w0) ? minX : w0;
            minY = (minY < h0) ? minY : h0;

            maxX = (maxX > w1) ? maxX : w1;
            maxY = (maxY > h1) ? maxY : h1;
        }

        var bounds = this._bounds;

        bounds.x = minX;
        bounds.width = maxX - minX;

        bounds.y = minY;
        bounds.height = maxY - minY;

        // store a reference so that if this function gets called again in the render cycle we do not have to recalculate
        this._currentBounds = bounds;
    }

    return this._currentBounds;
};

/**
 * Gets the local bounds of the sprite object.
 *
 */
Sprite.prototype.getLocalBounds = function ()
{
    this._bounds.x = -this._texture.orig.width * this.anchor.x;
    this._bounds.y = -this._texture.orig.height * this.anchor.y;
    this._bounds.width = this._texture.orig.width;
    this._bounds.height = this._texture.orig.height;
    return this._bounds;
};

/**
* Tests if a point is inside this sprite
*
* @param point {PIXI.Point} the point to test
* @return {boolean} the result of the test
*/
Sprite.prototype.containsPoint = function( point )
{
    this.worldTransform.applyInverse(point,  tempPoint);

    var width = this._texture.orig.width;
    var height = this._texture.orig.height;
    var x1 = -width * this.anchor.x;
    var y1;

    if ( tempPoint.x > x1 && tempPoint.x < x1 + width )
    {
        y1 = -height * this.anchor.y;

        if ( tempPoint.y > y1 && tempPoint.y < y1 + height )
        {
            return true;
        }
    }

    return false;
};

/**
 * Destroys this sprite and optionally its texture and children
 *
 * @param [options] {object|boolean} Options parameter. A boolean will act as if all options have been set to that value
 * @param [options.children=false] {boolean} if set to true, all the children will have their destroy
 *      method called as well. 'options' will be passed on to those calls.
 * @param [options.texture=false] {boolean} Should it destroy the current texture of the sprite as well
 * @param [options.baseTexture=false] {boolean} Should it destroy the base texture of the sprite as well
 */
Sprite.prototype.destroy = function (options)
{
    Container.prototype.destroy.call(this, options);

    this.anchor = null;

    var destroyTexture = typeof options === 'boolean' ? options : options && options.texture;
    if (destroyTexture)
    {
        var destroyBaseTexture = typeof options === 'boolean' ? options : options && options.baseTexture;
        this._texture.destroy(!!destroyBaseTexture);
    }

    this._texture = null;
    this.shader = null;
};

// some helper functions..

/**
 * Helper function that creates a new sprite based on the source you provide.
 * The soucre can be - frame id, image url, video url, canvae element, video element, base texture
 *
 * @static
 * @param source {}
 * @return {PIXI.Texture} A Texture
 */
Sprite.from = function (source)
{
    return new Sprite(Texture.from(source));
};

/**
 * Helper function that creates a sprite that will contain a texture from the TextureCache based on the frameId
 * The frame ids are created when a Texture packer file has been loaded
 *
 * @static
 * @param frameId {string} The frame Id of the texture in the cache
 * @return {PIXI.Sprite} A new Sprite using a texture from the texture cache matching the frameId
 */
Sprite.fromFrame = function (frameId)
{
    var texture = utils.TextureCache[frameId];

    if (!texture)
    {
        throw new Error('The frameId "' + frameId + '" does not exist in the texture cache');
    }

    return new Sprite(texture);
};

/**
 * Helper function that creates a sprite that will contain a texture based on an image url
 * If the image is not in the texture cache it will be loaded
 *
 * @static
 * @param imageId {string} The image url of the texture
 * @param [crossorigin=(auto)] {boolean} if you want to specify the cross-origin parameter
 * @param [scaleMode=PIXI.SCALE_MODES.DEFAULT] {number} if you want to specify the scale mode, see {@link PIXI.SCALE_MODES} for possible values
 * @return {PIXI.Sprite} A new Sprite using a texture from the texture cache matching the image id
 */
Sprite.fromImage = function (imageId, crossorigin, scaleMode)
{
    return new Sprite(Texture.fromImage(imageId, crossorigin, scaleMode));
};
<commit_msg>jshint<commit_after>var math = require('../math'),
    Texture = require('../textures/Texture'),
    Container = require('../display/Container'),
    utils = require('../utils'),
    CONST = require('../const'),
    tempPoint = new math.Point();

/**
 * The Sprite object is the base for all textured objects that are rendered to the screen
 *
 * A sprite can be created directly from an image like this:
 *
 * ```js
 * var sprite = new PIXI.Sprite.fromImage('assets/image.png');
 * ```
 *
 * @class
 * @extends PIXI.Container
 * @memberof PIXI
 * @param texture {PIXI.Texture} The texture for this sprite
 */
function Sprite(texture)
{
    Container.call(this);

    /**
     * The anchor sets the origin point of the texture.
     * The default is 0,0 this means the texture's origin is the top left
     * Setting the anchor to 0.5,0.5 means the texture's origin is centered
     * Setting the anchor to 1,1 would mean the texture's origin point will be the bottom right corner
     *
     * @member {PIXI.Point}
     */
    this.anchor = new math.Point();

    /**
     * The texture that the sprite is using
     *
     * @member {PIXI.Texture}
     * @private
     */
    this._texture = null;

    /**
     * The width of the sprite (this is initially set by the texture)
     *
     * @member {number}
     * @private
     */
    this._width = 0;

    /**
     * The height of the sprite (this is initially set by the texture)
     *
     * @member {number}
     * @private
     */
    this._height = 0;

    /**
     * The tint applied to the sprite. This is a hex value. A value of 0xFFFFFF will remove any tint effect.
     *
     * @member {number}
     * @default 0xFFFFFF
     */
    this.tint = 0xFFFFFF;

    /**
     * The blend mode to be applied to the sprite. Apply a value of `PIXI.BLEND_MODES.NORMAL` to reset the blend mode.
     *
     * @member {number}
     * @default PIXI.BLEND_MODES.NORMAL
     * @see PIXI.BLEND_MODES
     */
    this.blendMode = CONST.BLEND_MODES.NORMAL;

    /**
     * The shader that will be used to render the sprite. Set to null to remove a current shader.
     *
     * @member {PIXI.AbstractFilter|PIXI.Shader}
     */
    this.shader = null;

    /**
     * An internal cached value of the tint.
     *
     * @member {number}
     * @default 0xFFFFFF
     */
    this.cachedTint = 0xFFFFFF;

    // call texture setter
    this.texture = texture || Texture.EMPTY;
    this.textureDirty = true;
    this.vertexData = new Float32Array(16);
}

// constructor
Sprite.prototype = Object.create(Container.prototype);
Sprite.prototype.constructor = Sprite;
module.exports = Sprite;

Object.defineProperties(Sprite.prototype, {
    /**
     * The width of the sprite, setting this will actually modify the scale to achieve the value set
     *
     * @member {number}
     * @memberof PIXI.Sprite#
     */
    width: {
        get: function ()
        {
            return Math.abs(this.scale.x) * this.texture.orig.width;
        },
        set: function (value)
        {
            var sign = utils.sign(this.scale.x) || 1;
            this.scale.x = sign * value / this.texture.orig.width;
            this._width = value;
        }
    },

    /**
     * The height of the sprite, setting this will actually modify the scale to achieve the value set
     *
     * @member {number}
     * @memberof PIXI.Sprite#
     */
    height: {
        get: function ()
        {
            return  Math.abs(this.scale.y) * this.texture.orig.height;
        },
        set: function (value)
        {
            var sign = utils.sign(this.scale.y) || 1;
            this.scale.y = sign * value / this.texture.orig.height;
            this._height = value;
        }
    },

    /**
     * The texture that the sprite is using
     *
     * @member {PIXI.Texture}
     * @memberof PIXI.Sprite#
     */
    texture: {
        get: function ()
        {
            return  this._texture;
        },
        set: function (value)
        {
            if (this._texture === value)
            {
                return;
            }

            this._texture = value;
            this.cachedTint = 0xFFFFFF;

            this.textureDirty = true;

            if (value)
            {
                // wait for the texture to load
                if (value.baseTexture.hasLoaded)
                {
                    this._onTextureUpdate();
                }
                else
                {
                    value.once('update', this._onTextureUpdate, this);
                }
            }
        }
    }
});

/**
 * When the texture is updated, this event will fire to update the scale and frame
 *
 * @private
 */
Sprite.prototype._onTextureUpdate = function ()
{
    this.textureDirty = true;

    // so if _width is 0 then width was not set..
    if (this._width)
    {
        this.scale.x = utils.sign(this.scale.x) * this._width / this.texture.orig.width;
    }

    if (this._height)
    {
        this.scale.y = utils.sign(this.scale.y) * this._height / this.texture.orig.height;
    }
};

/**
 * calculates worldTransform * vertices, store it in vertexData
 */
Sprite.prototype.calculateVertices = function ()
{
    var texture = this._texture,
        wt = this.transform.worldTransform,
        a = wt.a, b = wt.b, c = wt.c, d = wt.d, tx = wt.tx, ty = wt.ty,
        vertexData = this.vertexData,
        w0, w1, h0, h1,
        trim = texture.trim,
        orig = texture.orig;

    if (trim)
    {
        // if the sprite is trimmed and is not a tilingsprite then we need to add the extra space before transforming the sprite coords..
        w1 = trim.x - this.anchor.x * orig.width;
        w0 = w1 + trim.width;

        h1 = trim.y - this.anchor.y * orig.height;
        h0 = h1 + trim.height;

    }
    else
    {
        w0 = (orig.width ) * (1-this.anchor.x);
        w1 = (orig.width ) * -this.anchor.x;

        h0 = orig.height * (1-this.anchor.y);
        h1 = orig.height * -this.anchor.y;
    }

    // xy
    vertexData[0] = a * w1 + c * h1 + tx;
    vertexData[1] = d * h1 + b * w1 + ty;

    // xy
    vertexData[2] = a * w0 + c * h1 + tx;
    vertexData[3] = d * h1 + b * w0 + ty;

     // xy
    vertexData[4] = a * w0 + c * h0 + tx;
    vertexData[5] = d * h0 + b * w0 + ty;

    // xy
    vertexData[6] = a * w1 + c * h0 + tx;
    vertexData[7] = d * h0 + b * w1 + ty;
};

/**
 * we need this method to be compatible with pixiv3. v3 does calculate bounds of original texture are, not trimmed one
 */
Sprite.prototype.calculateBoundsVertices = function ()
{
    var texture = this._texture,
        trim = texture.trim,
        vertexData = this.vertexData,
        orig = texture.orig;

    if (!trim || trim.width === orig.width && trim.height === orig.height) {
        vertexData[8] = vertexData[0];
        vertexData[9] = vertexData[1];
        vertexData[10] = vertexData[2];
        vertexData[11] = vertexData[3];
        vertexData[12] = vertexData[4];
        vertexData[13] = vertexData[5];
        vertexData[14] = vertexData[6];
        vertexData[15] = vertexData[7];
        return;
    }

    var wt = this.transform.worldTransform,
        a = wt.a, b = wt.b, c = wt.c, d = wt.d, tx = wt.tx, ty = wt.ty,
        w0, w1, h0, h1;

    w0 = (orig.width ) * (1-this.anchor.x);
    w1 = (orig.width ) * -this.anchor.x;

    h0 = orig.height * (1-this.anchor.y);
    h1 = orig.height * -this.anchor.y;

    // xy
    vertexData[8] = a * w1 + c * h1 + tx;
    vertexData[9] = d * h1 + b * w1 + ty;

    // xy
    vertexData[10] = a * w0 + c * h1 + tx;
    vertexData[11] = d * h1 + b * w0 + ty;

    // xy
    vertexData[12] = a * w0 + c * h0 + tx;
    vertexData[13] = d * h0 + b * w0 + ty;

    // xy
    vertexData[14] = a * w1 + c * h0 + tx;
    vertexData[15] = d * h0 + b * w1 + ty;
};

/**
*
* Renders the object using the WebGL renderer
*
* @param renderer {PIXI.WebGLRenderer}
* @private
*/
Sprite.prototype._renderWebGL = function (renderer)
{
    if(this.transform.updated || this.textureDirty)
    {
        this.textureDirty = false;
        // set the vertex data
        this.calculateVertices();
    }

    renderer.setObjectRenderer(renderer.plugins.sprite);
    renderer.plugins.sprite.render(this);
};

/**
* Renders the object using the Canvas renderer
*
* @param renderer {PIXI.CanvasRenderer} The renderer
* @private
*/
Sprite.prototype._renderCanvas = function (renderer)
{
    renderer.plugins.sprite.render(this);
};

/**
 * Returns the bounds of the Sprite as a rectangle. The bounds calculation takes the worldTransform into account.
 *
 * @return {PIXI.Rectangle} the framing rectangle
 */
Sprite.prototype.getBounds = function ()
{
    //TODO lookinto caching..
    if(!this._currentBounds)
    {
       // if(this.vertexDirty)
        {
            this.vertexDirty = false;

            // set the vertex data
            this.calculateBoundsVertices();

        }

        var minX, maxX, minY, maxY,
            w0, w1, h0, h1,
            vertexData = this.vertexData;

        var x1 = vertexData[8];
        var y1 = vertexData[9];

        var x2 = vertexData[10];
        var y2 = vertexData[11];

        var x3 = vertexData[12];
        var y3 = vertexData[13];

        var x4 = vertexData[14];
        var y4 = vertexData[15];

        minX = x1;
        minX = x2 < minX ? x2 : minX;
        minX = x3 < minX ? x3 : minX;
        minX = x4 < minX ? x4 : minX;

        minY = y1;
        minY = y2 < minY ? y2 : minY;
        minY = y3 < minY ? y3 : minY;
        minY = y4 < minY ? y4 : minY;

        maxX = x1;
        maxX = x2 > maxX ? x2 : maxX;
        maxX = x3 > maxX ? x3 : maxX;
        maxX = x4 > maxX ? x4 : maxX;

        maxY = y1;
        maxY = y2 > maxY ? y2 : maxY;
        maxY = y3 > maxY ? y3 : maxY;
        maxY = y4 > maxY ? y4 : maxY;

        // check for children
        if(this.children.length)
        {
            var childBounds = this.containerGetBounds();

            w0 = childBounds.x;
            w1 = childBounds.x + childBounds.width;
            h0 = childBounds.y;
            h1 = childBounds.y + childBounds.height;

            minX = (minX < w0) ? minX : w0;
            minY = (minY < h0) ? minY : h0;

            maxX = (maxX > w1) ? maxX : w1;
            maxY = (maxY > h1) ? maxY : h1;
        }

        var bounds = this._bounds;

        bounds.x = minX;
        bounds.width = maxX - minX;

        bounds.y = minY;
        bounds.height = maxY - minY;

        // store a reference so that if this function gets called again in the render cycle we do not have to recalculate
        this._currentBounds = bounds;
    }

    return this._currentBounds;
};

/**
 * Gets the local bounds of the sprite object.
 *
 */
Sprite.prototype.getLocalBounds = function ()
{
    this._bounds.x = -this._texture.orig.width * this.anchor.x;
    this._bounds.y = -this._texture.orig.height * this.anchor.y;
    this._bounds.width = this._texture.orig.width;
    this._bounds.height = this._texture.orig.height;
    return this._bounds;
};

/**
* Tests if a point is inside this sprite
*
* @param point {PIXI.Point} the point to test
* @return {boolean} the result of the test
*/
Sprite.prototype.containsPoint = function( point )
{
    this.worldTransform.applyInverse(point,  tempPoint);

    var width = this._texture.orig.width;
    var height = this._texture.orig.height;
    var x1 = -width * this.anchor.x;
    var y1;

    if ( tempPoint.x > x1 && tempPoint.x < x1 + width )
    {
        y1 = -height * this.anchor.y;

        if ( tempPoint.y > y1 && tempPoint.y < y1 + height )
        {
            return true;
        }
    }

    return false;
};

/**
 * Destroys this sprite and optionally its texture and children
 *
 * @param [options] {object|boolean} Options parameter. A boolean will act as if all options have been set to that value
 * @param [options.children=false] {boolean} if set to true, all the children will have their destroy
 *      method called as well. 'options' will be passed on to those calls.
 * @param [options.texture=false] {boolean} Should it destroy the current texture of the sprite as well
 * @param [options.baseTexture=false] {boolean} Should it destroy the base texture of the sprite as well
 */
Sprite.prototype.destroy = function (options)
{
    Container.prototype.destroy.call(this, options);

    this.anchor = null;

    var destroyTexture = typeof options === 'boolean' ? options : options && options.texture;
    if (destroyTexture)
    {
        var destroyBaseTexture = typeof options === 'boolean' ? options : options && options.baseTexture;
        this._texture.destroy(!!destroyBaseTexture);
    }

    this._texture = null;
    this.shader = null;
};

// some helper functions..

/**
 * Helper function that creates a new sprite based on the source you provide.
 * The soucre can be - frame id, image url, video url, canvae element, video element, base texture
 *
 * @static
 * @param source {}
 * @return {PIXI.Texture} A Texture
 */
Sprite.from = function (source)
{
    return new Sprite(Texture.from(source));
};

/**
 * Helper function that creates a sprite that will contain a texture from the TextureCache based on the frameId
 * The frame ids are created when a Texture packer file has been loaded
 *
 * @static
 * @param frameId {string} The frame Id of the texture in the cache
 * @return {PIXI.Sprite} A new Sprite using a texture from the texture cache matching the frameId
 */
Sprite.fromFrame = function (frameId)
{
    var texture = utils.TextureCache[frameId];

    if (!texture)
    {
        throw new Error('The frameId "' + frameId + '" does not exist in the texture cache');
    }

    return new Sprite(texture);
};

/**
 * Helper function that creates a sprite that will contain a texture based on an image url
 * If the image is not in the texture cache it will be loaded
 *
 * @static
 * @param imageId {string} The image url of the texture
 * @param [crossorigin=(auto)] {boolean} if you want to specify the cross-origin parameter
 * @param [scaleMode=PIXI.SCALE_MODES.DEFAULT] {number} if you want to specify the scale mode, see {@link PIXI.SCALE_MODES} for possible values
 * @return {PIXI.Sprite} A new Sprite using a texture from the texture cache matching the image id
 */
Sprite.fromImage = function (imageId, crossorigin, scaleMode)
{
    return new Sprite(Texture.fromImage(imageId, crossorigin, scaleMode));
};
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2012, Dienst Landelijk Gebied - Ministerie van Economische Zaken
 *
 * Gepubliceerd onder de BSD 2-clause licentie,
 * zie https://github.com/MinELenI/CBSviewer/blob/master/LICENSE.md voor de volledige licentie.
 */
/**
 * Viewer.
 *
 * @author mprins
 * @returns {Viewer} Viewer object
 * @class
 */
Viewer = function() {
	/**
	 * Map object, initially null.
	 *
	 * @private
	 * @type {OpenLayers.Map}
	 */
	var _map = null;

	/**
	 * Toggle vlag voor fullsize functie.
	 *
	 * @type {Boolean}
	 * @private
	 */
	var _fullSize = false;
	/**
	 * Window resize timout flag.
	 *
	 * @type {Boolean}
	 * @private
	 */
	var _resizeTimeOut = false;

	/**
	 * update het informatie element met feature info.
	 *
	 * @param {OpenLayers.Event}
	 *            evt Het featureinfo event
	 * @private
	 */
	function _showInfo(evt) {
		if (evt.text !== undefined) {
			jQuery('#' + config.featureInfoDiv).html(evt.text);
			jQuery('#' + config.featureInfoDiv).change();
		}
	}

	/**
	 * zorgt voor correct afhandelen van viewport resize.
	 *
	 * @private
	 */
	function _resize() {
		if (_fullSize) {
			var borderW = parseInt(jQuery('#' + this.config.mapDiv).css('borderLeftWidth'), 10)
					+ parseInt(jQuery('#' + this.config.mapDiv).css('borderRightWidth'), 10);
			var borderH = parseInt(jQuery('#' + this.config.mapDiv).css('borderTopWidth'), 10)
					+ parseInt(jQuery('#' + this.config.mapDiv).css('borderBottomWidth'), 10);
			var w = jQuery('#' + this.config.mapDiv).parent().width() - borderW;
			// var h = jQuery('#' + this.config.mapDiv).parent().height() -
			// borderH;
			var h = jQuery('#' + this.config.mapDiv).parent().parent().height() - borderH;

			jQuery('#' + this.config.mapDiv).width(w).height(h);
			_map.updateSize();
			var vectors = _map.getLayersByClass("OpenLayers.Layer.Vector");
			if (vectors.length > 0) {
				// in dit geval is er een kaartlaag met een featureinfo lokatie
				// verschuif naar die lokatie
				var bounds = vectors[0].getDataExtent();
				_map.panTo(bounds.getCenterLonLat());
			}
		}
	}
	/**
	 * Publieke interface van deze klasse.
	 *
	 * @returns {Viewer} publieke methodes
	 */
	return {

		/**
		 * Constructor, attach to the DOM.
		 *
		 * @param {object}
		 *            config Configratie object
		 */
		init : function(config) {
			this.config = config;
			OpenLayers.ImgPath = config.imgPath;
			OpenLayers.IMAGE_RELOAD_ATTEMPTS = 2;
			OpenLayers.Number.decimalSeparator = ",";

			// merge any controls met default
			jQuery.extend(true, this.config, {
				map : {
					controls : []
				}
			});
			jQuery(window).unload(function() {
				Viewer.destroy();
			});

			jQuery('#' + this.config.mapDiv).width(this.config.map.width).height(this.config.map.height);

			_map = new OpenLayers.Map(this.config.mapDiv, this.config.map);
			this.addBaseMap();
			this.addControls();
			_map.zoomTo(this.config.map.initialZoom);

			// toggle knop voor omschakelen basemap
			var aToggle = ''
					+ OpenLayers.i18n('KEY_TOGGLE_BASEMAP_LUFO') + '';
			jQuery('#' + config.mapDiv).prepend(aToggle);

			if (this.config.toggleSize) {
				// toggle knop voor vergroten/verkleinen van de kaart
				var aToggleMapSize = '';
				jQuery('#' + config.mapDiv).prepend(aToggleMapSize);
			}
			if (this.config.fullSize) {
				this.toggleFullSize();
			}
			jQuery(window).resize(function() {
				// aanhaken bij window resize
				if (_resizeTimeOut) {
					clearTimeout(_resizeTimeOut);
				}
				_resizeTimeOut = setTimeout(_resize, 200); // 200 is time in
				// miliseconds
			});
		},

		/**
		 * Accessor voor de kaart.
		 *
		 * @return {OpenLayers.Map} object van deze Viewer of null als het
		 *         object niet is geinitialiseerd
		 * @deprecated probeer deze niet te gebruiken
		 */
		getMap : function() {
			(window.console && console.warn('Deprecated method called: Viewer::getMap().'));
			return _map;
		},

		/**
		 * verplaats en zoom de kaart naar de gevraagde locatie.
		 *
		 * @param {number}
		 *            x de x coordinaat
		 * @param {number}
		 *            y de y coordinaat
		 * @param {number}
		 *            radius straal van het gebied
		 */
		zoomTo : function(x, y, radius) {
			_map.panTo(new OpenLayers.LonLat(x, y));
			var zm = _map.getZoomForExtent(new OpenLayers.Bounds(x - radius, y - radius, x + radius, y + radius));
			_map.zoomTo(zm);
		},

		/**
		 * Controls aan de kaart hangen.
		 *
		 * @private
		 */
		addControls : function() {
			_map.addControl(new UpdateLegendControl({
				div : jQuery('#' + this.config.legendDiv)[0]
			}));
			_map.addControl(new OpenLayers.Control.KeyboardDefaults({
				/* alleen actief als de kaart focus heeft */
				observeElement : this.config.mapDiv
			}));
			_map.addControl(new OpenLayers.Control.Zoom());
			_map.addControl(new OpenLayers.Control.Navigation({
				zoomWheelEnabled : false
			}));
			_map.addControl(new OpenLayers.Control.KeyboardClick({
				/* alleen actief als de kaart focus heeft */
				observeElement : this.config.mapDiv
			}));
			_map.addControl(new WMSGetFeatureInfo({
				eventListeners : {
					getfeatureinfo : _showInfo
				}
			}));
			_map.addControl(new ClickDrawControl());
		},

		/**
		 * cleanup. Moet aangeroepen voor dat een eventueel DOM element van de
		 * pagina wordt verwijderd. Wordt automatische aangeroepen bij verlaten
		 * van de pagina.
		 */
		destroy : function() {
			if (_map !== null) {
				_map.destroy();
				_map = null;
			}
		},

		/**
		 * Voeg WMS toe aan de kaart. Uitgangspunt is dat de WMS transparante
		 * PNG ondersteund. eerder geladen WMS lagen worden verwijderd
		 *
		 * @param {object}
		 *            wmsConfig Een object met WMS parameters.
		 * {
		 * 'name' : 'cbs_inwoners_2010_per_hectare',
		 * 'url' : 'http://geodata.nationaalgeoregister.nl/cbsvierkanten100m2010/ows',
		 * 'layers' : 'cbsvierkanten100m2010:cbs_inwoners_2000_per_hectare',
		 * 'styles' : 'cbsvierkant100m_inwoners_2000'
		 * }
		 *
		 */
		loadWMS : function(wmsConfig) {
			this.removeOverlays();
			var layer = new OpenLayers.Layer.WMS(wmsConfig.name, wmsConfig.url, {
				layers : wmsConfig.layers,
				styles : wmsConfig.styles,
				version : '1.3.0',
				format : 'image/png',
				transparent : true
			}, {
				isBaseLayer : false,
				visibility : true,
				singleTile : false,
				opacity : 0.8
			});
			_map.addLayer(layer);
		},

		/**
		 * verwijder de WMS uit de kaart (behalve als het een base layer is).
		 *
		 * @param {string}
		 *            wmsLyrName naam van de WMS service
		 */
		removeWMS : function(wmsLyrName) {
			var lyrs = _map.getLayersByName(wmsLyrName);
			for ( var lyr = 0; lyr < lyrs.length; lyr++) {
				if (!lyrs[lyr].isBaseLayer) {
					_map.removeLayer(lyrs[lyr]);
					lyrs[lyr].destroy();
				}
			}
		},

		/**
		 * verwijder alle overlays. Voorlopig alleen type {OpenLayers.Layer.WMS}
		 */
		removeOverlays : function() {
			var lyrs = _map.getLayersByClass('OpenLayers.Layer.WMS');
			for ( var lyr = 0; lyr < lyrs.length; lyr++) {
				if (!lyrs[lyr].isBaseLayer) {
					_map.removeLayer(lyrs[lyr]);
					lyrs[lyr].destroy();
				}
			}
		},

		/**
		 * Afmeting van de kaart aanpassen aan schermbreedte.
		 *
		 * @todo hoogte instellen werkt niet omdat de parent hoogte de afmeting
		 *       van de child heeft.
		 */
		toggleFullSize : function() {
			if (_fullSize) {
				// terugzetten
				jQuery('#' + this.config.mapDiv).width(this.config.map.width).height(this.config.map.height);
				jQuery('#toggleSize').toggleClass('restore max');
				_fullSize = false;
				_map.updateSize();

				var vectors = _map.getLayersByClass("OpenLayers.Layer.Vector");
				if (vectors.length > 0) {
					// in dit geval is er een kaartlaag met een featureinfo
					// lokatie verschuif naar die lokatie
					var bounds = vectors[0].getDataExtent();
					_map.panTo(bounds.getCenterLonLat());
				}
			} else {
				// vergroten
				var borderW = parseInt(jQuery('#' + this.config.mapDiv).css('borderLeftWidth'), 10)
						+ parseInt(jQuery('#' + this.config.mapDiv).css('borderRightWidth'), 10);
				var borderH = parseInt(jQuery('#' + this.config.mapDiv).css('borderTopWidth'), 10)
						+ parseInt(jQuery('#' + this.config.mapDiv).css('borderBottomWidth'), 10);

				var w = jQuery('#' + this.config.mapDiv).parent().width() - borderW;
				// var hh = jQuery('#' + this.config.mapDiv).parent().height();
				var h = jQuery('#' + this.config.mapDiv).parent().parent().height() - borderH;

				jQuery('#' + this.config.mapDiv).width(w).height(h);
				jQuery('#toggleSize').toggleClass('restore max');
				_fullSize = true;
				_map.updateSize();
			}
		},

		/**
		 * Stel de kaart in voor afdrukken.
		 *
		 * @returns
		 */
		printPrepare : function() {
			if (_fullSize) {
				this.toggleFullSize();
			}
		},

		/**
		 * Toggle basemap.
		 */
		toggleBaseMap : function() {
			var topo = _map.getLayersByName('topo')[0];
			var lufo = _map.getLayersByName('lufo')[0];
			if (topo.getVisibility()) {
				_map.setBaseLayer(lufo);
				jQuery('#toggleBaseMap').text(OpenLayers.i18n('KEY_TOGGLE_BASEMAP_TOPO'));
			} else {
				_map.setBaseLayer(topo);
				jQuery('#toggleBaseMap').text(OpenLayers.i18n('KEY_TOGGLE_BASEMAP_LUFO'));
			}
			jQuery('#toggleBaseMap').toggleClass('lufo topo');
		},

		/**
		 * set up basemap.
		 *
		 * @private
		 */
		addBaseMap : function() {
			// brtachtergrond
			var matrixIds = [ 13 ];
			for ( var i = 0; i < 13; ++i) {
				matrixIds[i] = "EPSG:28992:" + i;
			}
			_map.addLayer(new OpenLayers.Layer.WMTS({
				name : "topo",
				url : "http://geodata.nationaalgeoregister.nl/tiles/service/wmts/brtachtergrondkaart/",
				layer : "brtachtergrondkaart",
				matrixSet : 'EPSG:28992',
				matrixIds : matrixIds,
				format : 'image/png8',
				style : '_null'
			}));
			// luchtfoto
			_map.addLayer(new OpenLayers.Layer.WMS(
					'lufo', 'http://gisdemo2.agro.nl/arcgis/services/Luchtfoto2010/MapServer/WMSServer?service=WMS', {
						layers : 0,
						version : '1.3.0',
						format : 'image/jpeg',
						transparent : false
					}, {
						isBaseLayer : true,
						visibility : true,
						singleTile : false
					}));

		}
	};
}();
<commit_msg>wis featureinfo als thema wordt gwisseld<commit_after>/*
 * Copyright (c) 2012, Dienst Landelijk Gebied - Ministerie van Economische Zaken
 *
 * Gepubliceerd onder de BSD 2-clause licentie,
 * zie https://github.com/MinELenI/CBSviewer/blob/master/LICENSE.md voor de volledige licentie.
 */
/**
 * Viewer.
 *
 * @author mprins
 * @returns {Viewer} Viewer object
 * @class
 */
Viewer = function() {
	/**
	 * Map object, initially null.
	 *
	 * @private
	 * @type {OpenLayers.Map}
	 */
	var _map = null;

	/**
	 * Toggle vlag voor fullsize functie.
	 *
	 * @type {Boolean}
	 * @private
	 */
	var _fullSize = false;
	/**
	 * Window resize timout flag.
	 *
	 * @type {Boolean}
	 * @private
	 */
	var _resizeTimeOut = false;

	/**
	 * update het informatie element met feature info.
	 *
	 * @param {OpenLayers.Event}
	 *            evt Het featureinfo event
	 * @private
	 */
	function _showInfo(evt) {
		if (evt.text !== undefined) {
			jQuery('#' + config.featureInfoDiv).html(evt.text);
			jQuery('#' + config.featureInfoDiv).change();
		}
	}

	/**
	 * zorgt voor correct afhandelen van viewport resize.
	 *
	 * @private
	 */
	function _resize() {
		if (_fullSize) {
			var borderW = parseInt(jQuery('#' + this.config.mapDiv).css('borderLeftWidth'), 10)
					+ parseInt(jQuery('#' + this.config.mapDiv).css('borderRightWidth'), 10);
			var borderH = parseInt(jQuery('#' + this.config.mapDiv).css('borderTopWidth'), 10)
					+ parseInt(jQuery('#' + this.config.mapDiv).css('borderBottomWidth'), 10);
			var w = jQuery('#' + this.config.mapDiv).parent().width() - borderW;
			// var h = jQuery('#' + this.config.mapDiv).parent().height() -
			// borderH;
			var h = jQuery('#' + this.config.mapDiv).parent().parent().height() - borderH;

			jQuery('#' + this.config.mapDiv).width(w).height(h);
			_map.updateSize();
			var vectors = _map.getLayersByClass("OpenLayers.Layer.Vector");
			if (vectors.length > 0) {
				// in dit geval is er een kaartlaag met een featureinfo lokatie
				// verschuif naar die lokatie
				var bounds = vectors[0].getDataExtent();
				_map.panTo(bounds.getCenterLonLat());
			}
		}
	}
	/**
	 * Publieke interface van deze klasse.
	 *
	 * @returns {Viewer} publieke methodes
	 */
	return {

		/**
		 * Constructor, attach to the DOM.
		 *
		 * @param {object}
		 *            config Configratie object
		 */
		init : function(config) {
			this.config = config;
			OpenLayers.ImgPath = config.imgPath;
			OpenLayers.IMAGE_RELOAD_ATTEMPTS = 2;
			OpenLayers.Number.decimalSeparator = ",";

			// merge any controls met default
			jQuery.extend(true, this.config, {
				map : {
					controls : []
				}
			});
			jQuery(window).unload(function() {
				Viewer.destroy();
			});

			jQuery('#' + this.config.mapDiv).width(this.config.map.width).height(this.config.map.height);

			_map = new OpenLayers.Map(this.config.mapDiv, this.config.map);
			this.addBaseMap();
			this.addControls();
			_map.zoomTo(this.config.map.initialZoom);

			// toggle knop voor omschakelen basemap
			var aToggle = ''
					+ OpenLayers.i18n('KEY_TOGGLE_BASEMAP_LUFO') + '';
			jQuery('#' + config.mapDiv).prepend(aToggle);

			if (this.config.toggleSize) {
				// toggle knop voor vergroten/verkleinen van de kaart
				var aToggleMapSize = '';
				jQuery('#' + config.mapDiv).prepend(aToggleMapSize);
			}
			if (this.config.fullSize) {
				this.toggleFullSize();
			}
			jQuery(window).resize(function() {
				// aanhaken bij window resize
				if (_resizeTimeOut) {
					clearTimeout(_resizeTimeOut);
				}
				_resizeTimeOut = setTimeout(_resize, 200); // 200 is time in
				// miliseconds
			});
		},

		/**
		 * Accessor voor de kaart.
		 *
		 * @return {OpenLayers.Map} object van deze Viewer of null als het
		 *         object niet is geinitialiseerd
		 * @deprecated probeer deze niet te gebruiken
		 */
		getMap : function() {
			(window.console && console.warn('Deprecated method called: Viewer::getMap().'));
			return _map;
		},

		/**
		 * verplaats en zoom de kaart naar de gevraagde locatie.
		 *
		 * @param {number}
		 *            x de x coordinaat
		 * @param {number}
		 *            y de y coordinaat
		 * @param {number}
		 *            radius straal van het gebied
		 */
		zoomTo : function(x, y, radius) {
			_map.panTo(new OpenLayers.LonLat(x, y));
			var zm = _map.getZoomForExtent(new OpenLayers.Bounds(x - radius, y - radius, x + radius, y + radius));
			_map.zoomTo(zm);
		},

		/**
		 * Controls aan de kaart hangen.
		 *
		 * @private
		 */
		addControls : function() {
			_map.addControl(new UpdateLegendControl({
				div : jQuery('#' + this.config.legendDiv)[0]
			}));
			_map.addControl(new OpenLayers.Control.KeyboardDefaults({
				/* alleen actief als de kaart focus heeft */
				observeElement : this.config.mapDiv
			}));
			_map.addControl(new OpenLayers.Control.Zoom());
			_map.addControl(new OpenLayers.Control.Navigation({
				zoomWheelEnabled : false
			}));
			_map.addControl(new OpenLayers.Control.KeyboardClick({
				/* alleen actief als de kaart focus heeft */
				observeElement : this.config.mapDiv
			}));
			_map.addControl(new WMSGetFeatureInfo({
				eventListeners : {
					getfeatureinfo : _showInfo
				}
			}));
			_map.addControl(new ClickDrawControl());
		},

		/**
		 * cleanup. Moet aangeroepen voor dat een eventueel DOM element van de
		 * pagina wordt verwijderd. Wordt automatische aangeroepen bij verlaten
		 * van de pagina.
		 */
		destroy : function() {
			if (_map !== null) {
				_map.destroy();
				_map = null;
			}
		},

		/**
		 * Voeg WMS toe aan de kaart. Uitgangspunt is dat de WMS transparante
		 * PNG ondersteund. eerder geladen WMS lagen worden verwijderd
		 *
		 * @param {object}
		 *            wmsConfig Een object met WMS parameters.
		 * {
		 * 'name' : 'cbs_inwoners_2010_per_hectare',
		 * 'url' : 'http://geodata.nationaalgeoregister.nl/cbsvierkanten100m2010/ows',
		 * 'layers' : 'cbsvierkanten100m2010:cbs_inwoners_2000_per_hectare',
		 * 'styles' : 'cbsvierkant100m_inwoners_2000'
		 * }
		 *
		 */
		loadWMS : function(wmsConfig) {
			this.removeOverlays();
			var layer = new OpenLayers.Layer.WMS(wmsConfig.name, wmsConfig.url, {
				layers : wmsConfig.layers,
				styles : wmsConfig.styles,
				version : '1.3.0',
				format : 'image/png',
				transparent : true
			}, {
				isBaseLayer : false,
				visibility : true,
				singleTile : false,
				opacity : 0.8
			});
			_map.addLayer(layer);
			var fInfoControl = _map.getControlsByClass('WMSGetFeatureInfo');
			fInfoControl[0].url = wmsConfig.url;
		},

		/**
		 * verwijder de WMS uit de kaart (behalve als het een base layer is).
		 *
		 * @param {string}
		 *            wmsLyrName naam van de WMS service
		 */
		removeWMS : function(wmsLyrName) {
			var lyrs = _map.getLayersByName(wmsLyrName);
			for ( var lyr = 0; lyr < lyrs.length; lyr++) {
				if (!lyrs[lyr].isBaseLayer) {
					_map.removeLayer(lyrs[lyr]);
					lyrs[lyr].destroy();
				}
			}
		},

		/**
		 * verwijder alle overlays. Voorlopig alleen type {OpenLayers.Layer.WMS}
		 */
		removeOverlays : function() {
			// reset featureinfo text
			jQuery('#' + config.featureInfoDiv).html(OpenLayers.i18n('KEY_INFO_GEEN_FEATURES'));
			// verwijder ikoontjes die de controls tekenen
			var lyrs = _map.getLayersByName('ClickDrawControl');
			for ( var lyr = 0; lyr < lyrs.length; lyr++) {
				lyrs[lyr].removeAllFeatures();
			}
			lyrs = _map.getLayersByName('OpenLayers.Handler.KeyboardPoint');
			for ( var lyr = 0; lyr < lyrs.length; lyr++) {
				lyrs[lyr].removeAllFeatures();
			}

			// verwijder WMS lagen
			lyrs = _map.getLayersByClass('OpenLayers.Layer.WMS');
			for ( var lyr = 0; lyr < lyrs.length; lyr++) {
				if (!lyrs[lyr].isBaseLayer) {
					_map.removeLayer(lyrs[lyr]);
					lyrs[lyr].destroy();
				}
			}
		},

		/**
		 * Afmeting van de kaart aanpassen aan schermbreedte.
		 *
		 * @todo hoogte instellen werkt niet omdat de parent hoogte de afmeting
		 *       van de child heeft.
		 */
		toggleFullSize : function() {
			if (_fullSize) {
				// terugzetten
				jQuery('#' + this.config.mapDiv).width(this.config.map.width).height(this.config.map.height);
				jQuery('#toggleSize').toggleClass('restore max');
				_fullSize = false;
				_map.updateSize();

				var vectors = _map.getLayersByClass("OpenLayers.Layer.Vector");
				if (vectors.length > 0) {
					// in dit geval is er een kaartlaag met een featureinfo
					// lokatie verschuif naar die lokatie
					var bounds = vectors[0].getDataExtent();
					_map.panTo(bounds.getCenterLonLat());
				}
			} else {
				// vergroten
				var borderW = parseInt(jQuery('#' + this.config.mapDiv).css('borderLeftWidth'), 10)
						+ parseInt(jQuery('#' + this.config.mapDiv).css('borderRightWidth'), 10);
				var borderH = parseInt(jQuery('#' + this.config.mapDiv).css('borderTopWidth'), 10)
						+ parseInt(jQuery('#' + this.config.mapDiv).css('borderBottomWidth'), 10);

				var w = jQuery('#' + this.config.mapDiv).parent().width() - borderW;
				// var hh = jQuery('#' + this.config.mapDiv).parent().height();
				var h = jQuery('#' + this.config.mapDiv).parent().parent().height() - borderH;

				jQuery('#' + this.config.mapDiv).width(w).height(h);
				jQuery('#toggleSize').toggleClass('restore max');
				_fullSize = true;
				_map.updateSize();
			}
		},

		/**
		 * Stel de kaart in voor afdrukken.
		 *
		 * @returns
		 */
		printPrepare : function() {
			if (_fullSize) {
				this.toggleFullSize();
			}
		},

		/**
		 * Toggle basemap.
		 */
		toggleBaseMap : function() {
			var topo = _map.getLayersByName('topo')[0];
			var lufo = _map.getLayersByName('lufo')[0];
			if (topo.getVisibility()) {
				_map.setBaseLayer(lufo);
				jQuery('#toggleBaseMap').text(OpenLayers.i18n('KEY_TOGGLE_BASEMAP_TOPO'));
			} else {
				_map.setBaseLayer(topo);
				jQuery('#toggleBaseMap').text(OpenLayers.i18n('KEY_TOGGLE_BASEMAP_LUFO'));
			}
			jQuery('#toggleBaseMap').toggleClass('lufo topo');
		},

		/**
		 * set up basemap.
		 *
		 * @private
		 */
		addBaseMap : function() {
			// brtachtergrond
			var matrixIds = [ 13 ];
			for ( var i = 0; i < 13; ++i) {
				matrixIds[i] = "EPSG:28992:" + i;
			}
			_map.addLayer(new OpenLayers.Layer.WMTS({
				name : "topo",
				url : "http://geodata.nationaalgeoregister.nl/tiles/service/wmts/brtachtergrondkaart/",
				layer : "brtachtergrondkaart",
				matrixSet : 'EPSG:28992',
				matrixIds : matrixIds,
				format : 'image/png8',
				style : '_null'
			}));
			// luchtfoto
			_map.addLayer(new OpenLayers.Layer.WMS(
					'lufo', 'http://gisdemo2.agro.nl/arcgis/services/Luchtfoto2010/MapServer/WMSServer?service=WMS', {
						layers : 0,
						version : '1.3.0',
						format : 'image/jpeg',
						transparent : false
					}, {
						isBaseLayer : true,
						visibility : true,
						singleTile : false
					}));

		}
	};
}();
<|endoftext|>