text:
angular.module('textAngular.taBind', ['textAngular.factories', 'textAngular.DOM'])
.service('_taBlankTest', [function(){
	var INLINETAGS_NONBLANK = /<(a|abbr|acronym|bdi|bdo|big|cite|code|del|dfn|img|ins|kbd|label|map|mark|q|ruby|rp|rt|s|samp|time|tt|var)[^>]*(>|$)/i;
	return function(_defaultTest){
		return function(_blankVal){
			if(!_blankVal) return true;
			// find first non-tag match - ie start of string or after tag that is not whitespace
			var _firstMatch = /(^[^<]|>)[^<]/i.exec(_blankVal);
			var _firstTagIndex;
			if(!_firstMatch){
				// find the end of the first tag removing all the
				// Don't do a global replace as that would be waaayy too long, just replace the first 4 occurences should be enough
				_blankVal = _blankVal.toString().replace(/="[^"]*"/i, '').replace(/="[^"]*"/i, '').replace(/="[^"]*"/i, '').replace(/="[^"]*"/i, '');
				_firstTagIndex = _blankVal.indexOf('>');
			}else{
				_firstTagIndex = _firstMatch.index;
			}
			_blankVal = _blankVal.trim().substring(_firstTagIndex, _firstTagIndex + 100);
			// check for no tags entry
			if(/^[^<>]+$/i.test(_blankVal)) return false;
			// this regex is to match any number of whitespace only between two tags
			if (_blankVal.length === 0 || _blankVal === _defaultTest || /^>(\s| )*<\/[^>]+>$/ig.test(_blankVal)) return true;
			// this regex tests if there is a tag followed by some optional whitespace and some text after that
			else if (/>\s*[^\s<]/i.test(_blankVal) || INLINETAGS_NONBLANK.test(_blankVal)) return false;
			else return true;
		};
	};
}])
.directive('taButton', [function(){
	return {
		link: function(scope, element, attrs){
			element.attr('unselectable', 'on');
			element.on('mousedown', function(e, eventData){
				/* istanbul ignore else: this is for catching the jqLite testing*/
				if(eventData) angular.extend(e, eventData);
				// this prevents focusout from firing on the editor when clicking toolbar buttons
				e.preventDefault();
				return false;
			});
		}
	};
}])
.directive('taBind', [
		'taSanitize', '$timeout', '$window', '$document', 'taFixChrome', 'taBrowserTag',
		'taSelection', 'taSelectableElements', 'taApplyCustomRenderers', 'taOptions',
		'_taBlankTest', '$parse', 'taDOM', 'textAngularManager',
		function(
			taSanitize, $timeout, $window, $document, taFixChrome, taBrowserTag,
			taSelection, taSelectableElements, taApplyCustomRenderers, taOptions,
			_taBlankTest, $parse, taDOM, textAngularManager){
	// Uses for this are textarea or input with ng-model and ta-bind='text'
	// OR any non-form element with contenteditable="contenteditable" ta-bind="html|text" ng-model
	return {
		priority: 2, // So we override validators correctly
		require: ['ngModel','?ngModelOptions'],
		link: function(scope, element, attrs, controller){
			var ngModel = controller[0];
			var ngModelOptions = controller[1] || {};
			// the option to use taBind on an input or textarea is required as it will sanitize all input into it correctly.
			var _isContentEditable = element.attr('contenteditable') !== undefined && element.attr('contenteditable');
			var _isInputFriendly = _isContentEditable || element[0].tagName.toLowerCase() === 'textarea' || element[0].tagName.toLowerCase() === 'input';
			var _isReadonly = false;
			var _focussed = false;
			var _skipRender = false;
			var _disableSanitizer = attrs.taUnsafeSanitizer || taOptions.disableSanitizer;
			var _lastKey;
			// see http://www.javascripter.net/faq/keycodes.htm for good information
			// NOTE Mute On|Off 173 (Opera MSIE Safari Chrome) 181 (Firefox)
			// BLOCKED_KEYS are special keys...
			// Tab, pause/break, CapsLock, Esc, Page Up, End, Home,
			// Left arrow, Up arrow, Right arrow, Down arrow, Insert, Delete,
			// f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12
			// NumLock, ScrollLock
			var BLOCKED_KEYS = /^(9|19|20|27|33|34|35|36|37|38|39|40|45|112|113|114|115|116|117|118|119|120|121|122|123|144|145)$/i;
			// UNDO_TRIGGER_KEYS - spaces, enter, delete, backspace, all punctuation
			// Backspace, Enter, Space, Delete, (; :) (Firefox), (= +) (Firefox),
			// Numpad +, Numpad -, (; :), (= +),
			// (, <), (- _), (. >), (/ ?), (` ~), ([ {), (\ |), (] }), (' ")
			// NOTE - Firefox: 173 = (- _) -- adding this to UNDO_TRIGGER_KEYS
			var UNDO_TRIGGER_KEYS = /^(8|13|32|46|59|61|107|109|173|186|187|188|189|190|191|192|219|220|221|222)$/i;
			var _pasteHandler;

			// defaults to the paragraph element, but we need the line-break or it doesn't allow you to type into the empty element
			// non IE is '

', ie is '

' as for once IE gets it correct...
			var _defaultVal, _defaultTest;

			var _CTRL_KEY = 0x0001;
			var _META_KEY = 0x0002;
			var _ALT_KEY = 0x0004;
			var _SHIFT_KEY = 0x0008;
			// map events to special keys...
			// mappings is an array of maps from events to specialKeys as declared in textAngularSetup
			var _keyMappings = [
				//		ctrl/command + z
				{
					specialKey: 'UndoKey',
					forbiddenModifiers: _ALT_KEY + _SHIFT_KEY,
					mustHaveModifiers: [_META_KEY + _CTRL_KEY],
					keyCode: 90
				},
				//		ctrl/command + shift + z
				{
					specialKey: 'RedoKey',
					forbiddenModifiers: _ALT_KEY,
					mustHaveModifiers: [_META_KEY + _CTRL_KEY, _SHIFT_KEY],
					keyCode: 90
				},
				//		ctrl/command + y
				{
					specialKey: 'RedoKey',
					forbiddenModifiers: _ALT_KEY + _SHIFT_KEY,
					mustHaveModifiers: [_META_KEY + _CTRL_KEY],
					keyCode: 89
				},
				//		TabKey
				{
					specialKey: 'TabKey',
					forbiddenModifiers: _META_KEY + _SHIFT_KEY + _ALT_KEY + _CTRL_KEY,
					mustHaveModifiers: [],
					keyCode: 9
				},
				//		shift + TabKey
				{
					specialKey: 'ShiftTabKey',
					forbiddenModifiers: _META_KEY + _ALT_KEY + _CTRL_KEY,
					mustHaveModifiers: [_SHIFT_KEY],
					keyCode: 9
				}
			];
			function _mapKeys(event) {
				var specialKey;
				_keyMappings.forEach(function (map){
					if (map.keyCode === event.keyCode) {
						var netModifiers = (event.metaKey ? _META_KEY: 0) +
							(event.ctrlKey ? _CTRL_KEY: 0) +
							(event.shiftKey ? _SHIFT_KEY: 0) +
							(event.altKey ? _ALT_KEY: 0);
						if (map.forbiddenModifiers & netModifiers) return;
						if (map.mustHaveModifiers.every(function (modifier) { return netModifiers & modifier; })){
							specialKey = map.specialKey;
						}
					}
				});
				return specialKey;
			}

			// set the default to be a paragraph value
			if(attrs.taDefaultWrap === undefined) attrs.taDefaultWrap = 'p';
			/* istanbul ignore next: ie specific test */
			if(attrs.taDefaultWrap === ''){
				_defaultVal = '';
				_defaultTest = (_browserDetect.ie === undefined)? '

' : (_browserDetect.ie >= 11)? '

' : (_browserDetect.ie <= 8)? '

' : '

';
			}else{
				_defaultVal = (_browserDetect.ie === undefined || _browserDetect.ie >= 11)?
					'<' + attrs.taDefaultWrap + '>
</' + attrs.taDefaultWrap + '>' :
					(_browserDetect.ie <= 8)?
						'<' + attrs.taDefaultWrap.toUpperCase() + '></' + attrs.taDefaultWrap.toUpperCase() + '>' :
						'<' + attrs.taDefaultWrap + '></' + attrs.taDefaultWrap + '>';
				_defaultTest = (_browserDetect.ie === undefined || _browserDetect.ie >= 11)?
					'<' + attrs.taDefaultWrap + '>
</' + attrs.taDefaultWrap + '>' :
					(_browserDetect.ie <= 8)?
						'<' + attrs.taDefaultWrap.toUpperCase() + '> </' + attrs.taDefaultWrap.toUpperCase() + '>' :
						'<' + attrs.taDefaultWrap + '> </' + attrs.taDefaultWrap + '>';
			}

			/* istanbul ignore else */
			if(!ngModelOptions.$options) ngModelOptions.$options = {}; // ng-model-options support

			var _blankTest = _taBlankTest(_defaultTest);

			var _ensureContentWrapped = function(value){
				if(_blankTest(value)) return value;
				var domTest = angular.element("
" + value + "
");
				if(domTest.children().length === 0){
					value = "<" + attrs.taDefaultWrap + ">" + value + "</" + attrs.taDefaultWrap + ">";
				}else{
					var _children = domTest[0].childNodes;
					var i;
					var _foundBlockElement = false;
					for(i = 0; i < _children.length; i++){
						if(_foundBlockElement = _children[i].nodeName.toLowerCase().match(BLOCKELEMENTS)) break;
					}
					if(!_foundBlockElement){
						value = "<" + attrs.taDefaultWrap + ">" + value + "</" + attrs.taDefaultWrap + ">";
					}else{
						value = "";
						for(i = 0; i < _children.length; i++){
							if(!_children[i].nodeName.toLowerCase().match(BLOCKELEMENTS)){
								var _subVal = (_children[i].outerHTML || _children[i].nodeValue);
								/* istanbul ignore else: Doesn't seem to trigger on tests, is tested though */
								if(_subVal.trim() !== '')
									value += "<" + attrs.taDefaultWrap + ">" + _subVal + "</" + attrs.taDefaultWrap + ">";
								else value += _subVal;
							}else{
								value += _children[i].outerHTML;
							}
						}
					}
				}
				return value;
			};

			if(attrs.taPaste) _pasteHandler = $parse(attrs.taPaste);

			element.addClass('ta-bind');

			var _undoKeyupTimeout;

			scope['$undoManager' + (attrs.id || '')] = ngModel.$undoManager = {
				_stack: [],
				_index: 0,
				_max: 1000,
				push: function(value){
					if((typeof value === "undefined" || value === null) ||
						((typeof this.current() !== "undefined" && this.current() !== null) && value === this.current())) return value;
					if(this._index < this._stack.length - 1){
						this._stack = this._stack.slice(0,this._index+1);
					}
					this._stack.push(value);
					if(_undoKeyupTimeout) $timeout.cancel(_undoKeyupTimeout);
					if(this._stack.length > this._max) this._stack.shift();
					this._index = this._stack.length - 1;
					return value;
				},
				undo: function(){
					return this.setToIndex(this._index-1);
				},
				redo: function(){
					return this.setToIndex(this._index+1);
				},
				setToIndex: function(index){
					if(index < 0 || index > this._stack.length - 1){
						return undefined;
					}
					this._index = index;
					return this.current();
				},
				current: function(){
					return this._stack[this._index];
				}
			};

			var _redoUndoTimeout;
			var _undo = scope['$undoTaBind' + (attrs.id || '')] = function(){
				/* istanbul ignore else: can't really test it due to all changes being ignored as well in readonly */
				if(!_isReadonly && _isContentEditable){
					var content = ngModel.$undoManager.undo();
					if(typeof content !== "undefined" && content !== null){
						_setInnerHTML(content);
						_setViewValue(content, false);
						if(_redoUndoTimeout) $timeout.cancel(_redoUndoTimeout);
						_redoUndoTimeout = $timeout(function(){
							element[0].focus();
							taSelection.setSelectionToElementEnd(element[0]);
						}, 1);
					}
				}
			};

			var _redo = scope['$redoTaBind' + (attrs.id || '')] = function(){
				/* istanbul ignore else: can't really test it due to all changes being ignored as well in readonly */
				if(!_isReadonly && _isContentEditable){
					var content = ngModel.$undoManager.redo();
					if(typeof content !== "undefined" && content !== null){
						_setInnerHTML(content);
						_setViewValue(content, false);
						/* istanbul ignore next */
						if(_redoUndoTimeout) $timeout.cancel(_redoUndoTimeout);
						_redoUndoTimeout = $timeout(function(){
							element[0].focus();
							taSelection.setSelectionToElementEnd(element[0]);
						}, 1);
					}
				}
			};

			// in here we are undoing the converts used elsewhere to prevent the < > and & being displayed when they shouldn't in the code.
			var _compileHtml = function(){
				if(_isContentEditable) return element[0].innerHTML;
				if(_isInputFriendly) return element.val();
				throw ('textAngular Error: attempting to update non-editable taBind');
			};

			var _setViewValue = function(_val, triggerUndo, skipRender){
				_skipRender = skipRender || false;
				if(typeof triggerUndo === "undefined" || triggerUndo === null) triggerUndo = true && _isContentEditable; // if not contentEditable then the native undo/redo is fine
				if(typeof _val === "undefined" || _val === null) _val = _compileHtml();
				if(_blankTest(_val)){
					// this avoids us from tripping the ng-pristine flag if we click in and out with out typing
					if(ngModel.$viewValue !== '') ngModel.$setViewValue('');
					if(triggerUndo && ngModel.$undoManager.current() !== '') ngModel.$undoManager.push('');
				}else{
					_reApplyOnSelectorHandlers();
					if(ngModel.$viewValue !== _val){
						ngModel.$setViewValue(_val);
						if(triggerUndo) ngModel.$undoManager.push(_val);
					}
				}
				ngModel.$render();
			};

			//used for updating when inserting wrapped elements
			scope['updateTaBind' + (attrs.id || '')] = function(){
				if(!_isReadonly) _setViewValue(undefined, undefined, true);
			};

			// catch DOM XSS via taSanitize
			// Sanitizing both ways is identical
			var _sanitize = function(unsafe){
				return (ngModel.$oldViewValue = taSanitize(taFixChrome(unsafe), ngModel.$oldViewValue, _disableSanitizer));
			};

			// trigger the validation calls
			if(element.attr('required')) ngModel.$validators.required = function(modelValue, viewValue) {
				return !_blankTest(modelValue || viewValue);
			};
			// parsers trigger from the above keyup function or any other time that the viewValue is updated and parses it for storage in the ngModel
			ngModel.$parsers.push(_sanitize);
			ngModel.$parsers.unshift(_ensureContentWrapped);
			// because textAngular is bi-directional (which is awesome) we need to also sanitize values going in from the server
			ngModel.$formatters.push(_sanitize);
			ngModel.$formatters.unshift(_ensureContentWrapped);
			ngModel.$formatters.unshift(function(value){
				return ngModel.$undoManager.push(value || '');
			});

			//this code is used to update the models when data is entered/deleted
			if(_isInputFriendly){
				scope.events = {};
				if(!_isContentEditable){
					// if a textarea or input just add in change and blur handlers, everything else is done by angulars input directive
					element.on('change blur', scope.events.change = scope.events.blur = function(){
						if(!_isReadonly) ngModel.$setViewValue(_compileHtml());
					});

					element.on('keydown', scope.events.keydown = function(event, eventData){
						/* istanbul ignore else: this is for catching the jqLite testing*/
						if(eventData) angular.extend(event, eventData);
						// Reference to http://stackoverflow.com/questions/6140632/how-to-handle-tab-in-textarea
						/* istanbul ignore else: otherwise normal functionality */
						if(event.keyCode === 9){ // tab was pressed
							// get caret position/selection
							var start = this.selectionStart;
							var end = this.selectionEnd;

							var value = element.val();
							if(event.shiftKey){
								// find \t
								var _linebreak = value.lastIndexOf('\n', start), _tab = value.lastIndexOf('\t', start);
								if(_tab !== -1 && _tab >= _linebreak){
									// set textarea value to: text before caret + tab + text after caret
									element.val(value.substring(0, _tab) + value.substring(_tab + 1));

									// put caret at right position again (add one for the tab)
									this.selectionStart = this.selectionEnd = start - 1;
								}
							}else{
								// set textarea value to: text before caret + tab + text after caret
								element.val(value.substring(0, start) + "\t" + value.substring(end));

								// put caret at right position again (add one for the tab)
								this.selectionStart = this.selectionEnd = start + 1;
							}
							// prevent the focus lose
							event.preventDefault();
						}
					});

					var _repeat = function(string, n){
						var result = '';
						for(var _n = 0; _n < n; _n++) result += string;
						return result;
					};

					var recursiveListFormat = function(listNode, tablevel){
						var _html = '', _children = listNode.childNodes;
						tablevel++;
						_html += _repeat('\t', tablevel-1) + listNode.outerHTML.substring(0, listNode.outerHTML.indexOf('<li'));
						for(var _i = 0; _i < _children.length; _i++){
							/* istanbul ignore next: browser catch */
							if(!_children[_i].outerHTML) continue;
							if(_children[_i].nodeName.toLowerCase() === 'ul' || _children[_i].nodeName.toLowerCase() === 'ol')
								_html += '\n' + recursiveListFormat(_children[_i], tablevel);
							else
								_html += '\n' + _repeat('\t', tablevel) + _children[_i].outerHTML;
						}
						_html += '\n' + _repeat('\t', tablevel-1) + listNode.outerHTML.substring(listNode.outerHTML.lastIndexOf('<'));
						return _html;
					};
					ngModel.$formatters.unshift(function(htmlValue){
						// tabulate the HTML so it looks nicer
						var _children = angular.element('
' + htmlValue + '
')[0].childNodes;
						if(_children.length > 0){
							htmlValue = '';
							for(var i = 0; i < _children.length; i++){
								/* istanbul ignore next: browser catch */
								if(!_children[i].outerHTML) continue;
								if(htmlValue.length > 0) htmlValue += '\n';
								if(_children[i].nodeName.toLowerCase() === 'ul' || _children[i].nodeName.toLowerCase() === 'ol')
									htmlValue += '' + recursiveListFormat(_children[i], 0);
								else htmlValue += '' + _children[i].outerHTML;
							}
						}

						return htmlValue;
					});
				}else{
					// all the code specific to contenteditable divs
					var _processingPaste = false;
					/* istanbul ignore next: phantom js cannot test this for some reason */
					var processpaste = function(text) {
						/* istanbul ignore else: don't care if nothing pasted */
						if(text && text.trim().length){
							// test paste from word/microsoft product
							if(text.match(/class=["']*Mso(Normal|List)/i)){
								var textFragment = text.match(/([\s\S]*?)/i);
								if(!textFragment) textFragment = text;
								else textFragment = textFragment[1];
								textFragment = textFragment.replace(/<o:p>[\s\S]*?<\/o:p>/ig, '').replace(/class=(["']|)MsoNormal(["']|)/ig, '');
								var dom = angular.element("
" + textFragment + "
");
								var targetDom = angular.element("

");
								var _list = {
									element: null,
									lastIndent: [],
									lastLi: null,
									isUl: false
								};
								_list.lastIndent.peek = function(){
									var n = this.length;
									if (n>0) return this[n-1];
								};
								var _resetList = function(isUl){
									_list.isUl = isUl;
									_list.element = angular.element(isUl ? "
" : "
");
									_list.lastIndent = [];
									_list.lastIndent.peek = function(){
										var n = this.length;
										if (n>0) return this[n-1];
									};
									_list.lastLevelMatch = null;
								};
								for(var i = 0; i <= dom[0].childNodes.length; i++){
									if(!dom[0].childNodes[i] || dom[0].childNodes[i].nodeName === "#text" || dom[0].childNodes[i].tagName.toLowerCase() !== "p") continue;
									var el = angular.element(dom[0].childNodes[i]);
									var _listMatch = (el.attr('class') || '').match(/MsoList(Bullet|Number|Paragraph)(CxSp(First|Middle|Last)|)/i);

									if(_listMatch){
										if(el[0].childNodes.length < 2 || el[0].childNodes[1].childNodes.length < 1){
											continue;
										}
										var isUl = _listMatch[1].toLowerCase() === "bullet" || (_listMatch[1].toLowerCase() !== "number" && !(/^[^0-9a-z<]*[0-9a-z]+[^0-9a-z<>]</i.test(el[0].childNodes[1].innerHTML) || /^[^0-9a-z<]*[0-9a-z]+[^0-9a-z<>]</i.test(el[0].childNodes[1].childNodes[0].innerHTML)));
										var _indentMatch = (el.attr('style') || '').match(/margin-left:([\-\.0-9]*)/i);
										var indent = parseFloat((_indentMatch)?_indentMatch[1]:0);
										var _levelMatch = (el.attr('style') || '').match(/mso-list:l([0-9]+) level([0-9]+) lfo[0-9+]($|;)/i);
										// prefers the mso-list syntax

										if(_levelMatch && _levelMatch[2]) indent = parseInt(_levelMatch[2]);

										if ((_levelMatch && (!_list.lastLevelMatch || _levelMatch[1] !== _list.lastLevelMatch[1])) || !_listMatch[3] || _listMatch[3].toLowerCase() === "first" || (_list.lastIndent.peek() === null) || (_list.isUl !== isUl && _list.lastIndent.peek() === indent)) {
											_resetList(isUl);
											targetDom.append(_list.element);
										} else if (_list.lastIndent.peek() != null && _list.lastIndent.peek() < indent){
											_list.element = angular.element(isUl ? "
" : "
");
											_list.lastLi.append(_list.element);
										} else if (_list.lastIndent.peek() != null && _list.lastIndent.peek() > indent){
											while(_list.lastIndent.peek() != null && _list.lastIndent.peek() > indent){
												if(_list.element.parent()[0].tagName.toLowerCase() === 'li'){
													_list.element = _list.element.parent();
													continue;
												}else if(/[uo]l/i.test(_list.element.parent()[0].tagName.toLowerCase())){
													_list.element = _list.element.parent();
												}else{ // else it's it should be a sibling
													break;
												}
												_list.lastIndent.pop();
											}
											_list.isUl = _list.element[0].tagName.toLowerCase() === "ul";
											if (isUl !== _list.isUl) {
												_resetList(isUl);
												targetDom.append(_list.element);
											}
										}

										_list.lastLevelMatch = _levelMatch;
										if(indent !== _list.lastIndent.peek()) _list.lastIndent.push(indent);
										_list.lastLi = angular.element("
");
										_list.element.append(_list.lastLi);
										_list.lastLi.html(el.html().replace(/<!(--|)\[if !supportLists\](--|)>[\s\S]*?<!(--|)\[endif\](--|)>/ig, ''));
										el.remove();
									}else{
										_resetList(false);
										targetDom.append(el);
									}
								}
								var _unwrapElement = function(node){
									node = angular.element(node);
									for(var _n = node[0].childNodes.length - 1; _n >= 0; _n--) node.after(node[0].childNodes[_n]);
									node.remove();
								};

								angular.forEach(targetDom.find('span'), function(node){
									node.removeAttribute('lang');
									if(node.attributes.length <= 0) _unwrapElement(node);
								});
								angular.forEach(targetDom.find('font'), _unwrapElement);
								text = targetDom.html();
							}else{
								// remove unnecessary chrome insert
								text = text.replace(/<(|\/)meta[^>]*?>/ig, '');
								if(text.match(/<[^>]*?(ta-bind)[^>]*?>/)){
									// entire text-angular or ta-bind has been pasted, REMOVE AT ONCE!!
									if(text.match(/<[^>]*?(text-angular)[^>]*?>/)){
										var _el = angular.element("
" + text + "
");
										_el.find('textarea').remove();
										var binds = taDOM.getByAttribute(_el, 'ta-bind');
										for(var _b = 0; _b < binds.length; _b++){
											var _target = binds[_b][0].parentNode.parentNode;
											for(var _c = 0; _c < binds[_b][0].childNodes.length; _c++){
												_target.parentNode.insertBefore(binds[_b][0].childNodes[_c], _target);
											}
											_target.parentNode.removeChild(_target);
										}
										text = _el.html().replace('
', '');
									}
								}else if(text.match(/^<span/)){
									// in case of pasting only a span - chrome paste, remove them. THis is just some wierd formatting
									text = text.replace(/<(|\/)span[^>]*?>/ig, '');
								}
								// Webkit on Apple tags
								text = text.replace(/
]*?>/ig, '').replace(/( | )<\/span>/ig, ' ');
							}

							if (/
/i.test(text) && /(
|
).*
/i.test(text) === false) {
								// insert missing parent of li element
								text = text.replace(/
.*<\/li(\s.*)?>/i, '
$&
');
							}

							if(_pasteHandler) text = _pasteHandler(scope, {$html: text}) || text;

							text = taSanitize(text, '', _disableSanitizer);

							taSelection.insertHtml(text, element[0]);
							$timeout(function(){
								ngModel.$setViewValue(_compileHtml());
								_processingPaste = false;
								element.removeClass('processing-paste');
							}, 0);
						}else{
							_processingPaste = false;
							element.removeClass('processing-paste');
						}
					};

					element.on('paste', scope.events.paste = function(e, eventData){
						/* istanbul ignore else: this is for catching the jqLite testing*/
						if(eventData) angular.extend(e, eventData);
						if(_isReadonly || _processingPaste){
							e.stopPropagation();
							e.preventDefault();
							return false;
						}

						// Code adapted from http://stackoverflow.com/questions/2176861/javascript-get-clipboard-data-on-paste-event-cross-browser/6804718#6804718
						_processingPaste = true;
						element.addClass('processing-paste');
						var pastedContent;
						var clipboardData = (e.originalEvent || e).clipboardData;
						if (clipboardData && clipboardData.getData && clipboardData.types.length > 0) {// Webkit - get data from clipboard, put into editdiv, cleanup, then cancel event
							var _types = "";
							for(var _t = 0; _t < clipboardData.types.length; _t++){
								_types += " " + clipboardData.types[_t];
							}
							/* istanbul ignore next: browser tests */
							if (/text\/html/i.test(_types)) {
								pastedContent = clipboardData.getData('text/html');
							} else if (/text\/plain/i.test(_types)) {
								pastedContent = clipboardData.getData('text/plain');
							}

							processpaste(pastedContent);
							e.stopPropagation();
							e.preventDefault();
							return false;
						} else {// Everything else - empty editdiv and allow browser to paste content into it, then cleanup
							var _savedSelection = $window.rangy.saveSelection(),
								_tempDiv = angular.element('

');
							$document.find('body').append(_tempDiv);
							_tempDiv[0].focus();
							$timeout(function(){
								// restore selection
								$window.rangy.restoreSelection(_savedSelection);
								processpaste(_tempDiv[0].innerHTML);
								element[0].focus();
								_tempDiv.remove();
							}, 0);
						}
					});
					element.on('cut', scope.events.cut = function(e){
						// timeout to next is needed as otherwise the paste/cut event has not finished actually changing the display
						if(!_isReadonly) $timeout(function(){
							ngModel.$setViewValue(_compileHtml());
						}, 0);
						else e.preventDefault();
					});

					element.on('keydown', scope.events.keydown = function(event, eventData){
						/* istanbul ignore else: this is for catching the jqLite testing*/
						if(eventData) angular.extend(event, eventData);
						event.specialKey = _mapKeys(event);
						var userSpecialKey;
						/* istanbul ignore next: difficult to test */
						taOptions.keyMappings.forEach(function (mapping) {
							if (event.specialKey === mapping.commandKeyCode) {
								// taOptions has remapped this binding... so
								// we disable our own
								event.specialKey = undefined;
							}
							if (mapping.testForKey(event)) {
								userSpecialKey = mapping.commandKeyCode;
							}
							if ((mapping.commandKeyCode === 'UndoKey') || (mapping.commandKeyCode === 'RedoKey')) {
								// this is necessary to fully stop the propagation.
								if (!mapping.enablePropagation) {
									event.preventDefault();
								}
							}
						});
						/* istanbul ignore next: difficult to test */
						if (typeof userSpecialKey !== 'undefined') {
							event.specialKey = userSpecialKey;
						}
						/* istanbul ignore next: difficult to test as can't seem to select */
						if ((typeof event.specialKey !== 'undefined') && (
								event.specialKey !== 'UndoKey' || event.specialKey !== 'RedoKey'
							)) {
							event.preventDefault();
							textAngularManager.sendKeyCommand(scope, event);
						}
						/* istanbul ignore else: readonly check */
						if(!_isReadonly){
							if (event.specialKey==='UndoKey') {
								_undo();
								event.preventDefault();
							}
							if (event.specialKey==='RedoKey') {
								_redo();
								event.preventDefault();
							}
							/* istanbul ignore next: difficult to test as can't seem to select */
							if(event.keyCode === 13 && !event.shiftKey){
								var $selection;
								var selection = taSelection.getSelectionElement();
								if(!selection.tagName.match(VALIDELEMENTS)) return;
								var _new = angular.element(_defaultVal);
								if (/^
$/i.test(selection.innerHTML.trim()) && selection.parentNode.tagName.toLowerCase() === 'blockquote' && !selection.nextSibling) {
									// if last element in blockquote and element is blank, pull element outside of blockquote.
									$selection = angular.element(selection);
									var _parent = $selection.parent();
									_parent.after(_new);
									$selection.remove();
									if(_parent.children().length === 0) _parent.remove();
									taSelection.setSelectionToElementStart(_new[0]);
									event.preventDefault();
								}else if (/^<[^>]+>
<\/[^>]+>$/i.test(selection.innerHTML.trim()) && selection.tagName.toLowerCase() === 'blockquote'){
									$selection = angular.element(selection);
									$selection.after(_new);
									$selection.remove();
									taSelection.setSelectionToElementStart(_new[0]);
									event.preventDefault();
								}
							}
						}
					});
					var _keyupTimeout;
					element.on('keyup', scope.events.keyup = function(event, eventData){
						/* istanbul ignore else: this is for catching the jqLite testing*/
						if(eventData) angular.extend(event, eventData);
						/* istanbul ignore next: FF specific bug fix */
						if (event.keyCode === 9) {
							var _selection = taSelection.getSelection();
							if(_selection.start.element === element[0] && element.children().length) taSelection.setSelectionToElementStart(element.children()[0]);
							return;
						}
						if(_undoKeyupTimeout) $timeout.cancel(_undoKeyupTimeout);
						if(!_isReadonly && !BLOCKED_KEYS.test(event.keyCode)){
							// if enter - insert new taDefaultWrap, if shift+enter insert

							if(_defaultVal !== '' && event.keyCode === 13){
								if(!event.shiftKey){
									// new paragraph, br should be caught correctly
									var selection = taSelection.getSelectionElement();
									while(!selection.tagName.match(VALIDELEMENTS) && selection !== element[0]){
										selection = selection.parentNode;
									}

									if(selection.tagName.toLowerCase() !== attrs.taDefaultWrap && selection.tagName.toLowerCase() !== 'li' && (selection.innerHTML.trim() === '' || selection.innerHTML.trim() === '
')){
										var _new = angular.element(_defaultVal);
										angular.element(selection).replaceWith(_new);
										taSelection.setSelectionToElementStart(_new[0]);
									}
								}
							}
							var val = _compileHtml();
							if(_defaultVal !== '' && val.trim() === ''){
								_setInnerHTML(_defaultVal);
								taSelection.setSelectionToElementStart(element.children()[0]);
							}else if(val.substring(0, 1) !== '<' && attrs.taDefaultWrap !== ''){
								var _savedSelection = $window.rangy.saveSelection();
								val = _compileHtml();
								val = "<" + attrs.taDefaultWrap + ">" + val + "</" + attrs.taDefaultWrap + ">";
								_setInnerHTML(val);
								$window.rangy.restoreSelection(_savedSelection);
							}
							var triggerUndo = _lastKey !== event.keyCode && UNDO_TRIGGER_KEYS.test(event.keyCode);
							if(_keyupTimeout) $timeout.cancel(_keyupTimeout);
							_keyupTimeout = $timeout(function() {
								_setViewValue(val, triggerUndo, true);
							}, ngModelOptions.$options.debounce || 400);
							if(!triggerUndo) _undoKeyupTimeout = $timeout(function(){ ngModel.$undoManager.push(val); }, 250);
							_lastKey = event.keyCode;
						}
					});

					element.on('blur', scope.events.blur = function(){
						_focussed = false;
						/* istanbul ignore else: if readonly don't update model */
						if(!_isReadonly){
							_setViewValue(undefined, undefined, true);
						}else{
							_skipRender = true; // don't redo the whole thing, just check the placeholder logic
							ngModel.$render();
						}
					});

					// Placeholders not supported on ie 8 and below
					if(attrs.placeholder && (_browserDetect.ie > 8 || _browserDetect.ie === undefined)){
						var rule;
						if(attrs.id) rule = addCSSRule('#' + attrs.id + '.placeholder-text:before', 'content: "' + attrs.placeholder + '"');
						else throw('textAngular Error: An unique ID is required for placeholders to work');

						scope.$on('$destroy', function(){
							removeCSSRule(rule);
						});
					}

					element.on('focus', scope.events.focus = function(){
						_focussed = true;
						element.removeClass('placeholder-text');
						_reApplyOnSelectorHandlers();
					});

					element.on('mouseup', scope.events.mouseup = function(){
						var _selection = taSelection.getSelection();
						if(_selection.start.element === element[0] && element.children().length) taSelection.setSelectionToElementStart(element.children()[0]);
					});

					// prevent propagation on mousedown in editor, see #206
					element.on('mousedown', scope.events.mousedown = function(event, eventData){
						/* istanbul ignore else: this is for catching the jqLite testing*/
						if(eventData) angular.extend(event, eventData);
						event.stopPropagation();
					});
				}
			}

			var selectorClickHandler = function(event){
				// emit the element-select event, pass the element
				scope.$emit('ta-element-select', this);
				event.preventDefault();
				return false;
			};
			var fileDropHandler = function(event, eventData){
				/* istanbul ignore else: this is for catching the jqLite testing*/
				if(eventData) angular.extend(event, eventData);
				// emit the drop event, pass the element, preventing should be done elsewhere
				if(!dropFired && !_isReadonly){
					dropFired = true;
					var dataTransfer;
					if(event.originalEvent) dataTransfer = event.originalEvent.dataTransfer;
					else dataTransfer = event.dataTransfer;
					scope.$emit('ta-drop-event', this, event, dataTransfer);
					$timeout(function(){
						dropFired = false;
						_setViewValue(undefined, undefined, true);
					}, 100);
				}
			};

			//used for updating when inserting wrapped elements
			var _reApplyOnSelectorHandlers = scope['reApplyOnSelectorHandlers' + (attrs.id || '')] = function(){
				/* istanbul ignore else */
				if(!_isReadonly) angular.forEach(taSelectableElements, function(selector){
						// check we don't apply the handler twice
						element.find(selector)
							.off('click', selectorClickHandler)
							.on('click', selectorClickHandler);
					});
			};

			var _setInnerHTML = function(newval){
				element[0].innerHTML = newval;
			};
			var _renderTimeout;
			var _renderInProgress = false;
			// changes to the model variable from outside the html/text inputs
			ngModel.$render = function(){
				/* istanbul ignore if: Catches rogue renders, hard to replicate in tests */
				if(_renderInProgress) return;
				else _renderInProgress = true;
				// catch model being null or undefined
				var val = ngModel.$viewValue || '';
				// if the editor isn't focused it needs to be updated, otherwise it's receiving user input
				if(!_skipRender){
					/* istanbul ignore else: in other cases we don't care */
					if(_isContentEditable && _focussed){
						// update while focussed
						element.removeClass('placeholder-text');
						if(_renderTimeout) $timeout.cancel(_renderTimeout);
						_renderTimeout = $timeout(function(){
							/* istanbul ignore if: Can't be bothered testing this... */
							if(!_focussed){
								element[0].focus();
								taSelection.setSelectionToElementEnd(element.children()[element.children().length - 1]);
							}
							_renderTimeout = undefined;
						}, 1);
					}
					if(_isContentEditable){
						// WYSIWYG Mode
						if(attrs.placeholder){
							if(val === ''){
								// blank
								_setInnerHTML(_defaultVal);
							}else{
								// not-blank
								_setInnerHTML(val);
							}
						}else{
							_setInnerHTML((val === '') ? _defaultVal : val);
						}
						// if in WYSIWYG and readOnly we kill the use of links by clicking
						if(!_isReadonly){
							_reApplyOnSelectorHandlers();
							element.on('drop', fileDropHandler);
						}else{
							element.off('drop', fileDropHandler);
						}
					}else if(element[0].tagName.toLowerCase() !== 'textarea' && element[0].tagName.toLowerCase() !== 'input'){
						// make sure the end user can SEE the html code as a display. This is a read-only display element
						_setInnerHTML(taApplyCustomRenderers(val));
					}else{
						// only for input and textarea inputs
						element.val(val);
					}
				}
				if(_isContentEditable && attrs.placeholder){
					if(val === ''){
						if(_focussed) element.removeClass('placeholder-text');
						else element.addClass('placeholder-text');
					}else{
						element.removeClass('placeholder-text');
					}
				}
				_renderInProgress = _skipRender = false;
			};

			if(attrs.taReadonly){
				//set initial value
				_isReadonly = scope.$eval(attrs.taReadonly);
				if(_isReadonly){
					element.addClass('ta-readonly');
					// we changed to readOnly mode (taReadonly='true')
					if(element[0].tagName.toLowerCase() === 'textarea' || element[0].tagName.toLowerCase() === 'input'){
						element.attr('disabled', 'disabled');
					}
					if(element.attr('contenteditable') !== undefined && element.attr('contenteditable')){
						element.removeAttr('contenteditable');
					}
				}else{
					element.removeClass('ta-readonly');
					// we changed to NOT readOnly mode (taReadonly='false')
					if(element[0].tagName.toLowerCase() === 'textarea' || element[0].tagName.toLowerCase() === 'input'){
						element.removeAttr('disabled');
					}else if(_isContentEditable){
						element.attr('contenteditable', 'true');
					}
				}
				// taReadonly only has an effect if the taBind element is an input or textarea or has contenteditable='true' on it.
				// Otherwise it is readonly by default
				scope.$watch(attrs.taReadonly, function(newVal, oldVal){
					if(oldVal === newVal) return;
					if(newVal){
						element.addClass('ta-readonly');
						// we changed to readOnly mode (taReadonly='true')
						if(element[0].tagName.toLowerCase() === 'textarea' || element[0].tagName.toLowerCase() === 'input'){
							element.attr('disabled', 'disabled');
						}
						if(element.attr('contenteditable') !== undefined && element.attr('contenteditable')){
							element.removeAttr('contenteditable');
						}
						// turn ON selector click handlers
						angular.forEach(taSelectableElements, function(selector){
							element.find(selector).on('click', selectorClickHandler);
						});
						element.off('drop', fileDropHandler);
					}else{
						element.removeClass('ta-readonly');
						// we changed to NOT readOnly mode (taReadonly='false')
						if(element[0].tagName.toLowerCase() === 'textarea' || element[0].tagName.toLowerCase() === 'input'){
							element.removeAttr('disabled');
						}else if(_isContentEditable){
							element.attr('contenteditable', 'true');
						}
						// remove the selector click handlers
						angular.forEach(taSelectableElements, function(selector){
							element.find(selector).off('click', selectorClickHandler);
						});
						element.on('drop', fileDropHandler);
					}
					_isReadonly = newVal;
				});
			}

			// Initialise the selectableElements
			// if in WYSIWYG and readOnly we kill the use of links by clicking
			if(_isContentEditable && !_isReadonly){
				angular.forEach(taSelectableElements, function(selector){
					element.find(selector).on('click', selectorClickHandler);
				});
				element.on('drop', fileDropHandler);
				element.on('blur', function(){
					/* istanbul ignore next: webkit fix */
					if(_browserDetect.webkit) { // detect webkit
						globalContentEditableBlur = true;
					}
				});
			}
		}
	};
}]);


text:
using System;
using System.Net;
using System.Text;
using System.Collections.Generic;
using System.Threading.Tasks;
using Tmds.DBus.Transports;

namespace Tmds.DBus
{
    internal class AddressEntry
    {
        public static AddressEntry[] ParseEntries(string addresses)
        {
            if (addresses == null)
                throw new ArgumentNullException(nameof(addresses));

            List<AddressEntry> entries = new List<AddressEntry>();

            foreach (string entryStr in addresses.Split(';'))
                entries.Add(AddressEntry.Parse(entryStr));

            return entries.ToArray();
        }

        public string Method;
        public readonly IDictionary<string, string> Properties = new Dictionary<string, string>();
        public Guid Guid = Guid.Empty;

        public override string ToString()
        {
            StringBuilder sb = new StringBuilder();
            sb.Append(Method);
            sb.Append(':');

            bool first = true;
            foreach (KeyValuePair<string, string> prop in Properties)
            {
                if (first)
                    first = false;
                else
                    sb.Append(',');

                sb.Append(prop.Key);
                sb.Append('=');
                sb.Append(Escape(prop.Value));
            }

            if (Guid != Guid.Empty)
            {
                if (Properties.Count != 0)
                    sb.Append(',');
                sb.Append("guid");
                sb.Append('=');
                sb.Append(Guid.ToString("N"));
            }

            return sb.ToString();
        }

        static string Escape(string str)
        {
            if (str == null)
                return String.Empty;

            StringBuilder sb = new StringBuilder();
            int len = str.Length;

            for (int i = 0; i != len; i++)
            {
                char c = str[i];

                //everything other than the optionally escaped chars _must_ be escaped
                if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9')
                    || c == '-' || c == '_' || c == '/' || c == '\\' || c == '.')
                    sb.Append(c);
                else
                    sb.Append(HexEscape(c));
            }

            return sb.ToString();
        }

        static string Unescape(string str)
        {
            if (str == null)
                return String.Empty;

            StringBuilder sb = new StringBuilder();
            int len = str.Length;
            int i = 0;
            while (i != len)
            {
                if (IsHexEncoding(str, i))
                    sb.Append(HexUnescape(str, ref i));
                else
                    sb.Append(str[i++]);
            }

            return sb.ToString();
        }

        public static string HexEscape(char character)
        {
            if (character > '\xff')
            {
                throw new ArgumentOutOfRangeException("character");
            }
            char[] chars = new char[3];
            int pos = 0;
            EscapeAsciiChar(character, chars, ref pos);
            return new string(chars);
        }

        private const char c_DummyChar = (char)0xFFFF;
        private static readonly char[] s_hexUpperChars = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };

        internal static void EscapeAsciiChar(char ch, char[] to, ref int pos)
        {
            to[pos++] = '%';
            to[pos++] = s_hexUpperChars[(ch & 0xf0) >> 4];
            to[pos++] = s_hexUpperChars[ch & 0xf];
        }

        public static char HexUnescape(string pattern, ref int index)
        {
            if ((index < 0) || (index >= pattern.Length))
            {
                throw new ArgumentOutOfRangeException("index");
            }
            if ((pattern[index] == '%')
                && (pattern.Length - index >= 3))
            {
                char ret = EscapedAscii(pattern[index + 1], pattern[index + 2]);
                if (ret != c_DummyChar)
                {
                    index += 3;
                    return ret;
                }
            }
            return pattern[index++];
        }
        public static bool IsHexEncoding(string pattern, int index)
        {
            if ((pattern.Length - index) < 3)
            {
                return false;
            }
            if ((pattern[index] == '%') && EscapedAscii(pattern[index + 1], pattern[index + 2]) != c_DummyChar)
            {
                return true;
            }
            return false;
        }

        private static char EscapedAscii(char digit, char next)
        {
            if (!(((digit >= '0') && (digit <= '9'))
                || ((digit >= 'A') && (digit <= 'F'))
                || ((digit >= 'a') && (digit <= 'f'))))
            {
                return c_DummyChar;
            }

            int res = (digit <= '9')
                ? ((int)digit - (int)'0')
                : (((digit <= 'F')
                ? ((int)digit - (int)'A')
                : ((int)digit - (int)'a'))
                   + 10);

            if (!(((next >= '0') && (next <= '9'))
                || ((next >= 'A') && (next <= 'F'))
                || ((next >= 'a') && (next <= 'f'))))
            {
                return c_DummyChar;
            }

            return (char)((res << 4) + ((next <= '9')
                    ? ((int)next - (int)'0')
                    : (((next <= 'F')
                        ? ((int)next - (int)'A')
                        : ((int)next - (int)'a'))
                       + 10)));
        }

        public static AddressEntry Parse(string s)
        {
            AddressEntry entry = new AddressEntry();

            string[] parts = s.Split(new[] { ':' }, 2);

            if (parts.Length < 2)
                throw new FormatException("No colon found");

            entry.Method = parts[0];

            if (parts[1].Length > 0)
            {
                foreach (string propStr in parts[1].Split(','))
                {
                    parts = propStr.Split('=');

                    if (parts.Length < 2)
                        throw new FormatException("No equals sign found");
                    if (parts.Length > 2)
                        throw new FormatException("Too many equals signs found");

                    if (parts[0] == "guid")
                    {
                        try
                        {
                            entry.Guid = Guid.ParseExact(parts[1], "N");
                        }
                        catch
                        {
                            throw new FormatException("Invalid guid specified");
                        }
                        continue;
                    }

                    entry.Properties[parts[0]] = Unescape(parts[1]);
                }
            }

            return entry;
        }

        public async Task<EndPoint[]> ResolveAsync(bool listen = false)
        {
            switch (Method)
            {
                case "tcp":
                    {
                        string host, portStr, family;
                        int port = 0;

                        if (!Properties.TryGetValue ("host", out host))
                            host = "localhost";

                        if (!Properties.TryGetValue ("port", out portStr) && !listen)
                            throw new FormatException ("No port specified");

                        if (portStr != null && !Int32.TryParse (portStr, out port))
                            throw new FormatException("Invalid port: \"" + port + "\"");

                        if (!Properties.TryGetValue ("family", out family))
                            family = null;

                        if (string.IsNullOrEmpty(host))
                        {
                            throw new ArgumentException("host");
                        }

                        IPAddress[] addresses = await Dns.GetHostAddressesAsync(host).ConfigureAwait(false);

                        var endpoints = new IPEndPoint[addresses.Length];
                        for (int i = 0; i < endpoints.Length; i++)
                        {
                            endpoints[i] = new IPEndPoint(addresses[i], port);
                        }
                        return endpoints;
                    }
                case "unix":
                    {
                        string path;
                        bool abstr;

                        if (Properties.TryGetValue("path", out path))
                            abstr = false;
                        else if (Properties.TryGetValue("abstract", out path))
                            abstr = true;
                        else
                            throw new ArgumentException("No path specified for UNIX transport");

                        if (String.IsNullOrEmpty(path))
                        {
                            throw new ArgumentException("path");
                        }

                        if (abstr)
                        {
                            path = (char)'\0' + path;
                        }

                        return new EndPoint[] { new UnixDomainSocketEndPoint(path) };
                    }
                default:
                    throw new NotSupportedException("Transport method \"" + Method + "\" not supported");
            }
        }
    }
}

redpajama_set_name: RedPajamaGithub


text:
require 'contacts-service/version'

module ContactsService
  def self.settings
    @settings ||= {}
  end

  def self.configure
    if block_given?
      yield(self.settings)
    end

    self.settings[:public_dir] ||= File.expand_path('../../public/assets', __FILE__) # lib/../public/assets
    self.settings[:asset_paths] ||= [ File.expand_path('../../src', __FILE__) ]
    self.settings[:asset_paths].uniq!
  end

  module Sprockets
    # Append asset paths to an existing Sprockets environment
    def self.setup(environment, &block)
      ContactsService.configure(&block)
      ContactsService.settings[:asset_paths].each do |path|
        environment.append_path(path)
      end
    end
  end
end


text:
#ifndef EDDA_CURVILINEAR_GRID_H
#define EDDA_CURVILINEAR_GRID_H

#include "grid.h"
#include <vector>

namespace edda{
#define DIR_I 0
#define DIR_J 1
#define DIR_K 2

#if 0
//////////////  This CellTopoType is used in OSUFlow. In OSUFlow CVertex is defined in Grid.h. can be placed at another file for more organized code ////////////////
// define the cell type
enum CellTopoType
{
  T0_CELL,					// vertex
  T1_CELL,					// edge
  T2_CELL,					// triangle, quarilateral
  T3_CELL,					// tetrahedra, cube
  T4_CELL					// hetrahedra, added by lijie
};
#endif

typedef struct {
  int dir;
  int tetra;
  int face;
} Tetra_step;

#define CELL_TETRAHEDRON 1
#define CELL_HEXAHEDRON  2

  typedef struct {
          int type;
          VECTOR3  ijk;
          int      subid;
  } Cell;

  /*

  phys_to_cell
  |
  ---|
  |  locate
  |  |
  |   ---locate_close_vertex_cell
  |  |           |
  |  |           ---adaptive_vertex_cell_walk
  |  |
  |  ---tetrahedral_walk_locate
  |              |
  |               ---hexahedral_walk_locate
  |
  |
  ----phys_to_comp_coords

  */
class EDDA_EXPORT CurvilinearGrid : public CartesianGrid
{
private:
  VECTOR3 xyz_o, xyz_r, xyz_s, xyz_t, xyz_rs, xyz_rt, xyz_st, xyz_rst;
  VECTOR3* initial_location;
  VECTOR3* m_pVertex;
  bool left_handed_cells;

public:

  CurvilinearGrid(int xdim, int ydim, int zdim);
  CurvilinearGrid(int* dim, VECTOR3* pVertexGeom); //from OSUFlow. maybe can delete
  CurvilinearGrid(int* dim, float* point_ary);

  CurvilinearGrid();
  ~CurvilinearGrid();
  void Reset();
  // physical coordinate of vertex verIdx
  ReturnStatus at_vertex(int verIdx, VECTOR3& pos);
  // whether the physical point is on the boundary
  bool at_phys(VECTOR3& pos);
  // get vertex list of a cell
  ReturnStatus getCellVertices(int cellId, std::vector<size_t>& vVertices);
  // get the cell id and also interpolating coefficients for the given physical position
  ReturnStatus phys_to_cell(PointInfo& pInfo);
  // the volume of cell
  double cellVolume(int cellId);
  // cell type
  CellType getCellType() { return CUBE; }
  // set bounding box
  void setBoundary(VECTOR3& minB, VECTOR3& maxB);
  void setRealBoundary(VECTOR4& minB, VECTOR4& maxB);
  // get min and maximal boundary
  void boundary(VECTOR3& minB, VECTOR3& maxB);
  bool isInBBox(VECTOR3& pos);
  bool isInRealBBox(VECTOR3& pos);
  bool isInRealBBox(VECTOR3& pos, float t);
  void computeBBox();

  // boundary intersection
  void boundaryIntersection(VECTOR3&, VECTOR3&, VECTOR3&, float*, float){};//not implemented in OSUFlow. will do in the future
  // whether in a cell
  bool isInCell(PointInfo& pInfo, const int cellId){ return true; };//the implementation in OSUFlow is not correct. will do in the future
  // get grid spacing in x,y,z dimensions
  void getGridSpacing(int cellId, float& xspace, float& yspace, float& zspace)
  {
	  xspace = 0; yspace = 0; zspace = 0;
  };//grid spacing is not meaningful for curvilinear grid. need this function to override the abstract method in the parent classes

  int get_ijk_of_vertex(int vertexId, VECTOR3& ijk);
  int get_ijk_of_cell(int cellId, VECTOR3& ijk);

  /**********************************/
  //re-implemented functions
  int central_difference_neighbors(VECTOR3& vc, int dir);

  //interpolate
  int	phys_to_comp_coords(const VECTOR3  p, double& r, double& s, double& t);

  //	int get_ijk_of_vertex(int vertexId, VECTOR3& ijk);
  int init_jacobian_vectors(VECTOR3* dp);
  //  int	jacobian_at_vertex(VECTOR3, MATRIX3*);//not used
  //	int	jacobian_at_vertex_id(int verIdx, MATRIX3& jacobian);//not used

  //int inverse_jacobian(MATRIX3& mi, double r, double s, double t);
  int inverse_jacobian_t(MATRIX3& mi, double r, double s, double t);

  //point location
  void locate_initialization();
  int locate_close_vertex_cell(VECTOR3 pp, VECTOR3& vc);

  int	adaptive_vertex_cell_walk(VECTOR3& pp, VECTOR3& start_v, VECTOR3* v);

  int tetrahedral_walk_locate(VECTOR3, Cell, Cell&);

  int hexahedral_walk_locate(VECTOR3, Cell, Cell&);

  ReturnStatus locate(VECTOR3, Cell&);
  ReturnStatus locate(VECTOR3 pp, Cell& prev_cell, Cell& cell);
  //	int	locate(VECTOR3&, VECTOR3&, VECTOR3*) const;

  //auxiliary
  int coordinates_at_cell(VECTOR3 cell, VECTOR3* v);//return 8 velocity value
  int coordinates_at_vertex(VECTOR3 pos, VECTOR3* v);	//return 1 velocity value
  int	walk_on_x_boundary(VECTOR3 pp, int plane_pos, float& min_d2, VECTOR3& min_v);
  int	walk_on_y_boundary(VECTOR3 pp, int plane_pos, float& min_d2, VECTOR3& min_v);
  int	walk_on_z_boundary(VECTOR3 pp, int plane_pos, float& min_d2, VECTOR3& min_v);
  int simplicial_decomposition_odd(VECTOR3& ijk);
  int up_cells(VECTOR3 input_ijk, Cell& cell, int decompose = 1);

  static const int hexa_face[2][6][4];
  static const int subtetra_vertex[10][4];
  static const int subtetra_face[10][4][3];
  static const int quadrilateral_vertex[3][4];
  static const int subtriangle_vertex[20][3];
  static const int edge_vertex[21][2];
  static const Tetra_step tetra_step[10][4];
  int n_initial_locations;
};

#define FEL_DIR_0	0
#define FEL_DIR_NEG_I	1
#define FEL_DIR_POS_I	2
#define FEL_DIR_NEG_J	3
#define FEL_DIR_POS_J	4
#define FEL_DIR_NEG_K	5
#define FEL_DIR_POS_K	6

#define FEL_DIR_I       7
#define FEL_DIR_J       8
#define FEL_DIR_K       9

  // The canonical vertex numbering for a structured hexahedron.
  // The vertex indices in the tables below are in terms of this
  // hexahedron numbering.
  //
  //		    6________7
  //		   /|       /|  ^
  //		  / |      / |  |
  //		4/_______5/  |  k
  //		|  2|___ |___|3
  //		|  /     |  /  ^
  //		| /      | /  /
  //		|/_______|/  j
  //		0        1
  //		   i ->

}
#endif


text:
import HabooSdk from "@haboo/haboo-sdk";
import * as PropTypes from "prop-types";
import * as React from "react";
import { Link } from "react-router-dom";
import { config } from "../config";
import * as css from "./Menu.scss";

export default class Menu extends React.Component<{}, {}> {

    public static contextTypes = {
        router: PropTypes.object,
    };

    private router: any;
    constructor(props: any, context: any) {
        super(props, context);
        this.router = this.context.router;
    }

    public componentWillMount() {
    }

    public componentWillUnmount() {
    }

    public navigate(path: any) {
        this.router.history.push(path);
    }

    public render() {
        const menuItems = [
            { label: "Sales", link: "/sales", icon: "credit_card" },
            { label: "Students", link: "/students", icon: "school" },
            { label: "Account", link: "/account", icon: "school" },
            { label: "SignIn", link: "/account/sign-in", icon: "school" },
            { label: "SignUp", link: "/account/sign-up", icon: "school" },
            { label: "Profile", link: "/account/profile", icon: "school" },
            { label: "Settings", link: "/settings", icon: "settings" },
        ].map((item) => {
            return (

                    <Link to={item.link}>
                        {item.icon} {item.label}
                    </Link>

            );
        });

        return (

                    {menuItems}

        );
    }
}


text:
namespace GPO {

class RateGyroSensor : public Sensor {
 public:
  // The user must supply an array of the following measurements.
  struct Data {
    double rx, ry, rz;  // Rate vector, in radians/s (or delta angle in radians)
    double std_dev;     // Noise standard deviation for rx,ry,rz
  };

  // Create the sensor with the given measurements array, which must be valid
  // for the lifetime of this object. The samples[i] entry corresponds to time
  // step i. The first entry of this array is ignored.
  // D is the drifting bias *per-step* noise standard deviation.
  RateGyroSensor(int num_samples, Data *samples, double stepsize,
                 double D);

  ~RateGyroSensor();

  void SetSpin(double x, double y, double z);

  // Sensor virtual functions
  void GetInfo(SensorInfo *info);
  int MeasurementIndex(int i);
  void ComputeErrorVector(int i, const Number *prev_step,
    const Number *this_step, const Number *next_step, const Number *globals,
    Number *error);

private:
  int num_samples_;
  Data *samples_;
  double stepsize_;
  Vector3_d spin_;      // Earth spin vector
  double D_;            // Drifting bias *per-step* noise standard deviation
};

}; // namespace GPO

#endif


text:
export function factory(dict){
  return function(command, args, context){
    const f=dict[command]
    if (f)
      return f(args, context) || ""
    return undefined
  }
}

export function parse(txt, slashfs, context){
  let lines = txt.split('\n')
  lines = lines.map( (l) => {
    if (l[0] != "/")
      return l
    const spl = l.trim().split(' ')
    const slashc=spl[0].slice(1)
    const args=spl.slice(1)
    if (typeof(slashfs)=="function") // convert to list if its not
      slashfs=[slashfs]
    for(const f of slashfs){
      const r=f(slashc, args, context)
      if (r == "")
        return null
      if (r != undefined)
        return r
    }
    return l
  } ).filter( (l) => l!=null )
  return lines.join('\n')
}

export default {factory, parse}


text:
layout: post
title: Optimiser votre application NodeJS + Express
date: 2014-01-21 22:29:46.000000000 -05:00
---
# Optimiser le système (linux / CentOS)

La première des choses est d'avoir un système optimal sur le quel rouler notre application. Si le système est mal configuré, on pourra optimiser autant que l'on veut l'application, on n'aura jamais des performances optimal, et c'est pourquoi, cela va être mon premier axe d'optimisation.

## Optimiser les paramètre du Kernel

Le kernel, par défaut, possède des limites assez basse au niveau du réseau, on va tenter des les augmenter un petit peu.

### Augmenter le backlog de socket pour le kernel

Par défaut, le paramètre SOMAXCONN est à 128 sous CentOS ainsi que dans la plus part des distribution linux. Se paramètre détermine le nombre maximum de _listen()_ qu'un socket peut accepter simultanément. Cette limite est trop basse pour les serveurs actuels et peut dégrader les performances de notre application si on a plus de connection simultannée que cette limite.

Pour ceux qui disent que cette limite est dangereuse car elle peut utiliser trop de mémoire, pour un serveur 64b, chaque listen consomme 160b en mémoire, avec une valeur à 8k, cela représente seulement 1.25M.

Pour la bonne valeur à mettre ici, cela va dépendre, généralement, la bonne limite est entre 128 et 8192.

### Permettre au système de réutiliser les sockets plus utilisé (optionel)

Un des problèmes que j'ai rencontré est le nombre énorme de conenction en _TIME_WAIT_. J'ai pas de solution magique pour cela, sous très fort load, j'en ai encore beaucoup, par contre, ce qui peut aider le système à réutiliser ses sockets en fin de vie, les paramètres suivants peuvent être changé :

    tcp_tw_reuse = 1
    tcp_fin_timeout = 15 (in second)

Par défaut _tcp_fin_timeout_ est à 60s, c'est à dire que le kernel va attendre jusqu'à 60s avant de fermer la connection si c'est nous qui fermons la connection et non le client.

## Augmenter la limite de _file descriptor_

C'est l'un des points les plus importants. Sur CentOS, la limite est de 1024 _file descriptor_ par application, par défaut. C'est en gros le nombre de fichier que l'application peut d'avoir ouvert en même temps, mais comme, sous linux, tout est fichier, cela inclue le nombre de connection. C'est l'un des principaux problèmes de performance. Pour le modifier, il y a deux moyen, soit on le défini au niveau de l'utilisateur, soit de la session en cours.

De mon bord, l'application nodejs possède soit son propre utilisateur, soit il utilise _nobody_, et j'augmente la limite au niveau du système.

### Augmenter la limite pour la session en cours

	ulimit -n 9999
    node app.js
C'est aussi simple que cela.

### Augmenter la limite pour un utilisateur

	vim /etc/security/limits.d/99-nobody
    #user  soft/hard/all option    value
	nobody       -       nofile    9999

### Vérifier la limite pour le processus en cours

Si vous voulez vérifier la limite pour le processus en cours, vous devez avoir son PID :

	#  ps ax | grep node
    PID  [...]  COMMAND
    5699 [...] node app.js

Ensuite, on va voir les limites du PID :

	cat /proc/__PID__/limits
    Limit                     Soft Limit           Hard Limit           Units
    [...]
    Max open files            9999                 9999                 files

Et voilà, on a bien la limite de définie avant.


text:
define(["backbone"], function() {
    var Image = Backbone.Model.extend({
        url: null,
        isSelected: false,
        isFavorite: false,
        hasBeenSeen: false,
    });

    return Image;
});


text:
<resources>

    <style name="Exponential.Theme.Light" parent="Exponential.Theme.Base">
    </style>

    <style name="Exponential.Theme.Base" parent="Theme.AppCompat.Light.NoActionBar">
        <item name="colorPrimary">@color/primary</item>
        <item name="colorPrimaryDark">@color/primary_dark</item>
        <!-- FAB button color -->
        <item name="colorAccent">@color/accent</item>
        <item name="android:windowBackground">@color/window_background</item>
    </style>

    <style name="Exponential.Style.Fab" parent="Exponential.Theme.Base">
        <item name="android:layout_width">wrap_content</item>
        <item name="android:layout_height">wrap_content</item>
        <item name="android:layout_margin">@dimen/fab_margin</item>
        <item name="android:src">@drawable/ic_add</item>
        <item name="borderWidth">0dp</item>
        <item name="elevation">6dp</item>
        <item name="pressedTranslationZ">12dp</item>
    </style>

</resources>


text:
/*----------------------------------------------------------------------------
 Copyright (c) Sandia Corporation
 See Copyright.txt or http://www.paraview.org/HTML/Copyright.html for details.
----------------------------------------------------------------------------*/

// .NAME vtkQtTableRepresentation - set up a vtkTable in a Qt model
//
// .SECTION Description
//
// This class is a wrapper around vtkQtTableModelAdapter.  It
// performs the following functions:
//
//

//
Keep track of the key column, first data column, and last data column.
//     Populate the appropriate ivars on the Qt adapter.
//
Assign colors to each of the data series using a vtkLookupTable.
//     A default lookup table is provided or the user can supply one
//     using SetColorTable().
//

//
// The user must supply the following items:
//

//
the name of the column that contains the series names,
//
the names of the first and last data columns
//     (this range should not contain the key column), and
//
(optionally) a vtkLookupTable to use when assigning colors.
//

//
// .SECTION Caveats
//
// Call SetInputConnection with a table connection
// BEFORE the representation is added to a view or strange things
// may happen, including segfaults.

#ifndef vtkQtTableRepresentation_h
#define vtkQtTableRepresentation_h

#include "vtkViewsQtModule.h" // For export macro
#include "QVTKWin32Header.h"
#include "vtkDataRepresentation.h"

class vtkDoubleArray;
class vtkLookupTable;
class vtkQtTableModelAdapter;

// ----------------------------------------------------------------------

class VTKVIEWSQT_EXPORT vtkQtTableRepresentation : public vtkDataRepresentation
{
public:
  vtkTypeMacro(vtkQtTableRepresentation, vtkDataRepresentation);
  void PrintSelf(ostream &os, vtkIndent indent);

  // Description:
  // Set/get the lookup table that will be used to determine colors
  // for each series.  The table's range should be [0, 1).
  void SetColorTable(vtkLookupTable *t);
  vtkGetObjectMacro(ColorTable, vtkLookupTable);

  // Description:
  // Set/get the name of the column that contains series names.  This
  // must be called BEFORE the representation is added to a view.
  void SetKeyColumn(const char* col);
  char* GetKeyColumn();

  // Description:
  // Set/get the name of the first data column.  This must be called
  // BEFORE the representation is added to a view.
  vtkSetStringMacro(FirstDataColumn);
  vtkGetStringMacro(FirstDataColumn);

  // Description:
  // Set/get the name of the last data column.  This must be called
  // BEFORE the representation is added to a view.
  vtkSetStringMacro(LastDataColumn);
  vtkGetStringMacro(LastDataColumn);

 protected:
  vtkQtTableRepresentation();
  ~vtkQtTableRepresentation();

  // Description:
  // Update the table representation
  void UpdateTable();

  vtkSetStringMacro(KeyColumnInternal);
  vtkGetStringMacro(KeyColumnInternal);

  // ----------------------------------------------------------------------
  vtkQtTableModelAdapter *ModelAdapter;
  vtkLookupTable *ColorTable;
  vtkDoubleArray *SeriesColors;
  char *KeyColumnInternal;
  char *FirstDataColumn;
  char *LastDataColumn;

  // Description:
  // Prepare the input connections to this representation.
  virtual int RequestData(vtkInformation* request,
    vtkInformationVector** inputVector,
    vtkInformationVector* outputVector);

  virtual void ResetModel();
  virtual void CreateSeriesColors();

  // Description:
  // This should set the model type to DATA, METADATA or FULL
  // depending on what you want.
  virtual void SetModelType() { };

private:
  vtkQtTableRepresentation(const vtkQtTableRepresentation &);
  void operator=(const vtkQtTableRepresentation &);

};

#endif


text:
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { RouterTestingModule } from '@angular/router/testing';

import { LoginComponent } from './login.component';

describe('LoginComponent', () => {
  let component: LoginComponent;
  let fixture: ComponentFixture<LoginComponent>;

  beforeEach(async(() => {
    TestBed.configureTestingModule({
      imports: [
        RouterTestingModule
      ],
      declarations: [ LoginComponent ]
    })
    .compileComponents();
  }));

  beforeEach(() => {
    fixture = TestBed.createComponent(LoginComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();
  });

  it('should create', () => {
    expect(component).toBeTruthy();
  });
});


text:
namespace OpenApoc
{

const std::map<VEquipment::WeaponState, UString> VEquipment::WeaponStateMap = {
    {WeaponState::Ready, "ready"},
    {WeaponState::Disabled, "disabled"},
    {WeaponState::Reloading, "reloading"},
    {WeaponState::OutOfAmmo, "outofammo"},
};

VEquipment::VEquipment()
    : equippedPosition(0, 0), weaponState(WeaponState::Ready), ammo(0), reloadTime(0)
{
}

sp<Projectile> VEquipment::fire(Vec3<float> target)
{
	if (this->type->type != VEquipmentType::VEquipmentClass::Weapon)
	{
		LogError("fire() called on non-Weapon");
		return nullptr;
	}
	auto vehicleTile = owner->tileObject;
	if (!vehicleTile)
	{
		LogError("Called on vehicle with no tile object?");
	}
	if (this->weaponState != WeaponState::Ready)
	{
		UString stateName = "UNKNOWN";
		auto it = WeaponStateMap.find(this->weaponState);
		if (it != WeaponStateMap.end())
			stateName = it->second;
		LogWarning("Trying to fire weapon in state %s", stateName.cStr());
		return nullptr;
	}
	if (this->ammo <= 0 && this->type->max_ammo != 0)
	{
		LogWarning("Trying to fire weapon with no ammo");
		return nullptr;
	}
	this->reloadTime = type->fire_delay * TICK_SCALE;
	this->weaponState = WeaponState::Reloading;
	if (this->type->max_ammo != 0)
		this->ammo--;

	if (type->fire_sfx)
	{
		fw().soundBackend->playSample(type->fire_sfx, vehicleTile->getPosition());
	}

	if (this->ammo == 0 && this->type->max_ammo != 0)
	{
		this->weaponState = WeaponState::OutOfAmmo;
	}

	Vec3<float> velocity = target - vehicleTile->getPosition();
	velocity = glm::normalize(velocity);
	velocity *= type->speed;

	return mksp<Projectile>(owner, vehicleTile->getPosition(), velocity,
	                        static_cast<int>(this->getRange() / type->speed * TICK_SCALE),
	                        type->damage, type->tail_size, type->projectile_sprites);
}

void VEquipment::setInventoryPosition(Vec2<int> position) { equippedPosition = position; }

Vec2<int> VEquipment::getInventoryPosition() const { return equippedPosition; }

sp<EquipmentType> VEquipment::getType() const
{
	return std::static_pointer_cast<EquipmentType>(type.getSp());
}

EquipmentClass VEquipment::getClass() const
{
	return static_cast<EquipmentClass>(type->type); // equipment calss is VEquipmentClass
}

void VEquipment::update(int ticks)
{
	if (this->type->type != VEquipmentType::VEquipmentClass::Weapon)
	{
		LogError("update() called on non-Weapon");
		return;
	}
	if (this->reloadTime != 0)
	{
		if (ticks >= this->reloadTime)
			this->reloadTime = 0;
		else
			this->reloadTime -= ticks;
	}
	switch (this->weaponState)
	{
		case WeaponState::Reloading:
			if (this->reloadTime == 0)
				this->weaponState = WeaponState::Ready;
			return;
		case WeaponState::OutOfAmmo:
			if (this->ammo > 0)
				this->weaponState = WeaponState::Ready;
			return;
		default:
			return;
	}
}

int VEquipment::reload(int ammoAvailable)
{
	if (this->type->type != VEquipmentType::VEquipmentClass::Weapon)
	{
		LogError("reload() called on non-Weapon");
		return 0;
	}
	int ammoRequired = this->type->max_ammo - this->ammo;
	int reloadAmount = std::min(ammoRequired, ammoAvailable);
	this->ammo += reloadAmount;
	return reloadAmount;
}

float VEquipment::getRange() const
{
	if (this->type->type != VEquipmentType::VEquipmentClass::Weapon)
	{
		LogError("getRange() called on non-Weapon");
		return 0;
	}
	auto &type = this->type;
	return static_cast<float>(type->range);
}

void VEquipment::setReloadTime(int ticks)
{
	if (this->type->type != VEquipmentType::VEquipmentClass::Weapon)
	{
		LogError("setReloadTime() called on non-Weapon");
		return;
	}
	if (ticks <= 0)
	{
		this->reloadTime = 0;
	}
	else
	{
		this->weaponState = WeaponState::Reloading;
		this->reloadTime = ticks;
	}
}

bool VEquipment::canFire() const
{
	if (this->type->type != VEquipmentType::VEquipmentClass::Weapon)
	{
		LogError("canFire() called on non-Weapon");
		return false;
	}
	return this->weaponState == WeaponState::Ready;
}

} // namespace OpenApoc


text:
<?xml version="1.0" encoding="UTF-8"?>
<!--

    Licensed to the Apache Software Foundation (ASF) under one
    or more contributor license agreements.  See the NOTICE file
    distributed with this work for additional information
    regarding copyright ownership.  The ASF licenses this file
    to you under the Apache License, Version 2.0 (the
    "License"); you may not use this file except in compliance
    with the License.  You may obtain a copy of the License at

      http://www.apache.org/licenses/LICENSE-2.0

    Unless required by applicable law or agreed to in writing,
    software distributed under the License is distributed on an
    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    KIND, either express or implied.  See the License for the
    specific language governing permissions and limitations
    under the License.

-->
<taeDescription xmlns="http://uima.apache.org/resourceSpecifier">
<frameworkImplementation>org.apache.uima.java</frameworkImplementation>
<primitive>true</primitive>
<annotatorImplementationName>org.apache.ctakes.core.ae.NullAnnotator</annotatorImplementationName>
<analysisEngineMetaData>
<name>null annotator</name>
<description>This annotator does nothing.  The process method is overridden but is empty.  None of the other methods are overriden.  This annotator may be useful if you are using the CPE GUI and you are required to specify an analysis engine but you don't actually want to specify one.  </description>
<version></version>
<vendor>Mayo Clinic</vendor>
<configurationParameters/>
<configurationParameterSettings/>
<typeSystemDescription/>
<capabilities>
<capability>
<inputs/>
<outputs/>
<languagesSupported/>
</capability>
</capabilities>
<operationalProperties>
<modifiesCas>true</modifiesCas>
<multipleDeploymentAllowed>true</multipleDeploymentAllowed>
</operationalProperties>
</analysisEngineMetaData>
</taeDescription>


text:
Radio groups can have a single entry checked at any one time. A button styled alternative can be achieved using `type="button"` input property.

We don't intend to re-create all the native HTML input elements, but we intend to take all the tedious work away from you and at the same time making sure that your native elements have all the appropriate styles and are fully accessible. So yo are responsible to for writing the with the `ngl` attribute like this `<input ngl type="radio">` and hook it to `ngModel`, `formControl`, `disabled` etc based on your needs.

**Accessibility**:

  * `<label>` has a `for` attribute whose value is that input field's `id`.
  * Input element(s) with error, receives an `aria-describedby` attribute that references the `id` attribute of the error message.


text:
if __name__ == '__main__':
    import sys
    import os
    pkg_dir = os.path.split(os.path.abspath(__file__))[0]
    parent_dir, pkg_name = os.path.split(pkg_dir)
    is_pygame_pkg = (pkg_name == 'tests' and
                     os.path.split(parent_dir)[1] == 'pygame')
    if not is_pygame_pkg:
        sys.path.insert(0, parent_dir)
else:
    is_pygame_pkg = __name__.startswith('pygame.tests.')

if is_pygame_pkg:
    from pygame.tests.test_utils \
         import test_not_implemented, example_path, unittest, png
else:
    from test.test_utils \
         import test_not_implemented, example_path, unittest, png
import pygame, pygame.image, pygame.pkgdata
from pygame.compat import xrange_, ord_

import os
import array
import tempfile

def test_magic(f, magic_hex):
    """ tests a given file to see if the magic hex matches.
    """
    data = f.read(len(magic_hex))

    if len(data) != len(magic_hex):
        return 0

    for i in range(len(magic_hex)):
        if magic_hex[i] != ord_(data[i]):
            return 0

    return 1

class ImageModuleTest( unittest.TestCase ):
    def testLoadIcon(self):
        """ see if we can load the pygame icon.
        """
        f = pygame.pkgdata.getResource("pygame_icon.bmp")
        self.assertEqual(f.mode, "rb")

        surf = pygame.image.load_basic(f)

        self.assertEqual(surf.get_at((0,0)),(5, 4, 5, 255))
        self.assertEqual(surf.get_height(),32)
        self.assertEqual(surf.get_width(),32)

    def testLoadPNG(self):
        """ see if we can load a png with color values in the proper channels.
        """
        # Create a PNG file with known colors
        reddish_pixel = (210, 0, 0, 255)
        greenish_pixel = (0, 220, 0, 255)
        bluish_pixel = (0, 0, 230, 255)
        greyish_pixel = (110, 120, 130, 140)
        pixel_array = [reddish_pixel + greenish_pixel,
                       bluish_pixel + greyish_pixel]

        f_descriptor, f_path = tempfile.mkstemp(suffix='.png')
        f = os.fdopen(f_descriptor, 'wb')
        w = png.Writer(2, 2, alpha=True)
        w.write(f, pixel_array)
        f.close()

        # Read the PNG file and verify that pygame interprets it correctly
        surf = pygame.image.load(f_path)

        pixel_x0_y0 = surf.get_at((0, 0))
        pixel_x1_y0 = surf.get_at((1, 0))
        pixel_x0_y1 = surf.get_at((0, 1))
        pixel_x1_y1 = surf.get_at((1, 1))

        self.assertEquals(pixel_x0_y0, reddish_pixel)
        self.assertEquals(pixel_x1_y0, greenish_pixel)
        self.assertEquals(pixel_x0_y1, bluish_pixel)
        self.assertEquals(pixel_x1_y1, greyish_pixel)

        # Read the PNG file obj. and verify that pygame interprets it correctly
        f = open(f_path, 'rb')
        surf = pygame.image.load(f)
        f.close()

        pixel_x0_y0 = surf.get_at((0, 0))
        pixel_x1_y0 = surf.get_at((1, 0))
        pixel_x0_y1 = surf.get_at((0, 1))
        pixel_x1_y1 = surf.get_at((1, 1))

        self.assertEquals(pixel_x0_y0, reddish_pixel)
        self.assertEquals(pixel_x1_y0, greenish_pixel)
        self.assertEquals(pixel_x0_y1, bluish_pixel)
        self.assertEquals(pixel_x1_y1, greyish_pixel)

        os.remove(f_path)

    def testLoadJPG(self):
        """ see if we can load a jpg.
        """

        f = example_path('data/alien1.jpg')      # normalized
        # f = os.path.join("examples", "data", "alien1.jpg")
        surf = pygame.image.load(f)

        f = open(f, "rb")

        # f = open(os.path.join("examples", "data", "alien1.jpg"), "rb")

        surf = pygame.image.load(f)

        # surf = pygame.image.load(open(os.path.join("examples", "data", "alien1.jpg"), "rb"))

    def testSavePNG(self):
        """ see if we can save a png with color values in the proper channels.
        """
        # Create a PNG file with known colors
        reddish_pixel = (215, 0, 0, 255)
        greenish_pixel = (0, 225, 0, 255)
        bluish_pixel = (0, 0, 235, 255)
        greyish_pixel = (115, 125, 135, 145)

        surf = pygame.Surface((1, 4), pygame.SRCALPHA, 32)
        surf.set_at((0, 0), reddish_pixel)
        surf.set_at((0, 1), greenish_pixel)
        surf.set_at((0, 2), bluish_pixel)
        surf.set_at((0, 3), greyish_pixel)

        f_path = tempfile.mktemp(suffix='.png')
        pygame.image.save(surf, f_path)

        # Read the PNG file and verify that pygame saved it correctly
        width, height, pixels, metadata = png.Reader(filename=f_path).asRGBA8()
        pixels_as_tuples = []
        for pixel in pixels:
            pixels_as_tuples.append(tuple(pixel))

        self.assertEquals(pixels_as_tuples[0], reddish_pixel)
        self.assertEquals(pixels_as_tuples[1], greenish_pixel)
        self.assertEquals(pixels_as_tuples[2], bluish_pixel)
        self.assertEquals(pixels_as_tuples[3], greyish_pixel)

        os.remove(f_path)

    def test_save(self):

        s = pygame.Surface((10,10))
        s.fill((23,23,23))
        magic_hex = {}
        magic_hex['jpg'] = [0xff, 0xd8, 0xff, 0xe0]
        magic_hex['png'] = [0x89 ,0x50 ,0x4e ,0x47]
        magic_hex['tga'] = [0x0, 0x0, 0xa]
        magic_hex['bmp'] = [0x42, 0x4d]

        formats = ["jpg", "png", "tga", "bmp"]
        # uppercase too... JPG
        formats = formats + [x.upper() for x in formats]

        for fmt in formats:
            try:
                temp_filename = "%s.%s" % ("tmpimg", fmt)
                pygame.image.save(s, temp_filename)
                # test the magic numbers at the start of the file to ensure they are saved
                #   as the correct file type.
                self.assertEqual((1, fmt), (test_magic(open(temp_filename, "rb"), magic_hex[fmt.lower()]), fmt))
                # load the file to make sure it was saved correctly.
                #    Note load can load a jpg saved with a .png file name.
                s2 = pygame.image.load(temp_filename)
                #compare contents, might only work reliably for png...
                #   but because it's all one color it seems to work with jpg.
                self.assertEquals(s2.get_at((0,0)), s.get_at((0,0)))
            finally:
                #clean up the temp file, comment out to leave tmp file after run.
                os.remove(temp_filename)
                pass

    def test_save_colorkey(self):
        """ make sure the color key is not changed when saving.
        """
        s = pygame.Surface((10,10), pygame.SRCALPHA, 32)
        s.fill((23,23,23))
        s.set_colorkey((0,0,0))
        colorkey1 = s.get_colorkey()
        p1 = s.get_at((0,0))

        temp_filename = "tmpimg.png"
        try:
            pygame.image.save(s, temp_filename)
            s2 = pygame.image.load(temp_filename)
        finally:
            os.remove(temp_filename)

        colorkey2 = s.get_colorkey()
        # check that the pixel and the colorkey is correct.
        self.assertEqual(colorkey1, colorkey2)
        self.assertEqual(p1, s2.get_at((0,0)))

    def assertPremultipliedAreEqual(self, string1, string2, source_string):
        self.assertEqual(len(string1), len(string2))
        block_size = 20
        if string1 != string2:
            for block_start in xrange_(0, len(string1), block_size):
                block_end = min(block_start + block_size, len(string1))
                block1 = string1[block_start:block_end]
                block2 = string2[block_start:block_end]
                if block1 != block2:
                    source_block = source_string[block_start:block_end]
                    msg = "string difference in %d to %d of %d:\n%s\n%s\nsource:\n%s" % (block_start, block_end, len(string1), block1.encode("hex"), block2.encode("hex"), source_block.encode("hex"))
                    self.fail(msg)

    def test_to_string__premultiplied(self):
        """ test to make sure we can export a surface to a premultiplied alpha string
        """

        def convertRGBAtoPremultiplied(surface_to_modify):
            for x in xrange_(surface_to_modify.get_width()):
                for y in xrange_(surface_to_modify.get_height()):
                    color = surface_to_modify.get_at((x, y))
                    premult_color = (color[0]*color[3]/255,
                                     color[1]*color[3]/255,
                                     color[2]*color[3]/255,
                                     color[3])
                    surface_to_modify.set_at((x, y), premult_color)

        test_surface = pygame.Surface((256, 256), pygame.SRCALPHA, 32)
        for x in xrange_(test_surface.get_width()):
            for y in xrange_(test_surface.get_height()):
                i = x + y*test_surface.get_width()
                test_surface.set_at((x,y), ((i*7) % 256, (i*13) % 256, (i*27) % 256, y))
        premultiplied_copy = test_surface.copy()
        convertRGBAtoPremultiplied(premultiplied_copy)
        self.assertPremultipliedAreEqual(pygame.image.tostring(test_surface, "RGBA_PREMULT"),
                                         pygame.image.tostring(premultiplied_copy, "RGBA"),
                                         pygame.image.tostring(test_surface, "RGBA"))
        self.assertPremultipliedAreEqual(pygame.image.tostring(test_surface, "ARGB_PREMULT"),
                                         pygame.image.tostring(premultiplied_copy, "ARGB"),
                                         pygame.image.tostring(test_surface, "ARGB"))

        no_alpha_surface = pygame.Surface((256, 256), 0, 24)
        self.assertRaises(ValueError, pygame.image.tostring, no_alpha_surface, "RGBA_PREMULT")

    def test_fromstring__and_tostring(self):
        """ see if fromstring, and tostring methods are symmetric.
        """

        def AreSurfacesIdentical(surf_a, surf_b):
            if surf_a.get_width() != surf_b.get_width() or surf_a.get_height() != surf_b.get_height():
                return False
            for y in xrange_(surf_a.get_height()):
                for x in xrange_(surf_b.get_width()):
                    if surf_a.get_at((x,y)) != surf_b.get_at((x,y)):
                        return False
            return True

        ####################################################################
        def RotateRGBAtoARGB(str_buf):
            byte_buf = array.array("B", str_buf)
            num_quads = len(byte_buf)//4
            for i in xrange_(num_quads):
                alpha = byte_buf[i*4 + 3]
                byte_buf[i*4 + 3] = byte_buf[i*4 + 2]
                byte_buf[i*4 + 2] = byte_buf[i*4 + 1]
                byte_buf[i*4 + 1] = byte_buf[i*4 + 0]
                byte_buf[i*4 + 0] = alpha
            return byte_buf.tostring()

        ####################################################################
        def RotateARGBtoRGBA(str_buf):
            byte_buf = array.array("B", str_buf)
            num_quads = len(byte_buf)//4
            for i in xrange_(num_quads):
                alpha = byte_buf[i*4 + 0]
                byte_buf[i*4 + 0] = byte_buf[i*4 + 1]
                byte_buf[i*4 + 1] = byte_buf[i*4 + 2]
                byte_buf[i*4 + 2] = byte_buf[i*4 + 3]
                byte_buf[i*4 + 3] = alpha
            return byte_buf.tostring()

        ####################################################################
        test_surface = pygame.Surface((64, 256), flags=pygame.SRCALPHA, depth=32)
        for i in xrange_(256):
            for j in xrange_(16):
                intensity = j*16 + 15
                test_surface.set_at((j + 0, i), (intensity, i, i, i))
                test_surface.set_at((j + 16, i), (i, intensity, i, i))
                test_surface.set_at((j + 32, i), (i, i, intensity, i))
                test_surface.set_at((j + 32, i), (i, i, i, intensity))

        self.assert_(AreSurfacesIdentical(test_surface, test_surface))

        rgba_buf = pygame.image.tostring(test_surface, "RGBA")
        rgba_buf = RotateARGBtoRGBA(RotateRGBAtoARGB(rgba_buf))
        test_rotate_functions = pygame.image.fromstring(rgba_buf, test_surface.get_size(), "RGBA")

        self.assert_(AreSurfacesIdentical(test_surface, test_rotate_functions))

        rgba_buf = pygame.image.tostring(test_surface, "RGBA")
        argb_buf = RotateRGBAtoARGB(rgba_buf)
        test_from_argb_string = pygame.image.fromstring(argb_buf, test_surface.get_size(), "ARGB")

        self.assert_(AreSurfacesIdentical(test_surface, test_from_argb_string))
        #"ERROR: image.fromstring with ARGB failed"

        argb_buf = pygame.image.tostring(test_surface, "ARGB")
        rgba_buf = RotateARGBtoRGBA(argb_buf)
        test_to_argb_string = pygame.image.fromstring(rgba_buf, test_surface.get_size(), "RGBA")

        self.assert_(AreSurfacesIdentical(test_surface, test_to_argb_string))
        #"ERROR: image.tostring with ARGB failed"

        argb_buf = pygame.image.tostring(test_surface, "ARGB")
        test_to_from_argb_string = pygame.image.fromstring(argb_buf, test_surface.get_size(), "ARGB")

        self.assert_(AreSurfacesIdentical(test_surface, test_to_from_argb_string))
        #"ERROR: image.fromstring and image.tostring with ARGB are not symmetric"

    def todo_test_frombuffer(self):

        # __doc__ (as of 2008-08-02) for pygame.image.frombuffer:

          # pygame.image.frombuffer(string, size, format): return Surface
          # create a new Surface that shares data inside a string buffer
          #
          # Create a new Surface that shares pixel data directly from the string
          # buffer. This method takes the same arguments as
          # pygame.image.fromstring(), but is unable to vertically flip the
          # source data.
          #
          # This will run much faster than pygame.image.fromstring, since no
          # pixel data must be allocated and copied.

        self.fail()

    def todo_test_get_extended(self):

        # __doc__ (as of 2008-08-02) for pygame.image.get_extended:

          # pygame.image.get_extended(): return bool
          # test if extended image formats can be loaded
          #
          # If pygame is built with extended image formats this function will
          # return True. It is still not possible to determine which formats
          # will be available, but generally you will be able to load them all.

        self.fail()

    def todo_test_load_basic(self):

        # __doc__ (as of 2008-08-02) for pygame.image.load_basic:

          # pygame.image.load(filename): return Surface
          # pygame.image.load(fileobj, namehint=): return Surface
          # load new image from a file

        self.fail()

    def todo_test_load_extended(self):

        # __doc__ (as of 2008-08-02) for pygame.image.load_extended:

          # pygame module for image transfer

        self.fail()

    def todo_test_save_extended(self):

        # __doc__ (as of 2008-08-02) for pygame.image.save_extended:

          # pygame module for image transfer

        self.fail()

if __name__ == '__main__':
    unittest.main()


text:
/**
 * A mixin that gives Ext.Component and Ext.Widget the ability to process the "delegate"
 * event option.
 * @private
 */
Ext.define('Ext.mixin.ComponentDelegation', {
    extend: 'Ext.Mixin',
    mixinConfig: {
        id: 'componentDelegation'
    },

    privates: {
        /**
         * @private
         * Adds a listeners with the "delegate" event option.  Users should not invoke this
         * method directly.  Use the "delegate" event option of
         * {@link Ext.util.Observable#addListener addListener} instead.
         */
        addDelegatedListener: function(eventName, fn, scope, options, order, caller, manager) {
            var me = this,
                delegatedEvents, event, priority;

            eventName = Ext.canonicalEventName(eventName);

            // The following processing of the "order" option is typically done by the
            // doAddListener method of Ext.mixin.Observable, but that method does not
            // get called when adding a delegated listener, so we must do the conversion
            // of order to priority here.
            order = order || options.order;

            if (order) {
                priority = (options && options.priority);

                if (!priority) { // priority option takes precedence over order
                    // do not mutate the user's options
                    options = options ? Ext.Object.chain(options) : {};
                    options.priority = me.$orderToPriority[order];
                }
            }

            //<debug>
            if (options.target) {
                Ext.raise("Cannot add '" + eventName + "' listener to component: '"
                + me.id + "' - 'delegate' and 'target' event options are incompatible.");
            }
            //</debug>

            // Delegated events are tracked in a map keyed by event name, where the values
            // are instances of Ext.util.Event that track all of the delegate listeners
            // for the given event name.
            delegatedEvents = me.$delegatedEvents || (me.$delegatedEvents = {});
            event = delegatedEvents[eventName] ||
                    (delegatedEvents[eventName] = new Ext.util.Event(me, eventName));

            if (event.addListener(fn, scope, options, caller, manager)) {
                me.$hasDelegatedListeners._incr_(eventName);
            }
        },

        /**
         * @private
         * Clears all listeners that were attached using the "delegate" event option.
         * Users should not invoke this method directly.  It is called automatically as
         * part of normal {@link Ext.util.Observable#clearListeners clearListeners}
         * processing.
         */
        clearDelegatedListeners: function() {
            var me = this,
                delegatedEvents = me.$delegatedEvents,
                eventName, event, listenerCount;

            if (delegatedEvents) {
                for (eventName in delegatedEvents) {
                    event = delegatedEvents[eventName];
                    listenerCount = event.listeners.length;
                    event.clearListeners();
                    me.$hasDelegatedListeners._decr_(eventName, listenerCount);
                    delete delegatedEvents[eventName];
                }
            }
        },

        /**
         * @private
         * Fires a delegated event.  Users should not invoke this method directly.  It
         * is called automatically by the framework as needed (see the "delegate" event
         * option of {@link Ext.util.Observable#addListener addListener} for more
         * details.
         */
        doFireDelegatedEvent: function(eventName, args) {
            var me = this,
                ret = true,
                owner, delegatedEvents, event;

            // NOTE: $hasDelegatedListeners exists on the prototype of this mixin
            // which means it is inherited by both Ext.Component and Ext.Widget
            // This means that if any Component in the universe is listening for
            // the given eventName in a delegated manner, we need to traverse up the
            // hierarchy to see if that Component is in fact our ancestor, and if so
            // we need to fire the event on the ancestor.
            if (me.$hasDelegatedListeners[eventName]) {
                owner = me.getRefOwner();

                while (owner) {
                    delegatedEvents = owner.$delegatedEvents;
                    if (delegatedEvents ) {
                        event = delegatedEvents[eventName];

                        if (event) {
                            ret = event.fireDelegated(me, args);

                            if (ret === false) {
                                break;
                            }
                        }
                    }
                    owner = owner.getRefOwner();
                }
            }

            return ret;
        },

        /**
         * @private
         * Removes delegated listeners for a given eventName, function, and scope.
         * Users should not invoke this method directly.  It is called automatically by
         * the framework as part of {@link #removeListener} processing.
         */
        removeDelegatedListener: function(eventName, fn, scope) {
            var me = this,
                delegatedEvents = me.$delegatedEvents,
                event;

            if (delegatedEvents ) {
                event = delegatedEvents[eventName];
                if (event && event.removeListener(fn, scope)) {
                    me.$hasDelegatedListeners._decr_(eventName);

                    if (event.listeners.length === 0) {
                        delete delegatedEvents[eventName];
                    }
                }
            }
        },

        destroyComponentDelegation: function() {
            if (this.clearPropertiesOnDestroy) {
                this.$delegatedEvents = null;
            }
        }
    },

    onClassMixedIn: function(T) {
        // When a Component listener is attached with the "delegate" option, it means
        // All components anywhere in the hierarchy MUST now fire the event just in case
        // the Component with the delegate listener is an ancestor of the component that
        // fired the event (otherwise the ancestor will not have a chance to intercept
        // and process the event - see doFireDelegatedEvent).  To ensure that this happens
        // we chain the class-level hasListeners object of Ext.Component and Ext.Widget
        // to the single $hasDelegatedListeners object (see class-creation callback
        // of this class for more info)
        function HasListeners() {}
        T.prototype.HasListeners = T.HasListeners = HasListeners;
        HasListeners.prototype = T.hasListeners = new Ext.mixin.ComponentDelegation.HasDelegatedListeners();
    }
}, function(ComponentDelegation) {
    // Here We set up a HasListeners instance ($hasDelegatedListeners) that will be incremented
    // and decremented any time a Component or Widget adds or removes a listener using the
    // "delegate" event option.  This HasListeners instance is stored on the prototype
    // of the ComponentDelegation mixin, and therefore will be applied to the prototype
    // of both Ext.Component and Ext.Widget.  This means that Ext.Widget and Ext.Component
    // (intentionally) share the same $hasDelegatedListeners instance.  To understand the
    // reason for this common instance one must first understand how delegated events are
    // fired:
    //
    // When any component or widget fires an event of any kind, it must call doFireDelegatedEvent
    // to process possible delegated listeners.  The implementation of doFireDelegatedEvent
    // traverses up the component hierarchy searching for any ancestors that may be listening
    // for the event in a delegated manner; however, this traversal of the hierarchy can
    // be skipped if there are no known Components with delegated listeners for the given event.
    // The $hasDelegatedListeners instance is used to track whether or not there are any
    // delegated listeners for the given event name for this purpose.  Since Ext.Widgets
    // and Ext.Components can be part of the same hierarchy they must share the same
    // $hasDelegatesListeners instance.
    function HasDelegatedListeners() {}

    ComponentDelegation.HasDelegatedListeners = HasDelegatedListeners;

    HasDelegatedListeners.prototype = ComponentDelegation.prototype.$hasDelegatedListeners =
            new Ext.mixin.Observable.HasListeners();
});