Index: admin/js/_auth.js
===================================================================
--- admin/js/_auth.js	(revision 3851)
+++ 	(revision )
@@ -1,30 +1,0 @@
-/*global $ */
-'use strict';
-
-$(window).load(function() {
-  let uid = $('input[name=user_id]');
-  let upw = $('input[name=user_pwd]');
-  uid.focus();
-
-  if (upw.length == 0) {
-    return;
-  }
-  uid.keypress(evt => {
-    if (evt.which == 13 && upw.val() == '') {
-      upw.focus();
-      return false;
-    }
-    return true;
-  });
-
-  $.cookie('dc_admin_test_cookie', true);
-  if ($.cookie('dc_admin_test_cookie')) {
-    $('#cookie_help').hide();
-    $.cookie('dc_admin_test_cookie', '', {
-      'expires': -1
-    });
-  } else {
-    $('#cookie_help').show();
-  }
-  $('#issue #more').toggleWithLegend($('#issue').children().not('#more'));
-});
Index: admin/js/_blog_pref.js
===================================================================
--- admin/js/_blog_pref.js	(revision 3982)
+++ admin/js/_blog_pref.js	(revision 0)
@@ -1,58 +1,21 @@
-/*global $, dotclear, jsToolBar, getData */
-'use strict';
+function checkQueryString() {
+	var blogUrl = $('#blog_url')[0].value;
+	var urlScan = $('#url_scan')[0].value;
+	errorMsg = '';
+	if (/.*[^\/]$/.exec(blogUrl) && urlScan=='path_info') {
+		errorMsg = dotclear.msg.warning_path_info;
+	} else if (/.*[^\?]$/.exec(blogUrl) && urlScan=='query_string') {
+		errorMsg = dotclear.msg.warning_query_string;
+	}
+	$("p#urlwarning").remove();
+	if (errorMsg != '') {
+		$("#blog_url").parents('p').before('<p id="urlwarning" class="error">'+errorMsg+'</p>');
+	}
+}
 
-Object.assign(dotclear.msg, getData('blog_pref'));
 
 $(function() {
-  const blog_url = $('#blog_url');
-  if (blog_url.length > 0 && !blog_url.is(':hidden')) {
-    const checkQueryString = function() {
-      const url = blog_url[0].value;
-      const scan = $('#url_scan')[0].value;
-      let msg = '';
-      if (/.*[^\/]$/.exec(url) && scan == 'path_info') {
-        msg = dotclear.msg.warning_path_info;
-      } else if (/.*[^\?]$/.exec(url) && scan == 'query_string') {
-        msg = dotclear.msg.warning_query_string;
-      }
-      $('p#urlwarning').remove();
-      if (msg != '') {
-        blog_url.parents('p').after(`<p id="urlwarning" class="warning">${msg}</p>`);
-      }
-    };
-    checkQueryString();
-    blog_url.focusout(checkQueryString);
-    $('body').on('change', '#url_scan', checkQueryString);
-  }
-
-  $('#date_format_select,#time_format_select').change(function() {
-    if ($(this).prop('value') == '') {
-      return;
-    }
-    $('#' + $(this).attr('id').replace('_select', '')).prop('value', $(this).prop('value'));
-    $(this).parent().next('.chosen').html($(this).find(':selected').prop('label'));
-  });
-
-  // HTML text editor
-  if (typeof jsToolBar !== 'undefined' && $.isFunction(jsToolBar)) {
-    $('#blog_desc').each(function() {
-      let tbWidgetText = new jsToolBar(this);
-      tbWidgetText.context = 'blog_desc';
-      tbWidgetText.draw('xhtml');
-    });
-  }
-
-  // Hide advanced and plugins prefs sections
-  $('#standard-pref h3').toggleWithLegend($('#standard-pref').children().not('h3'), {
-    legend_click: true,
-    hide: false
-  });
-  $('#advanced-pref h3').toggleWithLegend($('#advanced-pref').children().not('h3'), {
-    legend_click: true,
-    user_pref: 'dcx_blog_pref_adv',
-  });
-  $('#plugins-pref h3').toggleWithLegend($('#plugins-pref').children().not('h3'), {
-    legend_click: true,
-    user_pref: 'dcx_blog_pref_plg',
-  });
+	checkQueryString();
+	$('#blog_url').focusout(checkQueryString);
+	$('#url_scan').live("change",checkQueryString);
 });
Index: admin/js/_blog_theme.js
===================================================================
--- admin/js/_blog_theme.js	(revision 3880)
+++ admin/js/_blog_theme.js	(revision 0)
@@ -1,89 +1,71 @@
-/*global $, dotclear */
-'use strict';
-
 $(function() {
-  // expend theme info
-  $('.module-sshot').not('.current-theme .module-sshot').each(function() {
-    const bar = $('<div>').addClass('bloc-toggler');
-    $(this).after(
-      $(bar).toggleWithLegend($(this).parent().children('.toggle-bloc'), {
-        img_on_txt: dotclear.img_plus_theme_txt,
-        img_on_alt: dotclear.img_plus_theme_alt,
-        img_off_txt: dotclear.img_minus_theme_txt,
-        img_off_alt: dotclear.img_minus_theme_alt,
-        legend_click: true
-      }));
-    $(this).children('img').click(function() {
-      // Click on theme thumbnail
-      $(this).parent().parent().children('.bloc-toggler').click();
-    });
-  });
-
-  // dirty short search blocker
-  $('div.modules-search form input[type=submit]').click(function() {
-    const mlen = $('input[name=m_search]', $(this).parent()).val();
-    if (mlen.length > 2) {
-      return true;
-    } else {
-      return false;
-    }
-  });
-
-  // checkboxes selection
-  $('.checkboxes-helpers').each(function() {
-    dotclear.checkboxesHelpers(this);
-  });
-
-  // actions tests
-  $('.modules-form-actions').each(function() {
-    const rxActionType = /^[^\[]+/;
-    const rxActionValue = /([^\[]+)\]$/;
-    const checkboxes = $(this).find('input[type=checkbox]');
-
-    // check if submit is a global action or one line action
-    $('input[type=submit]', this).click(function() {
-      const keyword = $(this).attr('name');
-      if (!keyword) {
-        return true;
-      }
-      const maction = keyword.match(rxActionType);
-      const action = maction[0];
-      const mvalues = keyword.match(rxActionValue);
-
-      // action on multiple modules
-      if (!mvalues) {
-        let checked = false;
-
-        // check if there is checkboxes in form
-        if (checkboxes.length > 0) {
-          // check if there is at least one checkbox checked
-          $(checkboxes).each(function() {
-            if (this.checked) {
-              checked = true;
-            }
-          });
-          if (!checked) {
-            //alert(dotclear.msg.no_selection);
-            return false;
-          }
-        }
-
-        // confirm delete
-        if (action == 'delete') {
-          return window.confirm(dotclear.msg.confirm_delete_themes);
-        }
-
-        // action on one module
-      } else {
-        const module = mvalues[1];
-
-        // confirm delete
-        if (action == 'delete') {
-          return window.confirm(dotclear.msg.confirm_delete_theme.replace('%s', module));
-        }
-      }
-
-      return true;
-    });
-  });
+	$('#themes-actions').hide();
+	var submit_s = $('#themes-actions input[name=select]');
+	var submit_r = $('#themes-actions input[name=remove]');
+	
+	var details = $('#themes div.theme-details');
+	$('div.theme-actions',details).hide();
+	$('input:radio',details).hide();
+	$('div.theme-info span, div.theme-info a',details).hide();
+	details.removeClass('theme-details').addClass('theme-details-js');
+	
+	var themes_wrapper = $('<div id="themes-wrapper"></div>');
+	var theme_box = $('<div id="theme-box"><div</div>');
+	$('#themes').wrap(themes_wrapper).before(theme_box);
+	
+	details.each(function() {
+		var box = this;
+		var a = $(document.createElement('a'));
+		a.attr('href','#');
+		a.attr('title',$('>div h3>label',this).text());
+		$(box).wrap(a);
+		$(box).parent().click(function(event) {
+			update_box(box);
+			event.preventDefault();
+			return false;
+		});
+	});
+	
+	function update_box(e) {
+		theme_box.empty();
+		var img = $('div.theme-shot',e).clone();
+		var info = $('div.theme-info',e).clone();
+		
+		if ($(e).hasClass('current-theme')) {
+			var actions = $('div.theme-actions',e).clone();
+			actions.show();
+		} else {
+			var actions = $('<div class="theme-actions"></div>');
+			if (submit_s.length > 0  && !$('input:radio',info).attr('disabled')) {
+				var select = $('<a href="#" class="button">' + dotclear.msg.use_this_theme + '</a>');
+				select.css('font-weight','bold').click(function() {
+					submit_s.click();
+					return false;
+				});
+				actions.append(select).append('&nbsp;&nbsp;');
+			}
+			if (submit_r.length > 0 && $('input:radio',info).attr('id') != 'theme_default') {
+				var remove = $('<a href="#" class="button">' + dotclear.msg.remove_this_theme + '</a>');
+				remove.click(function() {
+					var t_name = $(this).parents('#theme-box').find('div.theme-info h3:first').text();
+					t_name = $.trim(t_name);
+					if (window.confirm(dotclear.msg.confirm_delete_theme.replace('%s',t_name))) {
+						submit_r.click();
+					}
+					return false;
+				});
+				actions.append(remove);
+			}
+		}
+		
+		$('input:radio',info).remove();
+		$('span, a',info).show();
+		
+		theme_box.append(img).append(info).append(actions);
+		details.removeClass('theme-selected');
+		$(e).addClass('theme-selected');
+		$('input:radio',e).attr('checked','checked');
+	}
+	
+	update_box(details[0]);
 });
Index: admin/js/_blogs.js
===================================================================
--- admin/js/_blogs.js	(revision 4007)
+++ 	(revision )
@@ -1,17 +1,0 @@
-/*global $, dotclear */
-'use strict';
-
-$(function() {
-  $('.checkboxes-helpers').each(function() {
-    dotclear.checkboxesHelpers(this, undefined, '#form-blogs td input[type=checkbox]', '#form-blogs #do-action');
-  });
-  $('#form-blogs td input[type=checkbox]').enableShiftClick();
-  dotclear.condSubmit('#form-blogs td input[type=checkbox]', '#form-blogs #do-action');
-  dotclear.responsiveCellHeaders(document.querySelector('#form-blogs table'), '#form-blogs table', 1);
-  $('#form-blogs').submit(function() {
-    const action = $(this).find('select[name="action"]').val();
-    if (action == 'delete') {
-      return window.confirm(dotclear.msg.confirm_delete_blog.replace('%s', $('input[name="blogs[]"]:checked').size()));
-    }
-  });
-});
Index: admin/js/_blogs_actions.js
===================================================================
--- admin/js/_blogs_actions.js	(revision 3706)
+++ 	(revision )
@@ -1,6 +1,0 @@
-/*global $, dotclear */
-'use strict';
-
-$(function() {
-  dotclear.condSubmit('table.blogs-list td input[type=checkbox]', 'input[type=submit]');
-});
Index: admin/js/_categories.js
===================================================================
--- admin/js/_categories.js	(revision 3706)
+++ admin/js/_categories.js	(revision 0)
@@ -1,26 +1,14 @@
-/*global $, dotclear */
-'use strict';
+/* TODO: Some nice drag and drop on categories */
+$(function() {
+	$('form#delete-category').submit(function() {
+		var c_id = $('#del_cat').val();
+		var c_name = $('#del_cat option[value='+c_id+']').text();
+		return window.confirm(dotclear.msg.confirm_delete_category.replace('%s',c_name));
+	});
+});
 
 $(function() {
-  if ($.fn.nestedSortable !== undefined) {
-    $('#categories ul li').css('cursor', 'move');
-    $('#save-set-order').prop('disabled', true).addClass('disabled');
-    $('#categories ul').nestedSortable({
-      listType: 'ul',
-      items: 'li',
-      placeholder: 'placeholder',
-      update: function() {
-        $('#categories_order').attr('value', JSON.stringify($('#categories ul').nestedSortable('toArray')));
-        $('#save-set-order').prop('disabled', false).removeClass('disabled');
-      }
-    });
-  }
-
-  $('input[name^="delete"]').click(function() {
-    return window.confirm(dotclear.msg.confirm_delete_category.replace('%s', $(this).parents('li').first().find('.cat-title label a').text()));
-  });
-
-  $('input[name="reset"]').click(function() {
-    return window.confirm(dotclear.msg.confirm_reorder_categories);
-  });
+	$('form#reset-order').submit(function() {
+		return window.confirm(dotclear.msg.confirm_reorder_categories);
+	});
 });
Index: admin/js/_category.js
===================================================================
--- admin/js/_category.js	(revision 3936)
+++ admin/js/_category.js	(revision 0)
@@ -1,11 +1,6 @@
-/*global $, dotclear, jsToolBar */
-'use strict';
-
 $(function() {
-  dotclear.hideLockable();
-
-  if (typeof jsToolBar !== 'undefined' && $.isFunction(jsToolBar)) {
-    const tbCategory = new jsToolBar(document.getElementById('cat_desc'));
-    tbCategory.draw('xhtml');
-  }
+	dotclear.hideLockable();
+	
+	var tbCategory = new jsToolBar(document.getElementById('cat_desc'));
+	tbCategory.draw('xhtml');
 });
Index: admin/js/_charte.js
===================================================================
--- admin/js/_charte.js	(revision 3991)
+++ 	(revision )
@@ -1,20 +1,0 @@
-/*global $ */
-'use strict';
-
-$(function() {
-  $.pageTabs('two-boxes');
-  $('#pageslist').sortable({
-    'cursor': 'move'
-  });
-  $('#pageslist tr').hover(function() {
-    $(this).css({
-      'cursor': 'move'
-    });
-  }, function() {
-    $(this).css({
-      'cursor': 'auto'
-    });
-  });
-  $('#pageslist tr td input.position').hide();
-  $('#pageslist tr td.handle').addClass('handler');
-});
Index: admin/js/_comment.js
===================================================================
--- admin/js/_comment.js	(revision 3936)
+++ admin/js/_comment.js	(revision 0)
@@ -1,11 +1,8 @@
-/*global $, dotclear, jsToolBar */
-'use strict';
-
 $(function() {
-  if (typeof jsToolBar !== 'undefined' && $.isFunction(jsToolBar)) {
-		const tbComment = new jsToolBar(document.getElementById('comment_content'));
-		tbComment.draw('xhtml');
-	}
-
+	if (!document.getElementById) { return; }
+	
+	var tbComment = new jsToolBar(document.getElementById('comment_content'));
+	tbComment.draw('xhtml');
+	
 	$('#comment-form input[name="delete"]').click(function() {
 		return window.confirm(dotclear.msg.confirm_delete_comment);
Index: admin/js/_comments.js
===================================================================
--- admin/js/_comments.js	(revision 4007)
+++ admin/js/_comments.js	(revision 0)
@@ -1,60 +1,85 @@
-/*global $, dotclear */
-'use strict';
+dotclear.commentExpander = function(line) {
+	var td = line.firstChild;
+	
+	var img = document.createElement('img');
+	img.src = dotclear.img_plus_src;
+	img.alt = dotclear.img_plus_alt;
+	img.className = 'expand';
+	$(img).css('cursor','pointer');
+	img.line = line;
+	img.onclick = function() { dotclear.viewCommentContent(this,this.line); };
+	
+	td.insertBefore(img,td.firstChild);
+};
 
-dotclear.viewCommentContent = function(line, action, e) {
-  action = action || 'toggle';
-  if ($(line).attr('id') == undefined) {
-    return;
-  }
-
-  const commentId = $(line).attr('id').substr(1);
-  const lineId = `ce${commentId}`;
-  let tr = document.getElementById(lineId);
-
-  // If meta key down or it's a spam then display content HTML code
-  const clean = (e.metaKey || $(line).hasClass('sts-junk'));
-
-  if (!tr) {
-    // Get comment content if possible
-    dotclear.getCommentContent(commentId, function(content) {
-      if (content) {
-        // Content found
-        tr = document.createElement('tr');
-        tr.id = lineId;
-        const td = document.createElement('td');
-        td.colSpan = $(line).children('td').length;
-        td.className = 'expand';
-        tr.appendChild(td);
-        $(td).append(content);
-        $(line).addClass('expand');
-        line.parentNode.insertBefore(tr, line.nextSibling);
-      } else {
-        // No content, content not found or server error
-        $(line).removeClass('expand');
-      }
-    }, {
-      clean: clean
-    });
-  } else {
-    $(tr).toggle();
-    $(line).toggleClass('expand');
-  }
+dotclear.viewCommentContent = function(img,line) {
+	var commentId = line.id.substr(1);
+	
+	var tr = document.getElementById('ce'+commentId);
+	
+	if (!tr) {
+		tr = document.createElement('tr');
+		tr.id = 'ce'+commentId;
+		var td = document.createElement('td');
+		td.colSpan = 6;
+		td.className = 'expand';
+		tr.appendChild(td);
+		
+		img.src = dotclear.img_minus_src;
+		img.alt = dotclear.img_minus_alt;
+		
+		// Get comment content
+		$.get('services.php',{f:'getCommentById',id: commentId},function(data) {
+			var rsp = $(data).children('rsp')[0];
+			
+			if (rsp.attributes[0].value == 'ok') {
+				var comment = $(rsp).find('comment_display_content').text();
+				
+				if (comment) {
+					$(td).append(comment);
+					var comment_email = $(rsp).find('comment_email').text();
+					var comment_site = $(rsp).find('comment_site').text();
+					var comment_ip = $(rsp).find('comment_ip').text();
+					var comment_spam_disp = $(rsp).find('comment_spam_disp').text();
+					
+					$(td).append('<p><strong>' + dotclear.msg.website +
+					'</strong> ' + comment_site + '<br />' +
+					'<strong>' + dotclear.msg.email + '</strong> ' + comment_email + '<br />' +
+					'<strong>' + dotclear.msg.ip_address +
+					'</strong> <a href="comments.php?ip=' + comment_ip + '">' + comment_ip + '</a>' +
+					'<br />' + comment_spam_disp + '</p>');
+				}
+			} else {
+				alert($(rsp).find('message').text());
+			}
+		});
+		
+		$(line).toggleClass('expand');
+		line.parentNode.insertBefore(tr,line.nextSibling);
+	}
+	else if (tr.style.display == 'none')
+	{
+		$(tr).toggle();
+		$(line).toggleClass('expand');
+		img.src = dotclear.img_minus_src;
+		img.alt = dotclear.img_minus_alt;
+	}
+	else
+	{
+		$(tr).toggle();
+		$(line).toggleClass('expand');
+		img.src = dotclear.img_plus_src;
+		img.alt = dotclear.img_plus_alt;
+	}
 };
 
 $(function() {
-  $.expandContent({
-    line: $('#form-comments tr:not(.line)'),
-    lines: $('#form-comments tr.line'),
-    callback: dotclear.viewCommentContent
-  });
-  $('.checkboxes-helpers').each(function() {
-    dotclear.checkboxesHelpers(this, undefined, '#form-comments td input[type=checkbox]', '#form-comments #do-action');
-  });
-  $('#form-comments td input[type=checkbox]').enableShiftClick();
-  dotclear.commentsActionsHelper();
-  dotclear.condSubmit('#form-comments td input[type=checkbox]', '#form-comments #do-action');
-  dotclear.responsiveCellHeaders(document.querySelector('#form-comments table'), '#form-comments table', 1);
-  $('form input[type=submit][name=delete_all_spam]').click(function() {
-    return window.confirm(dotclear.msg.confirm_spam_delete);
-  });
+	$('#form-comments tr.line').each(function() {
+		dotclear.commentExpander(this);
+	});
+	$('.checkboxes-helpers').each(function() {
+		dotclear.checkboxesHelpers(this);
+	});
+	$('#form-comments td input[type=checkbox]').enableShiftClick();
+	dotclear.commentsActionsHelper();
 });
Index: admin/js/_comments_actions.js
===================================================================
--- admin/js/_comments_actions.js	(revision 3706)
+++ 	(revision )
@@ -1,6 +1,0 @@
-/*global $, dotclear */
-'use strict';
-
-$(function() {
-	dotclear.condSubmit('table.posts-list td input[type=checkbox]','input[type=submit]');
-});
Index: admin/js/_index.js
===================================================================
--- admin/js/_index.js	(revision 3967)
+++ admin/js/_index.js	(revision 0)
@@ -1,265 +1,69 @@
-/*global $, dotclear, jsToolBar, getData */
-'use strict';
-
-dotclear.dbCommentsCount = function() {
-  const params = {
-    f: 'getCommentsCount',
-    xd_check: dotclear.nonce,
-  };
-  $.get('services.php', params, function(data) {
-    if ($('rsp[status=failed]', data).length > 0) {
-      // For debugging purpose only:
-      // console.log($('rsp',data).attr('message'));
-      window.console.log('Dotclear REST server error');
-    } else {
-      const nb = $('rsp>count', data).attr('ret');
-      if (nb != dotclear.dbCommentsCount_Counter) {
-        // First pass or counter changed
-        const icon = $('#dashboard-main #icons p a[href="comments.php"]');
-        if (icon.length) {
-          // Update count if exists
-          const nb_label = icon.children('span.db-icon-title');
-          if (nb_label.length) {
-            nb_label.text(nb);
-          }
-        }
-        // Store current counter
-        dotclear.dbCommentsCount_Counter = nb;
-      }
-    }
-  });
-};
-dotclear.dbPostsCount = function() {
-  const params = {
-    f: 'getPostsCount',
-    xd_check: dotclear.nonce,
-  };
-  $.get('services.php', params, function(data) {
-    if ($('rsp[status=failed]', data).length > 0) {
-      // For debugging purpose only:
-      // console.log($('rsp',data).attr('message'));
-      window.console.log('Dotclear REST server error');
-    } else {
-      const nb = $('rsp>count', data).attr('ret');
-      if (nb != dotclear.dbPostsCount_Counter) {
-        // First pass or counter changed
-        const icon = $('#dashboard-main #icons p a[href="posts.php"]');
-        if (icon.length) {
-          // Update count if exists
-          const nb_label = icon.children('span.db-icon-title');
-          if (nb_label.length) {
-            nb_label.text(nb);
-          }
-        }
-        // Store current counter
-        dotclear.dbPostsCount_Counter = nb;
-      }
-    }
-  });
-};
 $(function() {
-  function quickPost(f, status) {
-    if (typeof jsToolBar !== 'undefined' && $.isFunction(jsToolBar) && contentTb.getMode() == 'wysiwyg') {
-      contentTb.syncContents('iframe');
-    }
-
-    const params = {
-      f: 'quickPost',
-      xd_check: dotclear.nonce,
-      post_title: $('#post_title', f).val(),
-      post_content: $('#post_content', f).val(),
-      cat_id: $('#cat_id', f).val(),
-      post_status: status,
-      post_format: $('#post_format', f).val(),
-      post_lang: $('#post_lang', f).val(),
-      new_cat_title: $('#new_cat_title', f).val(),
-      new_cat_parent: $('#new_cat_parent', f).val()
-    };
-
-    $('p.qinfo', f).remove();
-
-    $.post('services.php', params, function(data) {
-      let msg;
-      if ($('rsp[status=failed]', data).length > 0) {
-        msg = '<p class="qinfo"><strong>' + dotclear.msg.error +
-          '</strong> ' + $('rsp', data).text() + '</p>';
-      } else {
-        msg = '<p class="qinfo">' + dotclear.msg.entry_created +
-          ' - <a href="post.php?id=' + $('rsp>post', data).attr('id') + '">' +
-          dotclear.msg.edit_entry + '</a>';
-        if ($('rsp>post', data).attr('post_status') == 1) {
-          msg += ' - <a href="' + $('rsp>post', data).attr('post_url') + '">' +
-            dotclear.msg.view_entry + '</a>';
-        }
-        msg += '</p>';
-        $('#post_title', f).val('');
-        $('#post_content', f).val('');
-        $('#post_content', f).change();
-        if (typeof jsToolBar !== 'undefined' && $.isFunction(jsToolBar) && contentTb.getMode() == 'wysiwyg') {
-          contentTb.syncContents('textarea');
-        }
-        $('#cat_id', f).val('0');
-        $('#new_cat_title', f).val('');
-        $('#new_cat_parent', f).val('0');
-      }
-
-      $('fieldset', f).prepend(msg);
-    });
-  }
-
-  const f = $('#quick-entry');
-  if (f.length > 0) {
-    if (typeof jsToolBar !== 'undefined' && $.isFunction(jsToolBar)) {
-      var contentTb = new jsToolBar($('#post_content', f)[0]);
-      contentTb.switchMode($('#post_format', f).val());
-    }
-
-    $('input[name=save]', f).click(function() {
-      quickPost(f, -2);
-      return false;
-    });
-
-    if ($('input[name=save-publish]', f).length > 0) {
-      var btn = $('<input type="submit" value="' + $('input[name=save-publish]', f).val() + '" />');
-      $('input[name=save-publish]', f).remove();
-      $('input[name=save]', f).after(btn).after(' ');
-      btn.click(function() {
-        quickPost(f, 1);
-        return false;
-      });
-    }
-
-    $('#new_cat').toggleWithLegend($('#new_cat').parent().children().not('#new_cat'), {
-      // no cookie on new category as we don't use this every day
-      legend_click: true
-    });
-  }
-
-  // allow to hide quick entry div, and remember choice
-  $('#quick h3').toggleWithLegend($('#quick').children().not('h3'), {
-    legend_click: true,
-    user_pref: 'dcx_quick_entry'
-  });
-
-  // check if core update available
-  let params = {
-    f: 'checkCoreUpdate',
-    xd_check: dotclear.nonce
-  };
-  $.post('services.php', params, function(data) {
-    if ($('rsp[status=failed]', data).length > 0) {
-      // Silently fail as a forced checked my be done with admin update page
-    } else {
-      if ($('rsp>update', data).attr('check') == 1) {
-        // Something has to be displayed
-        const xml = $('rsp>update', data).attr('ret');
-        $('#content h2').after(xml);
-        // manage outgoing links
-        dotclear.outgoingLinks('#ajax-update a');
-      }
-    }
-  });
-
-  // check if some news are available
-  params = {
-    f: 'checkNewsUpdate',
-    xd_check: dotclear.nonce
-  };
-  $.post('services.php', params, function(data) {
-    if ($('rsp[status=failed]', data).length > 0) {
-      // Silently fail
-    } else {
-      if ($('rsp>news', data).attr('check') == 1) {
-        // Something has to be displayed
-        const xml = $('rsp>news', data).attr('ret');
-        if ($('#dashboard-boxes').length == 0) {
-          // Create the #dashboard-boxes container
-          $('#dashboard-main').append('<div id="dashboard-boxes"></div>');
-        }
-        if ($('#dashboard-boxes div.db-items').length == 0) {
-          // Create the #dashboard-boxes div.db-items container
-          $('#dashboard-boxes').prepend('<div class="db-items"></div>');
-        }
-        $('#dashboard-boxes div.db-items').prepend(xml);
-        // manage outgoing links
-        dotclear.outgoingLinks('#ajax-news a');
-      }
-    }
-  });
-
-  // run counters' update on some dashboard icons
-  // Comments (including everything)
-  if ($('#dashboard-main #icons p a[href="comments.php"]').length) {
-    // Icon exists on dashboard
-    // First pass
-    dotclear.dbCommentsCount();
-    // Then fired every 60 seconds (1 minute)
-    dotclear.dbCommentsCount_Timer = setInterval(dotclear.dbCommentsCount, 60 * 1000);
-  }
-  // Posts
-  if ($('#dashboard-main #icons p a[href="posts.php"]').length) {
-    // Icon exists on dashboard
-    // First pass
-    dotclear.dbPostsCount();
-    // Then fired every 600 seconds (10 minutes)
-    dotclear.dbPostsCount_Timer = setInterval(dotclear.dbPostsCount, 600 * 1000);
-  }
-
-  if (!dotclear.data.noDragDrop) {
-    // Dashboard boxes and their children are sortable
-    const set_positions = function(sel, id) {
-      const list = $(sel).sortable("toArray").join();
-      // Save positions (via services) for id
-      const params = {
-        f: 'setDashboardPositions',
-        xd_check: dotclear.nonce,
-        id: id,
-        list: list
-      };
-      $.post('services.php', params, function() {});
-    };
-    const init_positions = function(sel, id) {
-      $(sel).sortable({
-        cursor: 'move',
-        opacity: 0.5,
-        delay: 200,
-        distance: 10,
-        tolerance: "pointer",
-        update: function() {
-          set_positions(sel, id);
-        },
-        start: function() {
-          $(sel).addClass('sortable-area');
-        },
-        stop: function() {
-          $(sel).removeClass('sortable-area');
-        }
-      });
-    };
-    const reset_positions = function(sel) {
-      $(sel).sortable('destroy');
-    };
-    // List of sortable areas
-    const areas = [
-      ['#dashboard-main', 'main_order'],
-      ['#dashboard-boxes', 'boxes_order'],
-      ['#db-items', 'boxes_items_order'],
-      ['#db-contents', 'boxes_contents_order']
-    ];
-    // Set or reset sortable depending on #dragndrop checbkox value
-    $('#dragndrop').click(function() {
-      Object.assign(dotclear, getData('dotclear_dragndrop'));
-      if ($(this).is(':checked')) {
-        // Activate sorting feature
-        areas.forEach(element => init_positions(element[0], element[1]));
-        $(this).prop('title', dotclear.dragndrop_on);
-        $('#dragndrop-label').text(dotclear.dragndrop_on);
-      } else {
-        // Deactivate sorting feature
-        areas.forEach(element => reset_positions(element[0]));
-        $(this).prop('title', dotclear.dragndrop_off);
-        $('#dragndrop-label').text(dotclear.dragndrop_off);
-      }
-    });
-  }
+	var f = $('#quick-entry');
+	if (f.length > 0) {
+		var contentTb = new jsToolBar($('#post_content',f)[0]);
+		contentTb.switchMode($('#post_format',f).val());
+		
+		$('input[name=save]',f).click(function() {
+			quickPost(f,-2);
+			return false;
+		});
+		
+		if ($('input[name=save-publish]',f).length > 0) {
+			var btn = $('<input type="submit" class="submit" value="' + $('input[name=save-publish]',f).val() + '" tabindex="3" />');
+			$('input[name=save-publish]',f).remove();
+			$('input[name=save]',f).after(btn).after(' ');
+			btn.click(function() {
+				quickPost(f,1);
+				return false;
+			});
+		}
+		
+		function quickPost(f,status) {
+			if (contentTb.getMode() == 'wysiwyg') {
+				contentTb.syncContents('iframe');
+			}
+			
+			var params = {
+				f: 'quickPost',
+				xd_check: dotclear.nonce,
+				post_title: $('#post_title',f).val(),
+				post_content: $('#post_content',f).val(),
+				cat_id: $('#cat_id',f).val(),
+				post_status: status,
+				post_format: $('#post_format',f).val(),
+				post_lang: $('#post_lang',f).val()
+			}
+			
+			$('p.qinfo',f).remove();
+			
+			$.post('services.php',params,function(data) {
+				if ($('rsp[status=failed]',data).length > 0) {
+					var msg = '<p class="qinfo"><strong>' + dotclear.msg.error +
+					'</strong> ' + $('rsp',data).text() + '</p>';
+				} else {
+					var msg = '<p class="qinfo">' + dotclear.msg.entry_created +
+					' - <a href="post.php?id=' + $('rsp>post',data).attr('id') + '">' +
+					dotclear.msg.edit_entry + '</a>';
+					if ($('rsp>post',data).attr('post_status') == 1) {
+						msg += ' - <a href="' + $('rsp>post',data).attr('post_url') + '">' +
+						dotclear.msg.view_entry + '</a>';
+					}
+					msg += '</p>';
+					$('#post_title',f).val('');
+					$('#post_content',f).val('');
+					if (contentTb.getMode() == 'wysiwyg') {
+						contentTb.syncContents('textarea');
+					}
+				}
+				
+				$('fieldset',f).prepend(msg);
+			});
+		}
+	}
+	
+	// allow to hide quick entry div, and remember choice
+	$('#quick h3').toggleWithLegend($('#quick').children().not('h3'),{
+		cookie: 'dcx_quick_entry',
+	});
 });
Index: admin/js/_install.js
===================================================================
--- admin/js/_install.js	(revision 3986)
+++ 	(revision )
@@ -1,27 +1,0 @@
-/*global $, getData */
-'use strict';
-
-$(function() {
-  const login_re = new RegExp('[^A-Za-z0-9@._-]+', 'g');
-  $('#u_firstname').keyup(function() {
-    $('#u_login').val(this.value.toLowerCase().replace(login_re, '').substring(0, 32));
-  });
-  $('#u_login').keyup(function() {
-    $(this).val(this.value.replace(login_re, ''));
-  });
-
-  const texts = getData('install');
-  $('#u_pwd').pwstrength({
-    texts: texts
-  });
-
-  $('#u_login').parent().after($('<input type="hidden" name="u_date" value="' + Date().toLocaleString() + '" />'));
-
-  const show = getData('install_show');
-  const password_link = $('<a href="#" id="obfus">' + show + '</a>').click(function() {
-    $('#password').show();
-    $(this).remove();
-    return false;
-  });
-  $('#password').hide().before(password_link);
-});
Index: admin/js/_langs.js
===================================================================
--- admin/js/_langs.js	(revision 3880)
+++ admin/js/_langs.js	(revision 0)
@@ -1,8 +1,5 @@
-/*global $, dotclear */
-'use strict';
-
 $(function() {
 	$('table.plugins form input[type=submit][name=delete]').click(function() {
-		const l_name = $(this).parents('tr.line').find('td:first').text();
+		var l_name = $(this).parents('tr.line').find('td:first').text();
 		return window.confirm(dotclear.msg.confirm_delete_lang.replace('%s',l_name));
 	});
Index: admin/js/_media.js
===================================================================
--- admin/js/_media.js	(revision 3989)
+++ admin/js/_media.js	(revision 0)
@@ -1,222 +1,80 @@
-/*global $, jQuery, dotclear, template_upload, template_download */
-'use strict';
-
-(function($) {
-  $.fn.enhancedUploader = function() {
-    return this.each(function() {
-      const me = $(this);
-      const $container = $(me).parent();
-
-      function enableButton(button) {
-        button.prop('disabled', false).removeClass('disabled');
-      }
-
-      function disableButton(button) {
-        button.prop('disabled', true).addClass('disabled');
-      }
-
-      function displayMessageInQueue(n) {
-        let msg = '';
-        if (n == 1) {
-          msg = dotclear.jsUpload.msg.file_in_queue;
-        } else if (n > 1) {
-          msg = dotclear.jsUpload.msg.files_in_queue;
-          msg = msg.replace(/%d/, n);
-        } else {
-          msg = dotclear.jsUpload.msg.no_file_in_queue;
-        }
-        $('.queue-message', me).html(msg);
-      }
-
-      $('.button.choose_files').click(function(e) {
-        if ($container.hasClass('enhanced_uploader')) {
-          // Use the native click() of the file input.
-          $('#upfile').click();
-          e.preventDefault();
-        }
-      });
-
-      $('.button.cancel', '#fileupload .fileupload-buttonbar').click(function() {
-        $('.button.cancel', '#fileupload .fileupload-buttonbar').hide();
-        disableButton($('.button.start', '#fileupload .fileupload-buttonbar'));
-        displayMessageInQueue(0);
-      });
-
-      $(me).on('click', '.cancel', function() {
-        if ($('.fileupload-ctrl .files .template-upload', me).length == 0) {
-          $('.button.cancel', '#fileupload .fileupload-buttonbar').hide();
-          disableButton($('.button.start', '#fileupload .fileupload-buttonbar'));
-        }
-        displayMessageInQueue($('.files .template-upload', me).length);
-      });
-
-      $('.button.clean', me).click(function(e) {
-        $('.fileupload-ctrl .files .template-download', me).slideUp(500, function() {
-          $(this).remove();
-        });
-        $(this).hide();
-        e.preventDefault();
-      });
-
-      $(me).fileupload({
-        url: $(me).attr('action'),
-        autoUpload: false,
-        sequentialUploads: true,
-        uploadTemplateId: null,
-        downloadTemplateId: null,
-        uploadTemplate: template_upload,
-        downloadTemplate: template_download
-      }).bind('fileuploadadd', function() {
-        $('.button.cancel').css('display', 'inline-block');
-        $('#fileupload .fileupload-buttonbar').show();
-        enableButton($('.button.start', '#fileupload .fileupload-buttonbar'));
-      }).bind('fileuploadadded', function() {
-        displayMessageInQueue($('.files .template-upload', me).length);
-      }).bind('fileuploaddone', function(e, data) {
-        if (data.result.files[0].html !== undefined) {
-          $('.media-list .files-group').append(data.result.files[0].html);
-          $('#form-medias .hide').removeClass('hide');
-        }
-        $('.button.clean').css('display', 'inline-block');
-        $(me).show();
-      }).bind('fileuploadalways', function() {
-        displayMessageInQueue($('.files .template-upload', me).length);
-        if ($('.fileupload-ctrl .files .template-upload', me).length == 0) {
-          $('.button.cancel', '#fileupload .fileupload-buttonbar').hide();
-          disableButton($('.button.start', '#fileupload .fileupload-buttonbar'));
-        }
-      });
-
-      let $msg;
-      let label;
-
-      if ($container.hasClass('enhanced_uploader')) {
-        $msg = dotclear.msg.enhanced_uploader_disable;
-        label = dotclear.jsUpload.msg.choose_files;
-        $(me).fileupload({
-          disabled: false
-        });
-        displayMessageInQueue(0);
-        disableButton($('.button.start', '#fileupload .fileupload-buttonbar'));
-      } else {
-        $msg = dotclear.msg.enhanced_uploader_activate;
-        label = dotclear.jsUpload.msg.choose_file;
-        $(me).fileupload({
-          disabled: true
-        });
-      }
-
-      $(`<p class="clear"><button type="button" class="enhanced-toggle">${$msg}</button></p>`).click(function(e) {
-        if ($container.hasClass('enhanced_uploader')) {
-          $msg = dotclear.msg.enhanced_uploader_activate;
-          label = dotclear.jsUpload.msg.choose_file;
-          $('#upfile').attr('multiple', false);
-          enableButton($('.button.start', '#fileupload .fileupload-buttonbar'));
-
-          // when a user has clicked enhanced_uploader, and has added files
-          // We must remove files in table
-          $('.files .upload-file', me).remove();
-          $('.button.cancel,.button.clean', '#fileupload .fileupload-buttonbar').hide();
-          $(me).fileupload({
-            disabled: true
-          });
-          $('.queue-message', me).html('').hide();
-        } else {
-          $msg = dotclear.msg.enhanced_uploader_disable;
-          label = dotclear.jsUpload.msg.choose_files;
-          $('#upfile').attr('multiple', true);
-          const startButton = $('.button.start');
-          const buttonBar = $('#fileupload .fileupload-buttonbar');
-          disableButton(startButton);
-          disableButton(buttonBar);
-          startButton.css('display', 'inline-block');
-          buttonBar.show();
-          $(me).fileupload({
-            disabled: false
-          });
-          $('.queue-message', me).show();
-          displayMessageInQueue(0);
-        }
-        $(this).find('button').text($msg);
-        $('.add-label', me).text(label);
-
-        $container.toggleClass('enhanced_uploader');
-        e.preventDefault();
-      }).appendTo(me);
-    });
-  };
-})(jQuery);
-
 $(function() {
-  $('#fileupload').enhancedUploader();
-
-  $('.checkboxes-helpers').each(function() {
-    dotclear.checkboxesHelpers(this, undefined, '#form-medias input[type="checkbox"]', '#form-medias #delete_medias');
-  });
-  dotclear.condSubmit('#form-medias input[type="checkbox"]', '#form-medias #delete_medias');
-
-  $('#form-medias #delete_medias').click(function(e) {
-    const count_checked = $('input[name="medias[]"]:checked', $('#form-medias')).length;
-    if (count_checked == 0) {
-      e.preventDefault();
-      return false;
-    }
-    return window.confirm(dotclear.msg.confirm_delete_medias.replace('%d', count_checked));
-  });
-
-  // Preview media
-  $('.modal-image').magnificPopup({
-    type: 'image'
-  });
-
-  // attach media
-  $('#form-medias').on('click', '.media-item .attach-media', function(e) {
-    const parts = $(this).prop('href').split('?');
-    const str_params = parts[1].split('&');
-    let postData = {};
-
-    for (let n = 0; n < str_params.length; n++) {
-      const kv = str_params[n].split('=');
-      postData[kv[0]] = kv[1];
-    }
-    postData.xd_check = dotclear.nonce;
-
-    $.post(parts[0], postData, function(data) {
-      if (data.url !== undefined) {
-        document.location = data.url;
-      }
-    });
-
-    e.preventDefault();
-  });
-
-  // Replace remove links by a POST on hidden form
-  fileRemoveAct();
-
-  function fileRemoveAct() {
-    $('body').on('click', 'a.media-remove', function() {
-      const m_name = $(this).parents('.media-item').find('a.media-link').text();
-      let m_text = '';
-      if ($(this).parents('div.media-folder').length == 0) {
-        m_text = dotclear.msg.confirm_delete_media.replace('%s', m_name);
-      } else {
-        m_text = dotclear.msg.confirm_delete_directory.replace('%s', m_name);
-      }
-      if (window.confirm(m_text)) {
-        const f = $('#media-remove-hide').get(0);
-        f.elements.remove.value = this.href.replace(/^(.*)&remove=(.*?)(&|$)/, '$2');
-        this.href = '';
-        f.submit();
-      }
-      return false;
-    });
-  }
-
-  // Switch folder
-  const urlmenu = document.getElementById('switchfolder');
-  if (urlmenu) {
-    urlmenu.onchange = function() {
-      window.location = this.options[this.selectedIndex].value;
-    };
-  }
+	// Replace remove links by a POST on hidden form
+	fileRemoveAct();
+	
+	function fileRemoveAct() {
+		$('a.media-remove').click(function() {
+			var m_name = $(this).parents('ul').find('li:first>a').text();
+			if (window.confirm(dotclear.msg.confirm_delete_media.replace('%s',m_name))) {
+				var f = $('#media-remove-hide').get(0);
+				f.elements['remove'].value = this.href.replace(/^(.*)&remove=(.*?)(&|$)/,'$2');
+				this.href = '';
+				f.submit();
+			}
+			return false;
+		});
+	}
+	
+	if (!$.browser.opera) {
+		var upldr = $('<a href="#">' + dotclear.msg.activate_enhanced_uploader + '</a>')
+		.click(function() {
+			candyUploadInit();
+			return false;
+		});
+		$('#media-upload>fieldset').append($('<div></div>').append(upldr));
+		
+		if ($.cookie('dc_candy_upl') == 1) {
+			candyUploadInit();
+		}
+	}
+	
+	function candyUploadInit()
+	{
+		var candy_upload_success = false;
+		var candy_upload_form_url = $('#media-upload').attr('action') + '&file_sort=date-desc&d=' + $('#media-upload input[name=d]').val();
+		var candy_upload_limit = $('#media-upload input[name=MAX_FILE_SIZE]').val();
+		$('#media-upload').candyUpload({
+			upload_url: dotclear.candyUpload.base_url + '/media.php',
+			flash_movie: dotclear.candyUpload.movie_url,
+			file_size_limit: candy_upload_limit + 'b',
+			params: 'swfupload=1&amp;' + dotclear.candyUpload.params,
+			
+			callbacks: {
+				createControls: function() {
+					var _this = this;
+					var l = $('<a href="#">' + dotclear.msg.disable_enhanced_uploader + '</a>').click(function() {
+						_this.upldr.destroy();
+						_this.ctrl.block.empty().remove();
+						$('#media-upload').show();
+						delete _this;
+						$.cookie('dc_candy_upl','',{expires: -1});
+						return false;
+					});
+					this.ctrl.disable = $('<div class="cu-disable"></div>').append(l).appendTo(this.ctrl.block);
+				},
+				flashReady: function() {
+					this.ctrl.btn_browse.addClass('button');
+					this.ctrl.block.append(this.ctrl.disable);
+				},
+				uploadSuccess: function(o,data) {
+					if (data == 'ok') {
+						candy_upload_success = true;
+						this.fileMsg(o.id,this.locales.file_uploaded);
+					} else {
+						this.fileErrorMsg(o.id,data);
+					}
+					
+					// uploads finished and at least one success
+					if (candy_upload_success && $('div.cu-file:has(span.cu-filecancel a)',this.ctrl.files).length == 0) {
+						$.cookie('dc_candy_upl','1',{expires: 30});
+						$.get(candy_upload_form_url,function(data) {
+							var media = $('div.media-list');
+							media.after($('div.media-list',data)).remove();
+							fileRemoveAct();
+						});
+					}
+				}
+			}
+		});
+	}
 });
Index: admin/js/_media_item.js
===================================================================
--- admin/js/_media_item.js	(revision 3957)
+++ admin/js/_media_item.js	(revision 0)
@@ -1,96 +1,65 @@
-/*global $, dotclear, datePicker */
-'use strict';
-
 $(function() {
-  // Add datePicker if possible
-  const media_dt = document.getElementById('media_dt');
-  if (media_dt != undefined) {
-    const post_dtPick = new datePicker(media_dt);
-    post_dtPick.img_top = '1.5em';
-    post_dtPick.draw();
-  }
-
-  // Preview media
-  $('.modal-image').magnificPopup({
-    type: 'image'
-  });
-
-  // Display zip file content
-  $('#file-unzip').each(function() {
-    const a = document.createElement('a');
-    const mediaId = $(this).find('input[name=id]').val();
-    const This = $(this);
-
-    a.href = '#';
-    $(a).text(dotclear.msg.zip_file_content);
-    This.before(a);
-    $(a).wrap('<p></p>');
-
-    $(a).click(function() {
-      $.get('services.php', {
-        f: 'getZipMediaContent',
-        id: mediaId
-      }, function(data) {
-        const rsp = $(data).children('rsp')[0];
-
-        if (rsp.attributes[0].value == 'ok') {
-          const div = document.createElement('div');
-          const list = document.createElement('ul');
-          let expanded = false;
-
-          $(div).css({
-            overflow: 'auto',
-            margin: '1em 0',
-            padding: '1px 0.5em'
-          });
-          $(div).addClass('color-div');
-          $(div).append(list);
-          This.before(div);
-          $(a).hide();
-          $(div).before('<h3>' + dotclear.msg.zip_file_content + '</h3>');
-
-          $(rsp).find('file').each(function() {
-            $(list).append('<li>' + $(this).text() + '</li>');
-            if ($(div).height() > 200 && !expanded) {
-              $(div).css({
-                height: '200px'
-              });
-              expanded = true;
-            }
-          });
-        } else {
-          window.alert($(rsp).find('message').text());
-        }
-      });
-      return false;
-    });
-  });
-
-  // Confirm for inflating in current directory
-  $('#file-unzip').submit(function() {
-    if ($(this).find('#inflate_mode').val() == 'current') {
-      return window.confirm(dotclear.msg.confirm_extract_current);
-    }
-    return true;
-  });
-
-  // Confirm for deleting current medoa
-  $('#delete-form input[name="delete"]').click(function() {
-    let m_name = $('#delete-form input[name="remove"]').val();
-    return window.confirm(dotclear.msg.confirm_delete_media.replace('%s', m_name));
-  });
-
-  // Get current insertion settings
-  $('#save_settings').submit(function() {
-    $('input[name="pref_src"]').val($('input[name="src"][type=radio]:checked').attr('value'));
-    $('input[name="pref_alignment"]').val($('input[name="alignment"][type=radio]:checked').attr('value'));
-    $('input[name="pref_insertion"]').val($('input[name="insertion"][type=radio]:checked').attr('value'));
-    $('input[name="pref_legend"]').val($('input[name="legend"][type=radio]:checked').attr('value'));
-  });
-
-  // Set focus if in popup mode
-  $('#media-insert-form :input:visible:enabled:checked:first, #media-insert-form :input:visible:enabled:first').focus();
-
-  // Deal with enter key on media insert popup form : every form element will be filtered but Cancel button
-  dotclear.enterKeyInForm('#media-insert-form', '#media-insert-ok', '#media-insert-cancel');
+	$('#media-details-tab').onetabload(function() {
+		// Add date picker
+		var media_dt = document.getElementById('media_dt');
+		if (media_dt == undefined) { return; }
+		var post_dtPick = new datePicker(media_dt);
+		post_dtPick.img_top = '1.5em';
+		post_dtPick.draw();
+	});
+	
+	// Display zip file content
+	$('#file-unzip').each(function() {
+		var a = document.createElement('a');
+		var mediaId = $(this).find('input[name=id]').val();
+		var self = $(this);
+		
+		a.href = '#';
+		$(a).text(dotclear.msg.zip_file_content);
+		self.before(a);
+		$(a).wrap('<p></p>');
+		
+		$(a).click(function() {
+			$.get('services.php',{f:'getZipMediaContent',id: mediaId},function(data) {
+				var rsp = $(data).children('rsp')[0];
+				
+				if (rsp.attributes[0].value == 'ok') {
+					var div = document.createElement('div');
+					var list = document.createElement('ul');
+					var expanded = false;
+					
+					$(div).css({
+						overflow: 'auto',
+						border: '1px solid #ccc',
+						margin: '1em 0',
+						padding: '1px 0.5em'
+					});
+					
+					$(div).append(list);
+					self.before(div);
+					$(a).hide();
+					$(div).before('<h3>' + dotclear.msg.zip_file_content + '</h3>');
+					
+					$(rsp).find('file').each(function() {
+						$(list).append('<li>' + $(this).text() + '</li>');
+						if ($(div).height() > 200 && !expanded) {
+							$(div).css({height: '200px'});
+							expanded = true;
+						}
+					});
+				} else {
+					alert($(rsp).find('message').text());
+				}
+			});
+			return false;
+		});
+	});
+	
+	// Confirm for inflating in current directory
+	$('#file-unzip').submit(function() {
+		if ($(this).find('#inflate_mode').val() == 'current') {
+			return window.confirm(dotclear.msg.confirm_extract_current);
+		}
+		return true;
+	});
 });
Index: admin/js/_permissions.js
===================================================================
--- admin/js/_permissions.js	(revision 0)
+++ admin/js/_permissions.js	(revision 0)
@@ -0,0 +1,56 @@
+jQuery.fn.updatePermissionsForm = function() {
+	return this.each(function() {
+		var perms = {};
+		var re = /^perm\[(.+?)\]\[(.+?)\]$/;
+		var e,prop;
+		
+		// Building a nice object of form elements
+		for (var i=0; i<this.elements.length; i++) {
+			e = this.elements[i];
+			
+			if (e.name == undefined) {
+				continue;
+			}
+			prop = e.name.match(re);
+			if (!prop) {
+				continue;
+			}
+			if (perms[prop[1]] == undefined) {
+				perms[prop[1]] = {};
+			}
+			perms[prop[1]][prop[2]] = e;
+		}
+		
+		// Update elements status
+		var E;
+		for (blog in perms) {
+			for (perm in perms[blog]) {
+				E = perms[blog][perm];
+				E.onclick = function() {};
+				
+				if (perm == 'admin' && !E.disabled) {
+					perms[blog]['usage'].disabled = E.checked;
+					perms[blog]['publish'].disabled = E.checked;
+					perms[blog]['delete'].disabled = E.checked;
+					perms[blog]['contentadmin'].disabled = E.checked;
+					perms[blog]['categories'].disabled = E.checked;
+					perms[blog]['media'].disabled = E.checked;
+					perms[blog]['media_admin'].disabled = E.checked;
+					E.onclick = function() { $(this.form).updatePermissionsForm(); };
+				} else if (perm == 'contentadmin' && !E.disabled) {
+					perms[blog]['usage'].disabled = E.checked;
+					perms[blog]['publish'].disabled = E.checked;
+					perms[blog]['delete'].disabled = E.checked;
+					E.onclick = function() { $(this.form).updatePermissionsForm(); };
+				} else if (perm == 'media_admin' && !E.disabled) {
+					perms[blog]['media'].disabled = E.checked;
+					E.onclick = function() { $(this.form).updatePermissionsForm(); };
+				}
+			}
+		}
+	});
+};
+
+$(function() {
+	$('#permissions-form').updatePermissionsForm();
+});
Index: admin/js/_permissions_blog.js
===================================================================
--- admin/js/_permissions_blog.js	(revision 0)
+++ admin/js/_permissions_blog.js	(revision 0)
@@ -0,0 +1,5 @@
+$(function() {
+	$('.checkboxes-helpers').each(function() {
+		dotclear.checkboxesHelpers(this);
+	});
+});
Index: admin/js/_plugins.js
===================================================================
--- admin/js/_plugins.js	(revision 3880)
+++ admin/js/_plugins.js	(revision 0)
@@ -1,73 +1,6 @@
-/*global $, dotclear */
-'use strict';
-
 $(function() {
-  // expand a module line
-  $('table.modules.expandable tr.line').each(function() {
-    $('td.module-name, th.module-name', this).toggleWithLegend($(this).next('.module-more'), {
-      img_on_txt: dotclear.img_plus_txt,
-      img_on_alt: dotclear.img_plus_alt,
-      img_off_txt: dotclear.img_minus_txt,
-      img_off_alt: dotclear.img_minus_alt,
-      legend_click: true
-    });
-  });
-
-  // checkboxes selection
-  $('.checkboxes-helpers').each(function() {
-    dotclear.checkboxesHelpers(this);
-  });
-
-  // actions tests
-  $('.modules-form-actions').each(function() {
-    const rxActionType = /^[^\[]+/;
-    const rxActionValue = /([^\[]+)\]$/;
-    const checkboxes = $(this).find('input[type=checkbox]');
-
-    // check if submit is a global action or one line action
-    $('input[type=submit]', this).click(function() {
-      const keyword = $(this).attr('name');
-      if (!keyword) {
-        return true;
-      }
-      const maction = keyword.match(rxActionType);
-      const action = maction[0];
-      const mvalues = keyword.match(rxActionValue);
-
-      // action on multiple modules
-      if (!mvalues) {
-        let checked = false;
-
-        // check if there is checkboxes in form
-        if (checkboxes.length > 0) {
-          // check if there is at least one checkbox checked
-          $(checkboxes).each(function() {
-            if (this.checked) {
-              checked = true;
-            }
-          });
-          if (!checked) {
-            //alert(dotclear.msg.no_selection);
-            return false;
-          }
-        }
-
-        // confirm delete
-        if (action == 'delete') {
-          return window.confirm(dotclear.msg.confirm_delete_plugins);
-        }
-
-        // action on one module
-      } else {
-        const module = mvalues[1];
-
-        // confirm delete
-        if (action == 'delete') {
-          return window.confirm(dotclear.msg.confirm_delete_plugin.replace('%s', module));
-        }
-      }
-
-      return true;
-    });
-  });
+	$('table.plugins form input[type=submit][name=delete]').click(function() {
+		var p_name = $('input[name=plugin_id]',$(this).parent()).val();
+		return window.confirm(dotclear.msg.confirm_delete_plugin.replace('%s',p_name));
+	});
 });
Index: admin/js/_popup_link.js
===================================================================
--- admin/js/_popup_link.js	(revision 3725)
+++ 	(revision )
@@ -1,18 +1,0 @@
-/*global $, dotclear */
-'use strict';
-
-$(function() {
-  // Enable submet button only if mandotory field is not empty
-  $('#link-insert-ok').prop('disabled', true);
-  $('#link-insert-ok').addClass('disabled');
-  $('#href').keyup(function() {
-    $('#link-insert-ok').prop('disabled', (this.value == '' ? true : false));
-    $('#link-insert-ok').toggleClass('disabled', (this.value == '' ? true : false));
-  });
-
-  // Set focus on #href input
-  $('#href').focus();
-
-  // Deal with enter key on link insert popup form : every form element will be filtered but Cancel button
-  dotclear.enterKeyInForm('#link-insert-form', '#link-insert-ok', '#link-insert-cancel');
-});
Index: admin/js/_popup_posts.js
===================================================================
--- admin/js/_popup_posts.js	(revision 3706)
+++ 	(revision )
@@ -1,7 +1,0 @@
-/*global $ */
-'use strict';
-
-$(function() {
-  // Set focus on #type input
-  $('#type').focus();
-});
Index: admin/js/_post.js
===================================================================
--- admin/js/_post.js	(revision 3880)
+++ admin/js/_post.js	(revision 0)
@@ -1,184 +1,231 @@
-/*global $, dotclear, datePicker, commentTb */
-'use strict';
+dotclear.commentExpander = function(line) {
+	var td = line.firstChild;
+	
+	var img = document.createElement('img');
+	img.src = dotclear.img_plus_src;
+	img.alt = dotclear.img_plus_alt;
+	img.className = 'expand';
+	$(img).css('cursor','pointer');
+	img.line = line;
+	img.onclick = function() { dotclear.viewCommentContent(this,this.line); };
+	
+	td.insertBefore(img,td.firstChild);
+};
 
-dotclear.viewCommentContent = function(line, action, e) {
-  action = action || 'toggle';
-  if ($(line).attr('id') == undefined) {
-    return;
-  }
-
-  const commentId = $(line).attr('id').substr(1);
-  const lineId = `ce${commentId}`;
-  let tr = document.getElementById(lineId);
-
-  // If meta key down or it's a spam then display content HTML code
-  const clean = (e.metaKey || $(line).hasClass('sts-junk'));
-
-  if (!tr) {
-    // Get comment content
-    dotclear.getCommentContent(commentId, function(content) {
-      if (content) {
-        // Content found
-        tr = document.createElement('tr');
-        tr.id = lineId;
-        const td = document.createElement('td');
-        td.colSpan = $(line).children('td').length;
-        td.className = 'expand';
-        tr.appendChild(td);
-        $(td).append(content);
-        $(line).addClass('expand');
-        line.parentNode.insertBefore(tr, line.nextSibling);
-      } else {
-        // No content, content not found or server error
-        $(line).removeClass('expand');
-      }
-    }, {
-      ip: false,
-      clean: clean
-    });
-  } else {
-    $(tr).toggle();
-    $(line).toggleClass('expand');
-  }
+dotclear.viewCommentContent = function(img,line) {
+	var commentId = line.id.substr(1);
+	
+	var tr = document.getElementById('ce'+commentId);
+	
+	if (!tr) {
+		tr = document.createElement('tr');
+		tr.id = 'ce'+commentId;
+		var td = document.createElement('td');
+		td.colSpan = 6;
+		td.className = 'expand';
+		tr.appendChild(td);
+		
+		img.src = dotclear.img_minus_src;
+		img.alt = dotclear.img_minus_alt;
+		
+		// Get comment content
+		$.get('services.php',{f:'getCommentById',id: commentId},function(data) {
+			var rsp = $(data).children('rsp')[0];
+			
+			if (rsp.attributes[0].value == 'ok') {
+				var comment = $(rsp).find('comment_display_content').text();
+				
+				if (comment) {
+					$(td).append(comment);
+					var comment_email = $(rsp).find('comment_email').text();
+					var comment_site = $(rsp).find('comment_site').text();
+					var comment_ip = $(rsp).find('comment_ip').text();
+					var comment_spam_disp = $(rsp).find('comment_spam_disp').text();
+					
+					$(td).append('<p><strong>' + dotclear.msg.website +
+					'</strong> ' + comment_site + '<br />' +
+					'<strong>' + dotclear.msg.email + '</strong> ' +
+					comment_email + '<br />' + comment_spam_disp + '</p>');
+				}
+			} else {
+				alert($(rsp).find('message').text());
+			}
+		});
+		
+		$(line).toggleClass('expand');
+		line.parentNode.insertBefore(tr,line.nextSibling);
+	}
+	else if (tr.style.display == 'none')
+	{
+		$(tr).toggle();
+		$(line).toggleClass('expand');
+		img.src = dotclear.img_minus_src;
+		img.alt = dotclear.img_minus_alt;
+	}
+	else
+	{
+		$(tr).toggle();
+		$(line).toggleClass('expand');
+		img.src = dotclear.img_plus_src;
+		img.alt = dotclear.img_plus_alt;
+	}
 };
 
 $(function() {
-  // Post preview
-  let $preview_url = $('#post-preview').attr('href');
-  if ($preview_url) {
-
-    // Make $preview_url absolute
-    let $a = document.createElement('a');
-    $a.href = $('#post-preview').attr('href');
-    $preview_url = $a.href;
-
-    // Check if admin and blog have same protocol (ie not mixed-content)
-    if (window.location.protocol == $preview_url.substring(0, window.location.protocol.length)) {
-      // Open preview in a modal iframe
-      $('#post-preview').magnificPopup({
-        type: 'iframe',
-        iframe: {
-          patterns: {
-            dotclear_preview: {
-              index: $preview_url,
-              src: $preview_url
-            }
-          }
-        }
-      });
-    } else {
-      // Open preview on antother window
-      $('#post-preview').click(function(e) {
-        e.preventDefault();
-        window.open($(this).attr('href'));
-      });
-    }
-  }
-
-  // Tabs events
-  $('#edit-entry').onetabload(function() {
-    dotclear.hideLockable();
-
-    // Add date picker
-    const post_dtPick = new datePicker($('#post_dt').get(0));
-    post_dtPick.img_top = '1.5em';
-    post_dtPick.draw();
-
-    // Confirm post deletion
-    $('input[name="delete"]').click(function() {
-      return window.confirm(dotclear.msg.confirm_delete_post);
-    });
-
-    // Hide some fields
-    $('#notes-area label').toggleWithLegend($('#notes-area').children().not('label'), {
-      user_pref: 'dcx_post_notes',
-      legend_click: true,
-      hide: $('#post_notes').val() == ''
-    });
-    $('#post_lang').parent().children('label').toggleWithLegend($('#post_lang'), {
-      user_pref: 'dcx_post_lang',
-      legend_click: true
-    });
-    $('#post_password').parent().children('label').toggleWithLegend($('#post_password'), {
-      user_pref: 'dcx_post_password',
-      legend_click: true,
-      hide: $('#post_password').val() == ''
-    });
-    $('#post_status').parent().children('label').toggleWithLegend($('#post_status'), {
-      user_pref: 'dcx_post_status',
-      legend_click: true
-    });
-    $('#post_dt').parent().children('label').toggleWithLegend($('#post_dt').parent().children().not('label'), {
-      user_pref: 'dcx_post_dt',
-      legend_click: true
-    });
-    $('#label_format').toggleWithLegend($('#label_format').parent().children().not('#label_format'), {
-      user_pref: 'dcx_post_format',
-      legend_click: true
-    });
-    $('#label_cat_id').toggleWithLegend($('#label_cat_id').parent().children().not('#label_cat_id'), {
-      user_pref: 'dcx_cat_id',
-      legend_click: true
-    });
-    $('#create_cat').toggleWithLegend($('#create_cat').parent().children().not('#create_cat'), {
-      // no cookie on new category as we don't use this every day
-      legend_click: true
-    });
-    $('#label_comment_tb').toggleWithLegend($('#label_comment_tb').parent().children().not('#label_comment_tb'), {
-      user_pref: 'dcx_comment_tb',
-      legend_click: true
-    });
-    $('#post_url').parent().children('label').toggleWithLegend($('#post_url').parent().children().not('label'), {
-      user_pref: 'post_url',
-      legend_click: true
-    });
-    // We load toolbar on excerpt only when it's ready
-    $('#excerpt-area label').toggleWithLegend($('#excerpt-area').children().not('label'), {
-      user_pref: 'dcx_post_excerpt',
-      legend_click: true,
-      hide: $('#post_excerpt').val() == ''
-    });
-
-    // Replace attachment remove links by a POST form submit
-    $('a.attachment-remove').click(function() {
-      this.href = '';
-      const m_name = $(this).parents('ul').find('li:first>a').attr('title');
-      if (window.confirm(dotclear.msg.confirm_remove_attachment.replace('%s', m_name))) {
-        var f = $('#attachment-remove-hide').get(0);
-        f.elements.media_id.value = this.id.substring(11);
-        f.submit();
-      }
-      return false;
-    });
-  });
-
-  $('#comments').onetabload(function() {
-    $.expandContent({
-      line: $('#form-comments .comments-list tr:not(.line)'),
-      lines: $('#form-comments .comments-list tr.line'),
-      callback: dotclear.viewCommentContent
-    });
-    $('#form-comments .checkboxes-helpers').each(function() {
-      dotclear.checkboxesHelpers(this);
-    });
-
-    dotclear.commentsActionsHelper();
-  });
-
-  $('#trackbacks').onetabload(function() {
-    $.expandContent({
-      line: $('#form-trackbacks .comments-list tr:not(.line)'),
-      lines: $('#form-trackbacks .comments-list tr.line'),
-      callback: dotclear.viewCommentContent
-    });
-    $('#form-trackbacks .checkboxes-helpers').each(function() {
-      dotclear.checkboxesHelpers(this);
-    });
-
-    dotclear.commentsActionsHelper();
-  });
-
-  $('#add-comment').onetabload(function() {
-    commentTb.draw('xhtml');
-  });
+	if (!document.getElementById) { return; }
+	
+	if (document.getElementById('edit-entry'))
+	{
+		// Get document format and prepare toolbars
+		var formatField = $('#post_format').get(0);
+		$(formatField).change(function() {
+			excerptTb.switchMode(this.value);
+			contentTb.switchMode(this.value);
+		});
+		
+		var excerptTb = new jsToolBar(document.getElementById('post_excerpt'));
+		var contentTb = new jsToolBar(document.getElementById('post_content'));
+		excerptTb.context = contentTb.context = 'post';
+	}
+	
+	if (document.getElementById('comment_content')) {
+		var commentTb = new jsToolBar(document.getElementById('comment_content'));
+	}
+	
+	// Post preview
+	$('#post-preview').modalWeb($(window).width()-40,$(window).height()-40);
+	
+	// Tabs events
+	$('#edit-entry').onetabload(function() {
+		dotclear.hideLockable();
+		
+		// Add date picker
+		var post_dtPick = new datePicker($('#post_dt').get(0));
+		post_dtPick.img_top = '1.5em';
+		post_dtPick.draw();
+		
+		// Confirm post deletion
+		$('input[name="delete"]').click(function() {
+				return window.confirm(dotclear.msg.confirm_delete_post);
+		});
+		
+		// Hide some fields
+		$('#notes-area label').toggleWithLegend($('#notes-area').children().not('label'),{
+			cookie: 'dcx_post_notes',
+			hide: $('#post_notes').val() == ''
+		});
+		$('#post_lang').parent().toggleWithLegend($('#post_lang'),{
+			cookie: 'dcx_post_lang'
+		});
+		$('#post_password').parent().toggleWithLegend($('#post_password'),{
+			cookie: 'dcx_post_password',
+			hide: $('#post_password').val() == ''
+		});
+		
+		// We load toolbar on excerpt only when it's ready
+		$('#excerpt-area label').toggleWithLegend($('#excerpt-area').children().not('label'),{
+			fn: function() { excerptTb.switchMode(formatField.value); },
+			cookie: 'dcx_post_excerpt',
+			hide: $('#post_excerpt').val() == ''
+		});
+		
+		// Load toolbars
+		contentTb.switchMode(formatField.value);
+		
+		// Replace attachment remove links by a POST form submit
+		$('a.attachment-remove').click(function() {
+			this.href = '';
+			var m_name = $(this).parents('ul').find('li:first>a').attr('title');
+			if (window.confirm(dotclear.msg.confirm_remove_attachment.replace('%s',m_name))) {
+				var f = $('#attachment-remove-hide').get(0);
+				f.elements['media_id'].value = this.id.substring(11);
+				f.submit();
+			}
+			return false;
+		});
+		
+		// Markup validator
+		var h = document.createElement('h4');
+		var a = document.createElement('a');
+		a.href = '#';
+		$(a).click(function() {
+			var params = {
+				xd_check: dotclear.nonce,
+				f: 'validatePostMarkup',
+				excerpt: $('#post_excerpt').text(),
+				content: $('#post_content').text(),
+				format: $('#post_format').get(0).value,
+				lang: $('#post_lang').get(0).value
+			};
+			
+			$.post('services.php',params,function(data) {
+				if ($(data).find('rsp').attr('status') != 'ok') {
+					alert($(data).find('rsp message').text());
+					return false;
+				}
+				
+				if ($(data).find('valid').text() == 1) {
+					var p = document.createElement('p');
+					p.id = 'markup-validator';
+					
+					if ($('#markup-validator').length > 0) {
+						$('#markup-validator').remove();
+					}
+					
+					$(p).addClass('message');
+					$(p).text(dotclear.msg.xhtml_valid);
+					$(p).insertAfter(h);
+					$(p).backgroundFade({sColor:'#666666',eColor:'#ffcc00',steps:50},function() {
+							$(this).backgroundFade({sColor:'#ffcc00',eColor:'#666666'});
+					});
+				} else {
+					var div = document.createElement('div');
+					div.id = 'markup-validator';
+					
+					if ($('#markup-validator').length > 0) {
+						$('#markup-validator').remove();
+					}
+					
+					$(div).addClass('error');
+					$(div).html('<p><strong>' + dotclear.msg.xhtml_not_valid + '</strong></p>' + $(data).find('errors').text());
+					$(div).insertAfter(h);
+					$(div).backgroundFade({sColor:'#ffffff',eColor:'#ff9999',steps:50},function() {
+							$(this).backgroundFade({sColor:'#ff9999',eColor:'#ffffff'});
+					});
+				}
+				
+				return false;
+			});
+			
+			return false;
+		});
+		
+		a.appendChild(document.createTextNode(dotclear.msg.xhtml_validator));
+		h.appendChild(a);
+		$(h).appendTo('#entry-content');
+		
+		// Check unsaved changes before XHTML conversion
+		var excerpt = $('#post_excerpt').val();
+		var content = $('#post_content').val();
+		$('#convert-xhtml').click(function() {
+			if (excerpt != $('#post_excerpt').val() || content != $('#post_content').val()) {
+				return window.confirm(dotclear.msg.confirm_change_post_format);
+			}	
+		});
+	});
+	
+	$('#comments').onetabload(function() {
+		$('.comments-list tr.line').each(function() {
+			dotclear.commentExpander(this);
+		});
+		$('.checkboxes-helpers').each(function() {
+			dotclear.checkboxesHelpers(this);
+		});
+		
+		dotclear.commentsActionsHelper();
+	});
+	
+	$('#add-comment').onetabload(function() {
+		commentTb.draw('xhtml');
+	});
 });
Index: admin/js/_posts_actions.js
===================================================================
--- admin/js/_posts_actions.js	(revision 3992)
+++ 	(revision )
@@ -1,19 +1,0 @@
-/*global $, dotclear, getData */
-'use strict';
-
-$(function() {
-  const new_auth_id = $('#new_auth_id');
-  if (new_auth_id.length) {
-    const usersList = getData('users_list');
-    new_auth_id.autocomplete(usersList, {
-      delay: 1000,
-      matchSubset: true,
-      matchContains: true
-    });
-  }
-  $('#new_cat').toggleWithLegend($('#new_cat').parent().children().not('#new_cat'), {
-    // no cookie on new category as we don't use this every day
-    legend_click: true
-  });
-  dotclear.condSubmit('table.posts-list td input[type=checkbox]', 'input[type=submit]');
-});
Index: admin/js/_posts_list.js
===================================================================
--- admin/js/_posts_list.js	(revision 4007)
+++ admin/js/_posts_list.js	(revision 0)
@@ -1,58 +1,79 @@
-/*global $, dotclear */
-'use strict';
+dotclear.postExpander = function(line) {
+	var td = line.firstChild;
+	
+	var img = document.createElement('img');
+	img.src = dotclear.img_plus_src;
+	img.alt = dotclear.img_plus_alt;
+	img.className = 'expand';
+	$(img).css('cursor','pointer');
+	img.line = line;
+	img.onclick = function() { dotclear.viewPostContent(this,this.line); };
+	
+	td.insertBefore(img,td.firstChild);
+};
 
-dotclear.viewPostContent = function(line, action, e) {
-  action = action || 'toggle';
-  if ($(line).attr('id') == undefined) {
-    return;
-  }
-
-  const postId = $(line).attr('id').substr(1);
-  const lineId = `pe${postId}`;
-  let tr = document.getElementById(lineId);
-
-  if (!tr) {
-    // Get post content if possible
-    dotclear.getEntryContent(postId, function(content) {
-      if (content) {
-        // Content found
-        tr = document.createElement('tr');
-        tr.id = lineId;
-        const td = document.createElement('td');
-        td.colSpan = $(line).children('td').length;
-        td.className = 'expand';
-        tr.appendChild(td);
-        $(td).append(content);
-        $(line).addClass('expand');
-        line.parentNode.insertBefore(tr, line.nextSibling);
-      } else {
-        $(line).toggleClass('expand');
-      }
-    }, {
-      clean: (e.metaKey)
-    });
-  } else {
-    $(tr).toggle();
-    $(line).toggleClass('expand');
-  }
+dotclear.viewPostContent = function(img,line) {
+	var postId = line.id.substr(1);
+	var tr = document.getElementById('pe'+postId);
+	
+	if (!tr) {
+		tr = document.createElement('tr');
+		tr.id = 'pe'+postId;
+		var td = document.createElement('td');
+		td.colSpan = 8;
+		td.className = 'expand';
+		tr.appendChild(td);
+		
+		img.src = dotclear.img_minus_src;
+		img.alt = dotclear.img_minus_alt;
+		
+		// Get post content
+		$.get('services.php',{f:'getPostById', id: postId, post_type: ''},function(data) {
+			var rsp = $(data).children('rsp')[0];
+			
+			if (rsp.attributes[0].value == 'ok') {
+				var post = $(rsp).find('post_display_content').text();
+				var post_excerpt = $(rsp).find('post_display_excerpt').text();
+				var res = '';
+				
+				if (post) {
+					if (post_excerpt) {
+						res += post_excerpt + '<hr />';
+					}
+					res += post;
+					$(td).append(res);
+				}
+			} else {
+				alert($(rsp).find('message').text());
+			}
+		});
+		
+		$(line).toggleClass('expand');
+		line.parentNode.insertBefore(tr,line.nextSibling);
+	}
+	else if (tr.style.display == 'none')
+	{
+		$(tr).toggle();
+		$(line).toggleClass('expand');
+		img.src = dotclear.img_minus_src;
+		img.alt = dotclear.img_minus_alt;
+	}
+	else
+	{
+		$(tr).toggle();
+		$(line).toggleClass('expand');
+		img.src = dotclear.img_plus_src;
+		img.alt = dotclear.img_plus_alt;
+	}
 };
 
 $(function() {
-  // Entry type switcher
-  $('#type').change(function() {
-    this.form.submit();
-  });
-
-  $.expandContent({
-    line: $('#form-entries tr:not(.line)'),
-    lines: $('#form-entries tr.line'),
-    callback: dotclear.viewPostContent
-  });
-  $('.checkboxes-helpers').each(function() {
-    dotclear.checkboxesHelpers(this, undefined, '#form-entries td input[type=checkbox]', '#form-entries #do-action');
-  });
-  $('#form-entries td input[type=checkbox]').enableShiftClick();
-  dotclear.condSubmit('#form-entries td input[type=checkbox]', '#form-entries #do-action');
-  dotclear.postsActionsHelper();
-  dotclear.responsiveCellHeaders(document.querySelector('#form-entries table'), '#form-entries table', 1);
+	$('#form-entries tr.line').each(function() {
+		dotclear.postExpander(this);
+	});
+	$('.checkboxes-helpers').each(function() {
+		dotclear.checkboxesHelpers(this);
+	});
+	$('#form-entries td input[type=checkbox]').enableShiftClick();
+	dotclear.postsActionsHelper();
 });
Index: admin/js/_preferences-dragdrop.js
===================================================================
--- admin/js/_preferences-dragdrop.js	(revision 3880)
+++ 	(revision )
@@ -1,23 +1,0 @@
-/*global $ */
-'use strict';
-
-$(function() {
-  $('#my-favs ul').sortable({
-    'cursor': 'move'
-  });
-  $('#my-favs ul, #my-favs ul *').css({
-    'cursor': 'move'
-  });
-  $('#my-favs ul input').css({
-    'cursor': 'auto'
-  });
-  $('#favs-form').submit(function() {
-    let order = [];
-    $('#my-favs ul li input.position').each(function() {
-      order.push(this.name.replace(/^order\[([^\]]+)\]$/, '$1'));
-    });
-    $('input[name=favs_order]')[0].value = order.join(',');
-    return true;
-  });
-  $('#my-favs ul li input.position').hide();
-});
Index: admin/js/_preferences.js
===================================================================
--- admin/js/_preferences.js	(revision 3981)
+++ admin/js/_preferences.js	(revision 0)
@@ -1,27 +1,22 @@
-/*global $, getData */
-'use strict';
-
 $(function() {
-  if ($('#new_pwd').length == 0) {
-    return;
-  }
-  const texts = getData('preferences');
-  $('#new_pwd').pwstrength({
-    texts: texts
-  });
-  const user_email = $('#user_email').val();
-  $('#user-form').submit(function() {
-    var e = this.elements.cur_pwd;
-    if (e.value != '') {
-      return true;
-    }
-    if ($('#user_email').val() != user_email || $('#new_pwd').val() != '') {
-      $(e).addClass('missing').focusout(function() {
-        $(this).removeClass('missing');
-      });
-      e.focus();
-      return false;
-    }
-    return true;
-  });
+	if ($('#new_pwd').length == 0) {
+		return;
+	}
+	
+	var user_email = $('#user_email').val();
+	
+	$('#user-form').submit(function() {
+		var e = this.elements['cur_pwd'];
+		if (e.value != '') {
+			return true;
+		}
+		if ($('#user_email').val() != user_email || $('#new_pwd').val() != '') {
+			e.focus();
+			$(e).backgroundFade({sColor:'#ffffff',eColor:'#ff9999',steps:50},function() {
+				$(this).backgroundFade({sColor:'#ff9999',eColor:'#ffffff'});
+			});
+			return false;
+		}
+		return true;
+	});
 });
Index: admin/js/_trackbacks.js
===================================================================
--- admin/js/_trackbacks.js	(revision 3706)
+++ admin/js/_trackbacks.js	(revision 0)
@@ -1,10 +1,7 @@
-/*global $ */
-'use strict';
-
 $(function() {
-  $('#tb_excerpt').keypress(function() {
-    if (this.value.length > 255) {
-      this.value = this.value.substring(0, 255);
-    }
-  });
+	$('#tb_excerpt').keypress(function() {
+		if (this.value.length > 255) {
+			this.value = this.value.substring(0,255);
+		}
+	});
 });
Index: admin/js/_update.js
===================================================================
--- admin/js/_update.js	(revision 3706)
+++ 	(revision )
@@ -1,11 +1,0 @@
-/*global $, dotclear */
-'use strict';
-
-$(function() {
-  $('form input[type=submit][name=b_del]').click(function() {
-    return window.confirm(dotclear.msg.confirm_delete_backup);
-  });
-  $('form input[type=submit][name=b_revert]').click(function() {
-    return window.confirm(dotclear.msg.confirm_revert_backup);
-  });
-});
Index: admin/js/_user.js
===================================================================
--- admin/js/_user.js	(revision 3985)
+++ 	(revision )
@@ -1,12 +1,0 @@
-/*global $, getData */
-'use strict';
-
-$(function() {
-  if ($('#new_pwd').length == 0) {
-    return;
-  }
-  const texts = getData('user');
-  $('#new_pwd').pwstrength({
-    texts: texts
-  });
-});
Index: admin/js/_users.js
===================================================================
--- admin/js/_users.js	(revision 4007)
+++ admin/js/_users.js	(revision 0)
@@ -1,53 +1,46 @@
-/*global $, dotclear */
-'use strict';
-
 $(function() {
-  $('.checkboxes-helpers').each(function() {
-    dotclear.checkboxesHelpers(this, undefined, '#form-users input[type="checkbox"]', '#form-users #do-action');
-  });
-  dotclear.condSubmit('#form-users input[type="checkbox"]', '#form-users #do-action');
-  dotclear.responsiveCellHeaders(document.querySelector('#form-users table'), '#form-users table', 1);
-  $('#form-users').submit(function() {
-    const action = $(this).find('select[name="action"]').val();
-    let user_ids = [];
-    let nb_posts = [];
-    let i;
-    let msg_cannot_delete = false;
-
-    $(this).find('input[name="users[]"]').each(function() {
-      user_ids.push(this);
-    });
-    $(this).find('input[name="nb_post[]"]').each(function() {
-      nb_posts.push(this.value);
-    });
-
-    if (action == 'deleteuser') {
-      for (i = 0; i < user_ids.length; i++) {
-        if (nb_posts[i] > 0) {
-          if (user_ids[i].checked == true) {
-            msg_cannot_delete = true;
-            user_ids[i].checked = false;
-          }
-        }
-      }
-      if (msg_cannot_delete == true) {
-        window.alert(dotclear.msg.cannot_delete_users);
-      }
-    }
-
-    let selectfields = 0;
-    for (i = 0; i < user_ids.length; i++) {
-      selectfields += user_ids[i].checked;
-    }
-
-    if (selectfields == 0) {
-      return false;
-    }
-
-    if (action == 'deleteuser') {
-      return window.confirm(dotclear.msg.confirm_delete_user.replace('%s', $('input[name="users[]"]:checked').size()));
-    }
-
-    return true;
-  });
+	$('.checkboxes-helpers').each(function() {
+		dotclear.checkboxesHelpers(this);
+	});
+	$('#form-users').submit(function() {
+		var action = $(this).find('select[name="dispatch_action"]').val();
+		var user_ids = new Array();
+		var nb_posts = new Array();
+		var i;
+		var msg_cannot_delete = false;
+		
+		$(this).find('input[name="user_id[]"]').each(function() {
+			user_ids.push(this);
+		});
+		$(this).find('input[name="nb_post[]"]').each(function() {
+			nb_posts.push(this.value);
+		});
+		
+		if (action == 'deleteuser') {
+			for (i=0; i<user_ids.length; i++) {
+				if (nb_posts[i] > 0) {
+					user_ids[i].checked = false;
+					msg_cannot_delete = true;
+				}
+			}
+			if (msg_cannot_delete == true) {
+				alert(dotclear.msg.cannot_delete_users);
+			}
+		}
+		
+		var selectfields = 0;
+		for (i=0; i<user_ids.length; i++) {
+			selectfields += user_ids[i].checked;
+		}
+		
+		if (selectfields == 0) {
+			return false;
+		}
+		
+		if (action == 'deleteuser') {
+			return window.confirm(dotclear.msg.confirm_delete_user.replace('%s',$('input[name="user_id[]"]:checked').size()));
+		}
+		
+		return true;
+	});
 });
Index: admin/js/_users_actions.js
===================================================================
--- admin/js/_users_actions.js	(revision 3880)
+++ 	(revision )
@@ -1,109 +1,0 @@
-/*global $, jQuery, dotclear */
-'use strict';
-
-jQuery.fn.updatePermissionsForm = function() {
-  return this.each(function() {
-
-    let perms = {};
-    const re = /^perm\[(.+?)\]\[(.+?)\]$/;
-    let e, prop;
-
-    const admin = function(E, perms, re) {
-      const P = E.name.match(re);
-
-      perms[P[1]].usage.checked = E.checked;
-      perms[P[1]].publish.checked = E.checked;
-      perms[P[1]].delete.checked = E.checked;
-      perms[P[1]].contentadmin.checked = E.checked;
-      perms[P[1]].categories.checked = E.checked;
-      perms[P[1]].media.checked = E.checked;
-      perms[P[1]].media_admin.checked = E.checked;
-
-      perms[P[1]].usage.disabled = E.checked;
-      perms[P[1]].publish.disabled = E.checked;
-      perms[P[1]].delete.disabled = E.checked;
-      perms[P[1]].contentadmin.disabled = E.checked;
-      perms[P[1]].categories.disabled = E.checked;
-      perms[P[1]].media.disabled = E.checked;
-      perms[P[1]].media_admin.disabled = E.checked;
-    };
-
-    const contentadmin = function(E, perms, re) {
-      const P = E.name.match(re);
-
-      perms[P[1]].usage.checked = E.checked;
-      perms[P[1]].publish.checked = E.checked;
-      perms[P[1]].delete.checked = E.checked;
-
-      perms[P[1]].usage.disabled = E.checked;
-      perms[P[1]].publish.disabled = E.checked;
-      perms[P[1]].delete.disabled = E.checked;
-    };
-
-    const mediaadmin = function(E, perms, re) {
-      const P = E.name.match(re);
-
-      perms[P[1]].media.checked = E.checked;
-
-      perms[P[1]].media.disabled = E.checked;
-    };
-
-    // Building a nice object of form elements
-    for (let i = 0; i < this.elements.length; i++) {
-      e = this.elements[i];
-      if (e.name == undefined) {
-        continue;
-      }
-      prop = e.name.match(re);
-      if (!prop) {
-        continue;
-      }
-      if (perms[prop[1]] == undefined) {
-        perms[prop[1]] = {};
-      }
-      perms[prop[1]][prop[2]] = e;
-    }
-    // Populate states
-    for (let blog in perms) {
-      // Loop on blog
-      for (let element in perms[blog]) {
-        // Loop on permission
-        e = perms[blog][element];
-        prop = e.name.match(re);
-        if (prop[2] == 'admin') {
-          // select related permissions for admin
-          if (e.checked) {
-            admin(e, perms, re);
-          }
-          $(e).click(function() {
-            admin(this, perms, re);
-          });
-        } else if (prop[2] == 'contentadmin') {
-          // select related permissions for content admin
-          if (e.checked) {
-            contentadmin(e, perms, re);
-          }
-          $(e).click(function() {
-            contentadmin(this, perms, re);
-          });
-        } else if (prop[2] == 'media_admin') {
-          // select related permissions for media admin
-          if (e.checked) {
-            mediaadmin(e, perms, re);
-          }
-          $(e).click(function() {
-            mediaadmin(this, perms, re);
-          });
-        }
-      }
-    }
-  });
-};
-
-$(function() {
-  $('.checkboxes-helpers').each(function() {
-    dotclear.checkboxesHelpers(this, undefined, '#form-blogs input[type="checkbox"]', '#form-blogs #do-action');
-  });
-  dotclear.condSubmit('#form-blogs input[type="checkbox"]', '#form-blogs #do-action');
-  $('#permissions-form').updatePermissionsForm();
-});
Index: admin/js/codemirror.js
===================================================================
--- admin/js/codemirror.js	(revision 3934)
+++ 	(revision )
@@ -1,23 +1,0 @@
-/*global getData, CodeMirror */
-'use strict';
-
-// Store all instances
-let codemirror_instance = {};
-
-// Launch all requested codemirror instance
-for (let i of getData('codemirror')) {
-  codemirror_instance[i.name] = CodeMirror.fromTextArea(document.getElementById(i.id), {
-    mode: i.mode,
-    tabMode: 'indent',
-    lineWrapping: 1,
-    lineNumbers: 1,
-    matchBrackets: 1,
-    autoCloseBrackets: 1,
-    extraKeys: {
-      'F11': function(cm) {
-        cm.setOption("fullScreen", !cm.getOption("fullScreen"));
-      }
-    },
-    theme: i.theme
-  });
-}
Index: admin/js/codemirror/LICENSE
===================================================================
--- admin/js/codemirror/LICENSE	(revision 3532)
+++ 	(revision )
@@ -1,21 +1,0 @@
-MIT License
-
-Copyright (C) 2017 by Marijn Haverbeke <marijnh@gmail.com> and others
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
Index: admin/js/codemirror/addon/display/fullscreen.css
===================================================================
--- admin/js/codemirror/addon/display/fullscreen.css	(revision 3253)
+++ 	(revision )
@@ -1,6 +1,0 @@
-.CodeMirror-fullscreen {
-  position: fixed;
-  top: 0; left: 0; right: 0; bottom: 0;
-  height: auto;
-  z-index: 9;
-}
Index: admin/js/codemirror/addon/display/fullscreen.js
===================================================================
--- admin/js/codemirror/addon/display/fullscreen.js	(revision 3979)
+++ 	(revision )
@@ -1,41 +1,0 @@
-// CodeMirror, copyright (c) by Marijn Haverbeke and others
-// Distributed under an MIT license: https://codemirror.net/LICENSE
-
-(function(mod) {
-  if (typeof exports == "object" && typeof module == "object") // CommonJS
-    mod(require("../../lib/codemirror"));
-  else if (typeof define == "function" && define.amd) // AMD
-    define(["../../lib/codemirror"], mod);
-  else // Plain browser env
-    mod(CodeMirror);
-})(function(CodeMirror) {
-  "use strict";
-
-  CodeMirror.defineOption("fullScreen", false, function(cm, val, old) {
-    if (old == CodeMirror.Init) old = false;
-    if (!old == !val) return;
-    if (val) setFullscreen(cm);
-    else setNormal(cm);
-  });
-
-  function setFullscreen(cm) {
-    var wrap = cm.getWrapperElement();
-    cm.state.fullScreenRestore = {scrollTop: window.pageYOffset, scrollLeft: window.pageXOffset,
-                                  width: wrap.style.width, height: wrap.style.height};
-    wrap.style.width = "";
-    wrap.style.height = "auto";
-    wrap.className += " CodeMirror-fullscreen";
-    document.documentElement.style.overflow = "hidden";
-    cm.refresh();
-  }
-
-  function setNormal(cm) {
-    var wrap = cm.getWrapperElement();
-    wrap.className = wrap.className.replace(/\s*CodeMirror-fullscreen\b/, "");
-    document.documentElement.style.overflow = "";
-    var info = cm.state.fullScreenRestore;
-    wrap.style.width = info.width; wrap.style.height = info.height;
-    window.scrollTo(info.scrollLeft, info.scrollTop);
-    cm.refresh();
-  }
-});
Index: admin/js/codemirror/addon/edit/closebrackets.js
===================================================================
--- admin/js/codemirror/addon/edit/closebrackets.js	(revision 3979)
+++ 	(revision )
@@ -1,191 +1,0 @@
-// CodeMirror, copyright (c) by Marijn Haverbeke and others
-// Distributed under an MIT license: https://codemirror.net/LICENSE
-
-(function(mod) {
-  if (typeof exports == "object" && typeof module == "object") // CommonJS
-    mod(require("../../lib/codemirror"));
-  else if (typeof define == "function" && define.amd) // AMD
-    define(["../../lib/codemirror"], mod);
-  else // Plain browser env
-    mod(CodeMirror);
-})(function(CodeMirror) {
-  var defaults = {
-    pairs: "()[]{}''\"\"",
-    closeBefore: ")]}'\":;>",
-    triples: "",
-    explode: "[]{}"
-  };
-
-  var Pos = CodeMirror.Pos;
-
-  CodeMirror.defineOption("autoCloseBrackets", false, function(cm, val, old) {
-    if (old && old != CodeMirror.Init) {
-      cm.removeKeyMap(keyMap);
-      cm.state.closeBrackets = null;
-    }
-    if (val) {
-      ensureBound(getOption(val, "pairs"))
-      cm.state.closeBrackets = val;
-      cm.addKeyMap(keyMap);
-    }
-  });
-
-  function getOption(conf, name) {
-    if (name == "pairs" && typeof conf == "string") return conf;
-    if (typeof conf == "object" && conf[name] != null) return conf[name];
-    return defaults[name];
-  }
-
-  var keyMap = {Backspace: handleBackspace, Enter: handleEnter};
-  function ensureBound(chars) {
-    for (var i = 0; i < chars.length; i++) {
-      var ch = chars.charAt(i), key = "'" + ch + "'"
-      if (!keyMap[key]) keyMap[key] = handler(ch)
-    }
-  }
-  ensureBound(defaults.pairs + "`")
-
-  function handler(ch) {
-    return function(cm) { return handleChar(cm, ch); };
-  }
-
-  function getConfig(cm) {
-    var deflt = cm.state.closeBrackets;
-    if (!deflt || deflt.override) return deflt;
-    var mode = cm.getModeAt(cm.getCursor());
-    return mode.closeBrackets || deflt;
-  }
-
-  function handleBackspace(cm) {
-    var conf = getConfig(cm);
-    if (!conf || cm.getOption("disableInput")) return CodeMirror.Pass;
-
-    var pairs = getOption(conf, "pairs");
-    var ranges = cm.listSelections();
-    for (var i = 0; i < ranges.length; i++) {
-      if (!ranges[i].empty()) return CodeMirror.Pass;
-      var around = charsAround(cm, ranges[i].head);
-      if (!around || pairs.indexOf(around) % 2 != 0) return CodeMirror.Pass;
-    }
-    for (var i = ranges.length - 1; i >= 0; i--) {
-      var cur = ranges[i].head;
-      cm.replaceRange("", Pos(cur.line, cur.ch - 1), Pos(cur.line, cur.ch + 1), "+delete");
-    }
-  }
-
-  function handleEnter(cm) {
-    var conf = getConfig(cm);
-    var explode = conf && getOption(conf, "explode");
-    if (!explode || cm.getOption("disableInput")) return CodeMirror.Pass;
-
-    var ranges = cm.listSelections();
-    for (var i = 0; i < ranges.length; i++) {
-      if (!ranges[i].empty()) return CodeMirror.Pass;
-      var around = charsAround(cm, ranges[i].head);
-      if (!around || explode.indexOf(around) % 2 != 0) return CodeMirror.Pass;
-    }
-    cm.operation(function() {
-      var linesep = cm.lineSeparator() || "\n";
-      cm.replaceSelection(linesep + linesep, null);
-      cm.execCommand("goCharLeft");
-      ranges = cm.listSelections();
-      for (var i = 0; i < ranges.length; i++) {
-        var line = ranges[i].head.line;
-        cm.indentLine(line, null, true);
-        cm.indentLine(line + 1, null, true);
-      }
-    });
-  }
-
-  function contractSelection(sel) {
-    var inverted = CodeMirror.cmpPos(sel.anchor, sel.head) > 0;
-    return {anchor: new Pos(sel.anchor.line, sel.anchor.ch + (inverted ? -1 : 1)),
-            head: new Pos(sel.head.line, sel.head.ch + (inverted ? 1 : -1))};
-  }
-
-  function handleChar(cm, ch) {
-    var conf = getConfig(cm);
-    if (!conf || cm.getOption("disableInput")) return CodeMirror.Pass;
-
-    var pairs = getOption(conf, "pairs");
-    var pos = pairs.indexOf(ch);
-    if (pos == -1) return CodeMirror.Pass;
-
-    var closeBefore = getOption(conf,"closeBefore");
-
-    var triples = getOption(conf, "triples");
-
-    var identical = pairs.charAt(pos + 1) == ch;
-    var ranges = cm.listSelections();
-    var opening = pos % 2 == 0;
-
-    var type;
-    for (var i = 0; i < ranges.length; i++) {
-      var range = ranges[i], cur = range.head, curType;
-      var next = cm.getRange(cur, Pos(cur.line, cur.ch + 1));
-      if (opening && !range.empty()) {
-        curType = "surround";
-      } else if ((identical || !opening) && next == ch) {
-        if (identical && stringStartsAfter(cm, cur))
-          curType = "both";
-        else if (triples.indexOf(ch) >= 0 && cm.getRange(cur, Pos(cur.line, cur.ch + 3)) == ch + ch + ch)
-          curType = "skipThree";
-        else
-          curType = "skip";
-      } else if (identical && cur.ch > 1 && triples.indexOf(ch) >= 0 &&
-                 cm.getRange(Pos(cur.line, cur.ch - 2), cur) == ch + ch) {
-        if (cur.ch > 2 && /\bstring/.test(cm.getTokenTypeAt(Pos(cur.line, cur.ch - 2)))) return CodeMirror.Pass;
-        curType = "addFour";
-      } else if (identical) {
-        var prev = cur.ch == 0 ? " " : cm.getRange(Pos(cur.line, cur.ch - 1), cur)
-        if (!CodeMirror.isWordChar(next) && prev != ch && !CodeMirror.isWordChar(prev)) curType = "both";
-        else return CodeMirror.Pass;
-      } else if (opening && (next.length === 0 || /\s/.test(next) || closeBefore.indexOf(next) > -1)) {
-        curType = "both";
-      } else {
-        return CodeMirror.Pass;
-      }
-      if (!type) type = curType;
-      else if (type != curType) return CodeMirror.Pass;
-    }
-
-    var left = pos % 2 ? pairs.charAt(pos - 1) : ch;
-    var right = pos % 2 ? ch : pairs.charAt(pos + 1);
-    cm.operation(function() {
-      if (type == "skip") {
-        cm.execCommand("goCharRight");
-      } else if (type == "skipThree") {
-        for (var i = 0; i < 3; i++)
-          cm.execCommand("goCharRight");
-      } else if (type == "surround") {
-        var sels = cm.getSelections();
-        for (var i = 0; i < sels.length; i++)
-          sels[i] = left + sels[i] + right;
-        cm.replaceSelections(sels, "around");
-        sels = cm.listSelections().slice();
-        for (var i = 0; i < sels.length; i++)
-          sels[i] = contractSelection(sels[i]);
-        cm.setSelections(sels);
-      } else if (type == "both") {
-        cm.replaceSelection(left + right, null);
-        cm.triggerElectric(left + right);
-        cm.execCommand("goCharLeft");
-      } else if (type == "addFour") {
-        cm.replaceSelection(left + left + left + left, "before");
-        cm.execCommand("goCharRight");
-      }
-    });
-  }
-
-  function charsAround(cm, pos) {
-    var str = cm.getRange(Pos(pos.line, pos.ch - 1),
-                          Pos(pos.line, pos.ch + 1));
-    return str.length == 2 ? str : null;
-  }
-
-  function stringStartsAfter(cm, pos) {
-    var token = cm.getTokenAt(Pos(pos.line, pos.ch + 1))
-    return /\bstring/.test(token.type) && token.start == pos.ch &&
-      (pos.ch == 0 || !/\bstring/.test(cm.getTokenTypeAt(pos)))
-  }
-});
Index: admin/js/codemirror/addon/edit/matchbrackets.js
===================================================================
--- admin/js/codemirror/addon/edit/matchbrackets.js	(revision 3979)
+++ 	(revision )
@@ -1,150 +1,0 @@
-// CodeMirror, copyright (c) by Marijn Haverbeke and others
-// Distributed under an MIT license: https://codemirror.net/LICENSE
-
-(function(mod) {
-  if (typeof exports == "object" && typeof module == "object") // CommonJS
-    mod(require("../../lib/codemirror"));
-  else if (typeof define == "function" && define.amd) // AMD
-    define(["../../lib/codemirror"], mod);
-  else // Plain browser env
-    mod(CodeMirror);
-})(function(CodeMirror) {
-  var ie_lt8 = /MSIE \d/.test(navigator.userAgent) &&
-    (document.documentMode == null || document.documentMode < 8);
-
-  var Pos = CodeMirror.Pos;
-
-  var matching = {"(": ")>", ")": "(<", "[": "]>", "]": "[<", "{": "}>", "}": "{<", "<": ">>", ">": "<<"};
-
-  function bracketRegex(config) {
-    return config && config.bracketRegex || /[(){}[\]]/
-  }
-
-  function findMatchingBracket(cm, where, config) {
-    var line = cm.getLineHandle(where.line), pos = where.ch - 1;
-    var afterCursor = config && config.afterCursor
-    if (afterCursor == null)
-      afterCursor = /(^| )cm-fat-cursor($| )/.test(cm.getWrapperElement().className)
-    var re = bracketRegex(config)
-
-    // A cursor is defined as between two characters, but in in vim command mode
-    // (i.e. not insert mode), the cursor is visually represented as a
-    // highlighted box on top of the 2nd character. Otherwise, we allow matches
-    // from before or after the cursor.
-    var match = (!afterCursor && pos >= 0 && re.test(line.text.charAt(pos)) && matching[line.text.charAt(pos)]) ||
-        re.test(line.text.charAt(pos + 1)) && matching[line.text.charAt(++pos)];
-    if (!match) return null;
-    var dir = match.charAt(1) == ">" ? 1 : -1;
-    if (config && config.strict && (dir > 0) != (pos == where.ch)) return null;
-    var style = cm.getTokenTypeAt(Pos(where.line, pos + 1));
-
-    var found = scanForBracket(cm, Pos(where.line, pos + (dir > 0 ? 1 : 0)), dir, style || null, config);
-    if (found == null) return null;
-    return {from: Pos(where.line, pos), to: found && found.pos,
-            match: found && found.ch == match.charAt(0), forward: dir > 0};
-  }
-
-  // bracketRegex is used to specify which type of bracket to scan
-  // should be a regexp, e.g. /[[\]]/
-  //
-  // Note: If "where" is on an open bracket, then this bracket is ignored.
-  //
-  // Returns false when no bracket was found, null when it reached
-  // maxScanLines and gave up
-  function scanForBracket(cm, where, dir, style, config) {
-    var maxScanLen = (config && config.maxScanLineLength) || 10000;
-    var maxScanLines = (config && config.maxScanLines) || 1000;
-
-    var stack = [];
-    var re = bracketRegex(config)
-    var lineEnd = dir > 0 ? Math.min(where.line + maxScanLines, cm.lastLine() + 1)
-                          : Math.max(cm.firstLine() - 1, where.line - maxScanLines);
-    for (var lineNo = where.line; lineNo != lineEnd; lineNo += dir) {
-      var line = cm.getLine(lineNo);
-      if (!line) continue;
-      var pos = dir > 0 ? 0 : line.length - 1, end = dir > 0 ? line.length : -1;
-      if (line.length > maxScanLen) continue;
-      if (lineNo == where.line) pos = where.ch - (dir < 0 ? 1 : 0);
-      for (; pos != end; pos += dir) {
-        var ch = line.charAt(pos);
-        if (re.test(ch) && (style === undefined || cm.getTokenTypeAt(Pos(lineNo, pos + 1)) == style)) {
-          var match = matching[ch];
-          if (match && (match.charAt(1) == ">") == (dir > 0)) stack.push(ch);
-          else if (!stack.length) return {pos: Pos(lineNo, pos), ch: ch};
-          else stack.pop();
-        }
-      }
-    }
-    return lineNo - dir == (dir > 0 ? cm.lastLine() : cm.firstLine()) ? false : null;
-  }
-
-  function matchBrackets(cm, autoclear, config) {
-    // Disable brace matching in long lines, since it'll cause hugely slow updates
-    var maxHighlightLen = cm.state.matchBrackets.maxHighlightLineLength || 1000;
-    var marks = [], ranges = cm.listSelections();
-    for (var i = 0; i < ranges.length; i++) {
-      var match = ranges[i].empty() && findMatchingBracket(cm, ranges[i].head, config);
-      if (match && cm.getLine(match.from.line).length <= maxHighlightLen) {
-        var style = match.match ? "CodeMirror-matchingbracket" : "CodeMirror-nonmatchingbracket";
-        marks.push(cm.markText(match.from, Pos(match.from.line, match.from.ch + 1), {className: style}));
-        if (match.to && cm.getLine(match.to.line).length <= maxHighlightLen)
-          marks.push(cm.markText(match.to, Pos(match.to.line, match.to.ch + 1), {className: style}));
-      }
-    }
-
-    if (marks.length) {
-      // Kludge to work around the IE bug from issue #1193, where text
-      // input stops going to the textare whever this fires.
-      if (ie_lt8 && cm.state.focused) cm.focus();
-
-      var clear = function() {
-        cm.operation(function() {
-          for (var i = 0; i < marks.length; i++) marks[i].clear();
-        });
-      };
-      if (autoclear) setTimeout(clear, 800);
-      else return clear;
-    }
-  }
-
-  function doMatchBrackets(cm) {
-    cm.operation(function() {
-      if (cm.state.matchBrackets.currentlyHighlighted) {
-        cm.state.matchBrackets.currentlyHighlighted();
-        cm.state.matchBrackets.currentlyHighlighted = null;
-      }
-      cm.state.matchBrackets.currentlyHighlighted = matchBrackets(cm, false, cm.state.matchBrackets);
-    });
-  }
-
-  CodeMirror.defineOption("matchBrackets", false, function(cm, val, old) {
-    if (old && old != CodeMirror.Init) {
-      cm.off("cursorActivity", doMatchBrackets);
-      if (cm.state.matchBrackets && cm.state.matchBrackets.currentlyHighlighted) {
-        cm.state.matchBrackets.currentlyHighlighted();
-        cm.state.matchBrackets.currentlyHighlighted = null;
-      }
-    }
-    if (val) {
-      cm.state.matchBrackets = typeof val == "object" ? val : {};
-      cm.on("cursorActivity", doMatchBrackets);
-    }
-  });
-
-  CodeMirror.defineExtension("matchBrackets", function() {matchBrackets(this, true);});
-  CodeMirror.defineExtension("findMatchingBracket", function(pos, config, oldConfig){
-    // Backwards-compatibility kludge
-    if (oldConfig || typeof config == "boolean") {
-      if (!oldConfig) {
-        config = config ? {strict: true} : null
-      } else {
-        oldConfig.strict = config
-        config = oldConfig
-      }
-    }
-    return findMatchingBracket(this, pos, config)
-  });
-  CodeMirror.defineExtension("scanForBracket", function(pos, dir, style, config){
-    return scanForBracket(this, pos, dir, style, config);
-  });
-});
Index: admin/js/codemirror/addon/mode/multiplex.js
===================================================================
--- admin/js/codemirror/addon/mode/multiplex.js	(revision 3979)
+++ 	(revision )
@@ -1,131 +1,0 @@
-// CodeMirror, copyright (c) by Marijn Haverbeke and others
-// Distributed under an MIT license: https://codemirror.net/LICENSE
-
-(function(mod) {
-  if (typeof exports == "object" && typeof module == "object") // CommonJS
-    mod(require("../../lib/codemirror"));
-  else if (typeof define == "function" && define.amd) // AMD
-    define(["../../lib/codemirror"], mod);
-  else // Plain browser env
-    mod(CodeMirror);
-})(function(CodeMirror) {
-"use strict";
-
-CodeMirror.multiplexingMode = function(outer /*, others */) {
-  // Others should be {open, close, mode [, delimStyle] [, innerStyle]} objects
-  var others = Array.prototype.slice.call(arguments, 1);
-
-  function indexOf(string, pattern, from, returnEnd) {
-    if (typeof pattern == "string") {
-      var found = string.indexOf(pattern, from);
-      return returnEnd && found > -1 ? found + pattern.length : found;
-    }
-    var m = pattern.exec(from ? string.slice(from) : string);
-    return m ? m.index + from + (returnEnd ? m[0].length : 0) : -1;
-  }
-
-  return {
-    startState: function() {
-      return {
-        outer: CodeMirror.startState(outer),
-        innerActive: null,
-        inner: null
-      };
-    },
-
-    copyState: function(state) {
-      return {
-        outer: CodeMirror.copyState(outer, state.outer),
-        innerActive: state.innerActive,
-        inner: state.innerActive && CodeMirror.copyState(state.innerActive.mode, state.inner)
-      };
-    },
-
-    token: function(stream, state) {
-      if (!state.innerActive) {
-        var cutOff = Infinity, oldContent = stream.string;
-        for (var i = 0; i < others.length; ++i) {
-          var other = others[i];
-          var found = indexOf(oldContent, other.open, stream.pos);
-          if (found == stream.pos) {
-            if (!other.parseDelimiters) stream.match(other.open);
-            state.innerActive = other;
-
-            // Get the outer indent, making sure to handle CodeMirror.Pass
-            var outerIndent = 0;
-            if (outer.indent) {
-              var possibleOuterIndent = outer.indent(state.outer, "", "");
-              if (possibleOuterIndent !== CodeMirror.Pass) outerIndent = possibleOuterIndent;
-            }
-
-            state.inner = CodeMirror.startState(other.mode, outerIndent);
-            return other.delimStyle && (other.delimStyle + " " + other.delimStyle + "-open");
-          } else if (found != -1 && found < cutOff) {
-            cutOff = found;
-          }
-        }
-        if (cutOff != Infinity) stream.string = oldContent.slice(0, cutOff);
-        var outerToken = outer.token(stream, state.outer);
-        if (cutOff != Infinity) stream.string = oldContent;
-        return outerToken;
-      } else {
-        var curInner = state.innerActive, oldContent = stream.string;
-        if (!curInner.close && stream.sol()) {
-          state.innerActive = state.inner = null;
-          return this.token(stream, state);
-        }
-        var found = curInner.close ? indexOf(oldContent, curInner.close, stream.pos, curInner.parseDelimiters) : -1;
-        if (found == stream.pos && !curInner.parseDelimiters) {
-          stream.match(curInner.close);
-          state.innerActive = state.inner = null;
-          return curInner.delimStyle && (curInner.delimStyle + " " + curInner.delimStyle + "-close");
-        }
-        if (found > -1) stream.string = oldContent.slice(0, found);
-        var innerToken = curInner.mode.token(stream, state.inner);
-        if (found > -1) stream.string = oldContent;
-
-        if (found == stream.pos && curInner.parseDelimiters)
-          state.innerActive = state.inner = null;
-
-        if (curInner.innerStyle) {
-          if (innerToken) innerToken = innerToken + " " + curInner.innerStyle;
-          else innerToken = curInner.innerStyle;
-        }
-
-        return innerToken;
-      }
-    },
-
-    indent: function(state, textAfter, line) {
-      var mode = state.innerActive ? state.innerActive.mode : outer;
-      if (!mode.indent) return CodeMirror.Pass;
-      return mode.indent(state.innerActive ? state.inner : state.outer, textAfter, line);
-    },
-
-    blankLine: function(state) {
-      var mode = state.innerActive ? state.innerActive.mode : outer;
-      if (mode.blankLine) {
-        mode.blankLine(state.innerActive ? state.inner : state.outer);
-      }
-      if (!state.innerActive) {
-        for (var i = 0; i < others.length; ++i) {
-          var other = others[i];
-          if (other.open === "\n") {
-            state.innerActive = other;
-            state.inner = CodeMirror.startState(other.mode, mode.indent ? mode.indent(state.outer, "", "") : 0);
-          }
-        }
-      } else if (state.innerActive.close === "\n") {
-        state.innerActive = state.inner = null;
-      }
-    },
-
-    electricChars: outer.electricChars,
-
-    innerMode: function(state) {
-      return state.inner ? {state: state.inner, mode: state.innerActive.mode} : {state: state.outer, mode: outer};
-    }
-  };
-};
-
-});
Index: admin/js/codemirror/lib/codemirror.css
===================================================================
--- admin/js/codemirror/lib/codemirror.css	(revision 3758)
+++ 	(revision )
@@ -1,346 +1,0 @@
-/* BASICS */
-
-.CodeMirror {
-  /* Set height, width, borders, and global font properties here */
-  font-family: monospace;
-  height: 300px;
-  color: black;
-  direction: ltr;
-}
-
-/* PADDING */
-
-.CodeMirror-lines {
-  padding: 4px 0; /* Vertical padding around content */
-}
-.CodeMirror pre {
-  padding: 0 4px; /* Horizontal padding of content */
-}
-
-.CodeMirror-scrollbar-filler, .CodeMirror-gutter-filler {
-  background-color: white; /* The little square between H and V scrollbars */
-}
-
-/* GUTTER */
-
-.CodeMirror-gutters {
-  border-right: 1px solid #ddd;
-  background-color: #f7f7f7;
-  white-space: nowrap;
-}
-.CodeMirror-linenumbers {}
-.CodeMirror-linenumber {
-  padding: 0 3px 0 5px;
-  min-width: 20px;
-  text-align: right;
-  color: #999;
-  white-space: nowrap;
-}
-
-.CodeMirror-guttermarker { color: black; }
-.CodeMirror-guttermarker-subtle { color: #999; }
-
-/* CURSOR */
-
-.CodeMirror-cursor {
-  border-left: 1px solid black;
-  border-right: none;
-  width: 0;
-}
-/* Shown when moving in bi-directional text */
-.CodeMirror div.CodeMirror-secondarycursor {
-  border-left: 1px solid silver;
-}
-.cm-fat-cursor .CodeMirror-cursor {
-  width: auto;
-  border: 0 !important;
-  background: #7e7;
-}
-.cm-fat-cursor div.CodeMirror-cursors {
-  z-index: 1;
-}
-.cm-fat-cursor-mark {
-  background-color: rgba(20, 255, 20, 0.5);
-  -webkit-animation: blink 1.06s steps(1) infinite;
-  -moz-animation: blink 1.06s steps(1) infinite;
-  animation: blink 1.06s steps(1) infinite;
-}
-.cm-animate-fat-cursor {
-  width: auto;
-  border: 0;
-  -webkit-animation: blink 1.06s steps(1) infinite;
-  -moz-animation: blink 1.06s steps(1) infinite;
-  animation: blink 1.06s steps(1) infinite;
-  background-color: #7e7;
-}
-@-moz-keyframes blink {
-  0% {}
-  50% { background-color: transparent; }
-  100% {}
-}
-@-webkit-keyframes blink {
-  0% {}
-  50% { background-color: transparent; }
-  100% {}
-}
-@keyframes blink {
-  0% {}
-  50% { background-color: transparent; }
-  100% {}
-}
-
-/* Can style cursor different in overwrite (non-insert) mode */
-.CodeMirror-overwrite .CodeMirror-cursor {}
-
-.cm-tab { display: inline-block; text-decoration: inherit; }
-
-.CodeMirror-rulers {
-  position: absolute;
-  left: 0; right: 0; top: -50px; bottom: -20px;
-  overflow: hidden;
-}
-.CodeMirror-ruler {
-  border-left: 1px solid #ccc;
-  top: 0; bottom: 0;
-  position: absolute;
-}
-
-/* DEFAULT THEME */
-
-.cm-s-default .cm-header {color: blue;}
-.cm-s-default .cm-quote {color: #090;}
-.cm-negative {color: #d44;}
-.cm-positive {color: #292;}
-.cm-header, .cm-strong {font-weight: bold;}
-.cm-em {font-style: italic;}
-.cm-link {text-decoration: underline;}
-.cm-strikethrough {text-decoration: line-through;}
-
-.cm-s-default .cm-keyword {color: #708;}
-.cm-s-default .cm-atom {color: #219;}
-.cm-s-default .cm-number {color: #164;}
-.cm-s-default .cm-def {color: #00f;}
-.cm-s-default .cm-variable,
-.cm-s-default .cm-punctuation,
-.cm-s-default .cm-property,
-.cm-s-default .cm-operator {}
-.cm-s-default .cm-variable-2 {color: #05a;}
-.cm-s-default .cm-variable-3, .cm-s-default .cm-type {color: #085;}
-.cm-s-default .cm-comment {color: #a50;}
-.cm-s-default .cm-string {color: #a11;}
-.cm-s-default .cm-string-2 {color: #f50;}
-.cm-s-default .cm-meta {color: #555;}
-.cm-s-default .cm-qualifier {color: #555;}
-.cm-s-default .cm-builtin {color: #30a;}
-.cm-s-default .cm-bracket {color: #997;}
-.cm-s-default .cm-tag {color: #170;}
-.cm-s-default .cm-attribute {color: #00c;}
-.cm-s-default .cm-hr {color: #999;}
-.cm-s-default .cm-link {color: #00c;}
-
-.cm-s-default .cm-error {color: #f00;}
-.cm-invalidchar {color: #f00;}
-
-.CodeMirror-composing { border-bottom: 2px solid; }
-
-/* Default styles for common addons */
-
-div.CodeMirror span.CodeMirror-matchingbracket {color: #0b0;}
-div.CodeMirror span.CodeMirror-nonmatchingbracket {color: #a22;}
-.CodeMirror-matchingtag { background: rgba(255, 150, 0, .3); }
-.CodeMirror-activeline-background {background: #e8f2ff;}
-
-/* STOP */
-
-/* The rest of this file contains styles related to the mechanics of
-   the editor. You probably shouldn't touch them. */
-
-.CodeMirror {
-  position: relative;
-  overflow: hidden;
-  background: white;
-}
-
-.CodeMirror-scroll {
-  overflow: scroll !important; /* Things will break if this is overridden */
-  /* 30px is the magic margin used to hide the element's real scrollbars */
-  /* See overflow: hidden in .CodeMirror */
-  margin-bottom: -30px; margin-right: -30px;
-  padding-bottom: 30px;
-  height: 100%;
-  outline: none; /* Prevent dragging from highlighting the element */
-  position: relative;
-}
-.CodeMirror-sizer {
-  position: relative;
-  border-right: 30px solid transparent;
-}
-
-/* The fake, visible scrollbars. Used to force redraw during scrolling
-   before actual scrolling happens, thus preventing shaking and
-   flickering artifacts. */
-.CodeMirror-vscrollbar, .CodeMirror-hscrollbar, .CodeMirror-scrollbar-filler, .CodeMirror-gutter-filler {
-  position: absolute;
-  z-index: 6;
-  display: none;
-}
-.CodeMirror-vscrollbar {
-  right: 0; top: 0;
-  overflow-x: hidden;
-  overflow-y: scroll;
-}
-.CodeMirror-hscrollbar {
-  bottom: 0; left: 0;
-  overflow-y: hidden;
-  overflow-x: scroll;
-}
-.CodeMirror-scrollbar-filler {
-  right: 0; bottom: 0;
-}
-.CodeMirror-gutter-filler {
-  left: 0; bottom: 0;
-}
-
-.CodeMirror-gutters {
-  position: absolute; left: 0; top: 0;
-  min-height: 100%;
-  z-index: 3;
-}
-.CodeMirror-gutter {
-  white-space: normal;
-  height: 100%;
-  display: inline-block;
-  vertical-align: top;
-  margin-bottom: -30px;
-}
-.CodeMirror-gutter-wrapper {
-  position: absolute;
-  z-index: 4;
-  background: none !important;
-  border: none !important;
-}
-.CodeMirror-gutter-background {
-  position: absolute;
-  top: 0; bottom: 0;
-  z-index: 4;
-}
-.CodeMirror-gutter-elt {
-  position: absolute;
-  cursor: default;
-  z-index: 4;
-}
-.CodeMirror-gutter-wrapper ::selection { background-color: transparent }
-.CodeMirror-gutter-wrapper ::-moz-selection { background-color: transparent }
-
-.CodeMirror-lines {
-  cursor: text;
-  min-height: 1px; /* prevents collapsing before first draw */
-}
-.CodeMirror pre {
-  /* Reset some styles that the rest of the page might have set */
-  -moz-border-radius: 0; -webkit-border-radius: 0; border-radius: 0;
-  border-width: 0;
-  background: transparent;
-  font-family: inherit;
-  font-size: inherit;
-  margin: 0;
-  white-space: pre;
-  word-wrap: normal;
-  line-height: inherit;
-  color: inherit;
-  z-index: 2;
-  position: relative;
-  overflow: visible;
-  -webkit-tap-highlight-color: transparent;
-  -webkit-font-variant-ligatures: contextual;
-  font-variant-ligatures: contextual;
-}
-.CodeMirror-wrap pre {
-  word-wrap: break-word;
-  white-space: pre-wrap;
-  word-break: normal;
-}
-
-.CodeMirror-linebackground {
-  position: absolute;
-  left: 0; right: 0; top: 0; bottom: 0;
-  z-index: 0;
-}
-
-.CodeMirror-linewidget {
-  position: relative;
-  z-index: 2;
-  padding: 0.1px; /* Force widget margins to stay inside of the container */
-}
-
-.CodeMirror-widget {}
-
-.CodeMirror-rtl pre { direction: rtl; }
-
-.CodeMirror-code {
-  outline: none;
-}
-
-/* Force content-box sizing for the elements where we expect it */
-.CodeMirror-scroll,
-.CodeMirror-sizer,
-.CodeMirror-gutter,
-.CodeMirror-gutters,
-.CodeMirror-linenumber {
-  -moz-box-sizing: content-box;
-  box-sizing: content-box;
-}
-
-.CodeMirror-measure {
-  position: absolute;
-  width: 100%;
-  height: 0;
-  overflow: hidden;
-  visibility: hidden;
-}
-
-.CodeMirror-cursor {
-  position: absolute;
-  pointer-events: none;
-}
-.CodeMirror-measure pre { position: static; }
-
-div.CodeMirror-cursors {
-  visibility: hidden;
-  position: relative;
-  z-index: 3;
-}
-div.CodeMirror-dragcursors {
-  visibility: visible;
-}
-
-.CodeMirror-focused div.CodeMirror-cursors {
-  visibility: visible;
-}
-
-.CodeMirror-selected { background: #d9d9d9; }
-.CodeMirror-focused .CodeMirror-selected { background: #d7d4f0; }
-.CodeMirror-crosshair { cursor: crosshair; }
-.CodeMirror-line::selection, .CodeMirror-line > span::selection, .CodeMirror-line > span > span::selection { background: #d7d4f0; }
-.CodeMirror-line::-moz-selection, .CodeMirror-line > span::-moz-selection, .CodeMirror-line > span > span::-moz-selection { background: #d7d4f0; }
-
-.cm-searching {
-  background-color: #ffa;
-  background-color: rgba(255, 255, 0, .4);
-}
-
-/* Used to force a border model for a node */
-.cm-force-border { padding-right: .1px; }
-
-@media print {
-  /* Hide the cursor when printing */
-  .CodeMirror div.CodeMirror-cursors {
-    visibility: hidden;
-  }
-}
-
-/* See issue #2901 */
-.cm-tab-wrap-hack:after { content: ''; }
-
-/* Help users use markselection to safely style text background */
-span.CodeMirror-selectedtext { background: none; }
Index: admin/js/codemirror/lib/codemirror.js
===================================================================
--- admin/js/codemirror/lib/codemirror.js	(revision 3979)
+++ 	(revision )
@@ -1,9762 +1,0 @@
-// CodeMirror, copyright (c) by Marijn Haverbeke and others
-// Distributed under an MIT license: https://codemirror.net/LICENSE
-
-// This is CodeMirror (https://codemirror.net), a code editor
-// implemented in JavaScript on top of the browser's DOM.
-//
-// You can find some technical background for some of the code below
-// at http://marijnhaverbeke.nl/blog/#cm-internals .
-
-(function (global, factory) {
-  typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
-  typeof define === 'function' && define.amd ? define(factory) :
-  (global.CodeMirror = factory());
-}(this, (function () { 'use strict';
-
-  // Kludges for bugs and behavior differences that can't be feature
-  // detected are enabled based on userAgent etc sniffing.
-  var userAgent = navigator.userAgent;
-  var platform = navigator.platform;
-
-  var gecko = /gecko\/\d/i.test(userAgent);
-  var ie_upto10 = /MSIE \d/.test(userAgent);
-  var ie_11up = /Trident\/(?:[7-9]|\d{2,})\..*rv:(\d+)/.exec(userAgent);
-  var edge = /Edge\/(\d+)/.exec(userAgent);
-  var ie = ie_upto10 || ie_11up || edge;
-  var ie_version = ie && (ie_upto10 ? document.documentMode || 6 : +(edge || ie_11up)[1]);
-  var webkit = !edge && /WebKit\//.test(userAgent);
-  var qtwebkit = webkit && /Qt\/\d+\.\d+/.test(userAgent);
-  var chrome = !edge && /Chrome\//.test(userAgent);
-  var presto = /Opera\//.test(userAgent);
-  var safari = /Apple Computer/.test(navigator.vendor);
-  var mac_geMountainLion = /Mac OS X 1\d\D([8-9]|\d\d)\D/.test(userAgent);
-  var phantom = /PhantomJS/.test(userAgent);
-
-  var ios = !edge && /AppleWebKit/.test(userAgent) && /Mobile\/\w+/.test(userAgent);
-  var android = /Android/.test(userAgent);
-  // This is woefully incomplete. Suggestions for alternative methods welcome.
-  var mobile = ios || android || /webOS|BlackBerry|Opera Mini|Opera Mobi|IEMobile/i.test(userAgent);
-  var mac = ios || /Mac/.test(platform);
-  var chromeOS = /\bCrOS\b/.test(userAgent);
-  var windows = /win/i.test(platform);
-
-  var presto_version = presto && userAgent.match(/Version\/(\d*\.\d*)/);
-  if (presto_version) { presto_version = Number(presto_version[1]); }
-  if (presto_version && presto_version >= 15) { presto = false; webkit = true; }
-  // Some browsers use the wrong event properties to signal cmd/ctrl on OS X
-  var flipCtrlCmd = mac && (qtwebkit || presto && (presto_version == null || presto_version < 12.11));
-  var captureRightClick = gecko || (ie && ie_version >= 9);
-
-  function classTest(cls) { return new RegExp("(^|\\s)" + cls + "(?:$|\\s)\\s*") }
-
-  var rmClass = function(node, cls) {
-    var current = node.className;
-    var match = classTest(cls).exec(current);
-    if (match) {
-      var after = current.slice(match.index + match[0].length);
-      node.className = current.slice(0, match.index) + (after ? match[1] + after : "");
-    }
-  };
-
-  function removeChildren(e) {
-    for (var count = e.childNodes.length; count > 0; --count)
-      { e.removeChild(e.firstChild); }
-    return e
-  }
-
-  function removeChildrenAndAdd(parent, e) {
-    return removeChildren(parent).appendChild(e)
-  }
-
-  function elt(tag, content, className, style) {
-    var e = document.createElement(tag);
-    if (className) { e.className = className; }
-    if (style) { e.style.cssText = style; }
-    if (typeof content == "string") { e.appendChild(document.createTextNode(content)); }
-    else if (content) { for (var i = 0; i < content.length; ++i) { e.appendChild(content[i]); } }
-    return e
-  }
-  // wrapper for elt, which removes the elt from the accessibility tree
-  function eltP(tag, content, className, style) {
-    var e = elt(tag, content, className, style);
-    e.setAttribute("role", "presentation");
-    return e
-  }
-
-  var range;
-  if (document.createRange) { range = function(node, start, end, endNode) {
-    var r = document.createRange();
-    r.setEnd(endNode || node, end);
-    r.setStart(node, start);
-    return r
-  }; }
-  else { range = function(node, start, end) {
-    var r = document.body.createTextRange();
-    try { r.moveToElementText(node.parentNode); }
-    catch(e) { return r }
-    r.collapse(true);
-    r.moveEnd("character", end);
-    r.moveStart("character", start);
-    return r
-  }; }
-
-  function contains(parent, child) {
-    if (child.nodeType == 3) // Android browser always returns false when child is a textnode
-      { child = child.parentNode; }
-    if (parent.contains)
-      { return parent.contains(child) }
-    do {
-      if (child.nodeType == 11) { child = child.host; }
-      if (child == parent) { return true }
-    } while (child = child.parentNode)
-  }
-
-  function activeElt() {
-    // IE and Edge may throw an "Unspecified Error" when accessing document.activeElement.
-    // IE < 10 will throw when accessed while the page is loading or in an iframe.
-    // IE > 9 and Edge will throw when accessed in an iframe if document.body is unavailable.
-    var activeElement;
-    try {
-      activeElement = document.activeElement;
-    } catch(e) {
-      activeElement = document.body || null;
-    }
-    while (activeElement && activeElement.shadowRoot && activeElement.shadowRoot.activeElement)
-      { activeElement = activeElement.shadowRoot.activeElement; }
-    return activeElement
-  }
-
-  function addClass(node, cls) {
-    var current = node.className;
-    if (!classTest(cls).test(current)) { node.className += (current ? " " : "") + cls; }
-  }
-  function joinClasses(a, b) {
-    var as = a.split(" ");
-    for (var i = 0; i < as.length; i++)
-      { if (as[i] && !classTest(as[i]).test(b)) { b += " " + as[i]; } }
-    return b
-  }
-
-  var selectInput = function(node) { node.select(); };
-  if (ios) // Mobile Safari apparently has a bug where select() is broken.
-    { selectInput = function(node) { node.selectionStart = 0; node.selectionEnd = node.value.length; }; }
-  else if (ie) // Suppress mysterious IE10 errors
-    { selectInput = function(node) { try { node.select(); } catch(_e) {} }; }
-
-  function bind(f) {
-    var args = Array.prototype.slice.call(arguments, 1);
-    return function(){return f.apply(null, args)}
-  }
-
-  function copyObj(obj, target, overwrite) {
-    if (!target) { target = {}; }
-    for (var prop in obj)
-      { if (obj.hasOwnProperty(prop) && (overwrite !== false || !target.hasOwnProperty(prop)))
-        { target[prop] = obj[prop]; } }
-    return target
-  }
-
-  // Counts the column offset in a string, taking tabs into account.
-  // Used mostly to find indentation.
-  function countColumn(string, end, tabSize, startIndex, startValue) {
-    if (end == null) {
-      end = string.search(/[^\s\u00a0]/);
-      if (end == -1) { end = string.length; }
-    }
-    for (var i = startIndex || 0, n = startValue || 0;;) {
-      var nextTab = string.indexOf("\t", i);
-      if (nextTab < 0 || nextTab >= end)
-        { return n + (end - i) }
-      n += nextTab - i;
-      n += tabSize - (n % tabSize);
-      i = nextTab + 1;
-    }
-  }
-
-  var Delayed = function() {this.id = null;};
-  Delayed.prototype.set = function (ms, f) {
-    clearTimeout(this.id);
-    this.id = setTimeout(f, ms);
-  };
-
-  function indexOf(array, elt) {
-    for (var i = 0; i < array.length; ++i)
-      { if (array[i] == elt) { return i } }
-    return -1
-  }
-
-  // Number of pixels added to scroller and sizer to hide scrollbar
-  var scrollerGap = 30;
-
-  // Returned or thrown by various protocols to signal 'I'm not
-  // handling this'.
-  var Pass = {toString: function(){return "CodeMirror.Pass"}};
-
-  // Reused option objects for setSelection & friends
-  var sel_dontScroll = {scroll: false}, sel_mouse = {origin: "*mouse"}, sel_move = {origin: "+move"};
-
-  // The inverse of countColumn -- find the offset that corresponds to
-  // a particular column.
-  function findColumn(string, goal, tabSize) {
-    for (var pos = 0, col = 0;;) {
-      var nextTab = string.indexOf("\t", pos);
-      if (nextTab == -1) { nextTab = string.length; }
-      var skipped = nextTab - pos;
-      if (nextTab == string.length || col + skipped >= goal)
-        { return pos + Math.min(skipped, goal - col) }
-      col += nextTab - pos;
-      col += tabSize - (col % tabSize);
-      pos = nextTab + 1;
-      if (col >= goal) { return pos }
-    }
-  }
-
-  var spaceStrs = [""];
-  function spaceStr(n) {
-    while (spaceStrs.length <= n)
-      { spaceStrs.push(lst(spaceStrs) + " "); }
-    return spaceStrs[n]
-  }
-
-  function lst(arr) { return arr[arr.length-1] }
-
-  function map(array, f) {
-    var out = [];
-    for (var i = 0; i < array.length; i++) { out[i] = f(array[i], i); }
-    return out
-  }
-
-  function insertSorted(array, value, score) {
-    var pos = 0, priority = score(value);
-    while (pos < array.length && score(array[pos]) <= priority) { pos++; }
-    array.splice(pos, 0, value);
-  }
-
-  function nothing() {}
-
-  function createObj(base, props) {
-    var inst;
-    if (Object.create) {
-      inst = Object.create(base);
-    } else {
-      nothing.prototype = base;
-      inst = new nothing();
-    }
-    if (props) { copyObj(props, inst); }
-    return inst
-  }
-
-  var nonASCIISingleCaseWordChar = /[\u00df\u0587\u0590-\u05f4\u0600-\u06ff\u3040-\u309f\u30a0-\u30ff\u3400-\u4db5\u4e00-\u9fcc\uac00-\ud7af]/;
-  function isWordCharBasic(ch) {
-    return /\w/.test(ch) || ch > "\x80" &&
-      (ch.toUpperCase() != ch.toLowerCase() || nonASCIISingleCaseWordChar.test(ch))
-  }
-  function isWordChar(ch, helper) {
-    if (!helper) { return isWordCharBasic(ch) }
-    if (helper.source.indexOf("\\w") > -1 && isWordCharBasic(ch)) { return true }
-    return helper.test(ch)
-  }
-
-  function isEmpty(obj) {
-    for (var n in obj) { if (obj.hasOwnProperty(n) && obj[n]) { return false } }
-    return true
-  }
-
-  // Extending unicode characters. A series of a non-extending char +
-  // any number of extending chars is treated as a single unit as far
-  // as editing and measuring is concerned. This is not fully correct,
-  // since some scripts/fonts/browsers also treat other configurations
-  // of code points as a group.
-  var extendingChars = /[\u0300-\u036f\u0483-\u0489\u0591-\u05bd\u05bf\u05c1\u05c2\u05c4\u05c5\u05c7\u0610-\u061a\u064b-\u065e\u0670\u06d6-\u06dc\u06de-\u06e4\u06e7\u06e8\u06ea-\u06ed\u0711\u0730-\u074a\u07a6-\u07b0\u07eb-\u07f3\u0816-\u0819\u081b-\u0823\u0825-\u0827\u0829-\u082d\u0900-\u0902\u093c\u0941-\u0948\u094d\u0951-\u0955\u0962\u0963\u0981\u09bc\u09be\u09c1-\u09c4\u09cd\u09d7\u09e2\u09e3\u0a01\u0a02\u0a3c\u0a41\u0a42\u0a47\u0a48\u0a4b-\u0a4d\u0a51\u0a70\u0a71\u0a75\u0a81\u0a82\u0abc\u0ac1-\u0ac5\u0ac7\u0ac8\u0acd\u0ae2\u0ae3\u0b01\u0b3c\u0b3e\u0b3f\u0b41-\u0b44\u0b4d\u0b56\u0b57\u0b62\u0b63\u0b82\u0bbe\u0bc0\u0bcd\u0bd7\u0c3e-\u0c40\u0c46-\u0c48\u0c4a-\u0c4d\u0c55\u0c56\u0c62\u0c63\u0cbc\u0cbf\u0cc2\u0cc6\u0ccc\u0ccd\u0cd5\u0cd6\u0ce2\u0ce3\u0d3e\u0d41-\u0d44\u0d4d\u0d57\u0d62\u0d63\u0dca\u0dcf\u0dd2-\u0dd4\u0dd6\u0ddf\u0e31\u0e34-\u0e3a\u0e47-\u0e4e\u0eb1\u0eb4-\u0eb9\u0ebb\u0ebc\u0ec8-\u0ecd\u0f18\u0f19\u0f35\u0f37\u0f39\u0f71-\u0f7e\u0f80-\u0f84\u0f86\u0f87\u0f90-\u0f97\u0f99-\u0fbc\u0fc6\u102d-\u1030\u1032-\u1037\u1039\u103a\u103d\u103e\u1058\u1059\u105e-\u1060\u1071-\u1074\u1082\u1085\u1086\u108d\u109d\u135f\u1712-\u1714\u1732-\u1734\u1752\u1753\u1772\u1773\u17b7-\u17bd\u17c6\u17c9-\u17d3\u17dd\u180b-\u180d\u18a9\u1920-\u1922\u1927\u1928\u1932\u1939-\u193b\u1a17\u1a18\u1a56\u1a58-\u1a5e\u1a60\u1a62\u1a65-\u1a6c\u1a73-\u1a7c\u1a7f\u1b00-\u1b03\u1b34\u1b36-\u1b3a\u1b3c\u1b42\u1b6b-\u1b73\u1b80\u1b81\u1ba2-\u1ba5\u1ba8\u1ba9\u1c2c-\u1c33\u1c36\u1c37\u1cd0-\u1cd2\u1cd4-\u1ce0\u1ce2-\u1ce8\u1ced\u1dc0-\u1de6\u1dfd-\u1dff\u200c\u200d\u20d0-\u20f0\u2cef-\u2cf1\u2de0-\u2dff\u302a-\u302f\u3099\u309a\ua66f-\ua672\ua67c\ua67d\ua6f0\ua6f1\ua802\ua806\ua80b\ua825\ua826\ua8c4\ua8e0-\ua8f1\ua926-\ua92d\ua947-\ua951\ua980-\ua982\ua9b3\ua9b6-\ua9b9\ua9bc\uaa29-\uaa2e\uaa31\uaa32\uaa35\uaa36\uaa43\uaa4c\uaab0\uaab2-\uaab4\uaab7\uaab8\uaabe\uaabf\uaac1\uabe5\uabe8\uabed\udc00-\udfff\ufb1e\ufe00-\ufe0f\ufe20-\ufe26\uff9e\uff9f]/;
-  function isExtendingChar(ch) { return ch.charCodeAt(0) >= 768 && extendingChars.test(ch) }
-
-  // Returns a number from the range [`0`; `str.length`] unless `pos` is outside that range.
-  function skipExtendingChars(str, pos, dir) {
-    while ((dir < 0 ? pos > 0 : pos < str.length) && isExtendingChar(str.charAt(pos))) { pos += dir; }
-    return pos
-  }
-
-  // Returns the value from the range [`from`; `to`] that satisfies
-  // `pred` and is closest to `from`. Assumes that at least `to`
-  // satisfies `pred`. Supports `from` being greater than `to`.
-  function findFirst(pred, from, to) {
-    // At any point we are certain `to` satisfies `pred`, don't know
-    // whether `from` does.
-    var dir = from > to ? -1 : 1;
-    for (;;) {
-      if (from == to) { return from }
-      var midF = (from + to) / 2, mid = dir < 0 ? Math.ceil(midF) : Math.floor(midF);
-      if (mid == from) { return pred(mid) ? from : to }
-      if (pred(mid)) { to = mid; }
-      else { from = mid + dir; }
-    }
-  }
-
-  // BIDI HELPERS
-
-  function iterateBidiSections(order, from, to, f) {
-    if (!order) { return f(from, to, "ltr", 0) }
-    var found = false;
-    for (var i = 0; i < order.length; ++i) {
-      var part = order[i];
-      if (part.from < to && part.to > from || from == to && part.to == from) {
-        f(Math.max(part.from, from), Math.min(part.to, to), part.level == 1 ? "rtl" : "ltr", i);
-        found = true;
-      }
-    }
-    if (!found) { f(from, to, "ltr"); }
-  }
-
-  var bidiOther = null;
-  function getBidiPartAt(order, ch, sticky) {
-    var found;
-    bidiOther = null;
-    for (var i = 0; i < order.length; ++i) {
-      var cur = order[i];
-      if (cur.from < ch && cur.to > ch) { return i }
-      if (cur.to == ch) {
-        if (cur.from != cur.to && sticky == "before") { found = i; }
-        else { bidiOther = i; }
-      }
-      if (cur.from == ch) {
-        if (cur.from != cur.to && sticky != "before") { found = i; }
-        else { bidiOther = i; }
-      }
-    }
-    return found != null ? found : bidiOther
-  }
-
-  // Bidirectional ordering algorithm
-  // See http://unicode.org/reports/tr9/tr9-13.html for the algorithm
-  // that this (partially) implements.
-
-  // One-char codes used for character types:
-  // L (L):   Left-to-Right
-  // R (R):   Right-to-Left
-  // r (AL):  Right-to-Left Arabic
-  // 1 (EN):  European Number
-  // + (ES):  European Number Separator
-  // % (ET):  European Number Terminator
-  // n (AN):  Arabic Number
-  // , (CS):  Common Number Separator
-  // m (NSM): Non-Spacing Mark
-  // b (BN):  Boundary Neutral
-  // s (B):   Paragraph Separator
-  // t (S):   Segment Separator
-  // w (WS):  Whitespace
-  // N (ON):  Other Neutrals
-
-  // Returns null if characters are ordered as they appear
-  // (left-to-right), or an array of sections ({from, to, level}
-  // objects) in the order in which they occur visually.
-  var bidiOrdering = (function() {
-    // Character types for codepoints 0 to 0xff
-    var lowTypes = "bbbbbbbbbtstwsbbbbbbbbbbbbbbssstwNN%%%NNNNNN,N,N1111111111NNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNbbbbbbsbbbbbbbbbbbbbbbbbbbbbbbbbb,N%%%%NNNNLNNNNN%%11NLNNN1LNNNNNLLLLLLLLLLLLLLLLLLLLLLLNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLN";
-    // Character types for codepoints 0x600 to 0x6f9
-    var arabicTypes = "nnnnnnNNr%%r,rNNmmmmmmmmmmmrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrmmmmmmmmmmmmmmmmmmmmmnnnnnnnnnn%nnrrrmrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrmmmmmmmnNmmmmmmrrmmNmmmmrr1111111111";
-    function charType(code) {
-      if (code <= 0xf7) { return lowTypes.charAt(code) }
-      else if (0x590 <= code && code <= 0x5f4) { return "R" }
-      else if (0x600 <= code && code <= 0x6f9) { return arabicTypes.charAt(code - 0x600) }
-      else if (0x6ee <= code && code <= 0x8ac) { return "r" }
-      else if (0x2000 <= code && code <= 0x200b) { return "w" }
-      else if (code == 0x200c) { return "b" }
-      else { return "L" }
-    }
-
-    var bidiRE = /[\u0590-\u05f4\u0600-\u06ff\u0700-\u08ac]/;
-    var isNeutral = /[stwN]/, isStrong = /[LRr]/, countsAsLeft = /[Lb1n]/, countsAsNum = /[1n]/;
-
-    function BidiSpan(level, from, to) {
-      this.level = level;
-      this.from = from; this.to = to;
-    }
-
-    return function(str, direction) {
-      var outerType = direction == "ltr" ? "L" : "R";
-
-      if (str.length == 0 || direction == "ltr" && !bidiRE.test(str)) { return false }
-      var len = str.length, types = [];
-      for (var i = 0; i < len; ++i)
-        { types.push(charType(str.charCodeAt(i))); }
-
-      // W1. Examine each non-spacing mark (NSM) in the level run, and
-      // change the type of the NSM to the type of the previous
-      // character. If the NSM is at the start of the level run, it will
-      // get the type of sor.
-      for (var i$1 = 0, prev = outerType; i$1 < len; ++i$1) {
-        var type = types[i$1];
-        if (type == "m") { types[i$1] = prev; }
-        else { prev = type; }
-      }
-
-      // W2. Search backwards from each instance of a European number
-      // until the first strong type (R, L, AL, or sor) is found. If an
-      // AL is found, change the type of the European number to Arabic
-      // number.
-      // W3. Change all ALs to R.
-      for (var i$2 = 0, cur = outerType; i$2 < len; ++i$2) {
-        var type$1 = types[i$2];
-        if (type$1 == "1" && cur == "r") { types[i$2] = "n"; }
-        else if (isStrong.test(type$1)) { cur = type$1; if (type$1 == "r") { types[i$2] = "R"; } }
-      }
-
-      // W4. A single European separator between two European numbers
-      // changes to a European number. A single common separator between
-      // two numbers of the same type changes to that type.
-      for (var i$3 = 1, prev$1 = types[0]; i$3 < len - 1; ++i$3) {
-        var type$2 = types[i$3];
-        if (type$2 == "+" && prev$1 == "1" && types[i$3+1] == "1") { types[i$3] = "1"; }
-        else if (type$2 == "," && prev$1 == types[i$3+1] &&
-                 (prev$1 == "1" || prev$1 == "n")) { types[i$3] = prev$1; }
-        prev$1 = type$2;
-      }
-
-      // W5. A sequence of European terminators adjacent to European
-      // numbers changes to all European numbers.
-      // W6. Otherwise, separators and terminators change to Other
-      // Neutral.
-      for (var i$4 = 0; i$4 < len; ++i$4) {
-        var type$3 = types[i$4];
-        if (type$3 == ",") { types[i$4] = "N"; }
-        else if (type$3 == "%") {
-          var end = (void 0);
-          for (end = i$4 + 1; end < len && types[end] == "%"; ++end) {}
-          var replace = (i$4 && types[i$4-1] == "!") || (end < len && types[end] == "1") ? "1" : "N";
-          for (var j = i$4; j < end; ++j) { types[j] = replace; }
-          i$4 = end - 1;
-        }
-      }
-
-      // W7. Search backwards from each instance of a European number
-      // until the first strong type (R, L, or sor) is found. If an L is
-      // found, then change the type of the European number to L.
-      for (var i$5 = 0, cur$1 = outerType; i$5 < len; ++i$5) {
-        var type$4 = types[i$5];
-        if (cur$1 == "L" && type$4 == "1") { types[i$5] = "L"; }
-        else if (isStrong.test(type$4)) { cur$1 = type$4; }
-      }
-
-      // N1. A sequence of neutrals takes the direction of the
-      // surrounding strong text if the text on both sides has the same
-      // direction. European and Arabic numbers act as if they were R in
-      // terms of their influence on neutrals. Start-of-level-run (sor)
-      // and end-of-level-run (eor) are used at level run boundaries.
-      // N2. Any remaining neutrals take the embedding direction.
-      for (var i$6 = 0; i$6 < len; ++i$6) {
-        if (isNeutral.test(types[i$6])) {
-          var end$1 = (void 0);
-          for (end$1 = i$6 + 1; end$1 < len && isNeutral.test(types[end$1]); ++end$1) {}
-          var before = (i$6 ? types[i$6-1] : outerType) == "L";
-          var after = (end$1 < len ? types[end$1] : outerType) == "L";
-          var replace$1 = before == after ? (before ? "L" : "R") : outerType;
-          for (var j$1 = i$6; j$1 < end$1; ++j$1) { types[j$1] = replace$1; }
-          i$6 = end$1 - 1;
-        }
-      }
-
-      // Here we depart from the documented algorithm, in order to avoid
-      // building up an actual levels array. Since there are only three
-      // levels (0, 1, 2) in an implementation that doesn't take
-      // explicit embedding into account, we can build up the order on
-      // the fly, without following the level-based algorithm.
-      var order = [], m;
-      for (var i$7 = 0; i$7 < len;) {
-        if (countsAsLeft.test(types[i$7])) {
-          var start = i$7;
-          for (++i$7; i$7 < len && countsAsLeft.test(types[i$7]); ++i$7) {}
-          order.push(new BidiSpan(0, start, i$7));
-        } else {
-          var pos = i$7, at = order.length;
-          for (++i$7; i$7 < len && types[i$7] != "L"; ++i$7) {}
-          for (var j$2 = pos; j$2 < i$7;) {
-            if (countsAsNum.test(types[j$2])) {
-              if (pos < j$2) { order.splice(at, 0, new BidiSpan(1, pos, j$2)); }
-              var nstart = j$2;
-              for (++j$2; j$2 < i$7 && countsAsNum.test(types[j$2]); ++j$2) {}
-              order.splice(at, 0, new BidiSpan(2, nstart, j$2));
-              pos = j$2;
-            } else { ++j$2; }
-          }
-          if (pos < i$7) { order.splice(at, 0, new BidiSpan(1, pos, i$7)); }
-        }
-      }
-      if (direction == "ltr") {
-        if (order[0].level == 1 && (m = str.match(/^\s+/))) {
-          order[0].from = m[0].length;
-          order.unshift(new BidiSpan(0, 0, m[0].length));
-        }
-        if (lst(order).level == 1 && (m = str.match(/\s+$/))) {
-          lst(order).to -= m[0].length;
-          order.push(new BidiSpan(0, len - m[0].length, len));
-        }
-      }
-
-      return direction == "rtl" ? order.reverse() : order
-    }
-  })();
-
-  // Get the bidi ordering for the given line (and cache it). Returns
-  // false for lines that are fully left-to-right, and an array of
-  // BidiSpan objects otherwise.
-  function getOrder(line, direction) {
-    var order = line.order;
-    if (order == null) { order = line.order = bidiOrdering(line.text, direction); }
-    return order
-  }
-
-  // EVENT HANDLING
-
-  // Lightweight event framework. on/off also work on DOM nodes,
-  // registering native DOM handlers.
-
-  var noHandlers = [];
-
-  var on = function(emitter, type, f) {
-    if (emitter.addEventListener) {
-      emitter.addEventListener(type, f, false);
-    } else if (emitter.attachEvent) {
-      emitter.attachEvent("on" + type, f);
-    } else {
-      var map$$1 = emitter._handlers || (emitter._handlers = {});
-      map$$1[type] = (map$$1[type] || noHandlers).concat(f);
-    }
-  };
-
-  function getHandlers(emitter, type) {
-    return emitter._handlers && emitter._handlers[type] || noHandlers
-  }
-
-  function off(emitter, type, f) {
-    if (emitter.removeEventListener) {
-      emitter.removeEventListener(type, f, false);
-    } else if (emitter.detachEvent) {
-      emitter.detachEvent("on" + type, f);
-    } else {
-      var map$$1 = emitter._handlers, arr = map$$1 && map$$1[type];
-      if (arr) {
-        var index = indexOf(arr, f);
-        if (index > -1)
-          { map$$1[type] = arr.slice(0, index).concat(arr.slice(index + 1)); }
-      }
-    }
-  }
-
-  function signal(emitter, type /*, values...*/) {
-    var handlers = getHandlers(emitter, type);
-    if (!handlers.length) { return }
-    var args = Array.prototype.slice.call(arguments, 2);
-    for (var i = 0; i < handlers.length; ++i) { handlers[i].apply(null, args); }
-  }
-
-  // The DOM events that CodeMirror handles can be overridden by
-  // registering a (non-DOM) handler on the editor for the event name,
-  // and preventDefault-ing the event in that handler.
-  function signalDOMEvent(cm, e, override) {
-    if (typeof e == "string")
-      { e = {type: e, preventDefault: function() { this.defaultPrevented = true; }}; }
-    signal(cm, override || e.type, cm, e);
-    return e_defaultPrevented(e) || e.codemirrorIgnore
-  }
-
-  function signalCursorActivity(cm) {
-    var arr = cm._handlers && cm._handlers.cursorActivity;
-    if (!arr) { return }
-    var set = cm.curOp.cursorActivityHandlers || (cm.curOp.cursorActivityHandlers = []);
-    for (var i = 0; i < arr.length; ++i) { if (indexOf(set, arr[i]) == -1)
-      { set.push(arr[i]); } }
-  }
-
-  function hasHandler(emitter, type) {
-    return getHandlers(emitter, type).length > 0
-  }
-
-  // Add on and off methods to a constructor's prototype, to make
-  // registering events on such objects more convenient.
-  function eventMixin(ctor) {
-    ctor.prototype.on = function(type, f) {on(this, type, f);};
-    ctor.prototype.off = function(type, f) {off(this, type, f);};
-  }
-
-  // Due to the fact that we still support jurassic IE versions, some
-  // compatibility wrappers are needed.
-
-  function e_preventDefault(e) {
-    if (e.preventDefault) { e.preventDefault(); }
-    else { e.returnValue = false; }
-  }
-  function e_stopPropagation(e) {
-    if (e.stopPropagation) { e.stopPropagation(); }
-    else { e.cancelBubble = true; }
-  }
-  function e_defaultPrevented(e) {
-    return e.defaultPrevented != null ? e.defaultPrevented : e.returnValue == false
-  }
-  function e_stop(e) {e_preventDefault(e); e_stopPropagation(e);}
-
-  function e_target(e) {return e.target || e.srcElement}
-  function e_button(e) {
-    var b = e.which;
-    if (b == null) {
-      if (e.button & 1) { b = 1; }
-      else if (e.button & 2) { b = 3; }
-      else if (e.button & 4) { b = 2; }
-    }
-    if (mac && e.ctrlKey && b == 1) { b = 3; }
-    return b
-  }
-
-  // Detect drag-and-drop
-  var dragAndDrop = function() {
-    // There is *some* kind of drag-and-drop support in IE6-8, but I
-    // couldn't get it to work yet.
-    if (ie && ie_version < 9) { return false }
-    var div = elt('div');
-    return "draggable" in div || "dragDrop" in div
-  }();
-
-  var zwspSupported;
-  function zeroWidthElement(measure) {
-    if (zwspSupported == null) {
-      var test = elt("span", "\u200b");
-      removeChildrenAndAdd(measure, elt("span", [test, document.createTextNode("x")]));
-      if (measure.firstChild.offsetHeight != 0)
-        { zwspSupported = test.offsetWidth <= 1 && test.offsetHeight > 2 && !(ie && ie_version < 8); }
-    }
-    var node = zwspSupported ? elt("span", "\u200b") :
-      elt("span", "\u00a0", null, "display: inline-block; width: 1px; margin-right: -1px");
-    node.setAttribute("cm-text", "");
-    return node
-  }
-
-  // Feature-detect IE's crummy client rect reporting for bidi text
-  var badBidiRects;
-  function hasBadBidiRects(measure) {
-    if (badBidiRects != null) { return badBidiRects }
-    var txt = removeChildrenAndAdd(measure, document.createTextNode("A\u062eA"));
-    var r0 = range(txt, 0, 1).getBoundingClientRect();
-    var r1 = range(txt, 1, 2).getBoundingClientRect();
-    removeChildren(measure);
-    if (!r0 || r0.left == r0.right) { return false } // Safari returns null in some cases (#2780)
-    return badBidiRects = (r1.right - r0.right < 3)
-  }
-
-  // See if "".split is the broken IE version, if so, provide an
-  // alternative way to split lines.
-  var splitLinesAuto = "\n\nb".split(/\n/).length != 3 ? function (string) {
-    var pos = 0, result = [], l = string.length;
-    while (pos <= l) {
-      var nl = string.indexOf("\n", pos);
-      if (nl == -1) { nl = string.length; }
-      var line = string.slice(pos, string.charAt(nl - 1) == "\r" ? nl - 1 : nl);
-      var rt = line.indexOf("\r");
-      if (rt != -1) {
-        result.push(line.slice(0, rt));
-        pos += rt + 1;
-      } else {
-        result.push(line);
-        pos = nl + 1;
-      }
-    }
-    return result
-  } : function (string) { return string.split(/\r\n?|\n/); };
-
-  var hasSelection = window.getSelection ? function (te) {
-    try { return te.selectionStart != te.selectionEnd }
-    catch(e) { return false }
-  } : function (te) {
-    var range$$1;
-    try {range$$1 = te.ownerDocument.selection.createRange();}
-    catch(e) {}
-    if (!range$$1 || range$$1.parentElement() != te) { return false }
-    return range$$1.compareEndPoints("StartToEnd", range$$1) != 0
-  };
-
-  var hasCopyEvent = (function () {
-    var e = elt("div");
-    if ("oncopy" in e) { return true }
-    e.setAttribute("oncopy", "return;");
-    return typeof e.oncopy == "function"
-  })();
-
-  var badZoomedRects = null;
-  function hasBadZoomedRects(measure) {
-    if (badZoomedRects != null) { return badZoomedRects }
-    var node = removeChildrenAndAdd(measure, elt("span", "x"));
-    var normal = node.getBoundingClientRect();
-    var fromRange = range(node, 0, 1).getBoundingClientRect();
-    return badZoomedRects = Math.abs(normal.left - fromRange.left) > 1
-  }
-
-  // Known modes, by name and by MIME
-  var modes = {}, mimeModes = {};
-
-  // Extra arguments are stored as the mode's dependencies, which is
-  // used by (legacy) mechanisms like loadmode.js to automatically
-  // load a mode. (Preferred mechanism is the require/define calls.)
-  function defineMode(name, mode) {
-    if (arguments.length > 2)
-      { mode.dependencies = Array.prototype.slice.call(arguments, 2); }
-    modes[name] = mode;
-  }
-
-  function defineMIME(mime, spec) {
-    mimeModes[mime] = spec;
-  }
-
-  // Given a MIME type, a {name, ...options} config object, or a name
-  // string, return a mode config object.
-  function resolveMode(spec) {
-    if (typeof spec == "string" && mimeModes.hasOwnProperty(spec)) {
-      spec = mimeModes[spec];
-    } else if (spec && typeof spec.name == "string" && mimeModes.hasOwnProperty(spec.name)) {
-      var found = mimeModes[spec.name];
-      if (typeof found == "string") { found = {name: found}; }
-      spec = createObj(found, spec);
-      spec.name = found.name;
-    } else if (typeof spec == "string" && /^[\w\-]+\/[\w\-]+\+xml$/.test(spec)) {
-      return resolveMode("application/xml")
-    } else if (typeof spec == "string" && /^[\w\-]+\/[\w\-]+\+json$/.test(spec)) {
-      return resolveMode("application/json")
-    }
-    if (typeof spec == "string") { return {name: spec} }
-    else { return spec || {name: "null"} }
-  }
-
-  // Given a mode spec (anything that resolveMode accepts), find and
-  // initialize an actual mode object.
-  function getMode(options, spec) {
-    spec = resolveMode(spec);
-    var mfactory = modes[spec.name];
-    if (!mfactory) { return getMode(options, "text/plain") }
-    var modeObj = mfactory(options, spec);
-    if (modeExtensions.hasOwnProperty(spec.name)) {
-      var exts = modeExtensions[spec.name];
-      for (var prop in exts) {
-        if (!exts.hasOwnProperty(prop)) { continue }
-        if (modeObj.hasOwnProperty(prop)) { modeObj["_" + prop] = modeObj[prop]; }
-        modeObj[prop] = exts[prop];
-      }
-    }
-    modeObj.name = spec.name;
-    if (spec.helperType) { modeObj.helperType = spec.helperType; }
-    if (spec.modeProps) { for (var prop$1 in spec.modeProps)
-      { modeObj[prop$1] = spec.modeProps[prop$1]; } }
-
-    return modeObj
-  }
-
-  // This can be used to attach properties to mode objects from
-  // outside the actual mode definition.
-  var modeExtensions = {};
-  function extendMode(mode, properties) {
-    var exts = modeExtensions.hasOwnProperty(mode) ? modeExtensions[mode] : (modeExtensions[mode] = {});
-    copyObj(properties, exts);
-  }
-
-  function copyState(mode, state) {
-    if (state === true) { return state }
-    if (mode.copyState) { return mode.copyState(state) }
-    var nstate = {};
-    for (var n in state) {
-      var val = state[n];
-      if (val instanceof Array) { val = val.concat([]); }
-      nstate[n] = val;
-    }
-    return nstate
-  }
-
-  // Given a mode and a state (for that mode), find the inner mode and
-  // state at the position that the state refers to.
-  function innerMode(mode, state) {
-    var info;
-    while (mode.innerMode) {
-      info = mode.innerMode(state);
-      if (!info || info.mode == mode) { break }
-      state = info.state;
-      mode = info.mode;
-    }
-    return info || {mode: mode, state: state}
-  }
-
-  function startState(mode, a1, a2) {
-    return mode.startState ? mode.startState(a1, a2) : true
-  }
-
-  // STRING STREAM
-
-  // Fed to the mode parsers, provides helper functions to make
-  // parsers more succinct.
-
-  var StringStream = function(string, tabSize, lineOracle) {
-    this.pos = this.start = 0;
-    this.string = string;
-    this.tabSize = tabSize || 8;
-    this.lastColumnPos = this.lastColumnValue = 0;
-    this.lineStart = 0;
-    this.lineOracle = lineOracle;
-  };
-
-  StringStream.prototype.eol = function () {return this.pos >= this.string.length};
-  StringStream.prototype.sol = function () {return this.pos == this.lineStart};
-  StringStream.prototype.peek = function () {return this.string.charAt(this.pos) || undefined};
-  StringStream.prototype.next = function () {
-    if (this.pos < this.string.length)
-      { return this.string.charAt(this.pos++) }
-  };
-  StringStream.prototype.eat = function (match) {
-    var ch = this.string.charAt(this.pos);
-    var ok;
-    if (typeof match == "string") { ok = ch == match; }
-    else { ok = ch && (match.test ? match.test(ch) : match(ch)); }
-    if (ok) {++this.pos; return ch}
-  };
-  StringStream.prototype.eatWhile = function (match) {
-    var start = this.pos;
-    while (this.eat(match)){}
-    return this.pos > start
-  };
-  StringStream.prototype.eatSpace = function () {
-      var this$1 = this;
-
-    var start = this.pos;
-    while (/[\s\u00a0]/.test(this.string.charAt(this.pos))) { ++this$1.pos; }
-    return this.pos > start
-  };
-  StringStream.prototype.skipToEnd = function () {this.pos = this.string.length;};
-  StringStream.prototype.skipTo = function (ch) {
-    var found = this.string.indexOf(ch, this.pos);
-    if (found > -1) {this.pos = found; return true}
-  };
-  StringStream.prototype.backUp = function (n) {this.pos -= n;};
-  StringStream.prototype.column = function () {
-    if (this.lastColumnPos < this.start) {
-      this.lastColumnValue = countColumn(this.string, this.start, this.tabSize, this.lastColumnPos, this.lastColumnValue);
-      this.lastColumnPos = this.start;
-    }
-    return this.lastColumnValue - (this.lineStart ? countColumn(this.string, this.lineStart, this.tabSize) : 0)
-  };
-  StringStream.prototype.indentation = function () {
-    return countColumn(this.string, null, this.tabSize) -
-      (this.lineStart ? countColumn(this.string, this.lineStart, this.tabSize) : 0)
-  };
-  StringStream.prototype.match = function (pattern, consume, caseInsensitive) {
-    if (typeof pattern == "string") {
-      var cased = function (str) { return caseInsensitive ? str.toLowerCase() : str; };
-      var substr = this.string.substr(this.pos, pattern.length);
-      if (cased(substr) == cased(pattern)) {
-        if (consume !== false) { this.pos += pattern.length; }
-        return true
-      }
-    } else {
-      var match = this.string.slice(this.pos).match(pattern);
-      if (match && match.index > 0) { return null }
-      if (match && consume !== false) { this.pos += match[0].length; }
-      return match
-    }
-  };
-  StringStream.prototype.current = function (){return this.string.slice(this.start, this.pos)};
-  StringStream.prototype.hideFirstChars = function (n, inner) {
-    this.lineStart += n;
-    try { return inner() }
-    finally { this.lineStart -= n; }
-  };
-  StringStream.prototype.lookAhead = function (n) {
-    var oracle = this.lineOracle;
-    return oracle && oracle.lookAhead(n)
-  };
-  StringStream.prototype.baseToken = function () {
-    var oracle = this.lineOracle;
-    return oracle && oracle.baseToken(this.pos)
-  };
-
-  // Find the line object corresponding to the given line number.
-  function getLine(doc, n) {
-    n -= doc.first;
-    if (n < 0 || n >= doc.size) { throw new Error("There is no line " + (n + doc.first) + " in the document.") }
-    var chunk = doc;
-    while (!chunk.lines) {
-      for (var i = 0;; ++i) {
-        var child = chunk.children[i], sz = child.chunkSize();
-        if (n < sz) { chunk = child; break }
-        n -= sz;
-      }
-    }
-    return chunk.lines[n]
-  }
-
-  // Get the part of a document between two positions, as an array of
-  // strings.
-  function getBetween(doc, start, end) {
-    var out = [], n = start.line;
-    doc.iter(start.line, end.line + 1, function (line) {
-      var text = line.text;
-      if (n == end.line) { text = text.slice(0, end.ch); }
-      if (n == start.line) { text = text.slice(start.ch); }
-      out.push(text);
-      ++n;
-    });
-    return out
-  }
-  // Get the lines between from and to, as array of strings.
-  function getLines(doc, from, to) {
-    var out = [];
-    doc.iter(from, to, function (line) { out.push(line.text); }); // iter aborts when callback returns truthy value
-    return out
-  }
-
-  // Update the height of a line, propagating the height change
-  // upwards to parent nodes.
-  function updateLineHeight(line, height) {
-    var diff = height - line.height;
-    if (diff) { for (var n = line; n; n = n.parent) { n.height += diff; } }
-  }
-
-  // Given a line object, find its line number by walking up through
-  // its parent links.
-  function lineNo(line) {
-    if (line.parent == null) { return null }
-    var cur = line.parent, no = indexOf(cur.lines, line);
-    for (var chunk = cur.parent; chunk; cur = chunk, chunk = chunk.parent) {
-      for (var i = 0;; ++i) {
-        if (chunk.children[i] == cur) { break }
-        no += chunk.children[i].chunkSize();
-      }
-    }
-    return no + cur.first
-  }
-
-  // Find the line at the given vertical position, using the height
-  // information in the document tree.
-  function lineAtHeight(chunk, h) {
-    var n = chunk.first;
-    outer: do {
-      for (var i$1 = 0; i$1 < chunk.children.length; ++i$1) {
-        var child = chunk.children[i$1], ch = child.height;
-        if (h < ch) { chunk = child; continue outer }
-        h -= ch;
-        n += child.chunkSize();
-      }
-      return n
-    } while (!chunk.lines)
-    var i = 0;
-    for (; i < chunk.lines.length; ++i) {
-      var line = chunk.lines[i], lh = line.height;
-      if (h < lh) { break }
-      h -= lh;
-    }
-    return n + i
-  }
-
-  function isLine(doc, l) {return l >= doc.first && l < doc.first + doc.size}
-
-  function lineNumberFor(options, i) {
-    return String(options.lineNumberFormatter(i + options.firstLineNumber))
-  }
-
-  // A Pos instance represents a position within the text.
-  function Pos(line, ch, sticky) {
-    if ( sticky === void 0 ) sticky = null;
-
-    if (!(this instanceof Pos)) { return new Pos(line, ch, sticky) }
-    this.line = line;
-    this.ch = ch;
-    this.sticky = sticky;
-  }
-
-  // Compare two positions, return 0 if they are the same, a negative
-  // number when a is less, and a positive number otherwise.
-  function cmp(a, b) { return a.line - b.line || a.ch - b.ch }
-
-  function equalCursorPos(a, b) { return a.sticky == b.sticky && cmp(a, b) == 0 }
-
-  function copyPos(x) {return Pos(x.line, x.ch)}
-  function maxPos(a, b) { return cmp(a, b) < 0 ? b : a }
-  function minPos(a, b) { return cmp(a, b) < 0 ? a : b }
-
-  // Most of the external API clips given positions to make sure they
-  // actually exist within the document.
-  function clipLine(doc, n) {return Math.max(doc.first, Math.min(n, doc.first + doc.size - 1))}
-  function clipPos(doc, pos) {
-    if (pos.line < doc.first) { return Pos(doc.first, 0) }
-    var last = doc.first + doc.size - 1;
-    if (pos.line > last) { return Pos(last, getLine(doc, last).text.length) }
-    return clipToLen(pos, getLine(doc, pos.line).text.length)
-  }
-  function clipToLen(pos, linelen) {
-    var ch = pos.ch;
-    if (ch == null || ch > linelen) { return Pos(pos.line, linelen) }
-    else if (ch < 0) { return Pos(pos.line, 0) }
-    else { return pos }
-  }
-  function clipPosArray(doc, array) {
-    var out = [];
-    for (var i = 0; i < array.length; i++) { out[i] = clipPos(doc, array[i]); }
-    return out
-  }
-
-  var SavedContext = function(state, lookAhead) {
-    this.state = state;
-    this.lookAhead = lookAhead;
-  };
-
-  var Context = function(doc, state, line, lookAhead) {
-    this.state = state;
-    this.doc = doc;
-    this.line = line;
-    this.maxLookAhead = lookAhead || 0;
-    this.baseTokens = null;
-    this.baseTokenPos = 1;
-  };
-
-  Context.prototype.lookAhead = function (n) {
-    var line = this.doc.getLine(this.line + n);
-    if (line != null && n > this.maxLookAhead) { this.maxLookAhead = n; }
-    return line
-  };
-
-  Context.prototype.baseToken = function (n) {
-      var this$1 = this;
-
-    if (!this.baseTokens) { return null }
-    while (this.baseTokens[this.baseTokenPos] <= n)
-      { this$1.baseTokenPos += 2; }
-    var type = this.baseTokens[this.baseTokenPos + 1];
-    return {type: type && type.replace(/( |^)overlay .*/, ""),
-            size: this.baseTokens[this.baseTokenPos] - n}
-  };
-
-  Context.prototype.nextLine = function () {
-    this.line++;
-    if (this.maxLookAhead > 0) { this.maxLookAhead--; }
-  };
-
-  Context.fromSaved = function (doc, saved, line) {
-    if (saved instanceof SavedContext)
-      { return new Context(doc, copyState(doc.mode, saved.state), line, saved.lookAhead) }
-    else
-      { return new Context(doc, copyState(doc.mode, saved), line) }
-  };
-
-  Context.prototype.save = function (copy) {
-    var state = copy !== false ? copyState(this.doc.mode, this.state) : this.state;
-    return this.maxLookAhead > 0 ? new SavedContext(state, this.maxLookAhead) : state
-  };
-
-
-  // Compute a style array (an array starting with a mode generation
-  // -- for invalidation -- followed by pairs of end positions and
-  // style strings), which is used to highlight the tokens on the
-  // line.
-  function highlightLine(cm, line, context, forceToEnd) {
-    // A styles array always starts with a number identifying the
-    // mode/overlays that it is based on (for easy invalidation).
-    var st = [cm.state.modeGen], lineClasses = {};
-    // Compute the base array of styles
-    runMode(cm, line.text, cm.doc.mode, context, function (end, style) { return st.push(end, style); },
-            lineClasses, forceToEnd);
-    var state = context.state;
-
-    // Run overlays, adjust style array.
-    var loop = function ( o ) {
-      context.baseTokens = st;
-      var overlay = cm.state.overlays[o], i = 1, at = 0;
-      context.state = true;
-      runMode(cm, line.text, overlay.mode, context, function (end, style) {
-        var start = i;
-        // Ensure there's a token end at the current position, and that i points at it
-        while (at < end) {
-          var i_end = st[i];
-          if (i_end > end)
-            { st.splice(i, 1, end, st[i+1], i_end); }
-          i += 2;
-          at = Math.min(end, i_end);
-        }
-        if (!style) { return }
-        if (overlay.opaque) {
-          st.splice(start, i - start, end, "overlay " + style);
-          i = start + 2;
-        } else {
-          for (; start < i; start += 2) {
-            var cur = st[start+1];
-            st[start+1] = (cur ? cur + " " : "") + "overlay " + style;
-          }
-        }
-      }, lineClasses);
-      context.state = state;
-      context.baseTokens = null;
-      context.baseTokenPos = 1;
-    };
-
-    for (var o = 0; o < cm.state.overlays.length; ++o) loop( o );
-
-    return {styles: st, classes: lineClasses.bgClass || lineClasses.textClass ? lineClasses : null}
-  }
-
-  function getLineStyles(cm, line, updateFrontier) {
-    if (!line.styles || line.styles[0] != cm.state.modeGen) {
-      var context = getContextBefore(cm, lineNo(line));
-      var resetState = line.text.length > cm.options.maxHighlightLength && copyState(cm.doc.mode, context.state);
-      var result = highlightLine(cm, line, context);
-      if (resetState) { context.state = resetState; }
-      line.stateAfter = context.save(!resetState);
-      line.styles = result.styles;
-      if (result.classes) { line.styleClasses = result.classes; }
-      else if (line.styleClasses) { line.styleClasses = null; }
-      if (updateFrontier === cm.doc.highlightFrontier)
-        { cm.doc.modeFrontier = Math.max(cm.doc.modeFrontier, ++cm.doc.highlightFrontier); }
-    }
-    return line.styles
-  }
-
-  function getContextBefore(cm, n, precise) {
-    var doc = cm.doc, display = cm.display;
-    if (!doc.mode.startState) { return new Context(doc, true, n) }
-    var start = findStartLine(cm, n, precise);
-    var saved = start > doc.first && getLine(doc, start - 1).stateAfter;
-    var context = saved ? Context.fromSaved(doc, saved, start) : new Context(doc, startState(doc.mode), start);
-
-    doc.iter(start, n, function (line) {
-      processLine(cm, line.text, context);
-      var pos = context.line;
-      line.stateAfter = pos == n - 1 || pos % 5 == 0 || pos >= display.viewFrom && pos < display.viewTo ? context.save() : null;
-      context.nextLine();
-    });
-    if (precise) { doc.modeFrontier = context.line; }
-    return context
-  }
-
-  // Lightweight form of highlight -- proceed over this line and
-  // update state, but don't save a style array. Used for lines that
-  // aren't currently visible.
-  function processLine(cm, text, context, startAt) {
-    var mode = cm.doc.mode;
-    var stream = new StringStream(text, cm.options.tabSize, context);
-    stream.start = stream.pos = startAt || 0;
-    if (text == "") { callBlankLine(mode, context.state); }
-    while (!stream.eol()) {
-      readToken(mode, stream, context.state);
-      stream.start = stream.pos;
-    }
-  }
-
-  function callBlankLine(mode, state) {
-    if (mode.blankLine) { return mode.blankLine(state) }
-    if (!mode.innerMode) { return }
-    var inner = innerMode(mode, state);
-    if (inner.mode.blankLine) { return inner.mode.blankLine(inner.state) }
-  }
-
-  function readToken(mode, stream, state, inner) {
-    for (var i = 0; i < 10; i++) {
-      if (inner) { inner[0] = innerMode(mode, state).mode; }
-      var style = mode.token(stream, state);
-      if (stream.pos > stream.start) { return style }
-    }
-    throw new Error("Mode " + mode.name + " failed to advance stream.")
-  }
-
-  var Token = function(stream, type, state) {
-    this.start = stream.start; this.end = stream.pos;
-    this.string = stream.current();
-    this.type = type || null;
-    this.state = state;
-  };
-
-  // Utility for getTokenAt and getLineTokens
-  function takeToken(cm, pos, precise, asArray) {
-    var doc = cm.doc, mode = doc.mode, style;
-    pos = clipPos(doc, pos);
-    var line = getLine(doc, pos.line), context = getContextBefore(cm, pos.line, precise);
-    var stream = new StringStream(line.text, cm.options.tabSize, context), tokens;
-    if (asArray) { tokens = []; }
-    while ((asArray || stream.pos < pos.ch) && !stream.eol()) {
-      stream.start = stream.pos;
-      style = readToken(mode, stream, context.state);
-      if (asArray) { tokens.push(new Token(stream, style, copyState(doc.mode, context.state))); }
-    }
-    return asArray ? tokens : new Token(stream, style, context.state)
-  }
-
-  function extractLineClasses(type, output) {
-    if (type) { for (;;) {
-      var lineClass = type.match(/(?:^|\s+)line-(background-)?(\S+)/);
-      if (!lineClass) { break }
-      type = type.slice(0, lineClass.index) + type.slice(lineClass.index + lineClass[0].length);
-      var prop = lineClass[1] ? "bgClass" : "textClass";
-      if (output[prop] == null)
-        { output[prop] = lineClass[2]; }
-      else if (!(new RegExp("(?:^|\s)" + lineClass[2] + "(?:$|\s)")).test(output[prop]))
-        { output[prop] += " " + lineClass[2]; }
-    } }
-    return type
-  }
-
-  // Run the given mode's parser over a line, calling f for each token.
-  function runMode(cm, text, mode, context, f, lineClasses, forceToEnd) {
-    var flattenSpans = mode.flattenSpans;
-    if (flattenSpans == null) { flattenSpans = cm.options.flattenSpans; }
-    var curStart = 0, curStyle = null;
-    var stream = new StringStream(text, cm.options.tabSize, context), style;
-    var inner = cm.options.addModeClass && [null];
-    if (text == "") { extractLineClasses(callBlankLine(mode, context.state), lineClasses); }
-    while (!stream.eol()) {
-      if (stream.pos > cm.options.maxHighlightLength) {
-        flattenSpans = false;
-        if (forceToEnd) { processLine(cm, text, context, stream.pos); }
-        stream.pos = text.length;
-        style = null;
-      } else {
-        style = extractLineClasses(readToken(mode, stream, context.state, inner), lineClasses);
-      }
-      if (inner) {
-        var mName = inner[0].name;
-        if (mName) { style = "m-" + (style ? mName + " " + style : mName); }
-      }
-      if (!flattenSpans || curStyle != style) {
-        while (curStart < stream.start) {
-          curStart = Math.min(stream.start, curStart + 5000);
-          f(curStart, curStyle);
-        }
-        curStyle = style;
-      }
-      stream.start = stream.pos;
-    }
-    while (curStart < stream.pos) {
-      // Webkit seems to refuse to render text nodes longer than 57444
-      // characters, and returns inaccurate measurements in nodes
-      // starting around 5000 chars.
-      var pos = Math.min(stream.pos, curStart + 5000);
-      f(pos, curStyle);
-      curStart = pos;
-    }
-  }
-
-  // Finds the line to start with when starting a parse. Tries to
-  // find a line with a stateAfter, so that it can start with a
-  // valid state. If that fails, it returns the line with the
-  // smallest indentation, which tends to need the least context to
-  // parse correctly.
-  function findStartLine(cm, n, precise) {
-    var minindent, minline, doc = cm.doc;
-    var lim = precise ? -1 : n - (cm.doc.mode.innerMode ? 1000 : 100);
-    for (var search = n; search > lim; --search) {
-      if (search <= doc.first) { return doc.first }
-      var line = getLine(doc, search - 1), after = line.stateAfter;
-      if (after && (!precise || search + (after instanceof SavedContext ? after.lookAhead : 0) <= doc.modeFrontier))
-        { return search }
-      var indented = countColumn(line.text, null, cm.options.tabSize);
-      if (minline == null || minindent > indented) {
-        minline = search - 1;
-        minindent = indented;
-      }
-    }
-    return minline
-  }
-
-  function retreatFrontier(doc, n) {
-    doc.modeFrontier = Math.min(doc.modeFrontier, n);
-    if (doc.highlightFrontier < n - 10) { return }
-    var start = doc.first;
-    for (var line = n - 1; line > start; line--) {
-      var saved = getLine(doc, line).stateAfter;
-      // change is on 3
-      // state on line 1 looked ahead 2 -- so saw 3
-      // test 1 + 2 < 3 should cover this
-      if (saved && (!(saved instanceof SavedContext) || line + saved.lookAhead < n)) {
-        start = line + 1;
-        break
-      }
-    }
-    doc.highlightFrontier = Math.min(doc.highlightFrontier, start);
-  }
-
-  // Optimize some code when these features are not used.
-  var sawReadOnlySpans = false, sawCollapsedSpans = false;
-
-  function seeReadOnlySpans() {
-    sawReadOnlySpans = true;
-  }
-
-  function seeCollapsedSpans() {
-    sawCollapsedSpans = true;
-  }
-
-  // TEXTMARKER SPANS
-
-  function MarkedSpan(marker, from, to) {
-    this.marker = marker;
-    this.from = from; this.to = to;
-  }
-
-  // Search an array of spans for a span matching the given marker.
-  function getMarkedSpanFor(spans, marker) {
-    if (spans) { for (var i = 0; i < spans.length; ++i) {
-      var span = spans[i];
-      if (span.marker == marker) { return span }
-    } }
-  }
-  // Remove a span from an array, returning undefined if no spans are
-  // left (we don't store arrays for lines without spans).
-  function removeMarkedSpan(spans, span) {
-    var r;
-    for (var i = 0; i < spans.length; ++i)
-      { if (spans[i] != span) { (r || (r = [])).push(spans[i]); } }
-    return r
-  }
-  // Add a span to a line.
-  function addMarkedSpan(line, span) {
-    line.markedSpans = line.markedSpans ? line.markedSpans.concat([span]) : [span];
-    span.marker.attachLine(line);
-  }
-
-  // Used for the algorithm that adjusts markers for a change in the
-  // document. These functions cut an array of spans at a given
-  // character position, returning an array of remaining chunks (or
-  // undefined if nothing remains).
-  function markedSpansBefore(old, startCh, isInsert) {
-    var nw;
-    if (old) { for (var i = 0; i < old.length; ++i) {
-      var span = old[i], marker = span.marker;
-      var startsBefore = span.from == null || (marker.inclusiveLeft ? span.from <= startCh : span.from < startCh);
-      if (startsBefore || span.from == startCh && marker.type == "bookmark" && (!isInsert || !span.marker.insertLeft)) {
-        var endsAfter = span.to == null || (marker.inclusiveRight ? span.to >= startCh : span.to > startCh)
-        ;(nw || (nw = [])).push(new MarkedSpan(marker, span.from, endsAfter ? null : span.to));
-      }
-    } }
-    return nw
-  }
-  function markedSpansAfter(old, endCh, isInsert) {
-    var nw;
-    if (old) { for (var i = 0; i < old.length; ++i) {
-      var span = old[i], marker = span.marker;
-      var endsAfter = span.to == null || (marker.inclusiveRight ? span.to >= endCh : span.to > endCh);
-      if (endsAfter || span.from == endCh && marker.type == "bookmark" && (!isInsert || span.marker.insertLeft)) {
-        var startsBefore = span.from == null || (marker.inclusiveLeft ? span.from <= endCh : span.from < endCh)
-        ;(nw || (nw = [])).push(new MarkedSpan(marker, startsBefore ? null : span.from - endCh,
-                                              span.to == null ? null : span.to - endCh));
-      }
-    } }
-    return nw
-  }
-
-  // Given a change object, compute the new set of marker spans that
-  // cover the line in which the change took place. Removes spans
-  // entirely within the change, reconnects spans belonging to the
-  // same marker that appear on both sides of the change, and cuts off
-  // spans partially within the change. Returns an array of span
-  // arrays with one element for each line in (after) the change.
-  function stretchSpansOverChange(doc, change) {
-    if (change.full) { return null }
-    var oldFirst = isLine(doc, change.from.line) && getLine(doc, change.from.line).markedSpans;
-    var oldLast = isLine(doc, change.to.line) && getLine(doc, change.to.line).markedSpans;
-    if (!oldFirst && !oldLast) { return null }
-
-    var startCh = change.from.ch, endCh = change.to.ch, isInsert = cmp(change.from, change.to) == 0;
-    // Get the spans that 'stick out' on both sides
-    var first = markedSpansBefore(oldFirst, startCh, isInsert);
-    var last = markedSpansAfter(oldLast, endCh, isInsert);
-
-    // Next, merge those two ends
-    var sameLine = change.text.length == 1, offset = lst(change.text).length + (sameLine ? startCh : 0);
-    if (first) {
-      // Fix up .to properties of first
-      for (var i = 0; i < first.length; ++i) {
-        var span = first[i];
-        if (span.to == null) {
-          var found = getMarkedSpanFor(last, span.marker);
-          if (!found) { span.to = startCh; }
-          else if (sameLine) { span.to = found.to == null ? null : found.to + offset; }
-        }
-      }
-    }
-    if (last) {
-      // Fix up .from in last (or move them into first in case of sameLine)
-      for (var i$1 = 0; i$1 < last.length; ++i$1) {
-        var span$1 = last[i$1];
-        if (span$1.to != null) { span$1.to += offset; }
-        if (span$1.from == null) {
-          var found$1 = getMarkedSpanFor(first, span$1.marker);
-          if (!found$1) {
-            span$1.from = offset;
-            if (sameLine) { (first || (first = [])).push(span$1); }
-          }
-        } else {
-          span$1.from += offset;
-          if (sameLine) { (first || (first = [])).push(span$1); }
-        }
-      }
-    }
-    // Make sure we didn't create any zero-length spans
-    if (first) { first = clearEmptySpans(first); }
-    if (last && last != first) { last = clearEmptySpans(last); }
-
-    var newMarkers = [first];
-    if (!sameLine) {
-      // Fill gap with whole-line-spans
-      var gap = change.text.length - 2, gapMarkers;
-      if (gap > 0 && first)
-        { for (var i$2 = 0; i$2 < first.length; ++i$2)
-          { if (first[i$2].to == null)
-            { (gapMarkers || (gapMarkers = [])).push(new MarkedSpan(first[i$2].marker, null, null)); } } }
-      for (var i$3 = 0; i$3 < gap; ++i$3)
-        { newMarkers.push(gapMarkers); }
-      newMarkers.push(last);
-    }
-    return newMarkers
-  }
-
-  // Remove spans that are empty and don't have a clearWhenEmpty
-  // option of false.
-  function clearEmptySpans(spans) {
-    for (var i = 0; i < spans.length; ++i) {
-      var span = spans[i];
-      if (span.from != null && span.from == span.to && span.marker.clearWhenEmpty !== false)
-        { spans.splice(i--, 1); }
-    }
-    if (!spans.length) { return null }
-    return spans
-  }
-
-  // Used to 'clip' out readOnly ranges when making a change.
-  function removeReadOnlyRanges(doc, from, to) {
-    var markers = null;
-    doc.iter(from.line, to.line + 1, function (line) {
-      if (line.markedSpans) { for (var i = 0; i < line.markedSpans.length; ++i) {
-        var mark = line.markedSpans[i].marker;
-        if (mark.readOnly && (!markers || indexOf(markers, mark) == -1))
-          { (markers || (markers = [])).push(mark); }
-      } }
-    });
-    if (!markers) { return null }
-    var parts = [{from: from, to: to}];
-    for (var i = 0; i < markers.length; ++i) {
-      var mk = markers[i], m = mk.find(0);
-      for (var j = 0; j < parts.length; ++j) {
-        var p = parts[j];
-        if (cmp(p.to, m.from) < 0 || cmp(p.from, m.to) > 0) { continue }
-        var newParts = [j, 1], dfrom = cmp(p.from, m.from), dto = cmp(p.to, m.to);
-        if (dfrom < 0 || !mk.inclusiveLeft && !dfrom)
-          { newParts.push({from: p.from, to: m.from}); }
-        if (dto > 0 || !mk.inclusiveRight && !dto)
-          { newParts.push({from: m.to, to: p.to}); }
-        parts.splice.apply(parts, newParts);
-        j += newParts.length - 3;
-      }
-    }
-    return parts
-  }
-
-  // Connect or disconnect spans from a line.
-  function detachMarkedSpans(line) {
-    var spans = line.markedSpans;
-    if (!spans) { return }
-    for (var i = 0; i < spans.length; ++i)
-      { spans[i].marker.detachLine(line); }
-    line.markedSpans = null;
-  }
-  function attachMarkedSpans(line, spans) {
-    if (!spans) { return }
-    for (var i = 0; i < spans.length; ++i)
-      { spans[i].marker.attachLine(line); }
-    line.markedSpans = spans;
-  }
-
-  // Helpers used when computing which overlapping collapsed span
-  // counts as the larger one.
-  function extraLeft(marker) { return marker.inclusiveLeft ? -1 : 0 }
-  function extraRight(marker) { return marker.inclusiveRight ? 1 : 0 }
-
-  // Returns a number indicating which of two overlapping collapsed
-  // spans is larger (and thus includes the other). Falls back to
-  // comparing ids when the spans cover exactly the same range.
-  function compareCollapsedMarkers(a, b) {
-    var lenDiff = a.lines.length - b.lines.length;
-    if (lenDiff != 0) { return lenDiff }
-    var aPos = a.find(), bPos = b.find();
-    var fromCmp = cmp(aPos.from, bPos.from) || extraLeft(a) - extraLeft(b);
-    if (fromCmp) { return -fromCmp }
-    var toCmp = cmp(aPos.to, bPos.to) || extraRight(a) - extraRight(b);
-    if (toCmp) { return toCmp }
-    return b.id - a.id
-  }
-
-  // Find out whether a line ends or starts in a collapsed span. If
-  // so, return the marker for that span.
-  function collapsedSpanAtSide(line, start) {
-    var sps = sawCollapsedSpans && line.markedSpans, found;
-    if (sps) { for (var sp = (void 0), i = 0; i < sps.length; ++i) {
-      sp = sps[i];
-      if (sp.marker.collapsed && (start ? sp.from : sp.to) == null &&
-          (!found || compareCollapsedMarkers(found, sp.marker) < 0))
-        { found = sp.marker; }
-    } }
-    return found
-  }
-  function collapsedSpanAtStart(line) { return collapsedSpanAtSide(line, true) }
-  function collapsedSpanAtEnd(line) { return collapsedSpanAtSide(line, false) }
-
-  function collapsedSpanAround(line, ch) {
-    var sps = sawCollapsedSpans && line.markedSpans, found;
-    if (sps) { for (var i = 0; i < sps.length; ++i) {
-      var sp = sps[i];
-      if (sp.marker.collapsed && (sp.from == null || sp.from < ch) && (sp.to == null || sp.to > ch) &&
-          (!found || compareCollapsedMarkers(found, sp.marker) < 0)) { found = sp.marker; }
-    } }
-    return found
-  }
-
-  // Test whether there exists a collapsed span that partially
-  // overlaps (covers the start or end, but not both) of a new span.
-  // Such overlap is not allowed.
-  function conflictingCollapsedRange(doc, lineNo$$1, from, to, marker) {
-    var line = getLine(doc, lineNo$$1);
-    var sps = sawCollapsedSpans && line.markedSpans;
-    if (sps) { for (var i = 0; i < sps.length; ++i) {
-      var sp = sps[i];
-      if (!sp.marker.collapsed) { continue }
-      var found = sp.marker.find(0);
-      var fromCmp = cmp(found.from, from) || extraLeft(sp.marker) - extraLeft(marker);
-      var toCmp = cmp(found.to, to) || extraRight(sp.marker) - extraRight(marker);
-      if (fromCmp >= 0 && toCmp <= 0 || fromCmp <= 0 && toCmp >= 0) { continue }
-      if (fromCmp <= 0 && (sp.marker.inclusiveRight && marker.inclusiveLeft ? cmp(found.to, from) >= 0 : cmp(found.to, from) > 0) ||
-          fromCmp >= 0 && (sp.marker.inclusiveRight && marker.inclusiveLeft ? cmp(found.from, to) <= 0 : cmp(found.from, to) < 0))
-        { return true }
-    } }
-  }
-
-  // A visual line is a line as drawn on the screen. Folding, for
-  // example, can cause multiple logical lines to appear on the same
-  // visual line. This finds the start of the visual line that the
-  // given line is part of (usually that is the line itself).
-  function visualLine(line) {
-    var merged;
-    while (merged = collapsedSpanAtStart(line))
-      { line = merged.find(-1, true).line; }
-    return line
-  }
-
-  function visualLineEnd(line) {
-    var merged;
-    while (merged = collapsedSpanAtEnd(line))
-      { line = merged.find(1, true).line; }
-    return line
-  }
-
-  // Returns an array of logical lines that continue the visual line
-  // started by the argument, or undefined if there are no such lines.
-  function visualLineContinued(line) {
-    var merged, lines;
-    while (merged = collapsedSpanAtEnd(line)) {
-      line = merged.find(1, true).line
-      ;(lines || (lines = [])).push(line);
-    }
-    return lines
-  }
-
-  // Get the line number of the start of the visual line that the
-  // given line number is part of.
-  function visualLineNo(doc, lineN) {
-    var line = getLine(doc, lineN), vis = visualLine(line);
-    if (line == vis) { return lineN }
-    return lineNo(vis)
-  }
-
-  // Get the line number of the start of the next visual line after
-  // the given line.
-  function visualLineEndNo(doc, lineN) {
-    if (lineN > doc.lastLine()) { return lineN }
-    var line = getLine(doc, lineN), merged;
-    if (!lineIsHidden(doc, line)) { return lineN }
-    while (merged = collapsedSpanAtEnd(line))
-      { line = merged.find(1, true).line; }
-    return lineNo(line) + 1
-  }
-
-  // Compute whether a line is hidden. Lines count as hidden when they
-  // are part of a visual line that starts with another line, or when
-  // they are entirely covered by collapsed, non-widget span.
-  function lineIsHidden(doc, line) {
-    var sps = sawCollapsedSpans && line.markedSpans;
-    if (sps) { for (var sp = (void 0), i = 0; i < sps.length; ++i) {
-      sp = sps[i];
-      if (!sp.marker.collapsed) { continue }
-      if (sp.from == null) { return true }
-      if (sp.marker.widgetNode) { continue }
-      if (sp.from == 0 && sp.marker.inclusiveLeft && lineIsHiddenInner(doc, line, sp))
-        { return true }
-    } }
-  }
-  function lineIsHiddenInner(doc, line, span) {
-    if (span.to == null) {
-      var end = span.marker.find(1, true);
-      return lineIsHiddenInner(doc, end.line, getMarkedSpanFor(end.line.markedSpans, span.marker))
-    }
-    if (span.marker.inclusiveRight && span.to == line.text.length)
-      { return true }
-    for (var sp = (void 0), i = 0; i < line.markedSpans.length; ++i) {
-      sp = line.markedSpans[i];
-      if (sp.marker.collapsed && !sp.marker.widgetNode && sp.from == span.to &&
-          (sp.to == null || sp.to != span.from) &&
-          (sp.marker.inclusiveLeft || span.marker.inclusiveRight) &&
-          lineIsHiddenInner(doc, line, sp)) { return true }
-    }
-  }
-
-  // Find the height above the given line.
-  function heightAtLine(lineObj) {
-    lineObj = visualLine(lineObj);
-
-    var h = 0, chunk = lineObj.parent;
-    for (var i = 0; i < chunk.lines.length; ++i) {
-      var line = chunk.lines[i];
-      if (line == lineObj) { break }
-      else { h += line.height; }
-    }
-    for (var p = chunk.parent; p; chunk = p, p = chunk.parent) {
-      for (var i$1 = 0; i$1 < p.children.length; ++i$1) {
-        var cur = p.children[i$1];
-        if (cur == chunk) { break }
-        else { h += cur.height; }
-      }
-    }
-    return h
-  }
-
-  // Compute the character length of a line, taking into account
-  // collapsed ranges (see markText) that might hide parts, and join
-  // other lines onto it.
-  function lineLength(line) {
-    if (line.height == 0) { return 0 }
-    var len = line.text.length, merged, cur = line;
-    while (merged = collapsedSpanAtStart(cur)) {
-      var found = merged.find(0, true);
-      cur = found.from.line;
-      len += found.from.ch - found.to.ch;
-    }
-    cur = line;
-    while (merged = collapsedSpanAtEnd(cur)) {
-      var found$1 = merged.find(0, true);
-      len -= cur.text.length - found$1.from.ch;
-      cur = found$1.to.line;
-      len += cur.text.length - found$1.to.ch;
-    }
-    return len
-  }
-
-  // Find the longest line in the document.
-  function findMaxLine(cm) {
-    var d = cm.display, doc = cm.doc;
-    d.maxLine = getLine(doc, doc.first);
-    d.maxLineLength = lineLength(d.maxLine);
-    d.maxLineChanged = true;
-    doc.iter(function (line) {
-      var len = lineLength(line);
-      if (len > d.maxLineLength) {
-        d.maxLineLength = len;
-        d.maxLine = line;
-      }
-    });
-  }
-
-  // LINE DATA STRUCTURE
-
-  // Line objects. These hold state related to a line, including
-  // highlighting info (the styles array).
-  var Line = function(text, markedSpans, estimateHeight) {
-    this.text = text;
-    attachMarkedSpans(this, markedSpans);
-    this.height = estimateHeight ? estimateHeight(this) : 1;
-  };
-
-  Line.prototype.lineNo = function () { return lineNo(this) };
-  eventMixin(Line);
-
-  // Change the content (text, markers) of a line. Automatically
-  // invalidates cached information and tries to re-estimate the
-  // line's height.
-  function updateLine(line, text, markedSpans, estimateHeight) {
-    line.text = text;
-    if (line.stateAfter) { line.stateAfter = null; }
-    if (line.styles) { line.styles = null; }
-    if (line.order != null) { line.order = null; }
-    detachMarkedSpans(line);
-    attachMarkedSpans(line, markedSpans);
-    var estHeight = estimateHeight ? estimateHeight(line) : 1;
-    if (estHeight != line.height) { updateLineHeight(line, estHeight); }
-  }
-
-  // Detach a line from the document tree and its markers.
-  function cleanUpLine(line) {
-    line.parent = null;
-    detachMarkedSpans(line);
-  }
-
-  // Convert a style as returned by a mode (either null, or a string
-  // containing one or more styles) to a CSS style. This is cached,
-  // and also looks for line-wide styles.
-  var styleToClassCache = {}, styleToClassCacheWithMode = {};
-  function interpretTokenStyle(style, options) {
-    if (!style || /^\s*$/.test(style)) { return null }
-    var cache = options.addModeClass ? styleToClassCacheWithMode : styleToClassCache;
-    return cache[style] ||
-      (cache[style] = style.replace(/\S+/g, "cm-$&"))
-  }
-
-  // Render the DOM representation of the text of a line. Also builds
-  // up a 'line map', which points at the DOM nodes that represent
-  // specific stretches of text, and is used by the measuring code.
-  // The returned object contains the DOM node, this map, and
-  // information about line-wide styles that were set by the mode.
-  function buildLineContent(cm, lineView) {
-    // The padding-right forces the element to have a 'border', which
-    // is needed on Webkit to be able to get line-level bounding
-    // rectangles for it (in measureChar).
-    var content = eltP("span", null, null, webkit ? "padding-right: .1px" : null);
-    var builder = {pre: eltP("pre", [content], "CodeMirror-line"), content: content,
-                   col: 0, pos: 0, cm: cm,
-                   trailingSpace: false,
-                   splitSpaces: cm.getOption("lineWrapping")};
-    lineView.measure = {};
-
-    // Iterate over the logical lines that make up this visual line.
-    for (var i = 0; i <= (lineView.rest ? lineView.rest.length : 0); i++) {
-      var line = i ? lineView.rest[i - 1] : lineView.line, order = (void 0);
-      builder.pos = 0;
-      builder.addToken = buildToken;
-      // Optionally wire in some hacks into the token-rendering
-      // algorithm, to deal with browser quirks.
-      if (hasBadBidiRects(cm.display.measure) && (order = getOrder(line, cm.doc.direction)))
-        { builder.addToken = buildTokenBadBidi(builder.addToken, order); }
-      builder.map = [];
-      var allowFrontierUpdate = lineView != cm.display.externalMeasured && lineNo(line);
-      insertLineContent(line, builder, getLineStyles(cm, line, allowFrontierUpdate));
-      if (line.styleClasses) {
-        if (line.styleClasses.bgClass)
-          { builder.bgClass = joinClasses(line.styleClasses.bgClass, builder.bgClass || ""); }
-        if (line.styleClasses.textClass)
-          { builder.textClass = joinClasses(line.styleClasses.textClass, builder.textClass || ""); }
-      }
-
-      // Ensure at least a single node is present, for measuring.
-      if (builder.map.length == 0)
-        { builder.map.push(0, 0, builder.content.appendChild(zeroWidthElement(cm.display.measure))); }
-
-      // Store the map and a cache object for the current logical line
-      if (i == 0) {
-        lineView.measure.map = builder.map;
-        lineView.measure.cache = {};
-      } else {
-  (lineView.measure.maps || (lineView.measure.maps = [])).push(builder.map)
-        ;(lineView.measure.caches || (lineView.measure.caches = [])).push({});
-      }
-    }
-
-    // See issue #2901
-    if (webkit) {
-      var last = builder.content.lastChild;
-      if (/\bcm-tab\b/.test(last.className) || (last.querySelector && last.querySelector(".cm-tab")))
-        { builder.content.className = "cm-tab-wrap-hack"; }
-    }
-
-    signal(cm, "renderLine", cm, lineView.line, builder.pre);
-    if (builder.pre.className)
-      { builder.textClass = joinClasses(builder.pre.className, builder.textClass || ""); }
-
-    return builder
-  }
-
-  function defaultSpecialCharPlaceholder(ch) {
-    var token = elt("span", "\u2022", "cm-invalidchar");
-    token.title = "\\u" + ch.charCodeAt(0).toString(16);
-    token.setAttribute("aria-label", token.title);
-    return token
-  }
-
-  // Build up the DOM representation for a single token, and add it to
-  // the line map. Takes care to render special characters separately.
-  function buildToken(builder, text, style, startStyle, endStyle, css, attributes) {
-    if (!text) { return }
-    var displayText = builder.splitSpaces ? splitSpaces(text, builder.trailingSpace) : text;
-    var special = builder.cm.state.specialChars, mustWrap = false;
-    var content;
-    if (!special.test(text)) {
-      builder.col += text.length;
-      content = document.createTextNode(displayText);
-      builder.map.push(builder.pos, builder.pos + text.length, content);
-      if (ie && ie_version < 9) { mustWrap = true; }
-      builder.pos += text.length;
-    } else {
-      content = document.createDocumentFragment();
-      var pos = 0;
-      while (true) {
-        special.lastIndex = pos;
-        var m = special.exec(text);
-        var skipped = m ? m.index - pos : text.length - pos;
-        if (skipped) {
-          var txt = document.createTextNode(displayText.slice(pos, pos + skipped));
-          if (ie && ie_version < 9) { content.appendChild(elt("span", [txt])); }
-          else { content.appendChild(txt); }
-          builder.map.push(builder.pos, builder.pos + skipped, txt);
-          builder.col += skipped;
-          builder.pos += skipped;
-        }
-        if (!m) { break }
-        pos += skipped + 1;
-        var txt$1 = (void 0);
-        if (m[0] == "\t") {
-          var tabSize = builder.cm.options.tabSize, tabWidth = tabSize - builder.col % tabSize;
-          txt$1 = content.appendChild(elt("span", spaceStr(tabWidth), "cm-tab"));
-          txt$1.setAttribute("role", "presentation");
-          txt$1.setAttribute("cm-text", "\t");
-          builder.col += tabWidth;
-        } else if (m[0] == "\r" || m[0] == "\n") {
-          txt$1 = content.appendChild(elt("span", m[0] == "\r" ? "\u240d" : "\u2424", "cm-invalidchar"));
-          txt$1.setAttribute("cm-text", m[0]);
-          builder.col += 1;
-        } else {
-          txt$1 = builder.cm.options.specialCharPlaceholder(m[0]);
-          txt$1.setAttribute("cm-text", m[0]);
-          if (ie && ie_version < 9) { content.appendChild(elt("span", [txt$1])); }
-          else { content.appendChild(txt$1); }
-          builder.col += 1;
-        }
-        builder.map.push(builder.pos, builder.pos + 1, txt$1);
-        builder.pos++;
-      }
-    }
-    builder.trailingSpace = displayText.charCodeAt(text.length - 1) == 32;
-    if (style || startStyle || endStyle || mustWrap || css) {
-      var fullStyle = style || "";
-      if (startStyle) { fullStyle += startStyle; }
-      if (endStyle) { fullStyle += endStyle; }
-      var token = elt("span", [content], fullStyle, css);
-      if (attributes) {
-        for (var attr in attributes) { if (attributes.hasOwnProperty(attr) && attr != "style" && attr != "class")
-          { token.setAttribute(attr, attributes[attr]); } }
-      }
-      return builder.content.appendChild(token)
-    }
-    builder.content.appendChild(content);
-  }
-
-  // Change some spaces to NBSP to prevent the browser from collapsing
-  // trailing spaces at the end of a line when rendering text (issue #1362).
-  function splitSpaces(text, trailingBefore) {
-    if (text.length > 1 && !/  /.test(text)) { return text }
-    var spaceBefore = trailingBefore, result = "";
-    for (var i = 0; i < text.length; i++) {
-      var ch = text.charAt(i);
-      if (ch == " " && spaceBefore && (i == text.length - 1 || text.charCodeAt(i + 1) == 32))
-        { ch = "\u00a0"; }
-      result += ch;
-      spaceBefore = ch == " ";
-    }
-    return result
-  }
-
-  // Work around nonsense dimensions being reported for stretches of
-  // right-to-left text.
-  function buildTokenBadBidi(inner, order) {
-    return function (builder, text, style, startStyle, endStyle, css, attributes) {
-      style = style ? style + " cm-force-border" : "cm-force-border";
-      var start = builder.pos, end = start + text.length;
-      for (;;) {
-        // Find the part that overlaps with the start of this text
-        var part = (void 0);
-        for (var i = 0; i < order.length; i++) {
-          part = order[i];
-          if (part.to > start && part.from <= start) { break }
-        }
-        if (part.to >= end) { return inner(builder, text, style, startStyle, endStyle, css, attributes) }
-        inner(builder, text.slice(0, part.to - start), style, startStyle, null, css, attributes);
-        startStyle = null;
-        text = text.slice(part.to - start);
-        start = part.to;
-      }
-    }
-  }
-
-  function buildCollapsedSpan(builder, size, marker, ignoreWidget) {
-    var widget = !ignoreWidget && marker.widgetNode;
-    if (widget) { builder.map.push(builder.pos, builder.pos + size, widget); }
-    if (!ignoreWidget && builder.cm.display.input.needsContentAttribute) {
-      if (!widget)
-        { widget = builder.content.appendChild(document.createElement("span")); }
-      widget.setAttribute("cm-marker", marker.id);
-    }
-    if (widget) {
-      builder.cm.display.input.setUneditable(widget);
-      builder.content.appendChild(widget);
-    }
-    builder.pos += size;
-    builder.trailingSpace = false;
-  }
-
-  // Outputs a number of spans to make up a line, taking highlighting
-  // and marked text into account.
-  function insertLineContent(line, builder, styles) {
-    var spans = line.markedSpans, allText = line.text, at = 0;
-    if (!spans) {
-      for (var i$1 = 1; i$1 < styles.length; i$1+=2)
-        { builder.addToken(builder, allText.slice(at, at = styles[i$1]), interpretTokenStyle(styles[i$1+1], builder.cm.options)); }
-      return
-    }
-
-    var len = allText.length, pos = 0, i = 1, text = "", style, css;
-    var nextChange = 0, spanStyle, spanEndStyle, spanStartStyle, collapsed, attributes;
-    for (;;) {
-      if (nextChange == pos) { // Update current marker set
-        spanStyle = spanEndStyle = spanStartStyle = css = "";
-        attributes = null;
-        collapsed = null; nextChange = Infinity;
-        var foundBookmarks = [], endStyles = (void 0);
-        for (var j = 0; j < spans.length; ++j) {
-          var sp = spans[j], m = sp.marker;
-          if (m.type == "bookmark" && sp.from == pos && m.widgetNode) {
-            foundBookmarks.push(m);
-          } else if (sp.from <= pos && (sp.to == null || sp.to > pos || m.collapsed && sp.to == pos && sp.from == pos)) {
-            if (sp.to != null && sp.to != pos && nextChange > sp.to) {
-              nextChange = sp.to;
-              spanEndStyle = "";
-            }
-            if (m.className) { spanStyle += " " + m.className; }
-            if (m.css) { css = (css ? css + ";" : "") + m.css; }
-            if (m.startStyle && sp.from == pos) { spanStartStyle += " " + m.startStyle; }
-            if (m.endStyle && sp.to == nextChange) { (endStyles || (endStyles = [])).push(m.endStyle, sp.to); }
-            // support for the old title property
-            // https://github.com/codemirror/CodeMirror/pull/5673
-            if (m.title) { (attributes || (attributes = {})).title = m.title; }
-            if (m.attributes) {
-              for (var attr in m.attributes)
-                { (attributes || (attributes = {}))[attr] = m.attributes[attr]; }
-            }
-            if (m.collapsed && (!collapsed || compareCollapsedMarkers(collapsed.marker, m) < 0))
-              { collapsed = sp; }
-          } else if (sp.from > pos && nextChange > sp.from) {
-            nextChange = sp.from;
-          }
-        }
-        if (endStyles) { for (var j$1 = 0; j$1 < endStyles.length; j$1 += 2)
-          { if (endStyles[j$1 + 1] == nextChange) { spanEndStyle += " " + endStyles[j$1]; } } }
-
-        if (!collapsed || collapsed.from == pos) { for (var j$2 = 0; j$2 < foundBookmarks.length; ++j$2)
-          { buildCollapsedSpan(builder, 0, foundBookmarks[j$2]); } }
-        if (collapsed && (collapsed.from || 0) == pos) {
-          buildCollapsedSpan(builder, (collapsed.to == null ? len + 1 : collapsed.to) - pos,
-                             collapsed.marker, collapsed.from == null);
-          if (collapsed.to == null) { return }
-          if (collapsed.to == pos) { collapsed = false; }
-        }
-      }
-      if (pos >= len) { break }
-
-      var upto = Math.min(len, nextChange);
-      while (true) {
-        if (text) {
-          var end = pos + text.length;
-          if (!collapsed) {
-            var tokenText = end > upto ? text.slice(0, upto - pos) : text;
-            builder.addToken(builder, tokenText, style ? style + spanStyle : spanStyle,
-                             spanStartStyle, pos + tokenText.length == nextChange ? spanEndStyle : "", css, attributes);
-          }
-          if (end >= upto) {text = text.slice(upto - pos); pos = upto; break}
-          pos = end;
-          spanStartStyle = "";
-        }
-        text = allText.slice(at, at = styles[i++]);
-        style = interpretTokenStyle(styles[i++], builder.cm.options);
-      }
-    }
-  }
-
-
-  // These objects are used to represent the visible (currently drawn)
-  // part of the document. A LineView may correspond to multiple
-  // logical lines, if those are connected by collapsed ranges.
-  function LineView(doc, line, lineN) {
-    // The starting line
-    this.line = line;
-    // Continuing lines, if any
-    this.rest = visualLineContinued(line);
-    // Number of logical lines in this visual line
-    this.size = this.rest ? lineNo(lst(this.rest)) - lineN + 1 : 1;
-    this.node = this.text = null;
-    this.hidden = lineIsHidden(doc, line);
-  }
-
-  // Create a range of LineView objects for the given lines.
-  function buildViewArray(cm, from, to) {
-    var array = [], nextPos;
-    for (var pos = from; pos < to; pos = nextPos) {
-      var view = new LineView(cm.doc, getLine(cm.doc, pos), pos);
-      nextPos = pos + view.size;
-      array.push(view);
-    }
-    return array
-  }
-
-  var operationGroup = null;
-
-  function pushOperation(op) {
-    if (operationGroup) {
-      operationGroup.ops.push(op);
-    } else {
-      op.ownsGroup = operationGroup = {
-        ops: [op],
-        delayedCallbacks: []
-      };
-    }
-  }
-
-  function fireCallbacksForOps(group) {
-    // Calls delayed callbacks and cursorActivity handlers until no
-    // new ones appear
-    var callbacks = group.delayedCallbacks, i = 0;
-    do {
-      for (; i < callbacks.length; i++)
-        { callbacks[i].call(null); }
-      for (var j = 0; j < group.ops.length; j++) {
-        var op = group.ops[j];
-        if (op.cursorActivityHandlers)
-          { while (op.cursorActivityCalled < op.cursorActivityHandlers.length)
-            { op.cursorActivityHandlers[op.cursorActivityCalled++].call(null, op.cm); } }
-      }
-    } while (i < callbacks.length)
-  }
-
-  function finishOperation(op, endCb) {
-    var group = op.ownsGroup;
-    if (!group) { return }
-
-    try { fireCallbacksForOps(group); }
-    finally {
-      operationGroup = null;
-      endCb(group);
-    }
-  }
-
-  var orphanDelayedCallbacks = null;
-
-  // Often, we want to signal events at a point where we are in the
-  // middle of some work, but don't want the handler to start calling
-  // other methods on the editor, which might be in an inconsistent
-  // state or simply not expect any other events to happen.
-  // signalLater looks whether there are any handlers, and schedules
-  // them to be executed when the last operation ends, or, if no
-  // operation is active, when a timeout fires.
-  function signalLater(emitter, type /*, values...*/) {
-    var arr = getHandlers(emitter, type);
-    if (!arr.length) { return }
-    var args = Array.prototype.slice.call(arguments, 2), list;
-    if (operationGroup) {
-      list = operationGroup.delayedCallbacks;
-    } else if (orphanDelayedCallbacks) {
-      list = orphanDelayedCallbacks;
-    } else {
-      list = orphanDelayedCallbacks = [];
-      setTimeout(fireOrphanDelayed, 0);
-    }
-    var loop = function ( i ) {
-      list.push(function () { return arr[i].apply(null, args); });
-    };
-
-    for (var i = 0; i < arr.length; ++i)
-      loop( i );
-  }
-
-  function fireOrphanDelayed() {
-    var delayed = orphanDelayedCallbacks;
-    orphanDelayedCallbacks = null;
-    for (var i = 0; i < delayed.length; ++i) { delayed[i](); }
-  }
-
-  // When an aspect of a line changes, a string is added to
-  // lineView.changes. This updates the relevant part of the line's
-  // DOM structure.
-  function updateLineForChanges(cm, lineView, lineN, dims) {
-    for (var j = 0; j < lineView.changes.length; j++) {
-      var type = lineView.changes[j];
-      if (type == "text") { updateLineText(cm, lineView); }
-      else if (type == "gutter") { updateLineGutter(cm, lineView, lineN, dims); }
-      else if (type == "class") { updateLineClasses(cm, lineView); }
-      else if (type == "widget") { updateLineWidgets(cm, lineView, dims); }
-    }
-    lineView.changes = null;
-  }
-
-  // Lines with gutter elements, widgets or a background class need to
-  // be wrapped, and have the extra elements added to the wrapper div
-  function ensureLineWrapped(lineView) {
-    if (lineView.node == lineView.text) {
-      lineView.node = elt("div", null, null, "position: relative");
-      if (lineView.text.parentNode)
-        { lineView.text.parentNode.replaceChild(lineView.node, lineView.text); }
-      lineView.node.appendChild(lineView.text);
-      if (ie && ie_version < 8) { lineView.node.style.zIndex = 2; }
-    }
-    return lineView.node
-  }
-
-  function updateLineBackground(cm, lineView) {
-    var cls = lineView.bgClass ? lineView.bgClass + " " + (lineView.line.bgClass || "") : lineView.line.bgClass;
-    if (cls) { cls += " CodeMirror-linebackground"; }
-    if (lineView.background) {
-      if (cls) { lineView.background.className = cls; }
-      else { lineView.background.parentNode.removeChild(lineView.background); lineView.background = null; }
-    } else if (cls) {
-      var wrap = ensureLineWrapped(lineView);
-      lineView.background = wrap.insertBefore(elt("div", null, cls), wrap.firstChild);
-      cm.display.input.setUneditable(lineView.background);
-    }
-  }
-
-  // Wrapper around buildLineContent which will reuse the structure
-  // in display.externalMeasured when possible.
-  function getLineContent(cm, lineView) {
-    var ext = cm.display.externalMeasured;
-    if (ext && ext.line == lineView.line) {
-      cm.display.externalMeasured = null;
-      lineView.measure = ext.measure;
-      return ext.built
-    }
-    return buildLineContent(cm, lineView)
-  }
-
-  // Redraw the line's text. Interacts with the background and text
-  // classes because the mode may output tokens that influence these
-  // classes.
-  function updateLineText(cm, lineView) {
-    var cls = lineView.text.className;
-    var built = getLineContent(cm, lineView);
-    if (lineView.text == lineView.node) { lineView.node = built.pre; }
-    lineView.text.parentNode.replaceChild(built.pre, lineView.text);
-    lineView.text = built.pre;
-    if (built.bgClass != lineView.bgClass || built.textClass != lineView.textClass) {
-      lineView.bgClass = built.bgClass;
-      lineView.textClass = built.textClass;
-      updateLineClasses(cm, lineView);
-    } else if (cls) {
-      lineView.text.className = cls;
-    }
-  }
-
-  function updateLineClasses(cm, lineView) {
-    updateLineBackground(cm, lineView);
-    if (lineView.line.wrapClass)
-      { ensureLineWrapped(lineView).className = lineView.line.wrapClass; }
-    else if (lineView.node != lineView.text)
-      { lineView.node.className = ""; }
-    var textClass = lineView.textClass ? lineView.textClass + " " + (lineView.line.textClass || "") : lineView.line.textClass;
-    lineView.text.className = textClass || "";
-  }
-
-  function updateLineGutter(cm, lineView, lineN, dims) {
-    if (lineView.gutter) {
-      lineView.node.removeChild(lineView.gutter);
-      lineView.gutter = null;
-    }
-    if (lineView.gutterBackground) {
-      lineView.node.removeChild(lineView.gutterBackground);
-      lineView.gutterBackground = null;
-    }
-    if (lineView.line.gutterClass) {
-      var wrap = ensureLineWrapped(lineView);
-      lineView.gutterBackground = elt("div", null, "CodeMirror-gutter-background " + lineView.line.gutterClass,
-                                      ("left: " + (cm.options.fixedGutter ? dims.fixedPos : -dims.gutterTotalWidth) + "px; width: " + (dims.gutterTotalWidth) + "px"));
-      cm.display.input.setUneditable(lineView.gutterBackground);
-      wrap.insertBefore(lineView.gutterBackground, lineView.text);
-    }
-    var markers = lineView.line.gutterMarkers;
-    if (cm.options.lineNumbers || markers) {
-      var wrap$1 = ensureLineWrapped(lineView);
-      var gutterWrap = lineView.gutter = elt("div", null, "CodeMirror-gutter-wrapper", ("left: " + (cm.options.fixedGutter ? dims.fixedPos : -dims.gutterTotalWidth) + "px"));
-      cm.display.input.setUneditable(gutterWrap);
-      wrap$1.insertBefore(gutterWrap, lineView.text);
-      if (lineView.line.gutterClass)
-        { gutterWrap.className += " " + lineView.line.gutterClass; }
-      if (cm.options.lineNumbers && (!markers || !markers["CodeMirror-linenumbers"]))
-        { lineView.lineNumber = gutterWrap.appendChild(
-          elt("div", lineNumberFor(cm.options, lineN),
-              "CodeMirror-linenumber CodeMirror-gutter-elt",
-              ("left: " + (dims.gutterLeft["CodeMirror-linenumbers"]) + "px; width: " + (cm.display.lineNumInnerWidth) + "px"))); }
-      if (markers) { for (var k = 0; k < cm.display.gutterSpecs.length; ++k) {
-        var id = cm.display.gutterSpecs[k].className, found = markers.hasOwnProperty(id) && markers[id];
-        if (found)
-          { gutterWrap.appendChild(elt("div", [found], "CodeMirror-gutter-elt",
-                                     ("left: " + (dims.gutterLeft[id]) + "px; width: " + (dims.gutterWidth[id]) + "px"))); }
-      } }
-    }
-  }
-
-  function updateLineWidgets(cm, lineView, dims) {
-    if (lineView.alignable) { lineView.alignable = null; }
-    for (var node = lineView.node.firstChild, next = (void 0); node; node = next) {
-      next = node.nextSibling;
-      if (node.className == "CodeMirror-linewidget")
-        { lineView.node.removeChild(node); }
-    }
-    insertLineWidgets(cm, lineView, dims);
-  }
-
-  // Build a line's DOM representation from scratch
-  function buildLineElement(cm, lineView, lineN, dims) {
-    var built = getLineContent(cm, lineView);
-    lineView.text = lineView.node = built.pre;
-    if (built.bgClass) { lineView.bgClass = built.bgClass; }
-    if (built.textClass) { lineView.textClass = built.textClass; }
-
-    updateLineClasses(cm, lineView);
-    updateLineGutter(cm, lineView, lineN, dims);
-    insertLineWidgets(cm, lineView, dims);
-    return lineView.node
-  }
-
-  // A lineView may contain multiple logical lines (when merged by
-  // collapsed spans). The widgets for all of them need to be drawn.
-  function insertLineWidgets(cm, lineView, dims) {
-    insertLineWidgetsFor(cm, lineView.line, lineView, dims, true);
-    if (lineView.rest) { for (var i = 0; i < lineView.rest.length; i++)
-      { insertLineWidgetsFor(cm, lineView.rest[i], lineView, dims, false); } }
-  }
-
-  function insertLineWidgetsFor(cm, line, lineView, dims, allowAbove) {
-    if (!line.widgets) { return }
-    var wrap = ensureLineWrapped(lineView);
-    for (var i = 0, ws = line.widgets; i < ws.length; ++i) {
-      var widget = ws[i], node = elt("div", [widget.node], "CodeMirror-linewidget");
-      if (!widget.handleMouseEvents) { node.setAttribute("cm-ignore-events", "true"); }
-      positionLineWidget(widget, node, lineView, dims);
-      cm.display.input.setUneditable(node);
-      if (allowAbove && widget.above)
-        { wrap.insertBefore(node, lineView.gutter || lineView.text); }
-      else
-        { wrap.appendChild(node); }
-      signalLater(widget, "redraw");
-    }
-  }
-
-  function positionLineWidget(widget, node, lineView, dims) {
-    if (widget.noHScroll) {
-  (lineView.alignable || (lineView.alignable = [])).push(node);
-      var width = dims.wrapperWidth;
-      node.style.left = dims.fixedPos + "px";
-      if (!widget.coverGutter) {
-        width -= dims.gutterTotalWidth;
-        node.style.paddingLeft = dims.gutterTotalWidth + "px";
-      }
-      node.style.width = width + "px";
-    }
-    if (widget.coverGutter) {
-      node.style.zIndex = 5;
-      node.style.position = "relative";
-      if (!widget.noHScroll) { node.style.marginLeft = -dims.gutterTotalWidth + "px"; }
-    }
-  }
-
-  function widgetHeight(widget) {
-    if (widget.height != null) { return widget.height }
-    var cm = widget.doc.cm;
-    if (!cm) { return 0 }
-    if (!contains(document.body, widget.node)) {
-      var parentStyle = "position: relative;";
-      if (widget.coverGutter)
-        { parentStyle += "margin-left: -" + cm.display.gutters.offsetWidth + "px;"; }
-      if (widget.noHScroll)
-        { parentStyle += "width: " + cm.display.wrapper.clientWidth + "px;"; }
-      removeChildrenAndAdd(cm.display.measure, elt("div", [widget.node], null, parentStyle));
-    }
-    return widget.height = widget.node.parentNode.offsetHeight
-  }
-
-  // Return true when the given mouse event happened in a widget
-  function eventInWidget(display, e) {
-    for (var n = e_target(e); n != display.wrapper; n = n.parentNode) {
-      if (!n || (n.nodeType == 1 && n.getAttribute("cm-ignore-events") == "true") ||
-          (n.parentNode == display.sizer && n != display.mover))
-        { return true }
-    }
-  }
-
-  // POSITION MEASUREMENT
-
-  function paddingTop(display) {return display.lineSpace.offsetTop}
-  function paddingVert(display) {return display.mover.offsetHeight - display.lineSpace.offsetHeight}
-  function paddingH(display) {
-    if (display.cachedPaddingH) { return display.cachedPaddingH }
-    var e = removeChildrenAndAdd(display.measure, elt("pre", "x"));
-    var style = window.getComputedStyle ? window.getComputedStyle(e) : e.currentStyle;
-    var data = {left: parseInt(style.paddingLeft), right: parseInt(style.paddingRight)};
-    if (!isNaN(data.left) && !isNaN(data.right)) { display.cachedPaddingH = data; }
-    return data
-  }
-
-  function scrollGap(cm) { return scrollerGap - cm.display.nativeBarWidth }
-  function displayWidth(cm) {
-    return cm.display.scroller.clientWidth - scrollGap(cm) - cm.display.barWidth
-  }
-  function displayHeight(cm) {
-    return cm.display.scroller.clientHeight - scrollGap(cm) - cm.display.barHeight
-  }
-
-  // Ensure the lineView.wrapping.heights array is populated. This is
-  // an array of bottom offsets for the lines that make up a drawn
-  // line. When lineWrapping is on, there might be more than one
-  // height.
-  function ensureLineHeights(cm, lineView, rect) {
-    var wrapping = cm.options.lineWrapping;
-    var curWidth = wrapping && displayWidth(cm);
-    if (!lineView.measure.heights || wrapping && lineView.measure.width != curWidth) {
-      var heights = lineView.measure.heights = [];
-      if (wrapping) {
-        lineView.measure.width = curWidth;
-        var rects = lineView.text.firstChild.getClientRects();
-        for (var i = 0; i < rects.length - 1; i++) {
-          var cur = rects[i], next = rects[i + 1];
-          if (Math.abs(cur.bottom - next.bottom) > 2)
-            { heights.push((cur.bottom + next.top) / 2 - rect.top); }
-        }
-      }
-      heights.push(rect.bottom - rect.top);
-    }
-  }
-
-  // Find a line map (mapping character offsets to text nodes) and a
-  // measurement cache for the given line number. (A line view might
-  // contain multiple lines when collapsed ranges are present.)
-  function mapFromLineView(lineView, line, lineN) {
-    if (lineView.line == line)
-      { return {map: lineView.measure.map, cache: lineView.measure.cache} }
-    for (var i = 0; i < lineView.rest.length; i++)
-      { if (lineView.rest[i] == line)
-        { return {map: lineView.measure.maps[i], cache: lineView.measure.caches[i]} } }
-    for (var i$1 = 0; i$1 < lineView.rest.length; i$1++)
-      { if (lineNo(lineView.rest[i$1]) > lineN)
-        { return {map: lineView.measure.maps[i$1], cache: lineView.measure.caches[i$1], before: true} } }
-  }
-
-  // Render a line into the hidden node display.externalMeasured. Used
-  // when measurement is needed for a line that's not in the viewport.
-  function updateExternalMeasurement(cm, line) {
-    line = visualLine(line);
-    var lineN = lineNo(line);
-    var view = cm.display.externalMeasured = new LineView(cm.doc, line, lineN);
-    view.lineN = lineN;
-    var built = view.built = buildLineContent(cm, view);
-    view.text = built.pre;
-    removeChildrenAndAdd(cm.display.lineMeasure, built.pre);
-    return view
-  }
-
-  // Get a {top, bottom, left, right} box (in line-local coordinates)
-  // for a given character.
-  function measureChar(cm, line, ch, bias) {
-    return measureCharPrepared(cm, prepareMeasureForLine(cm, line), ch, bias)
-  }
-
-  // Find a line view that corresponds to the given line number.
-  function findViewForLine(cm, lineN) {
-    if (lineN >= cm.display.viewFrom && lineN < cm.display.viewTo)
-      { return cm.display.view[findViewIndex(cm, lineN)] }
-    var ext = cm.display.externalMeasured;
-    if (ext && lineN >= ext.lineN && lineN < ext.lineN + ext.size)
-      { return ext }
-  }
-
-  // Measurement can be split in two steps, the set-up work that
-  // applies to the whole line, and the measurement of the actual
-  // character. Functions like coordsChar, that need to do a lot of
-  // measurements in a row, can thus ensure that the set-up work is
-  // only done once.
-  function prepareMeasureForLine(cm, line) {
-    var lineN = lineNo(line);
-    var view = findViewForLine(cm, lineN);
-    if (view && !view.text) {
-      view = null;
-    } else if (view && view.changes) {
-      updateLineForChanges(cm, view, lineN, getDimensions(cm));
-      cm.curOp.forceUpdate = true;
-    }
-    if (!view)
-      { view = updateExternalMeasurement(cm, line); }
-
-    var info = mapFromLineView(view, line, lineN);
-    return {
-      line: line, view: view, rect: null,
-      map: info.map, cache: info.cache, before: info.before,
-      hasHeights: false
-    }
-  }
-
-  // Given a prepared measurement object, measures the position of an
-  // actual character (or fetches it from the cache).
-  function measureCharPrepared(cm, prepared, ch, bias, varHeight) {
-    if (prepared.before) { ch = -1; }
-    var key = ch + (bias || ""), found;
-    if (prepared.cache.hasOwnProperty(key)) {
-      found = prepared.cache[key];
-    } else {
-      if (!prepared.rect)
-        { prepared.rect = prepared.view.text.getBoundingClientRect(); }
-      if (!prepared.hasHeights) {
-        ensureLineHeights(cm, prepared.view, prepared.rect);
-        prepared.hasHeights = true;
-      }
-      found = measureCharInner(cm, prepared, ch, bias);
-      if (!found.bogus) { prepared.cache[key] = found; }
-    }
-    return {left: found.left, right: found.right,
-            top: varHeight ? found.rtop : found.top,
-            bottom: varHeight ? found.rbottom : found.bottom}
-  }
-
-  var nullRect = {left: 0, right: 0, top: 0, bottom: 0};
-
-  function nodeAndOffsetInLineMap(map$$1, ch, bias) {
-    var node, start, end, collapse, mStart, mEnd;
-    // First, search the line map for the text node corresponding to,
-    // or closest to, the target character.
-    for (var i = 0; i < map$$1.length; i += 3) {
-      mStart = map$$1[i];
-      mEnd = map$$1[i + 1];
-      if (ch < mStart) {
-        start = 0; end = 1;
-        collapse = "left";
-      } else if (ch < mEnd) {
-        start = ch - mStart;
-        end = start + 1;
-      } else if (i == map$$1.length - 3 || ch == mEnd && map$$1[i + 3] > ch) {
-        end = mEnd - mStart;
-        start = end - 1;
-        if (ch >= mEnd) { collapse = "right"; }
-      }
-      if (start != null) {
-        node = map$$1[i + 2];
-        if (mStart == mEnd && bias == (node.insertLeft ? "left" : "right"))
-          { collapse = bias; }
-        if (bias == "left" && start == 0)
-          { while (i && map$$1[i - 2] == map$$1[i - 3] && map$$1[i - 1].insertLeft) {
-            node = map$$1[(i -= 3) + 2];
-            collapse = "left";
-          } }
-        if (bias == "right" && start == mEnd - mStart)
-          { while (i < map$$1.length - 3 && map$$1[i + 3] == map$$1[i + 4] && !map$$1[i + 5].insertLeft) {
-            node = map$$1[(i += 3) + 2];
-            collapse = "right";
-          } }
-        break
-      }
-    }
-    return {node: node, start: start, end: end, collapse: collapse, coverStart: mStart, coverEnd: mEnd}
-  }
-
-  function getUsefulRect(rects, bias) {
-    var rect = nullRect;
-    if (bias == "left") { for (var i = 0; i < rects.length; i++) {
-      if ((rect = rects[i]).left != rect.right) { break }
-    } } else { for (var i$1 = rects.length - 1; i$1 >= 0; i$1--) {
-      if ((rect = rects[i$1]).left != rect.right) { break }
-    } }
-    return rect
-  }
-
-  function measureCharInner(cm, prepared, ch, bias) {
-    var place = nodeAndOffsetInLineMap(prepared.map, ch, bias);
-    var node = place.node, start = place.start, end = place.end, collapse = place.collapse;
-
-    var rect;
-    if (node.nodeType == 3) { // If it is a text node, use a range to retrieve the coordinates.
-      for (var i$1 = 0; i$1 < 4; i$1++) { // Retry a maximum of 4 times when nonsense rectangles are returned
-        while (start && isExtendingChar(prepared.line.text.charAt(place.coverStart + start))) { --start; }
-        while (place.coverStart + end < place.coverEnd && isExtendingChar(prepared.line.text.charAt(place.coverStart + end))) { ++end; }
-        if (ie && ie_version < 9 && start == 0 && end == place.coverEnd - place.coverStart)
-          { rect = node.parentNode.getBoundingClientRect(); }
-        else
-          { rect = getUsefulRect(range(node, start, end).getClientRects(), bias); }
-        if (rect.left || rect.right || start == 0) { break }
-        end = start;
-        start = start - 1;
-        collapse = "right";
-      }
-      if (ie && ie_version < 11) { rect = maybeUpdateRectForZooming(cm.display.measure, rect); }
-    } else { // If it is a widget, simply get the box for the whole widget.
-      if (start > 0) { collapse = bias = "right"; }
-      var rects;
-      if (cm.options.lineWrapping && (rects = node.getClientRects()).length > 1)
-        { rect = rects[bias == "right" ? rects.length - 1 : 0]; }
-      else
-        { rect = node.getBoundingClientRect(); }
-    }
-    if (ie && ie_version < 9 && !start && (!rect || !rect.left && !rect.right)) {
-      var rSpan = node.parentNode.getClientRects()[0];
-      if (rSpan)
-        { rect = {left: rSpan.left, right: rSpan.left + charWidth(cm.display), top: rSpan.top, bottom: rSpan.bottom}; }
-      else
-        { rect = nullRect; }
-    }
-
-    var rtop = rect.top - prepared.rect.top, rbot = rect.bottom - prepared.rect.top;
-    var mid = (rtop + rbot) / 2;
-    var heights = prepared.view.measure.heights;
-    var i = 0;
-    for (; i < heights.length - 1; i++)
-      { if (mid < heights[i]) { break } }
-    var top = i ? heights[i - 1] : 0, bot = heights[i];
-    var result = {left: (collapse == "right" ? rect.right : rect.left) - prepared.rect.left,
-                  right: (collapse == "left" ? rect.left : rect.right) - prepared.rect.left,
-                  top: top, bottom: bot};
-    if (!rect.left && !rect.right) { result.bogus = true; }
-    if (!cm.options.singleCursorHeightPerLine) { result.rtop = rtop; result.rbottom = rbot; }
-
-    return result
-  }
-
-  // Work around problem with bounding client rects on ranges being
-  // returned incorrectly when zoomed on IE10 and below.
-  function maybeUpdateRectForZooming(measure, rect) {
-    if (!window.screen || screen.logicalXDPI == null ||
-        screen.logicalXDPI == screen.deviceXDPI || !hasBadZoomedRects(measure))
-      { return rect }
-    var scaleX = screen.logicalXDPI / screen.deviceXDPI;
-    var scaleY = screen.logicalYDPI / screen.deviceYDPI;
-    return {left: rect.left * scaleX, right: rect.right * scaleX,
-            top: rect.top * scaleY, bottom: rect.bottom * scaleY}
-  }
-
-  function clearLineMeasurementCacheFor(lineView) {
-    if (lineView.measure) {
-      lineView.measure.cache = {};
-      lineView.measure.heights = null;
-      if (lineView.rest) { for (var i = 0; i < lineView.rest.length; i++)
-        { lineView.measure.caches[i] = {}; } }
-    }
-  }
-
-  function clearLineMeasurementCache(cm) {
-    cm.display.externalMeasure = null;
-    removeChildren(cm.display.lineMeasure);
-    for (var i = 0; i < cm.display.view.length; i++)
-      { clearLineMeasurementCacheFor(cm.display.view[i]); }
-  }
-
-  function clearCaches(cm) {
-    clearLineMeasurementCache(cm);
-    cm.display.cachedCharWidth = cm.display.cachedTextHeight = cm.display.cachedPaddingH = null;
-    if (!cm.options.lineWrapping) { cm.display.maxLineChanged = true; }
-    cm.display.lineNumChars = null;
-  }
-
-  function pageScrollX() {
-    // Work around https://bugs.chromium.org/p/chromium/issues/detail?id=489206
-    // which causes page_Offset and bounding client rects to use
-    // different reference viewports and invalidate our calculations.
-    if (chrome && android) { return -(document.body.getBoundingClientRect().left - parseInt(getComputedStyle(document.body).marginLeft)) }
-    return window.pageXOffset || (document.documentElement || document.body).scrollLeft
-  }
-  function pageScrollY() {
-    if (chrome && android) { return -(document.body.getBoundingClientRect().top - parseInt(getComputedStyle(document.body).marginTop)) }
-    return window.pageYOffset || (document.documentElement || document.body).scrollTop
-  }
-
-  function widgetTopHeight(lineObj) {
-    var height = 0;
-    if (lineObj.widgets) { for (var i = 0; i < lineObj.widgets.length; ++i) { if (lineObj.widgets[i].above)
-      { height += widgetHeight(lineObj.widgets[i]); } } }
-    return height
-  }
-
-  // Converts a {top, bottom, left, right} box from line-local
-  // coordinates into another coordinate system. Context may be one of
-  // "line", "div" (display.lineDiv), "local"./null (editor), "window",
-  // or "page".
-  function intoCoordSystem(cm, lineObj, rect, context, includeWidgets) {
-    if (!includeWidgets) {
-      var height = widgetTopHeight(lineObj);
-      rect.top += height; rect.bottom += height;
-    }
-    if (context == "line") { return rect }
-    if (!context) { context = "local"; }
-    var yOff = heightAtLine(lineObj);
-    if (context == "local") { yOff += paddingTop(cm.display); }
-    else { yOff -= cm.display.viewOffset; }
-    if (context == "page" || context == "window") {
-      var lOff = cm.display.lineSpace.getBoundingClientRect();
-      yOff += lOff.top + (context == "window" ? 0 : pageScrollY());
-      var xOff = lOff.left + (context == "window" ? 0 : pageScrollX());
-      rect.left += xOff; rect.right += xOff;
-    }
-    rect.top += yOff; rect.bottom += yOff;
-    return rect
-  }
-
-  // Coverts a box from "div" coords to another coordinate system.
-  // Context may be "window", "page", "div", or "local"./null.
-  function fromCoordSystem(cm, coords, context) {
-    if (context == "div") { return coords }
-    var left = coords.left, top = coords.top;
-    // First move into "page" coordinate system
-    if (context == "page") {
-      left -= pageScrollX();
-      top -= pageScrollY();
-    } else if (context == "local" || !context) {
-      var localBox = cm.display.sizer.getBoundingClientRect();
-      left += localBox.left;
-      top += localBox.top;
-    }
-
-    var lineSpaceBox = cm.display.lineSpace.getBoundingClientRect();
-    return {left: left - lineSpaceBox.left, top: top - lineSpaceBox.top}
-  }
-
-  function charCoords(cm, pos, context, lineObj, bias) {
-    if (!lineObj) { lineObj = getLine(cm.doc, pos.line); }
-    return intoCoordSystem(cm, lineObj, measureChar(cm, lineObj, pos.ch, bias), context)
-  }
-
-  // Returns a box for a given cursor position, which may have an
-  // 'other' property containing the position of the secondary cursor
-  // on a bidi boundary.
-  // A cursor Pos(line, char, "before") is on the same visual line as `char - 1`
-  // and after `char - 1` in writing order of `char - 1`
-  // A cursor Pos(line, char, "after") is on the same visual line as `char`
-  // and before `char` in writing order of `char`
-  // Examples (upper-case letters are RTL, lower-case are LTR):
-  //     Pos(0, 1, ...)
-  //     before   after
-  // ab     a|b     a|b
-  // aB     a|B     aB|
-  // Ab     |Ab     A|b
-  // AB     B|A     B|A
-  // Every position after the last character on a line is considered to stick
-  // to the last character on the line.
-  function cursorCoords(cm, pos, context, lineObj, preparedMeasure, varHeight) {
-    lineObj = lineObj || getLine(cm.doc, pos.line);
-    if (!preparedMeasure) { preparedMeasure = prepareMeasureForLine(cm, lineObj); }
-    function get(ch, right) {
-      var m = measureCharPrepared(cm, preparedMeasure, ch, right ? "right" : "left", varHeight);
-      if (right) { m.left = m.right; } else { m.right = m.left; }
-      return intoCoordSystem(cm, lineObj, m, context)
-    }
-    var order = getOrder(lineObj, cm.doc.direction), ch = pos.ch, sticky = pos.sticky;
-    if (ch >= lineObj.text.length) {
-      ch = lineObj.text.length;
-      sticky = "before";
-    } else if (ch <= 0) {
-      ch = 0;
-      sticky = "after";
-    }
-    if (!order) { return get(sticky == "before" ? ch - 1 : ch, sticky == "before") }
-
-    function getBidi(ch, partPos, invert) {
-      var part = order[partPos], right = part.level == 1;
-      return get(invert ? ch - 1 : ch, right != invert)
-    }
-    var partPos = getBidiPartAt(order, ch, sticky);
-    var other = bidiOther;
-    var val = getBidi(ch, partPos, sticky == "before");
-    if (other != null) { val.other = getBidi(ch, other, sticky != "before"); }
-    return val
-  }
-
-  // Used to cheaply estimate the coordinates for a position. Used for
-  // intermediate scroll updates.
-  function estimateCoords(cm, pos) {
-    var left = 0;
-    pos = clipPos(cm.doc, pos);
-    if (!cm.options.lineWrapping) { left = charWidth(cm.display) * pos.ch; }
-    var lineObj = getLine(cm.doc, pos.line);
-    var top = heightAtLine(lineObj) + paddingTop(cm.display);
-    return {left: left, right: left, top: top, bottom: top + lineObj.height}
-  }
-
-  // Positions returned by coordsChar contain some extra information.
-  // xRel is the relative x position of the input coordinates compared
-  // to the found position (so xRel > 0 means the coordinates are to
-  // the right of the character position, for example). When outside
-  // is true, that means the coordinates lie outside the line's
-  // vertical range.
-  function PosWithInfo(line, ch, sticky, outside, xRel) {
-    var pos = Pos(line, ch, sticky);
-    pos.xRel = xRel;
-    if (outside) { pos.outside = true; }
-    return pos
-  }
-
-  // Compute the character position closest to the given coordinates.
-  // Input must be lineSpace-local ("div" coordinate system).
-  function coordsChar(cm, x, y) {
-    var doc = cm.doc;
-    y += cm.display.viewOffset;
-    if (y < 0) { return PosWithInfo(doc.first, 0, null, true, -1) }
-    var lineN = lineAtHeight(doc, y), last = doc.first + doc.size - 1;
-    if (lineN > last)
-      { return PosWithInfo(doc.first + doc.size - 1, getLine(doc, last).text.length, null, true, 1) }
-    if (x < 0) { x = 0; }
-
-    var lineObj = getLine(doc, lineN);
-    for (;;) {
-      var found = coordsCharInner(cm, lineObj, lineN, x, y);
-      var collapsed = collapsedSpanAround(lineObj, found.ch + (found.xRel > 0 ? 1 : 0));
-      if (!collapsed) { return found }
-      var rangeEnd = collapsed.find(1);
-      if (rangeEnd.line == lineN) { return rangeEnd }
-      lineObj = getLine(doc, lineN = rangeEnd.line);
-    }
-  }
-
-  function wrappedLineExtent(cm, lineObj, preparedMeasure, y) {
-    y -= widgetTopHeight(lineObj);
-    var end = lineObj.text.length;
-    var begin = findFirst(function (ch) { return measureCharPrepared(cm, preparedMeasure, ch - 1).bottom <= y; }, end, 0);
-    end = findFirst(function (ch) { return measureCharPrepared(cm, preparedMeasure, ch).top > y; }, begin, end);
-    return {begin: begin, end: end}
-  }
-
-  function wrappedLineExtentChar(cm, lineObj, preparedMeasure, target) {
-    if (!preparedMeasure) { preparedMeasure = prepareMeasureForLine(cm, lineObj); }
-    var targetTop = intoCoordSystem(cm, lineObj, measureCharPrepared(cm, preparedMeasure, target), "line").top;
-    return wrappedLineExtent(cm, lineObj, preparedMeasure, targetTop)
-  }
-
-  // Returns true if the given side of a box is after the given
-  // coordinates, in top-to-bottom, left-to-right order.
-  function boxIsAfter(box, x, y, left) {
-    return box.bottom <= y ? false : box.top > y ? true : (left ? box.left : box.right) > x
-  }
-
-  function coordsCharInner(cm, lineObj, lineNo$$1, x, y) {
-    // Move y into line-local coordinate space
-    y -= heightAtLine(lineObj);
-    var preparedMeasure = prepareMeasureForLine(cm, lineObj);
-    // When directly calling `measureCharPrepared`, we have to adjust
-    // for the widgets at this line.
-    var widgetHeight$$1 = widgetTopHeight(lineObj);
-    var begin = 0, end = lineObj.text.length, ltr = true;
-
-    var order = getOrder(lineObj, cm.doc.direction);
-    // If the line isn't plain left-to-right text, first figure out
-    // which bidi section the coordinates fall into.
-    if (order) {
-      var part = (cm.options.lineWrapping ? coordsBidiPartWrapped : coordsBidiPart)
-                   (cm, lineObj, lineNo$$1, preparedMeasure, order, x, y);
-      ltr = part.level != 1;
-      // The awkward -1 offsets are needed because findFirst (called
-      // on these below) will treat its first bound as inclusive,
-      // second as exclusive, but we want to actually address the
-      // characters in the part's range
-      begin = ltr ? part.from : part.to - 1;
-      end = ltr ? part.to : part.from - 1;
-    }
-
-    // A binary search to find the first character whose bounding box
-    // starts after the coordinates. If we run across any whose box wrap
-    // the coordinates, store that.
-    var chAround = null, boxAround = null;
-    var ch = findFirst(function (ch) {
-      var box = measureCharPrepared(cm, preparedMeasure, ch);
-      box.top += widgetHeight$$1; box.bottom += widgetHeight$$1;
-      if (!boxIsAfter(box, x, y, false)) { return false }
-      if (box.top <= y && box.left <= x) {
-        chAround = ch;
-        boxAround = box;
-      }
-      return true
-    }, begin, end);
-
-    var baseX, sticky, outside = false;
-    // If a box around the coordinates was found, use that
-    if (boxAround) {
-      // Distinguish coordinates nearer to the left or right side of the box
-      var atLeft = x - boxAround.left < boxAround.right - x, atStart = atLeft == ltr;
-      ch = chAround + (atStart ? 0 : 1);
-      sticky = atStart ? "after" : "before";
-      baseX = atLeft ? boxAround.left : boxAround.right;
-    } else {
-      // (Adjust for extended bound, if necessary.)
-      if (!ltr && (ch == end || ch == begin)) { ch++; }
-      // To determine which side to associate with, get the box to the
-      // left of the character and compare it's vertical position to the
-      // coordinates
-      sticky = ch == 0 ? "after" : ch == lineObj.text.length ? "before" :
-        (measureCharPrepared(cm, preparedMeasure, ch - (ltr ? 1 : 0)).bottom + widgetHeight$$1 <= y) == ltr ?
-        "after" : "before";
-      // Now get accurate coordinates for this place, in order to get a
-      // base X position
-      var coords = cursorCoords(cm, Pos(lineNo$$1, ch, sticky), "line", lineObj, preparedMeasure);
-      baseX = coords.left;
-      outside = y < coords.top || y >= coords.bottom;
-    }
-
-    ch = skipExtendingChars(lineObj.text, ch, 1);
-    return PosWithInfo(lineNo$$1, ch, sticky, outside, x - baseX)
-  }
-
-  function coordsBidiPart(cm, lineObj, lineNo$$1, preparedMeasure, order, x, y) {
-    // Bidi parts are sorted left-to-right, and in a non-line-wrapping
-    // situation, we can take this ordering to correspond to the visual
-    // ordering. This finds the first part whose end is after the given
-    // coordinates.
-    var index = findFirst(function (i) {
-      var part = order[i], ltr = part.level != 1;
-      return boxIsAfter(cursorCoords(cm, Pos(lineNo$$1, ltr ? part.to : part.from, ltr ? "before" : "after"),
-                                     "line", lineObj, preparedMeasure), x, y, true)
-    }, 0, order.length - 1);
-    var part = order[index];
-    // If this isn't the first part, the part's start is also after
-    // the coordinates, and the coordinates aren't on the same line as
-    // that start, move one part back.
-    if (index > 0) {
-      var ltr = part.level != 1;
-      var start = cursorCoords(cm, Pos(lineNo$$1, ltr ? part.from : part.to, ltr ? "after" : "before"),
-                               "line", lineObj, preparedMeasure);
-      if (boxIsAfter(start, x, y, true) && start.top > y)
-        { part = order[index - 1]; }
-    }
-    return part
-  }
-
-  function coordsBidiPartWrapped(cm, lineObj, _lineNo, preparedMeasure, order, x, y) {
-    // In a wrapped line, rtl text on wrapping boundaries can do things
-    // that don't correspond to the ordering in our `order` array at
-    // all, so a binary search doesn't work, and we want to return a
-    // part that only spans one line so that the binary search in
-    // coordsCharInner is safe. As such, we first find the extent of the
-    // wrapped line, and then do a flat search in which we discard any
-    // spans that aren't on the line.
-    var ref = wrappedLineExtent(cm, lineObj, preparedMeasure, y);
-    var begin = ref.begin;
-    var end = ref.end;
-    if (/\s/.test(lineObj.text.charAt(end - 1))) { end--; }
-    var part = null, closestDist = null;
-    for (var i = 0; i < order.length; i++) {
-      var p = order[i];
-      if (p.from >= end || p.to <= begin) { continue }
-      var ltr = p.level != 1;
-      var endX = measureCharPrepared(cm, preparedMeasure, ltr ? Math.min(end, p.to) - 1 : Math.max(begin, p.from)).right;
-      // Weigh against spans ending before this, so that they are only
-      // picked if nothing ends after
-      var dist = endX < x ? x - endX + 1e9 : endX - x;
-      if (!part || closestDist > dist) {
-        part = p;
-        closestDist = dist;
-      }
-    }
-    if (!part) { part = order[order.length - 1]; }
-    // Clip the part to the wrapped line.
-    if (part.from < begin) { part = {from: begin, to: part.to, level: part.level}; }
-    if (part.to > end) { part = {from: part.from, to: end, level: part.level}; }
-    return part
-  }
-
-  var measureText;
-  // Compute the default text height.
-  function textHeight(display) {
-    if (display.cachedTextHeight != null) { return display.cachedTextHeight }
-    if (measureText == null) {
-      measureText = elt("pre");
-      // Measure a bunch of lines, for browsers that compute
-      // fractional heights.
-      for (var i = 0; i < 49; ++i) {
-        measureText.appendChild(document.createTextNode("x"));
-        measureText.appendChild(elt("br"));
-      }
-      measureText.appendChild(document.createTextNode("x"));
-    }
-    removeChildrenAndAdd(display.measure, measureText);
-    var height = measureText.offsetHeight / 50;
-    if (height > 3) { display.cachedTextHeight = height; }
-    removeChildren(display.measure);
-    return height || 1
-  }
-
-  // Compute the default character width.
-  function charWidth(display) {
-    if (display.cachedCharWidth != null) { return display.cachedCharWidth }
-    var anchor = elt("span", "xxxxxxxxxx");
-    var pre = elt("pre", [anchor]);
-    removeChildrenAndAdd(display.measure, pre);
-    var rect = anchor.getBoundingClientRect(), width = (rect.right - rect.left) / 10;
-    if (width > 2) { display.cachedCharWidth = width; }
-    return width || 10
-  }
-
-  // Do a bulk-read of the DOM positions and sizes needed to draw the
-  // view, so that we don't interleave reading and writing to the DOM.
-  function getDimensions(cm) {
-    var d = cm.display, left = {}, width = {};
-    var gutterLeft = d.gutters.clientLeft;
-    for (var n = d.gutters.firstChild, i = 0; n; n = n.nextSibling, ++i) {
-      var id = cm.display.gutterSpecs[i].className;
-      left[id] = n.offsetLeft + n.clientLeft + gutterLeft;
-      width[id] = n.clientWidth;
-    }
-    return {fixedPos: compensateForHScroll(d),
-            gutterTotalWidth: d.gutters.offsetWidth,
-            gutterLeft: left,
-            gutterWidth: width,
-            wrapperWidth: d.wrapper.clientWidth}
-  }
-
-  // Computes display.scroller.scrollLeft + display.gutters.offsetWidth,
-  // but using getBoundingClientRect to get a sub-pixel-accurate
-  // result.
-  function compensateForHScroll(display) {
-    return display.scroller.getBoundingClientRect().left - display.sizer.getBoundingClientRect().left
-  }
-
-  // Returns a function that estimates the height of a line, to use as
-  // first approximation until the line becomes visible (and is thus
-  // properly measurable).
-  function estimateHeight(cm) {
-    var th = textHeight(cm.display), wrapping = cm.options.lineWrapping;
-    var perLine = wrapping && Math.max(5, cm.display.scroller.clientWidth / charWidth(cm.display) - 3);
-    return function (line) {
-      if (lineIsHidden(cm.doc, line)) { return 0 }
-
-      var widgetsHeight = 0;
-      if (line.widgets) { for (var i = 0; i < line.widgets.length; i++) {
-        if (line.widgets[i].height) { widgetsHeight += line.widgets[i].height; }
-      } }
-
-      if (wrapping)
-        { return widgetsHeight + (Math.ceil(line.text.length / perLine) || 1) * th }
-      else
-        { return widgetsHeight + th }
-    }
-  }
-
-  function estimateLineHeights(cm) {
-    var doc = cm.doc, est = estimateHeight(cm);
-    doc.iter(function (line) {
-      var estHeight = est(line);
-      if (estHeight != line.height) { updateLineHeight(line, estHeight); }
-    });
-  }
-
-  // Given a mouse event, find the corresponding position. If liberal
-  // is false, it checks whether a gutter or scrollbar was clicked,
-  // and returns null if it was. forRect is used by rectangular
-  // selections, and tries to estimate a character position even for
-  // coordinates beyond the right of the text.
-  function posFromMouse(cm, e, liberal, forRect) {
-    var display = cm.display;
-    if (!liberal && e_target(e).getAttribute("cm-not-content") == "true") { return null }
-
-    var x, y, space = display.lineSpace.getBoundingClientRect();
-    // Fails unpredictably on IE[67] when mouse is dragged around quickly.
-    try { x = e.clientX - space.left; y = e.clientY - space.top; }
-    catch (e) { return null }
-    var coords = coordsChar(cm, x, y), line;
-    if (forRect && coords.xRel == 1 && (line = getLine(cm.doc, coords.line).text).length == coords.ch) {
-      var colDiff = countColumn(line, line.length, cm.options.tabSize) - line.length;
-      coords = Pos(coords.line, Math.max(0, Math.round((x - paddingH(cm.display).left) / charWidth(cm.display)) - colDiff));
-    }
-    return coords
-  }
-
-  // Find the view element corresponding to a given line. Return null
-  // when the line isn't visible.
-  function findViewIndex(cm, n) {
-    if (n >= cm.display.viewTo) { return null }
-    n -= cm.display.viewFrom;
-    if (n < 0) { return null }
-    var view = cm.display.view;
-    for (var i = 0; i < view.length; i++) {
-      n -= view[i].size;
-      if (n < 0) { return i }
-    }
-  }
-
-  // Updates the display.view data structure for a given change to the
-  // document. From and to are in pre-change coordinates. Lendiff is
-  // the amount of lines added or subtracted by the change. This is
-  // used for changes that span multiple lines, or change the way
-  // lines are divided into visual lines. regLineChange (below)
-  // registers single-line changes.
-  function regChange(cm, from, to, lendiff) {
-    if (from == null) { from = cm.doc.first; }
-    if (to == null) { to = cm.doc.first + cm.doc.size; }
-    if (!lendiff) { lendiff = 0; }
-
-    var display = cm.display;
-    if (lendiff && to < display.viewTo &&
-        (display.updateLineNumbers == null || display.updateLineNumbers > from))
-      { display.updateLineNumbers = from; }
-
-    cm.curOp.viewChanged = true;
-
-    if (from >= display.viewTo) { // Change after
-      if (sawCollapsedSpans && visualLineNo(cm.doc, from) < display.viewTo)
-        { resetView(cm); }
-    } else if (to <= display.viewFrom) { // Change before
-      if (sawCollapsedSpans && visualLineEndNo(cm.doc, to + lendiff) > display.viewFrom) {
-        resetView(cm);
-      } else {
-        display.viewFrom += lendiff;
-        display.viewTo += lendiff;
-      }
-    } else if (from <= display.viewFrom && to >= display.viewTo) { // Full overlap
-      resetView(cm);
-    } else if (from <= display.viewFrom) { // Top overlap
-      var cut = viewCuttingPoint(cm, to, to + lendiff, 1);
-      if (cut) {
-        display.view = display.view.slice(cut.index);
-        display.viewFrom = cut.lineN;
-        display.viewTo += lendiff;
-      } else {
-        resetView(cm);
-      }
-    } else if (to >= display.viewTo) { // Bottom overlap
-      var cut$1 = viewCuttingPoint(cm, from, from, -1);
-      if (cut$1) {
-        display.view = display.view.slice(0, cut$1.index);
-        display.viewTo = cut$1.lineN;
-      } else {
-        resetView(cm);
-      }
-    } else { // Gap in the middle
-      var cutTop = viewCuttingPoint(cm, from, from, -1);
-      var cutBot = viewCuttingPoint(cm, to, to + lendiff, 1);
-      if (cutTop && cutBot) {
-        display.view = display.view.slice(0, cutTop.index)
-          .concat(buildViewArray(cm, cutTop.lineN, cutBot.lineN))
-          .concat(display.view.slice(cutBot.index));
-        display.viewTo += lendiff;
-      } else {
-        resetView(cm);
-      }
-    }
-
-    var ext = display.externalMeasured;
-    if (ext) {
-      if (to < ext.lineN)
-        { ext.lineN += lendiff; }
-      else if (from < ext.lineN + ext.size)
-        { display.externalMeasured = null; }
-    }
-  }
-
-  // Register a change to a single line. Type must be one of "text",
-  // "gutter", "class", "widget"
-  function regLineChange(cm, line, type) {
-    cm.curOp.viewChanged = true;
-    var display = cm.display, ext = cm.display.externalMeasured;
-    if (ext && line >= ext.lineN && line < ext.lineN + ext.size)
-      { display.externalMeasured = null; }
-
-    if (line < display.viewFrom || line >= display.viewTo) { return }
-    var lineView = display.view[findViewIndex(cm, line)];
-    if (lineView.node == null) { return }
-    var arr = lineView.changes || (lineView.changes = []);
-    if (indexOf(arr, type) == -1) { arr.push(type); }
-  }
-
-  // Clear the view.
-  function resetView(cm) {
-    cm.display.viewFrom = cm.display.viewTo = cm.doc.first;
-    cm.display.view = [];
-    cm.display.viewOffset = 0;
-  }
-
-  function viewCuttingPoint(cm, oldN, newN, dir) {
-    var index = findViewIndex(cm, oldN), diff, view = cm.display.view;
-    if (!sawCollapsedSpans || newN == cm.doc.first + cm.doc.size)
-      { return {index: index, lineN: newN} }
-    var n = cm.display.viewFrom;
-    for (var i = 0; i < index; i++)
-      { n += view[i].size; }
-    if (n != oldN) {
-      if (dir > 0) {
-        if (index == view.length - 1) { return null }
-        diff = (n + view[index].size) - oldN;
-        index++;
-      } else {
-        diff = n - oldN;
-      }
-      oldN += diff; newN += diff;
-    }
-    while (visualLineNo(cm.doc, newN) != newN) {
-      if (index == (dir < 0 ? 0 : view.length - 1)) { return null }
-      newN += dir * view[index - (dir < 0 ? 1 : 0)].size;
-      index += dir;
-    }
-    return {index: index, lineN: newN}
-  }
-
-  // Force the view to cover a given range, adding empty view element
-  // or clipping off existing ones as needed.
-  function adjustView(cm, from, to) {
-    var display = cm.display, view = display.view;
-    if (view.length == 0 || from >= display.viewTo || to <= display.viewFrom) {
-      display.view = buildViewArray(cm, from, to);
-      display.viewFrom = from;
-    } else {
-      if (display.viewFrom > from)
-        { display.view = buildViewArray(cm, from, display.viewFrom).concat(display.view); }
-      else if (display.viewFrom < from)
-        { display.view = display.view.slice(findViewIndex(cm, from)); }
-      display.viewFrom = from;
-      if (display.viewTo < to)
-        { display.view = display.view.concat(buildViewArray(cm, display.viewTo, to)); }
-      else if (display.viewTo > to)
-        { display.view = display.view.slice(0, findViewIndex(cm, to)); }
-    }
-    display.viewTo = to;
-  }
-
-  // Count the number of lines in the view whose DOM representation is
-  // out of date (or nonexistent).
-  function countDirtyView(cm) {
-    var view = cm.display.view, dirty = 0;
-    for (var i = 0; i < view.length; i++) {
-      var lineView = view[i];
-      if (!lineView.hidden && (!lineView.node || lineView.changes)) { ++dirty; }
-    }
-    return dirty
-  }
-
-  function updateSelection(cm) {
-    cm.display.input.showSelection(cm.display.input.prepareSelection());
-  }
-
-  function prepareSelection(cm, primary) {
-    if ( primary === void 0 ) primary = true;
-
-    var doc = cm.doc, result = {};
-    var curFragment = result.cursors = document.createDocumentFragment();
-    var selFragment = result.selection = document.createDocumentFragment();
-
-    for (var i = 0; i < doc.sel.ranges.length; i++) {
-      if (!primary && i == doc.sel.primIndex) { continue }
-      var range$$1 = doc.sel.ranges[i];
-      if (range$$1.from().line >= cm.display.viewTo || range$$1.to().line < cm.display.viewFrom) { continue }
-      var collapsed = range$$1.empty();
-      if (collapsed || cm.options.showCursorWhenSelecting)
-        { drawSelectionCursor(cm, range$$1.head, curFragment); }
-      if (!collapsed)
-        { drawSelectionRange(cm, range$$1, selFragment); }
-    }
-    return result
-  }
-
-  // Draws a cursor for the given range
-  function drawSelectionCursor(cm, head, output) {
-    var pos = cursorCoords(cm, head, "div", null, null, !cm.options.singleCursorHeightPerLine);
-
-    var cursor = output.appendChild(elt("div", "\u00a0", "CodeMirror-cursor"));
-    cursor.style.left = pos.left + "px";
-    cursor.style.top = pos.top + "px";
-    cursor.style.height = Math.max(0, pos.bottom - pos.top) * cm.options.cursorHeight + "px";
-
-    if (pos.other) {
-      // Secondary cursor, shown when on a 'jump' in bi-directional text
-      var otherCursor = output.appendChild(elt("div", "\u00a0", "CodeMirror-cursor CodeMirror-secondarycursor"));
-      otherCursor.style.display = "";
-      otherCursor.style.left = pos.other.left + "px";
-      otherCursor.style.top = pos.other.top + "px";
-      otherCursor.style.height = (pos.other.bottom - pos.other.top) * .85 + "px";
-    }
-  }
-
-  function cmpCoords(a, b) { return a.top - b.top || a.left - b.left }
-
-  // Draws the given range as a highlighted selection
-  function drawSelectionRange(cm, range$$1, output) {
-    var display = cm.display, doc = cm.doc;
-    var fragment = document.createDocumentFragment();
-    var padding = paddingH(cm.display), leftSide = padding.left;
-    var rightSide = Math.max(display.sizerWidth, displayWidth(cm) - display.sizer.offsetLeft) - padding.right;
-    var docLTR = doc.direction == "ltr";
-
-    function add(left, top, width, bottom) {
-      if (top < 0) { top = 0; }
-      top = Math.round(top);
-      bottom = Math.round(bottom);
-      fragment.appendChild(elt("div", null, "CodeMirror-selected", ("position: absolute; left: " + left + "px;\n                             top: " + top + "px; width: " + (width == null ? rightSide - left : width) + "px;\n                             height: " + (bottom - top) + "px")));
-    }
-
-    function drawForLine(line, fromArg, toArg) {
-      var lineObj = getLine(doc, line);
-      var lineLen = lineObj.text.length;
-      var start, end;
-      function coords(ch, bias) {
-        return charCoords(cm, Pos(line, ch), "div", lineObj, bias)
-      }
-
-      function wrapX(pos, dir, side) {
-        var extent = wrappedLineExtentChar(cm, lineObj, null, pos);
-        var prop = (dir == "ltr") == (side == "after") ? "left" : "right";
-        var ch = side == "after" ? extent.begin : extent.end - (/\s/.test(lineObj.text.charAt(extent.end - 1)) ? 2 : 1);
-        return coords(ch, prop)[prop]
-      }
-
-      var order = getOrder(lineObj, doc.direction);
-      iterateBidiSections(order, fromArg || 0, toArg == null ? lineLen : toArg, function (from, to, dir, i) {
-        var ltr = dir == "ltr";
-        var fromPos = coords(from, ltr ? "left" : "right");
-        var toPos = coords(to - 1, ltr ? "right" : "left");
-
-        var openStart = fromArg == null && from == 0, openEnd = toArg == null && to == lineLen;
-        var first = i == 0, last = !order || i == order.length - 1;
-        if (toPos.top - fromPos.top <= 3) { // Single line
-          var openLeft = (docLTR ? openStart : openEnd) && first;
-          var openRight = (docLTR ? openEnd : openStart) && last;
-          var left = openLeft ? leftSide : (ltr ? fromPos : toPos).left;
-          var right = openRight ? rightSide : (ltr ? toPos : fromPos).right;
-          add(left, fromPos.top, right - left, fromPos.bottom);
-        } else { // Multiple lines
-          var topLeft, topRight, botLeft, botRight;
-          if (ltr) {
-            topLeft = docLTR && openStart && first ? leftSide : fromPos.left;
-            topRight = docLTR ? rightSide : wrapX(from, dir, "before");
-            botLeft = docLTR ? leftSide : wrapX(to, dir, "after");
-            botRight = docLTR && openEnd && last ? rightSide : toPos.right;
-          } else {
-            topLeft = !docLTR ? leftSide : wrapX(from, dir, "before");
-            topRight = !docLTR && openStart && first ? rightSide : fromPos.right;
-            botLeft = !docLTR && openEnd && last ? leftSide : toPos.left;
-            botRight = !docLTR ? rightSide : wrapX(to, dir, "after");
-          }
-          add(topLeft, fromPos.top, topRight - topLeft, fromPos.bottom);
-          if (fromPos.bottom < toPos.top) { add(leftSide, fromPos.bottom, null, toPos.top); }
-          add(botLeft, toPos.top, botRight - botLeft, toPos.bottom);
-        }
-
-        if (!start || cmpCoords(fromPos, start) < 0) { start = fromPos; }
-        if (cmpCoords(toPos, start) < 0) { start = toPos; }
-        if (!end || cmpCoords(fromPos, end) < 0) { end = fromPos; }
-        if (cmpCoords(toPos, end) < 0) { end = toPos; }
-      });
-      return {start: start, end: end}
-    }
-
-    var sFrom = range$$1.from(), sTo = range$$1.to();
-    if (sFrom.line == sTo.line) {
-      drawForLine(sFrom.line, sFrom.ch, sTo.ch);
-    } else {
-      var fromLine = getLine(doc, sFrom.line), toLine = getLine(doc, sTo.line);
-      var singleVLine = visualLine(fromLine) == visualLine(toLine);
-      var leftEnd = drawForLine(sFrom.line, sFrom.ch, singleVLine ? fromLine.text.length + 1 : null).end;
-      var rightStart = drawForLine(sTo.line, singleVLine ? 0 : null, sTo.ch).start;
-      if (singleVLine) {
-        if (leftEnd.top < rightStart.top - 2) {
-          add(leftEnd.right, leftEnd.top, null, leftEnd.bottom);
-          add(leftSide, rightStart.top, rightStart.left, rightStart.bottom);
-        } else {
-          add(leftEnd.right, leftEnd.top, rightStart.left - leftEnd.right, leftEnd.bottom);
-        }
-      }
-      if (leftEnd.bottom < rightStart.top)
-        { add(leftSide, leftEnd.bottom, null, rightStart.top); }
-    }
-
-    output.appendChild(fragment);
-  }
-
-  // Cursor-blinking
-  function restartBlink(cm) {
-    if (!cm.state.focused) { return }
-    var display = cm.display;
-    clearInterval(display.blinker);
-    var on = true;
-    display.cursorDiv.style.visibility = "";
-    if (cm.options.cursorBlinkRate > 0)
-      { display.blinker = setInterval(function () { return display.cursorDiv.style.visibility = (on = !on) ? "" : "hidden"; },
-        cm.options.cursorBlinkRate); }
-    else if (cm.options.cursorBlinkRate < 0)
-      { display.cursorDiv.style.visibility = "hidden"; }
-  }
-
-  function ensureFocus(cm) {
-    if (!cm.state.focused) { cm.display.input.focus(); onFocus(cm); }
-  }
-
-  function delayBlurEvent(cm) {
-    cm.state.delayingBlurEvent = true;
-    setTimeout(function () { if (cm.state.delayingBlurEvent) {
-      cm.state.delayingBlurEvent = false;
-      onBlur(cm);
-    } }, 100);
-  }
-
-  function onFocus(cm, e) {
-    if (cm.state.delayingBlurEvent) { cm.state.delayingBlurEvent = false; }
-
-    if (cm.options.readOnly == "nocursor") { return }
-    if (!cm.state.focused) {
-      signal(cm, "focus", cm, e);
-      cm.state.focused = true;
-      addClass(cm.display.wrapper, "CodeMirror-focused");
-      // This test prevents this from firing when a context
-      // menu is closed (since the input reset would kill the
-      // select-all detection hack)
-      if (!cm.curOp && cm.display.selForContextMenu != cm.doc.sel) {
-        cm.display.input.reset();
-        if (webkit) { setTimeout(function () { return cm.display.input.reset(true); }, 20); } // Issue #1730
-      }
-      cm.display.input.receivedFocus();
-    }
-    restartBlink(cm);
-  }
-  function onBlur(cm, e) {
-    if (cm.state.delayingBlurEvent) { return }
-
-    if (cm.state.focused) {
-      signal(cm, "blur", cm, e);
-      cm.state.focused = false;
-      rmClass(cm.display.wrapper, "CodeMirror-focused");
-    }
-    clearInterval(cm.display.blinker);
-    setTimeout(function () { if (!cm.state.focused) { cm.display.shift = false; } }, 150);
-  }
-
-  // Read the actual heights of the rendered lines, and update their
-  // stored heights to match.
-  function updateHeightsInViewport(cm) {
-    var display = cm.display;
-    var prevBottom = display.lineDiv.offsetTop;
-    for (var i = 0; i < display.view.length; i++) {
-      var cur = display.view[i], wrapping = cm.options.lineWrapping;
-      var height = (void 0), width = 0;
-      if (cur.hidden) { continue }
-      if (ie && ie_version < 8) {
-        var bot = cur.node.offsetTop + cur.node.offsetHeight;
-        height = bot - prevBottom;
-        prevBottom = bot;
-      } else {
-        var box = cur.node.getBoundingClientRect();
-        height = box.bottom - box.top;
-        // Check that lines don't extend past the right of the current
-        // editor width
-        if (!wrapping && cur.text.firstChild)
-          { width = cur.text.firstChild.getBoundingClientRect().right - box.left - 1; }
-      }
-      var diff = cur.line.height - height;
-      if (diff > .005 || diff < -.005) {
-        updateLineHeight(cur.line, height);
-        updateWidgetHeight(cur.line);
-        if (cur.rest) { for (var j = 0; j < cur.rest.length; j++)
-          { updateWidgetHeight(cur.rest[j]); } }
-      }
-      if (width > cm.display.sizerWidth) {
-        var chWidth = Math.ceil(width / charWidth(cm.display));
-        if (chWidth > cm.display.maxLineLength) {
-          cm.display.maxLineLength = chWidth;
-          cm.display.maxLine = cur.line;
-          cm.display.maxLineChanged = true;
-        }
-      }
-    }
-  }
-
-  // Read and store the height of line widgets associated with the
-  // given line.
-  function updateWidgetHeight(line) {
-    if (line.widgets) { for (var i = 0; i < line.widgets.length; ++i) {
-      var w = line.widgets[i], parent = w.node.parentNode;
-      if (parent) { w.height = parent.offsetHeight; }
-    } }
-  }
-
-  // Compute the lines that are visible in a given viewport (defaults
-  // the the current scroll position). viewport may contain top,
-  // height, and ensure (see op.scrollToPos) properties.
-  function visibleLines(display, doc, viewport) {
-    var top = viewport && viewport.top != null ? Math.max(0, viewport.top) : display.scroller.scrollTop;
-    top = Math.floor(top - paddingTop(display));
-    var bottom = viewport && viewport.bottom != null ? viewport.bottom : top + display.wrapper.clientHeight;
-
-    var from = lineAtHeight(doc, top), to = lineAtHeight(doc, bottom);
-    // Ensure is a {from: {line, ch}, to: {line, ch}} object, and
-    // forces those lines into the viewport (if possible).
-    if (viewport && viewport.ensure) {
-      var ensureFrom = viewport.ensure.from.line, ensureTo = viewport.ensure.to.line;
-      if (ensureFrom < from) {
-        from = ensureFrom;
-        to = lineAtHeight(doc, heightAtLine(getLine(doc, ensureFrom)) + display.wrapper.clientHeight);
-      } else if (Math.min(ensureTo, doc.lastLine()) >= to) {
-        from = lineAtHeight(doc, heightAtLine(getLine(doc, ensureTo)) - display.wrapper.clientHeight);
-        to = ensureTo;
-      }
-    }
-    return {from: from, to: Math.max(to, from + 1)}
-  }
-
-  // SCROLLING THINGS INTO VIEW
-
-  // If an editor sits on the top or bottom of the window, partially
-  // scrolled out of view, this ensures that the cursor is visible.
-  function maybeScrollWindow(cm, rect) {
-    if (signalDOMEvent(cm, "scrollCursorIntoView")) { return }
-
-    var display = cm.display, box = display.sizer.getBoundingClientRect(), doScroll = null;
-    if (rect.top + box.top < 0) { doScroll = true; }
-    else if (rect.bottom + box.top > (window.innerHeight || document.documentElement.clientHeight)) { doScroll = false; }
-    if (doScroll != null && !phantom) {
-      var scrollNode = elt("div", "\u200b", null, ("position: absolute;\n                         top: " + (rect.top - display.viewOffset - paddingTop(cm.display)) + "px;\n                         height: " + (rect.bottom - rect.top + scrollGap(cm) + display.barHeight) + "px;\n                         left: " + (rect.left) + "px; width: " + (Math.max(2, rect.right - rect.left)) + "px;"));
-      cm.display.lineSpace.appendChild(scrollNode);
-      scrollNode.scrollIntoView(doScroll);
-      cm.display.lineSpace.removeChild(scrollNode);
-    }
-  }
-
-  // Scroll a given position into view (immediately), verifying that
-  // it actually became visible (as line heights are accurately
-  // measured, the position of something may 'drift' during drawing).
-  function scrollPosIntoView(cm, pos, end, margin) {
-    if (margin == null) { margin = 0; }
-    var rect;
-    if (!cm.options.lineWrapping && pos == end) {
-      // Set pos and end to the cursor positions around the character pos sticks to
-      // If pos.sticky == "before", that is around pos.ch - 1, otherwise around pos.ch
-      // If pos == Pos(_, 0, "before"), pos and end are unchanged
-      pos = pos.ch ? Pos(pos.line, pos.sticky == "before" ? pos.ch - 1 : pos.ch, "after") : pos;
-      end = pos.sticky == "before" ? Pos(pos.line, pos.ch + 1, "before") : pos;
-    }
-    for (var limit = 0; limit < 5; limit++) {
-      var changed = false;
-      var coords = cursorCoords(cm, pos);
-      var endCoords = !end || end == pos ? coords : cursorCoords(cm, end);
-      rect = {left: Math.min(coords.left, endCoords.left),
-              top: Math.min(coords.top, endCoords.top) - margin,
-              right: Math.max(coords.left, endCoords.left),
-              bottom: Math.max(coords.bottom, endCoords.bottom) + margin};
-      var scrollPos = calculateScrollPos(cm, rect);
-      var startTop = cm.doc.scrollTop, startLeft = cm.doc.scrollLeft;
-      if (scrollPos.scrollTop != null) {
-        updateScrollTop(cm, scrollPos.scrollTop);
-        if (Math.abs(cm.doc.scrollTop - startTop) > 1) { changed = true; }
-      }
-      if (scrollPos.scrollLeft != null) {
-        setScrollLeft(cm, scrollPos.scrollLeft);
-        if (Math.abs(cm.doc.scrollLeft - startLeft) > 1) { changed = true; }
-      }
-      if (!changed) { break }
-    }
-    return rect
-  }
-
-  // Scroll a given set of coordinates into view (immediately).
-  function scrollIntoView(cm, rect) {
-    var scrollPos = calculateScrollPos(cm, rect);
-    if (scrollPos.scrollTop != null) { updateScrollTop(cm, scrollPos.scrollTop); }
-    if (scrollPos.scrollLeft != null) { setScrollLeft(cm, scrollPos.scrollLeft); }
-  }
-
-  // Calculate a new scroll position needed to scroll the given
-  // rectangle into view. Returns an object with scrollTop and
-  // scrollLeft properties. When these are undefined, the
-  // vertical/horizontal position does not need to be adjusted.
-  function calculateScrollPos(cm, rect) {
-    var display = cm.display, snapMargin = textHeight(cm.display);
-    if (rect.top < 0) { rect.top = 0; }
-    var screentop = cm.curOp && cm.curOp.scrollTop != null ? cm.curOp.scrollTop : display.scroller.scrollTop;
-    var screen = displayHeight(cm), result = {};
-    if (rect.bottom - rect.top > screen) { rect.bottom = rect.top + screen; }
-    var docBottom = cm.doc.height + paddingVert(display);
-    var atTop = rect.top < snapMargin, atBottom = rect.bottom > docBottom - snapMargin;
-    if (rect.top < screentop) {
-      result.scrollTop = atTop ? 0 : rect.top;
-    } else if (rect.bottom > screentop + screen) {
-      var newTop = Math.min(rect.top, (atBottom ? docBottom : rect.bottom) - screen);
-      if (newTop != screentop) { result.scrollTop = newTop; }
-    }
-
-    var screenleft = cm.curOp && cm.curOp.scrollLeft != null ? cm.curOp.scrollLeft : display.scroller.scrollLeft;
-    var screenw = displayWidth(cm) - (cm.options.fixedGutter ? display.gutters.offsetWidth : 0);
-    var tooWide = rect.right - rect.left > screenw;
-    if (tooWide) { rect.right = rect.left + screenw; }
-    if (rect.left < 10)
-      { result.scrollLeft = 0; }
-    else if (rect.left < screenleft)
-      { result.scrollLeft = Math.max(0, rect.left - (tooWide ? 0 : 10)); }
-    else if (rect.right > screenw + screenleft - 3)
-      { result.scrollLeft = rect.right + (tooWide ? 0 : 10) - screenw; }
-    return result
-  }
-
-  // Store a relative adjustment to the scroll position in the current
-  // operation (to be applied when the operation finishes).
-  function addToScrollTop(cm, top) {
-    if (top == null) { return }
-    resolveScrollToPos(cm);
-    cm.curOp.scrollTop = (cm.curOp.scrollTop == null ? cm.doc.scrollTop : cm.curOp.scrollTop) + top;
-  }
-
-  // Make sure that at the end of the operation the current cursor is
-  // shown.
-  function ensureCursorVisible(cm) {
-    resolveScrollToPos(cm);
-    var cur = cm.getCursor();
-    cm.curOp.scrollToPos = {from: cur, to: cur, margin: cm.options.cursorScrollMargin};
-  }
-
-  function scrollToCoords(cm, x, y) {
-    if (x != null || y != null) { resolveScrollToPos(cm); }
-    if (x != null) { cm.curOp.scrollLeft = x; }
-    if (y != null) { cm.curOp.scrollTop = y; }
-  }
-
-  function scrollToRange(cm, range$$1) {
-    resolveScrollToPos(cm);
-    cm.curOp.scrollToPos = range$$1;
-  }
-
-  // When an operation has its scrollToPos property set, and another
-  // scroll action is applied before the end of the operation, this
-  // 'simulates' scrolling that position into view in a cheap way, so
-  // that the effect of intermediate scroll commands is not ignored.
-  function resolveScrollToPos(cm) {
-    var range$$1 = cm.curOp.scrollToPos;
-    if (range$$1) {
-      cm.curOp.scrollToPos = null;
-      var from = estimateCoords(cm, range$$1.from), to = estimateCoords(cm, range$$1.to);
-      scrollToCoordsRange(cm, from, to, range$$1.margin);
-    }
-  }
-
-  function scrollToCoordsRange(cm, from, to, margin) {
-    var sPos = calculateScrollPos(cm, {
-      left: Math.min(from.left, to.left),
-      top: Math.min(from.top, to.top) - margin,
-      right: Math.max(from.right, to.right),
-      bottom: Math.max(from.bottom, to.bottom) + margin
-    });
-    scrollToCoords(cm, sPos.scrollLeft, sPos.scrollTop);
-  }
-
-  // Sync the scrollable area and scrollbars, ensure the viewport
-  // covers the visible area.
-  function updateScrollTop(cm, val) {
-    if (Math.abs(cm.doc.scrollTop - val) < 2) { return }
-    if (!gecko) { updateDisplaySimple(cm, {top: val}); }
-    setScrollTop(cm, val, true);
-    if (gecko) { updateDisplaySimple(cm); }
-    startWorker(cm, 100);
-  }
-
-  function setScrollTop(cm, val, forceScroll) {
-    val = Math.min(cm.display.scroller.scrollHeight - cm.display.scroller.clientHeight, val);
-    if (cm.display.scroller.scrollTop == val && !forceScroll) { return }
-    cm.doc.scrollTop = val;
-    cm.display.scrollbars.setScrollTop(val);
-    if (cm.display.scroller.scrollTop != val) { cm.display.scroller.scrollTop = val; }
-  }
-
-  // Sync scroller and scrollbar, ensure the gutter elements are
-  // aligned.
-  function setScrollLeft(cm, val, isScroller, forceScroll) {
-    val = Math.min(val, cm.display.scroller.scrollWidth - cm.display.scroller.clientWidth);
-    if ((isScroller ? val == cm.doc.scrollLeft : Math.abs(cm.doc.scrollLeft - val) < 2) && !forceScroll) { return }
-    cm.doc.scrollLeft = val;
-    alignHorizontally(cm);
-    if (cm.display.scroller.scrollLeft != val) { cm.display.scroller.scrollLeft = val; }
-    cm.display.scrollbars.setScrollLeft(val);
-  }
-
-  // SCROLLBARS
-
-  // Prepare DOM reads needed to update the scrollbars. Done in one
-  // shot to minimize update/measure roundtrips.
-  function measureForScrollbars(cm) {
-    var d = cm.display, gutterW = d.gutters.offsetWidth;
-    var docH = Math.round(cm.doc.height + paddingVert(cm.display));
-    return {
-      clientHeight: d.scroller.clientHeight,
-      viewHeight: d.wrapper.clientHeight,
-      scrollWidth: d.scroller.scrollWidth, clientWidth: d.scroller.clientWidth,
-      viewWidth: d.wrapper.clientWidth,
-      barLeft: cm.options.fixedGutter ? gutterW : 0,
-      docHeight: docH,
-      scrollHeight: docH + scrollGap(cm) + d.barHeight,
-      nativeBarWidth: d.nativeBarWidth,
-      gutterWidth: gutterW
-    }
-  }
-
-  var NativeScrollbars = function(place, scroll, cm) {
-    this.cm = cm;
-    var vert = this.vert = elt("div", [elt("div", null, null, "min-width: 1px")], "CodeMirror-vscrollbar");
-    var horiz = this.horiz = elt("div", [elt("div", null, null, "height: 100%; min-height: 1px")], "CodeMirror-hscrollbar");
-    vert.tabIndex = horiz.tabIndex = -1;
-    place(vert); place(horiz);
-
-    on(vert, "scroll", function () {
-      if (vert.clientHeight) { scroll(vert.scrollTop, "vertical"); }
-    });
-    on(horiz, "scroll", function () {
-      if (horiz.clientWidth) { scroll(horiz.scrollLeft, "horizontal"); }
-    });
-
-    this.checkedZeroWidth = false;
-    // Need to set a minimum width to see the scrollbar on IE7 (but must not set it on IE8).
-    if (ie && ie_version < 8) { this.horiz.style.minHeight = this.vert.style.minWidth = "18px"; }
-  };
-
-  NativeScrollbars.prototype.update = function (measure) {
-    var needsH = measure.scrollWidth > measure.clientWidth + 1;
-    var needsV = measure.scrollHeight > measure.clientHeight + 1;
-    var sWidth = measure.nativeBarWidth;
-
-    if (needsV) {
-      this.vert.style.display = "block";
-      this.vert.style.bottom = needsH ? sWidth + "px" : "0";
-      var totalHeight = measure.viewHeight - (needsH ? sWidth : 0);
-      // A bug in IE8 can cause this value to be negative, so guard it.
-      this.vert.firstChild.style.height =
-        Math.max(0, measure.scrollHeight - measure.clientHeight + totalHeight) + "px";
-    } else {
-      this.vert.style.display = "";
-      this.vert.firstChild.style.height = "0";
-    }
-
-    if (needsH) {
-      this.horiz.style.display = "block";
-      this.horiz.style.right = needsV ? sWidth + "px" : "0";
-      this.horiz.style.left = measure.barLeft + "px";
-      var totalWidth = measure.viewWidth - measure.barLeft - (needsV ? sWidth : 0);
-      this.horiz.firstChild.style.width =
-        Math.max(0, measure.scrollWidth - measure.clientWidth + totalWidth) + "px";
-    } else {
-      this.horiz.style.display = "";
-      this.horiz.firstChild.style.width = "0";
-    }
-
-    if (!this.checkedZeroWidth && measure.clientHeight > 0) {
-      if (sWidth == 0) { this.zeroWidthHack(); }
-      this.checkedZeroWidth = true;
-    }
-
-    return {right: needsV ? sWidth : 0, bottom: needsH ? sWidth : 0}
-  };
-
-  NativeScrollbars.prototype.setScrollLeft = function (pos) {
-    if (this.horiz.scrollLeft != pos) { this.horiz.scrollLeft = pos; }
-    if (this.disableHoriz) { this.enableZeroWidthBar(this.horiz, this.disableHoriz, "horiz"); }
-  };
-
-  NativeScrollbars.prototype.setScrollTop = function (pos) {
-    if (this.vert.scrollTop != pos) { this.vert.scrollTop = pos; }
-    if (this.disableVert) { this.enableZeroWidthBar(this.vert, this.disableVert, "vert"); }
-  };
-
-  NativeScrollbars.prototype.zeroWidthHack = function () {
-    var w = mac && !mac_geMountainLion ? "12px" : "18px";
-    this.horiz.style.height = this.vert.style.width = w;
-    this.horiz.style.pointerEvents = this.vert.style.pointerEvents = "none";
-    this.disableHoriz = new Delayed;
-    this.disableVert = new Delayed;
-  };
-
-  NativeScrollbars.prototype.enableZeroWidthBar = function (bar, delay, type) {
-    bar.style.pointerEvents = "auto";
-    function maybeDisable() {
-      // To find out whether the scrollbar is still visible, we
-      // check whether the element under the pixel in the bottom
-      // right corner of the scrollbar box is the scrollbar box
-      // itself (when the bar is still visible) or its filler child
-      // (when the bar is hidden). If it is still visible, we keep
-      // it enabled, if it's hidden, we disable pointer events.
-      var box = bar.getBoundingClientRect();
-      var elt$$1 = type == "vert" ? document.elementFromPoint(box.right - 1, (box.top + box.bottom) / 2)
-          : document.elementFromPoint((box.right + box.left) / 2, box.bottom - 1);
-      if (elt$$1 != bar) { bar.style.pointerEvents = "none"; }
-      else { delay.set(1000, maybeDisable); }
-    }
-    delay.set(1000, maybeDisable);
-  };
-
-  NativeScrollbars.prototype.clear = function () {
-    var parent = this.horiz.parentNode;
-    parent.removeChild(this.horiz);
-    parent.removeChild(this.vert);
-  };
-
-  var NullScrollbars = function () {};
-
-  NullScrollbars.prototype.update = function () { return {bottom: 0, right: 0} };
-  NullScrollbars.prototype.setScrollLeft = function () {};
-  NullScrollbars.prototype.setScrollTop = function () {};
-  NullScrollbars.prototype.clear = function () {};
-
-  function updateScrollbars(cm, measure) {
-    if (!measure) { measure = measureForScrollbars(cm); }
-    var startWidth = cm.display.barWidth, startHeight = cm.display.barHeight;
-    updateScrollbarsInner(cm, measure);
-    for (var i = 0; i < 4 && startWidth != cm.display.barWidth || startHeight != cm.display.barHeight; i++) {
-      if (startWidth != cm.display.barWidth && cm.options.lineWrapping)
-        { updateHeightsInViewport(cm); }
-      updateScrollbarsInner(cm, measureForScrollbars(cm));
-      startWidth = cm.display.barWidth; startHeight = cm.display.barHeight;
-    }
-  }
-
-  // Re-synchronize the fake scrollbars with the actual size of the
-  // content.
-  function updateScrollbarsInner(cm, measure) {
-    var d = cm.display;
-    var sizes = d.scrollbars.update(measure);
-
-    d.sizer.style.paddingRight = (d.barWidth = sizes.right) + "px";
-    d.sizer.style.paddingBottom = (d.barHeight = sizes.bottom) + "px";
-    d.heightForcer.style.borderBottom = sizes.bottom + "px solid transparent";
-
-    if (sizes.right && sizes.bottom) {
-      d.scrollbarFiller.style.display = "block";
-      d.scrollbarFiller.style.height = sizes.bottom + "px";
-      d.scrollbarFiller.style.width = sizes.right + "px";
-    } else { d.scrollbarFiller.style.display = ""; }
-    if (sizes.bottom && cm.options.coverGutterNextToScrollbar && cm.options.fixedGutter) {
-      d.gutterFiller.style.display = "block";
-      d.gutterFiller.style.height = sizes.bottom + "px";
-      d.gutterFiller.style.width = measure.gutterWidth + "px";
-    } else { d.gutterFiller.style.display = ""; }
-  }
-
-  var scrollbarModel = {"native": NativeScrollbars, "null": NullScrollbars};
-
-  function initScrollbars(cm) {
-    if (cm.display.scrollbars) {
-      cm.display.scrollbars.clear();
-      if (cm.display.scrollbars.addClass)
-        { rmClass(cm.display.wrapper, cm.display.scrollbars.addClass); }
-    }
-
-    cm.display.scrollbars = new scrollbarModel[cm.options.scrollbarStyle](function (node) {
-      cm.display.wrapper.insertBefore(node, cm.display.scrollbarFiller);
-      // Prevent clicks in the scrollbars from killing focus
-      on(node, "mousedown", function () {
-        if (cm.state.focused) { setTimeout(function () { return cm.display.input.focus(); }, 0); }
-      });
-      node.setAttribute("cm-not-content", "true");
-    }, function (pos, axis) {
-      if (axis == "horizontal") { setScrollLeft(cm, pos); }
-      else { updateScrollTop(cm, pos); }
-    }, cm);
-    if (cm.display.scrollbars.addClass)
-      { addClass(cm.display.wrapper, cm.display.scrollbars.addClass); }
-  }
-
-  // Operations are used to wrap a series of changes to the editor
-  // state in such a way that each change won't have to update the
-  // cursor and display (which would be awkward, slow, and
-  // error-prone). Instead, display updates are batched and then all
-  // combined and executed at once.
-
-  var nextOpId = 0;
-  // Start a new operation.
-  function startOperation(cm) {
-    cm.curOp = {
-      cm: cm,
-      viewChanged: false,      // Flag that indicates that lines might need to be redrawn
-      startHeight: cm.doc.height, // Used to detect need to update scrollbar
-      forceUpdate: false,      // Used to force a redraw
-      updateInput: 0,       // Whether to reset the input textarea
-      typing: false,           // Whether this reset should be careful to leave existing text (for compositing)
-      changeObjs: null,        // Accumulated changes, for firing change events
-      cursorActivityHandlers: null, // Set of handlers to fire cursorActivity on
-      cursorActivityCalled: 0, // Tracks which cursorActivity handlers have been called already
-      selectionChanged: false, // Whether the selection needs to be redrawn
-      updateMaxLine: false,    // Set when the widest line needs to be determined anew
-      scrollLeft: null, scrollTop: null, // Intermediate scroll position, not pushed to DOM yet
-      scrollToPos: null,       // Used to scroll to a specific position
-      focus: false,
-      id: ++nextOpId           // Unique ID
-    };
-    pushOperation(cm.curOp);
-  }
-
-  // Finish an operation, updating the display and signalling delayed events
-  function endOperation(cm) {
-    var op = cm.curOp;
-    if (op) { finishOperation(op, function (group) {
-      for (var i = 0; i < group.ops.length; i++)
-        { group.ops[i].cm.curOp = null; }
-      endOperations(group);
-    }); }
-  }
-
-  // The DOM updates done when an operation finishes are batched so
-  // that the minimum number of relayouts are required.
-  function endOperations(group) {
-    var ops = group.ops;
-    for (var i = 0; i < ops.length; i++) // Read DOM
-      { endOperation_R1(ops[i]); }
-    for (var i$1 = 0; i$1 < ops.length; i$1++) // Write DOM (maybe)
-      { endOperation_W1(ops[i$1]); }
-    for (var i$2 = 0; i$2 < ops.length; i$2++) // Read DOM
-      { endOperation_R2(ops[i$2]); }
-    for (var i$3 = 0; i$3 < ops.length; i$3++) // Write DOM (maybe)
-      { endOperation_W2(ops[i$3]); }
-    for (var i$4 = 0; i$4 < ops.length; i$4++) // Read DOM
-      { endOperation_finish(ops[i$4]); }
-  }
-
-  function endOperation_R1(op) {
-    var cm = op.cm, display = cm.display;
-    maybeClipScrollbars(cm);
-    if (op.updateMaxLine) { findMaxLine(cm); }
-
-    op.mustUpdate = op.viewChanged || op.forceUpdate || op.scrollTop != null ||
-      op.scrollToPos && (op.scrollToPos.from.line < display.viewFrom ||
-                         op.scrollToPos.to.line >= display.viewTo) ||
-      display.maxLineChanged && cm.options.lineWrapping;
-    op.update = op.mustUpdate &&
-      new DisplayUpdate(cm, op.mustUpdate && {top: op.scrollTop, ensure: op.scrollToPos}, op.forceUpdate);
-  }
-
-  function endOperation_W1(op) {
-    op.updatedDisplay = op.mustUpdate && updateDisplayIfNeeded(op.cm, op.update);
-  }
-
-  function endOperation_R2(op) {
-    var cm = op.cm, display = cm.display;
-    if (op.updatedDisplay) { updateHeightsInViewport(cm); }
-
-    op.barMeasure = measureForScrollbars(cm);
-
-    // If the max line changed since it was last measured, measure it,
-    // and ensure the document's width matches it.
-    // updateDisplay_W2 will use these properties to do the actual resizing
-    if (display.maxLineChanged && !cm.options.lineWrapping) {
-      op.adjustWidthTo = measureChar(cm, display.maxLine, display.maxLine.text.length).left + 3;
-      cm.display.sizerWidth = op.adjustWidthTo;
-      op.barMeasure.scrollWidth =
-        Math.max(display.scroller.clientWidth, display.sizer.offsetLeft + op.adjustWidthTo + scrollGap(cm) + cm.display.barWidth);
-      op.maxScrollLeft = Math.max(0, display.sizer.offsetLeft + op.adjustWidthTo - displayWidth(cm));
-    }
-
-    if (op.updatedDisplay || op.selectionChanged)
-      { op.preparedSelection = display.input.prepareSelection(); }
-  }
-
-  function endOperation_W2(op) {
-    var cm = op.cm;
-
-    if (op.adjustWidthTo != null) {
-      cm.display.sizer.style.minWidth = op.adjustWidthTo + "px";
-      if (op.maxScrollLeft < cm.doc.scrollLeft)
-        { setScrollLeft(cm, Math.min(cm.display.scroller.scrollLeft, op.maxScrollLeft), true); }
-      cm.display.maxLineChanged = false;
-    }
-
-    var takeFocus = op.focus && op.focus == activeElt();
-    if (op.preparedSelection)
-      { cm.display.input.showSelection(op.preparedSelection, takeFocus); }
-    if (op.updatedDisplay || op.startHeight != cm.doc.height)
-      { updateScrollbars(cm, op.barMeasure); }
-    if (op.updatedDisplay)
-      { setDocumentHeight(cm, op.barMeasure); }
-
-    if (op.selectionChanged) { restartBlink(cm); }
-
-    if (cm.state.focused && op.updateInput)
-      { cm.display.input.reset(op.typing); }
-    if (takeFocus) { ensureFocus(op.cm); }
-  }
-
-  function endOperation_finish(op) {
-    var cm = op.cm, display = cm.display, doc = cm.doc;
-
-    if (op.updatedDisplay) { postUpdateDisplay(cm, op.update); }
-
-    // Abort mouse wheel delta measurement, when scrolling explicitly
-    if (display.wheelStartX != null && (op.scrollTop != null || op.scrollLeft != null || op.scrollToPos))
-      { display.wheelStartX = display.wheelStartY = null; }
-
-    // Propagate the scroll position to the actual DOM scroller
-    if (op.scrollTop != null) { setScrollTop(cm, op.scrollTop, op.forceScroll); }
-
-    if (op.scrollLeft != null) { setScrollLeft(cm, op.scrollLeft, true, true); }
-    // If we need to scroll a specific position into view, do so.
-    if (op.scrollToPos) {
-      var rect = scrollPosIntoView(cm, clipPos(doc, op.scrollToPos.from),
-                                   clipPos(doc, op.scrollToPos.to), op.scrollToPos.margin);
-      maybeScrollWindow(cm, rect);
-    }
-
-    // Fire events for markers that are hidden/unidden by editing or
-    // undoing
-    var hidden = op.maybeHiddenMarkers, unhidden = op.maybeUnhiddenMarkers;
-    if (hidden) { for (var i = 0; i < hidden.length; ++i)
-      { if (!hidden[i].lines.length) { signal(hidden[i], "hide"); } } }
-    if (unhidden) { for (var i$1 = 0; i$1 < unhidden.length; ++i$1)
-      { if (unhidden[i$1].lines.length) { signal(unhidden[i$1], "unhide"); } } }
-
-    if (display.wrapper.offsetHeight)
-      { doc.scrollTop = cm.display.scroller.scrollTop; }
-
-    // Fire change events, and delayed event handlers
-    if (op.changeObjs)
-      { signal(cm, "changes", cm, op.changeObjs); }
-    if (op.update)
-      { op.update.finish(); }
-  }
-
-  // Run the given function in an operation
-  function runInOp(cm, f) {
-    if (cm.curOp) { return f() }
-    startOperation(cm);
-    try { return f() }
-    finally { endOperation(cm); }
-  }
-  // Wraps a function in an operation. Returns the wrapped function.
-  function operation(cm, f) {
-    return function() {
-      if (cm.curOp) { return f.apply(cm, arguments) }
-      startOperation(cm);
-      try { return f.apply(cm, arguments) }
-      finally { endOperation(cm); }
-    }
-  }
-  // Used to add methods to editor and doc instances, wrapping them in
-  // operations.
-  function methodOp(f) {
-    return function() {
-      if (this.curOp) { return f.apply(this, arguments) }
-      startOperation(this);
-      try { return f.apply(this, arguments) }
-      finally { endOperation(this); }
-    }
-  }
-  function docMethodOp(f) {
-    return function() {
-      var cm = this.cm;
-      if (!cm || cm.curOp) { return f.apply(this, arguments) }
-      startOperation(cm);
-      try { return f.apply(this, arguments) }
-      finally { endOperation(cm); }
-    }
-  }
-
-  // HIGHLIGHT WORKER
-
-  function startWorker(cm, time) {
-    if (cm.doc.highlightFrontier < cm.display.viewTo)
-      { cm.state.highlight.set(time, bind(highlightWorker, cm)); }
-  }
-
-  function highlightWorker(cm) {
-    var doc = cm.doc;
-    if (doc.highlightFrontier >= cm.display.viewTo) { return }
-    var end = +new Date + cm.options.workTime;
-    var context = getContextBefore(cm, doc.highlightFrontier);
-    var changedLines = [];
-
-    doc.iter(context.line, Math.min(doc.first + doc.size, cm.display.viewTo + 500), function (line) {
-      if (context.line >= cm.display.viewFrom) { // Visible
-        var oldStyles = line.styles;
-        var resetState = line.text.length > cm.options.maxHighlightLength ? copyState(doc.mode, context.state) : null;
-        var highlighted = highlightLine(cm, line, context, true);
-        if (resetState) { context.state = resetState; }
-        line.styles = highlighted.styles;
-        var oldCls = line.styleClasses, newCls = highlighted.classes;
-        if (newCls) { line.styleClasses = newCls; }
-        else if (oldCls) { line.styleClasses = null; }
-        var ischange = !oldStyles || oldStyles.length != line.styles.length ||
-          oldCls != newCls && (!oldCls || !newCls || oldCls.bgClass != newCls.bgClass || oldCls.textClass != newCls.textClass);
-        for (var i = 0; !ischange && i < oldStyles.length; ++i) { ischange = oldStyles[i] != line.styles[i]; }
-        if (ischange) { changedLines.push(context.line); }
-        line.stateAfter = context.save();
-        context.nextLine();
-      } else {
-        if (line.text.length <= cm.options.maxHighlightLength)
-          { processLine(cm, line.text, context); }
-        line.stateAfter = context.line % 5 == 0 ? context.save() : null;
-        context.nextLine();
-      }
-      if (+new Date > end) {
-        startWorker(cm, cm.options.workDelay);
-        return true
-      }
-    });
-    doc.highlightFrontier = context.line;
-    doc.modeFrontier = Math.max(doc.modeFrontier, context.line);
-    if (changedLines.length) { runInOp(cm, function () {
-      for (var i = 0; i < changedLines.length; i++)
-        { regLineChange(cm, changedLines[i], "text"); }
-    }); }
-  }
-
-  // DISPLAY DRAWING
-
-  var DisplayUpdate = function(cm, viewport, force) {
-    var display = cm.display;
-
-    this.viewport = viewport;
-    // Store some values that we'll need later (but don't want to force a relayout for)
-    this.visible = visibleLines(display, cm.doc, viewport);
-    this.editorIsHidden = !display.wrapper.offsetWidth;
-    this.wrapperHeight = display.wrapper.clientHeight;
-    this.wrapperWidth = display.wrapper.clientWidth;
-    this.oldDisplayWidth = displayWidth(cm);
-    this.force = force;
-    this.dims = getDimensions(cm);
-    this.events = [];
-  };
-
-  DisplayUpdate.prototype.signal = function (emitter, type) {
-    if (hasHandler(emitter, type))
-      { this.events.push(arguments); }
-  };
-  DisplayUpdate.prototype.finish = function () {
-      var this$1 = this;
-
-    for (var i = 0; i < this.events.length; i++)
-      { signal.apply(null, this$1.events[i]); }
-  };
-
-  function maybeClipScrollbars(cm) {
-    var display = cm.display;
-    if (!display.scrollbarsClipped && display.scroller.offsetWidth) {
-      display.nativeBarWidth = display.scroller.offsetWidth - display.scroller.clientWidth;
-      display.heightForcer.style.height = scrollGap(cm) + "px";
-      display.sizer.style.marginBottom = -display.nativeBarWidth + "px";
-      display.sizer.style.borderRightWidth = scrollGap(cm) + "px";
-      display.scrollbarsClipped = true;
-    }
-  }
-
-  function selectionSnapshot(cm) {
-    if (cm.hasFocus()) { return null }
-    var active = activeElt();
-    if (!active || !contains(cm.display.lineDiv, active)) { return null }
-    var result = {activeElt: active};
-    if (window.getSelection) {
-      var sel = window.getSelection();
-      if (sel.anchorNode && sel.extend && contains(cm.display.lineDiv, sel.anchorNode)) {
-        result.anchorNode = sel.anchorNode;
-        result.anchorOffset = sel.anchorOffset;
-        result.focusNode = sel.focusNode;
-        result.focusOffset = sel.focusOffset;
-      }
-    }
-    return result
-  }
-
-  function restoreSelection(snapshot) {
-    if (!snapshot || !snapshot.activeElt || snapshot.activeElt == activeElt()) { return }
-    snapshot.activeElt.focus();
-    if (snapshot.anchorNode && contains(document.body, snapshot.anchorNode) && contains(document.body, snapshot.focusNode)) {
-      var sel = window.getSelection(), range$$1 = document.createRange();
-      range$$1.setEnd(snapshot.anchorNode, snapshot.anchorOffset);
-      range$$1.collapse(false);
-      sel.removeAllRanges();
-      sel.addRange(range$$1);
-      sel.extend(snapshot.focusNode, snapshot.focusOffset);
-    }
-  }
-
-  // Does the actual updating of the line display. Bails out
-  // (returning false) when there is nothing to be done and forced is
-  // false.
-  function updateDisplayIfNeeded(cm, update) {
-    var display = cm.display, doc = cm.doc;
-
-    if (update.editorIsHidden) {
-      resetView(cm);
-      return false
-    }
-
-    // Bail out if the visible area is already rendered and nothing changed.
-    if (!update.force &&
-        update.visible.from >= display.viewFrom && update.visible.to <= display.viewTo &&
-        (display.updateLineNumbers == null || display.updateLineNumbers >= display.viewTo) &&
-        display.renderedView == display.view && countDirtyView(cm) == 0)
-      { return false }
-
-    if (maybeUpdateLineNumberWidth(cm)) {
-      resetView(cm);
-      update.dims = getDimensions(cm);
-    }
-
-    // Compute a suitable new viewport (from & to)
-    var end = doc.first + doc.size;
-    var from = Math.max(update.visible.from - cm.options.viewportMargin, doc.first);
-    var to = Math.min(end, update.visible.to + cm.options.viewportMargin);
-    if (display.viewFrom < from && from - display.viewFrom < 20) { from = Math.max(doc.first, display.viewFrom); }
-    if (display.viewTo > to && display.viewTo - to < 20) { to = Math.min(end, display.viewTo); }
-    if (sawCollapsedSpans) {
-      from = visualLineNo(cm.doc, from);
-      to = visualLineEndNo(cm.doc, to);
-    }
-
-    var different = from != display.viewFrom || to != display.viewTo ||
-      display.lastWrapHeight != update.wrapperHeight || display.lastWrapWidth != update.wrapperWidth;
-    adjustView(cm, from, to);
-
-    display.viewOffset = heightAtLine(getLine(cm.doc, display.viewFrom));
-    // Position the mover div to align with the current scroll position
-    cm.display.mover.style.top = display.viewOffset + "px";
-
-    var toUpdate = countDirtyView(cm);
-    if (!different && toUpdate == 0 && !update.force && display.renderedView == display.view &&
-        (display.updateLineNumbers == null || display.updateLineNumbers >= display.viewTo))
-      { return false }
-
-    // For big changes, we hide the enclosing element during the
-    // update, since that speeds up the operations on most browsers.
-    var selSnapshot = selectionSnapshot(cm);
-    if (toUpdate > 4) { display.lineDiv.style.display = "none"; }
-    patchDisplay(cm, display.updateLineNumbers, update.dims);
-    if (toUpdate > 4) { display.lineDiv.style.display = ""; }
-    display.renderedView = display.view;
-    // There might have been a widget with a focused element that got
-    // hidden or updated, if so re-focus it.
-    restoreSelection(selSnapshot);
-
-    // Prevent selection and cursors from interfering with the scroll
-    // width and height.
-    removeChildren(display.cursorDiv);
-    removeChildren(display.selectionDiv);
-    display.gutters.style.height = display.sizer.style.minHeight = 0;
-
-    if (different) {
-      display.lastWrapHeight = update.wrapperHeight;
-      display.lastWrapWidth = update.wrapperWidth;
-      startWorker(cm, 400);
-    }
-
-    display.updateLineNumbers = null;
-
-    return true
-  }
-
-  function postUpdateDisplay(cm, update) {
-    var viewport = update.viewport;
-
-    for (var first = true;; first = false) {
-      if (!first || !cm.options.lineWrapping || update.oldDisplayWidth == displayWidth(cm)) {
-        // Clip forced viewport to actual scrollable area.
-        if (viewport && viewport.top != null)
-          { viewport = {top: Math.min(cm.doc.height + paddingVert(cm.display) - displayHeight(cm), viewport.top)}; }
-        // Updated line heights might result in the drawn area not
-        // actually covering the viewport. Keep looping until it does.
-        update.visible = visibleLines(cm.display, cm.doc, viewport);
-        if (update.visible.from >= cm.display.viewFrom && update.visible.to <= cm.display.viewTo)
-          { break }
-      }
-      if (!updateDisplayIfNeeded(cm, update)) { break }
-      updateHeightsInViewport(cm);
-      var barMeasure = measureForScrollbars(cm);
-      updateSelection(cm);
-      updateScrollbars(cm, barMeasure);
-      setDocumentHeight(cm, barMeasure);
-      update.force = false;
-    }
-
-    update.signal(cm, "update", cm);
-    if (cm.display.viewFrom != cm.display.reportedViewFrom || cm.display.viewTo != cm.display.reportedViewTo) {
-      update.signal(cm, "viewportChange", cm, cm.display.viewFrom, cm.display.viewTo);
-      cm.display.reportedViewFrom = cm.display.viewFrom; cm.display.reportedViewTo = cm.display.viewTo;
-    }
-  }
-
-  function updateDisplaySimple(cm, viewport) {
-    var update = new DisplayUpdate(cm, viewport);
-    if (updateDisplayIfNeeded(cm, update)) {
-      updateHeightsInViewport(cm);
-      postUpdateDisplay(cm, update);
-      var barMeasure = measureForScrollbars(cm);
-      updateSelection(cm);
-      updateScrollbars(cm, barMeasure);
-      setDocumentHeight(cm, barMeasure);
-      update.finish();
-    }
-  }
-
-  // Sync the actual display DOM structure with display.view, removing
-  // nodes for lines that are no longer in view, and creating the ones
-  // that are not there yet, and updating the ones that are out of
-  // date.
-  function patchDisplay(cm, updateNumbersFrom, dims) {
-    var display = cm.display, lineNumbers = cm.options.lineNumbers;
-    var container = display.lineDiv, cur = container.firstChild;
-
-    function rm(node) {
-      var next = node.nextSibling;
-      // Works around a throw-scroll bug in OS X Webkit
-      if (webkit && mac && cm.display.currentWheelTarget == node)
-        { node.style.display = "none"; }
-      else
-        { node.parentNode.removeChild(node); }
-      return next
-    }
-
-    var view = display.view, lineN = display.viewFrom;
-    // Loop over the elements in the view, syncing cur (the DOM nodes
-    // in display.lineDiv) with the view as we go.
-    for (var i = 0; i < view.length; i++) {
-      var lineView = view[i];
-      if (lineView.hidden) ; else if (!lineView.node || lineView.node.parentNode != container) { // Not drawn yet
-        var node = buildLineElement(cm, lineView, lineN, dims);
-        container.insertBefore(node, cur);
-      } else { // Already drawn
-        while (cur != lineView.node) { cur = rm(cur); }
-        var updateNumber = lineNumbers && updateNumbersFrom != null &&
-          updateNumbersFrom <= lineN && lineView.lineNumber;
-        if (lineView.changes) {
-          if (indexOf(lineView.changes, "gutter") > -1) { updateNumber = false; }
-          updateLineForChanges(cm, lineView, lineN, dims);
-        }
-        if (updateNumber) {
-          removeChildren(lineView.lineNumber);
-          lineView.lineNumber.appendChild(document.createTextNode(lineNumberFor(cm.options, lineN)));
-        }
-        cur = lineView.node.nextSibling;
-      }
-      lineN += lineView.size;
-    }
-    while (cur) { cur = rm(cur); }
-  }
-
-  function updateGutterSpace(display) {
-    var width = display.gutters.offsetWidth;
-    display.sizer.style.marginLeft = width + "px";
-  }
-
-  function setDocumentHeight(cm, measure) {
-    cm.display.sizer.style.minHeight = measure.docHeight + "px";
-    cm.display.heightForcer.style.top = measure.docHeight + "px";
-    cm.display.gutters.style.height = (measure.docHeight + cm.display.barHeight + scrollGap(cm)) + "px";
-  }
-
-  // Re-align line numbers and gutter marks to compensate for
-  // horizontal scrolling.
-  function alignHorizontally(cm) {
-    var display = cm.display, view = display.view;
-    if (!display.alignWidgets && (!display.gutters.firstChild || !cm.options.fixedGutter)) { return }
-    var comp = compensateForHScroll(display) - display.scroller.scrollLeft + cm.doc.scrollLeft;
-    var gutterW = display.gutters.offsetWidth, left = comp + "px";
-    for (var i = 0; i < view.length; i++) { if (!view[i].hidden) {
-      if (cm.options.fixedGutter) {
-        if (view[i].gutter)
-          { view[i].gutter.style.left = left; }
-        if (view[i].gutterBackground)
-          { view[i].gutterBackground.style.left = left; }
-      }
-      var align = view[i].alignable;
-      if (align) { for (var j = 0; j < align.length; j++)
-        { align[j].style.left = left; } }
-    } }
-    if (cm.options.fixedGutter)
-      { display.gutters.style.left = (comp + gutterW) + "px"; }
-  }
-
-  // Used to ensure that the line number gutter is still the right
-  // size for the current document size. Returns true when an update
-  // is needed.
-  function maybeUpdateLineNumberWidth(cm) {
-    if (!cm.options.lineNumbers) { return false }
-    var doc = cm.doc, last = lineNumberFor(cm.options, doc.first + doc.size - 1), display = cm.display;
-    if (last.length != display.lineNumChars) {
-      var test = display.measure.appendChild(elt("div", [elt("div", last)],
-                                                 "CodeMirror-linenumber CodeMirror-gutter-elt"));
-      var innerW = test.firstChild.offsetWidth, padding = test.offsetWidth - innerW;
-      display.lineGutter.style.width = "";
-      display.lineNumInnerWidth = Math.max(innerW, display.lineGutter.offsetWidth - padding) + 1;
-      display.lineNumWidth = display.lineNumInnerWidth + padding;
-      display.lineNumChars = display.lineNumInnerWidth ? last.length : -1;
-      display.lineGutter.style.width = display.lineNumWidth + "px";
-      updateGutterSpace(cm.display);
-      return true
-    }
-    return false
-  }
-
-  function getGutters(gutters, lineNumbers) {
-    var result = [], sawLineNumbers = false;
-    for (var i = 0; i < gutters.length; i++) {
-      var name = gutters[i], style = null;
-      if (typeof name != "string") { style = name.style; name = name.className; }
-      if (name == "CodeMirror-linenumbers") {
-        if (!lineNumbers) { continue }
-        else { sawLineNumbers = true; }
-      }
-      result.push({className: name, style: style});
-    }
-    if (lineNumbers && !sawLineNumbers) { result.push({className: "CodeMirror-linenumbers", style: null}); }
-    return result
-  }
-
-  // Rebuild the gutter elements, ensure the margin to the left of the
-  // code matches their width.
-  function renderGutters(display) {
-    var gutters = display.gutters, specs = display.gutterSpecs;
-    removeChildren(gutters);
-    display.lineGutter = null;
-    for (var i = 0; i < specs.length; ++i) {
-      var ref = specs[i];
-      var className = ref.className;
-      var style = ref.style;
-      var gElt = gutters.appendChild(elt("div", null, "CodeMirror-gutter " + className));
-      if (style) { gElt.style.cssText = style; }
-      if (className == "CodeMirror-linenumbers") {
-        display.lineGutter = gElt;
-        gElt.style.width = (display.lineNumWidth || 1) + "px";
-      }
-    }
-    gutters.style.display = specs.length ? "" : "none";
-    updateGutterSpace(display);
-  }
-
-  function updateGutters(cm) {
-    renderGutters(cm.display);
-    regChange(cm);
-    alignHorizontally(cm);
-  }
-
-  // The display handles the DOM integration, both for input reading
-  // and content drawing. It holds references to DOM nodes and
-  // display-related state.
-
-  function Display(place, doc, input, options) {
-    var d = this;
-    this.input = input;
-
-    // Covers bottom-right square when both scrollbars are present.
-    d.scrollbarFiller = elt("div", null, "CodeMirror-scrollbar-filler");
-    d.scrollbarFiller.setAttribute("cm-not-content", "true");
-    // Covers bottom of gutter when coverGutterNextToScrollbar is on
-    // and h scrollbar is present.
-    d.gutterFiller = elt("div", null, "CodeMirror-gutter-filler");
-    d.gutterFiller.setAttribute("cm-not-content", "true");
-    // Will contain the actual code, positioned to cover the viewport.
-    d.lineDiv = eltP("div", null, "CodeMirror-code");
-    // Elements are added to these to represent selection and cursors.
-    d.selectionDiv = elt("div", null, null, "position: relative; z-index: 1");
-    d.cursorDiv = elt("div", null, "CodeMirror-cursors");
-    // A visibility: hidden element used to find the size of things.
-    d.measure = elt("div", null, "CodeMirror-measure");
-    // When lines outside of the viewport are measured, they are drawn in this.
-    d.lineMeasure = elt("div", null, "CodeMirror-measure");
-    // Wraps everything that needs to exist inside the vertically-padded coordinate system
-    d.lineSpace = eltP("div", [d.measure, d.lineMeasure, d.selectionDiv, d.cursorDiv, d.lineDiv],
-                      null, "position: relative; outline: none");
-    var lines = eltP("div", [d.lineSpace], "CodeMirror-lines");
-    // Moved around its parent to cover visible view.
-    d.mover = elt("div", [lines], null, "position: relative");
-    // Set to the height of the document, allowing scrolling.
-    d.sizer = elt("div", [d.mover], "CodeMirror-sizer");
-    d.sizerWidth = null;
-    // Behavior of elts with overflow: auto and padding is
-    // inconsistent across browsers. This is used to ensure the
-    // scrollable area is big enough.
-    d.heightForcer = elt("div", null, null, "position: absolute; height: " + scrollerGap + "px; width: 1px;");
-    // Will contain the gutters, if any.
-    d.gutters = elt("div", null, "CodeMirror-gutters");
-    d.lineGutter = null;
-    // Actual scrollable element.
-    d.scroller = elt("div", [d.sizer, d.heightForcer, d.gutters], "CodeMirror-scroll");
-    d.scroller.setAttribute("tabIndex", "-1");
-    // The element in which the editor lives.
-    d.wrapper = elt("div", [d.scrollbarFiller, d.gutterFiller, d.scroller], "CodeMirror");
-
-    // Work around IE7 z-index bug (not perfect, hence IE7 not really being supported)
-    if (ie && ie_version < 8) { d.gutters.style.zIndex = -1; d.scroller.style.paddingRight = 0; }
-    if (!webkit && !(gecko && mobile)) { d.scroller.draggable = true; }
-
-    if (place) {
-      if (place.appendChild) { place.appendChild(d.wrapper); }
-      else { place(d.wrapper); }
-    }
-
-    // Current rendered range (may be bigger than the view window).
-    d.viewFrom = d.viewTo = doc.first;
-    d.reportedViewFrom = d.reportedViewTo = doc.first;
-    // Information about the rendered lines.
-    d.view = [];
-    d.renderedView = null;
-    // Holds info about a single rendered line when it was rendered
-    // for measurement, while not in view.
-    d.externalMeasured = null;
-    // Empty space (in pixels) above the view
-    d.viewOffset = 0;
-    d.lastWrapHeight = d.lastWrapWidth = 0;
-    d.updateLineNumbers = null;
-
-    d.nativeBarWidth = d.barHeight = d.barWidth = 0;
-    d.scrollbarsClipped = false;
-
-    // Used to only resize the line number gutter when necessary (when
-    // the amount of lines crosses a boundary that makes its width change)
-    d.lineNumWidth = d.lineNumInnerWidth = d.lineNumChars = null;
-    // Set to true when a non-horizontal-scrolling line widget is
-    // added. As an optimization, line widget aligning is skipped when
-    // this is false.
-    d.alignWidgets = false;
-
-    d.cachedCharWidth = d.cachedTextHeight = d.cachedPaddingH = null;
-
-    // Tracks the maximum line length so that the horizontal scrollbar
-    // can be kept static when scrolling.
-    d.maxLine = null;
-    d.maxLineLength = 0;
-    d.maxLineChanged = false;
-
-    // Used for measuring wheel scrolling granularity
-    d.wheelDX = d.wheelDY = d.wheelStartX = d.wheelStartY = null;
-
-    // True when shift is held down.
-    d.shift = false;
-
-    // Used to track whether anything happened since the context menu
-    // was opened.
-    d.selForContextMenu = null;
-
-    d.activeTouch = null;
-
-    d.gutterSpecs = getGutters(options.gutters, options.lineNumbers);
-    renderGutters(d);
-
-    input.init(d);
-  }
-
-  // Since the delta values reported on mouse wheel events are
-  // unstandardized between browsers and even browser versions, and
-  // generally horribly unpredictable, this code starts by measuring
-  // the scroll effect that the first few mouse wheel events have,
-  // and, from that, detects the way it can convert deltas to pixel
-  // offsets afterwards.
-  //
-  // The reason we want to know the amount a wheel event will scroll
-  // is that it gives us a chance to update the display before the
-  // actual scrolling happens, reducing flickering.
-
-  var wheelSamples = 0, wheelPixelsPerUnit = null;
-  // Fill in a browser-detected starting value on browsers where we
-  // know one. These don't have to be accurate -- the result of them
-  // being wrong would just be a slight flicker on the first wheel
-  // scroll (if it is large enough).
-  if (ie) { wheelPixelsPerUnit = -.53; }
-  else if (gecko) { wheelPixelsPerUnit = 15; }
-  else if (chrome) { wheelPixelsPerUnit = -.7; }
-  else if (safari) { wheelPixelsPerUnit = -1/3; }
-
-  function wheelEventDelta(e) {
-    var dx = e.wheelDeltaX, dy = e.wheelDeltaY;
-    if (dx == null && e.detail && e.axis == e.HORIZONTAL_AXIS) { dx = e.detail; }
-    if (dy == null && e.detail && e.axis == e.VERTICAL_AXIS) { dy = e.detail; }
-    else if (dy == null) { dy = e.wheelDelta; }
-    return {x: dx, y: dy}
-  }
-  function wheelEventPixels(e) {
-    var delta = wheelEventDelta(e);
-    delta.x *= wheelPixelsPerUnit;
-    delta.y *= wheelPixelsPerUnit;
-    return delta
-  }
-
-  function onScrollWheel(cm, e) {
-    var delta = wheelEventDelta(e), dx = delta.x, dy = delta.y;
-
-    var display = cm.display, scroll = display.scroller;
-    // Quit if there's nothing to scroll here
-    var canScrollX = scroll.scrollWidth > scroll.clientWidth;
-    var canScrollY = scroll.scrollHeight > scroll.clientHeight;
-    if (!(dx && canScrollX || dy && canScrollY)) { return }
-
-    // Webkit browsers on OS X abort momentum scrolls when the target
-    // of the scroll event is removed from the scrollable element.
-    // This hack (see related code in patchDisplay) makes sure the
-    // element is kept around.
-    if (dy && mac && webkit) {
-      outer: for (var cur = e.target, view = display.view; cur != scroll; cur = cur.parentNode) {
-        for (var i = 0; i < view.length; i++) {
-          if (view[i].node == cur) {
-            cm.display.currentWheelTarget = cur;
-            break outer
-          }
-        }
-      }
-    }
-
-    // On some browsers, horizontal scrolling will cause redraws to
-    // happen before the gutter has been realigned, causing it to
-    // wriggle around in a most unseemly way. When we have an
-    // estimated pixels/delta value, we just handle horizontal
-    // scrolling entirely here. It'll be slightly off from native, but
-    // better than glitching out.
-    if (dx && !gecko && !presto && wheelPixelsPerUnit != null) {
-      if (dy && canScrollY)
-        { updateScrollTop(cm, Math.max(0, scroll.scrollTop + dy * wheelPixelsPerUnit)); }
-      setScrollLeft(cm, Math.max(0, scroll.scrollLeft + dx * wheelPixelsPerUnit));
-      // Only prevent default scrolling if vertical scrolling is
-      // actually possible. Otherwise, it causes vertical scroll
-      // jitter on OSX trackpads when deltaX is small and deltaY
-      // is large (issue #3579)
-      if (!dy || (dy && canScrollY))
-        { e_preventDefault(e); }
-      display.wheelStartX = null; // Abort measurement, if in progress
-      return
-    }
-
-    // 'Project' the visible viewport to cover the area that is being
-    // scrolled into view (if we know enough to estimate it).
-    if (dy && wheelPixelsPerUnit != null) {
-      var pixels = dy * wheelPixelsPerUnit;
-      var top = cm.doc.scrollTop, bot = top + display.wrapper.clientHeight;
-      if (pixels < 0) { top = Math.max(0, top + pixels - 50); }
-      else { bot = Math.min(cm.doc.height, bot + pixels + 50); }
-      updateDisplaySimple(cm, {top: top, bottom: bot});
-    }
-
-    if (wheelSamples < 20) {
-      if (display.wheelStartX == null) {
-        display.wheelStartX = scroll.scrollLeft; display.wheelStartY = scroll.scrollTop;
-        display.wheelDX = dx; display.wheelDY = dy;
-        setTimeout(function () {
-          if (display.wheelStartX == null) { return }
-          var movedX = scroll.scrollLeft - display.wheelStartX;
-          var movedY = scroll.scrollTop - display.wheelStartY;
-          var sample = (movedY && display.wheelDY && movedY / display.wheelDY) ||
-            (movedX && display.wheelDX && movedX / display.wheelDX);
-          display.wheelStartX = display.wheelStartY = null;
-          if (!sample) { return }
-          wheelPixelsPerUnit = (wheelPixelsPerUnit * wheelSamples + sample) / (wheelSamples + 1);
-          ++wheelSamples;
-        }, 200);
-      } else {
-        display.wheelDX += dx; display.wheelDY += dy;
-      }
-    }
-  }
-
-  // Selection objects are immutable. A new one is created every time
-  // the selection changes. A selection is one or more non-overlapping
-  // (and non-touching) ranges, sorted, and an integer that indicates
-  // which one is the primary selection (the one that's scrolled into
-  // view, that getCursor returns, etc).
-  var Selection = function(ranges, primIndex) {
-    this.ranges = ranges;
-    this.primIndex = primIndex;
-  };
-
-  Selection.prototype.primary = function () { return this.ranges[this.primIndex] };
-
-  Selection.prototype.equals = function (other) {
-      var this$1 = this;
-
-    if (other == this) { return true }
-    if (other.primIndex != this.primIndex || other.ranges.length != this.ranges.length) { return false }
-    for (var i = 0; i < this.ranges.length; i++) {
-      var here = this$1.ranges[i], there = other.ranges[i];
-      if (!equalCursorPos(here.anchor, there.anchor) || !equalCursorPos(here.head, there.head)) { return false }
-    }
-    return true
-  };
-
-  Selection.prototype.deepCopy = function () {
-      var this$1 = this;
-
-    var out = [];
-    for (var i = 0; i < this.ranges.length; i++)
-      { out[i] = new Range(copyPos(this$1.ranges[i].anchor), copyPos(this$1.ranges[i].head)); }
-    return new Selection(out, this.primIndex)
-  };
-
-  Selection.prototype.somethingSelected = function () {
-      var this$1 = this;
-
-    for (var i = 0; i < this.ranges.length; i++)
-      { if (!this$1.ranges[i].empty()) { return true } }
-    return false
-  };
-
-  Selection.prototype.contains = function (pos, end) {
-      var this$1 = this;
-
-    if (!end) { end = pos; }
-    for (var i = 0; i < this.ranges.length; i++) {
-      var range = this$1.ranges[i];
-      if (cmp(end, range.from()) >= 0 && cmp(pos, range.to()) <= 0)
-        { return i }
-    }
-    return -1
-  };
-
-  var Range = function(anchor, head) {
-    this.anchor = anchor; this.head = head;
-  };
-
-  Range.prototype.from = function () { return minPos(this.anchor, this.head) };
-  Range.prototype.to = function () { return maxPos(this.anchor, this.head) };
-  Range.prototype.empty = function () { return this.head.line == this.anchor.line && this.head.ch == this.anchor.ch };
-
-  // Take an unsorted, potentially overlapping set of ranges, and
-  // build a selection out of it. 'Consumes' ranges array (modifying
-  // it).
-  function normalizeSelection(cm, ranges, primIndex) {
-    var mayTouch = cm && cm.options.selectionsMayTouch;
-    var prim = ranges[primIndex];
-    ranges.sort(function (a, b) { return cmp(a.from(), b.from()); });
-    primIndex = indexOf(ranges, prim);
-    for (var i = 1; i < ranges.length; i++) {
-      var cur = ranges[i], prev = ranges[i - 1];
-      var diff = cmp(prev.to(), cur.from());
-      if (mayTouch && !cur.empty() ? diff > 0 : diff >= 0) {
-        var from = minPos(prev.from(), cur.from()), to = maxPos(prev.to(), cur.to());
-        var inv = prev.empty() ? cur.from() == cur.head : prev.from() == prev.head;
-        if (i <= primIndex) { --primIndex; }
-        ranges.splice(--i, 2, new Range(inv ? to : from, inv ? from : to));
-      }
-    }
-    return new Selection(ranges, primIndex)
-  }
-
-  function simpleSelection(anchor, head) {
-    return new Selection([new Range(anchor, head || anchor)], 0)
-  }
-
-  // Compute the position of the end of a change (its 'to' property
-  // refers to the pre-change end).
-  function changeEnd(change) {
-    if (!change.text) { return change.to }
-    return Pos(change.from.line + change.text.length - 1,
-               lst(change.text).length + (change.text.length == 1 ? change.from.ch : 0))
-  }
-
-  // Adjust a position to refer to the post-change position of the
-  // same text, or the end of the change if the change covers it.
-  function adjustForChange(pos, change) {
-    if (cmp(pos, change.from) < 0) { return pos }
-    if (cmp(pos, change.to) <= 0) { return changeEnd(change) }
-
-    var line = pos.line + change.text.length - (change.to.line - change.from.line) - 1, ch = pos.ch;
-    if (pos.line == change.to.line) { ch += changeEnd(change).ch - change.to.ch; }
-    return Pos(line, ch)
-  }
-
-  function computeSelAfterChange(doc, change) {
-    var out = [];
-    for (var i = 0; i < doc.sel.ranges.length; i++) {
-      var range = doc.sel.ranges[i];
-      out.push(new Range(adjustForChange(range.anchor, change),
-                         adjustForChange(range.head, change)));
-    }
-    return normalizeSelection(doc.cm, out, doc.sel.primIndex)
-  }
-
-  function offsetPos(pos, old, nw) {
-    if (pos.line == old.line)
-      { return Pos(nw.line, pos.ch - old.ch + nw.ch) }
-    else
-      { return Pos(nw.line + (pos.line - old.line), pos.ch) }
-  }
-
-  // Used by replaceSelections to allow moving the selection to the
-  // start or around the replaced test. Hint may be "start" or "around".
-  function computeReplacedSel(doc, changes, hint) {
-    var out = [];
-    var oldPrev = Pos(doc.first, 0), newPrev = oldPrev;
-    for (var i = 0; i < changes.length; i++) {
-      var change = changes[i];
-      var from = offsetPos(change.from, oldPrev, newPrev);
-      var to = offsetPos(changeEnd(change), oldPrev, newPrev);
-      oldPrev = change.to;
-      newPrev = to;
-      if (hint == "around") {
-        var range = doc.sel.ranges[i], inv = cmp(range.head, range.anchor) < 0;
-        out[i] = new Range(inv ? to : from, inv ? from : to);
-      } else {
-        out[i] = new Range(from, from);
-      }
-    }
-    return new Selection(out, doc.sel.primIndex)
-  }
-
-  // Used to get the editor into a consistent state again when options change.
-
-  function loadMode(cm) {
-    cm.doc.mode = getMode(cm.options, cm.doc.modeOption);
-    resetModeState(cm);
-  }
-
-  function resetModeState(cm) {
-    cm.doc.iter(function (line) {
-      if (line.stateAfter) { line.stateAfter = null; }
-      if (line.styles) { line.styles = null; }
-    });
-    cm.doc.modeFrontier = cm.doc.highlightFrontier = cm.doc.first;
-    startWorker(cm, 100);
-    cm.state.modeGen++;
-    if (cm.curOp) { regChange(cm); }
-  }
-
-  // DOCUMENT DATA STRUCTURE
-
-  // By default, updates that start and end at the beginning of a line
-  // are treated specially, in order to make the association of line
-  // widgets and marker elements with the text behave more intuitive.
-  function isWholeLineUpdate(doc, change) {
-    return change.from.ch == 0 && change.to.ch == 0 && lst(change.text) == "" &&
-      (!doc.cm || doc.cm.options.wholeLineUpdateBefore)
-  }
-
-  // Perform a change on the document data structure.
-  function updateDoc(doc, change, markedSpans, estimateHeight$$1) {
-    function spansFor(n) {return markedSpans ? markedSpans[n] : null}
-    function update(line, text, spans) {
-      updateLine(line, text, spans, estimateHeight$$1);
-      signalLater(line, "change", line, change);
-    }
-    function linesFor(start, end) {
-      var result = [];
-      for (var i = start; i < end; ++i)
-        { result.push(new Line(text[i], spansFor(i), estimateHeight$$1)); }
-      return result
-    }
-
-    var from = change.from, to = change.to, text = change.text;
-    var firstLine = getLine(doc, from.line), lastLine = getLine(doc, to.line);
-    var lastText = lst(text), lastSpans = spansFor(text.length - 1), nlines = to.line - from.line;
-
-    // Adjust the line structure
-    if (change.full) {
-      doc.insert(0, linesFor(0, text.length));
-      doc.remove(text.length, doc.size - text.length);
-    } else if (isWholeLineUpdate(doc, change)) {
-      // This is a whole-line replace. Treated specially to make
-      // sure line objects move the way they are supposed to.
-      var added = linesFor(0, text.length - 1);
-      update(lastLine, lastLine.text, lastSpans);
-      if (nlines) { doc.remove(from.line, nlines); }
-      if (added.length) { doc.insert(from.line, added); }
-    } else if (firstLine == lastLine) {
-      if (text.length == 1) {
-        update(firstLine, firstLine.text.slice(0, from.ch) + lastText + firstLine.text.slice(to.ch), lastSpans);
-      } else {
-        var added$1 = linesFor(1, text.length - 1);
-        added$1.push(new Line(lastText + firstLine.text.slice(to.ch), lastSpans, estimateHeight$$1));
-        update(firstLine, firstLine.text.slice(0, from.ch) + text[0], spansFor(0));
-        doc.insert(from.line + 1, added$1);
-      }
-    } else if (text.length == 1) {
-      update(firstLine, firstLine.text.slice(0, from.ch) + text[0] + lastLine.text.slice(to.ch), spansFor(0));
-      doc.remove(from.line + 1, nlines);
-    } else {
-      update(firstLine, firstLine.text.slice(0, from.ch) + text[0], spansFor(0));
-      update(lastLine, lastText + lastLine.text.slice(to.ch), lastSpans);
-      var added$2 = linesFor(1, text.length - 1);
-      if (nlines > 1) { doc.remove(from.line + 1, nlines - 1); }
-      doc.insert(from.line + 1, added$2);
-    }
-
-    signalLater(doc, "change", doc, change);
-  }
-
-  // Call f for all linked documents.
-  function linkedDocs(doc, f, sharedHistOnly) {
-    function propagate(doc, skip, sharedHist) {
-      if (doc.linked) { for (var i = 0; i < doc.linked.length; ++i) {
-        var rel = doc.linked[i];
-        if (rel.doc == skip) { continue }
-        var shared = sharedHist && rel.sharedHist;
-        if (sharedHistOnly && !shared) { continue }
-        f(rel.doc, shared);
-        propagate(rel.doc, doc, shared);
-      } }
-    }
-    propagate(doc, null, true);
-  }
-
-  // Attach a document to an editor.
-  function attachDoc(cm, doc) {
-    if (doc.cm) { throw new Error("This document is already in use.") }
-    cm.doc = doc;
-    doc.cm = cm;
-    estimateLineHeights(cm);
-    loadMode(cm);
-    setDirectionClass(cm);
-    if (!cm.options.lineWrapping) { findMaxLine(cm); }
-    cm.options.mode = doc.modeOption;
-    regChange(cm);
-  }
-
-  function setDirectionClass(cm) {
-  (cm.doc.direction == "rtl" ? addClass : rmClass)(cm.display.lineDiv, "CodeMirror-rtl");
-  }
-
-  function directionChanged(cm) {
-    runInOp(cm, function () {
-      setDirectionClass(cm);
-      regChange(cm);
-    });
-  }
-
-  function History(startGen) {
-    // Arrays of change events and selections. Doing something adds an
-    // event to done and clears undo. Undoing moves events from done
-    // to undone, redoing moves them in the other direction.
-    this.done = []; this.undone = [];
-    this.undoDepth = Infinity;
-    // Used to track when changes can be merged into a single undo
-    // event
-    this.lastModTime = this.lastSelTime = 0;
-    this.lastOp = this.lastSelOp = null;
-    this.lastOrigin = this.lastSelOrigin = null;
-    // Used by the isClean() method
-    this.generation = this.maxGeneration = startGen || 1;
-  }
-
-  // Create a history change event from an updateDoc-style change
-  // object.
-  function historyChangeFromChange(doc, change) {
-    var histChange = {from: copyPos(change.from), to: changeEnd(change), text: getBetween(doc, change.from, change.to)};
-    attachLocalSpans(doc, histChange, change.from.line, change.to.line + 1);
-    linkedDocs(doc, function (doc) { return attachLocalSpans(doc, histChange, change.from.line, change.to.line + 1); }, true);
-    return histChange
-  }
-
-  // Pop all selection events off the end of a history array. Stop at
-  // a change event.
-  function clearSelectionEvents(array) {
-    while (array.length) {
-      var last = lst(array);
-      if (last.ranges) { array.pop(); }
-      else { break }
-    }
-  }
-
-  // Find the top change event in the history. Pop off selection
-  // events that are in the way.
-  function lastChangeEvent(hist, force) {
-    if (force) {
-      clearSelectionEvents(hist.done);
-      return lst(hist.done)
-    } else if (hist.done.length && !lst(hist.done).ranges) {
-      return lst(hist.done)
-    } else if (hist.done.length > 1 && !hist.done[hist.done.length - 2].ranges) {
-      hist.done.pop();
-      return lst(hist.done)
-    }
-  }
-
-  // Register a change in the history. Merges changes that are within
-  // a single operation, or are close together with an origin that
-  // allows merging (starting with "+") into a single event.
-  function addChangeToHistory(doc, change, selAfter, opId) {
-    var hist = doc.history;
-    hist.undone.length = 0;
-    var time = +new Date, cur;
-    var last;
-
-    if ((hist.lastOp == opId ||
-         hist.lastOrigin == change.origin && change.origin &&
-         ((change.origin.charAt(0) == "+" && hist.lastModTime > time - (doc.cm ? doc.cm.options.historyEventDelay : 500)) ||
-          change.origin.charAt(0) == "*")) &&
-        (cur = lastChangeEvent(hist, hist.lastOp == opId))) {
-      // Merge this change into the last event
-      last = lst(cur.changes);
-      if (cmp(change.from, change.to) == 0 && cmp(change.from, last.to) == 0) {
-        // Optimized case for simple insertion -- don't want to add
-        // new changesets for every character typed
-        last.to = changeEnd(change);
-      } else {
-        // Add new sub-event
-        cur.changes.push(historyChangeFromChange(doc, change));
-      }
-    } else {
-      // Can not be merged, start a new event.
-      var before = lst(hist.done);
-      if (!before || !before.ranges)
-        { pushSelectionToHistory(doc.sel, hist.done); }
-      cur = {changes: [historyChangeFromChange(doc, change)],
-             generation: hist.generation};
-      hist.done.push(cur);
-      while (hist.done.length > hist.undoDepth) {
-        hist.done.shift();
-        if (!hist.done[0].ranges) { hist.done.shift(); }
-      }
-    }
-    hist.done.push(selAfter);
-    hist.generation = ++hist.maxGeneration;
-    hist.lastModTime = hist.lastSelTime = time;
-    hist.lastOp = hist.lastSelOp = opId;
-    hist.lastOrigin = hist.lastSelOrigin = change.origin;
-
-    if (!last) { signal(doc, "historyAdded"); }
-  }
-
-  function selectionEventCanBeMerged(doc, origin, prev, sel) {
-    var ch = origin.charAt(0);
-    return ch == "*" ||
-      ch == "+" &&
-      prev.ranges.length == sel.ranges.length &&
-      prev.somethingSelected() == sel.somethingSelected() &&
-      new Date - doc.history.lastSelTime <= (doc.cm ? doc.cm.options.historyEventDelay : 500)
-  }
-
-  // Called whenever the selection changes, sets the new selection as
-  // the pending selection in the history, and pushes the old pending
-  // selection into the 'done' array when it was significantly
-  // different (in number of selected ranges, emptiness, or time).
-  function addSelectionToHistory(doc, sel, opId, options) {
-    var hist = doc.history, origin = options && options.origin;
-
-    // A new event is started when the previous origin does not match
-    // the current, or the origins don't allow matching. Origins
-    // starting with * are always merged, those starting with + are
-    // merged when similar and close together in time.
-    if (opId == hist.lastSelOp ||
-        (origin && hist.lastSelOrigin == origin &&
-         (hist.lastModTime == hist.lastSelTime && hist.lastOrigin == origin ||
-          selectionEventCanBeMerged(doc, origin, lst(hist.done), sel))))
-      { hist.done[hist.done.length - 1] = sel; }
-    else
-      { pushSelectionToHistory(sel, hist.done); }
-
-    hist.lastSelTime = +new Date;
-    hist.lastSelOrigin = origin;
-    hist.lastSelOp = opId;
-    if (options && options.clearRedo !== false)
-      { clearSelectionEvents(hist.undone); }
-  }
-
-  function pushSelectionToHistory(sel, dest) {
-    var top = lst(dest);
-    if (!(top && top.ranges && top.equals(sel)))
-      { dest.push(sel); }
-  }
-
-  // Used to store marked span information in the history.
-  function attachLocalSpans(doc, change, from, to) {
-    var existing = change["spans_" + doc.id], n = 0;
-    doc.iter(Math.max(doc.first, from), Math.min(doc.first + doc.size, to), function (line) {
-      if (line.markedSpans)
-        { (existing || (existing = change["spans_" + doc.id] = {}))[n] = line.markedSpans; }
-      ++n;
-    });
-  }
-
-  // When un/re-doing restores text containing marked spans, those
-  // that have been explicitly cleared should not be restored.
-  function removeClearedSpans(spans) {
-    if (!spans) { return null }
-    var out;
-    for (var i = 0; i < spans.length; ++i) {
-      if (spans[i].marker.explicitlyCleared) { if (!out) { out = spans.slice(0, i); } }
-      else if (out) { out.push(spans[i]); }
-    }
-    return !out ? spans : out.length ? out : null
-  }
-
-  // Retrieve and filter the old marked spans stored in a change event.
-  function getOldSpans(doc, change) {
-    var found = change["spans_" + doc.id];
-    if (!found) { return null }
-    var nw = [];
-    for (var i = 0; i < change.text.length; ++i)
-      { nw.push(removeClearedSpans(found[i])); }
-    return nw
-  }
-
-  // Used for un/re-doing changes from the history. Combines the
-  // result of computing the existing spans with the set of spans that
-  // existed in the history (so that deleting around a span and then
-  // undoing brings back the span).
-  function mergeOldSpans(doc, change) {
-    var old = getOldSpans(doc, change);
-    var stretched = stretchSpansOverChange(doc, change);
-    if (!old) { return stretched }
-    if (!stretched) { return old }
-
-    for (var i = 0; i < old.length; ++i) {
-      var oldCur = old[i], stretchCur = stretched[i];
-      if (oldCur && stretchCur) {
-        spans: for (var j = 0; j < stretchCur.length; ++j) {
-          var span = stretchCur[j];
-          for (var k = 0; k < oldCur.length; ++k)
-            { if (oldCur[k].marker == span.marker) { continue spans } }
-          oldCur.push(span);
-        }
-      } else if (stretchCur) {
-        old[i] = stretchCur;
-      }
-    }
-    return old
-  }
-
-  // Used both to provide a JSON-safe object in .getHistory, and, when
-  // detaching a document, to split the history in two
-  function copyHistoryArray(events, newGroup, instantiateSel) {
-    var copy = [];
-    for (var i = 0; i < events.length; ++i) {
-      var event = events[i];
-      if (event.ranges) {
-        copy.push(instantiateSel ? Selection.prototype.deepCopy.call(event) : event);
-        continue
-      }
-      var changes = event.changes, newChanges = [];
-      copy.push({changes: newChanges});
-      for (var j = 0; j < changes.length; ++j) {
-        var change = changes[j], m = (void 0);
-        newChanges.push({from: change.from, to: change.to, text: change.text});
-        if (newGroup) { for (var prop in change) { if (m = prop.match(/^spans_(\d+)$/)) {
-          if (indexOf(newGroup, Number(m[1])) > -1) {
-            lst(newChanges)[prop] = change[prop];
-            delete change[prop];
-          }
-        } } }
-      }
-    }
-    return copy
-  }
-
-  // The 'scroll' parameter given to many of these indicated whether
-  // the new cursor position should be scrolled into view after
-  // modifying the selection.
-
-  // If shift is held or the extend flag is set, extends a range to
-  // include a given position (and optionally a second position).
-  // Otherwise, simply returns the range between the given positions.
-  // Used for cursor motion and such.
-  function extendRange(range, head, other, extend) {
-    if (extend) {
-      var anchor = range.anchor;
-      if (other) {
-        var posBefore = cmp(head, anchor) < 0;
-        if (posBefore != (cmp(other, anchor) < 0)) {
-          anchor = head;
-          head = other;
-        } else if (posBefore != (cmp(head, other) < 0)) {
-          head = other;
-        }
-      }
-      return new Range(anchor, head)
-    } else {
-      return new Range(other || head, head)
-    }
-  }
-
-  // Extend the primary selection range, discard the rest.
-  function extendSelection(doc, head, other, options, extend) {
-    if (extend == null) { extend = doc.cm && (doc.cm.display.shift || doc.extend); }
-    setSelection(doc, new Selection([extendRange(doc.sel.primary(), head, other, extend)], 0), options);
-  }
-
-  // Extend all selections (pos is an array of selections with length
-  // equal the number of selections)
-  function extendSelections(doc, heads, options) {
-    var out = [];
-    var extend = doc.cm && (doc.cm.display.shift || doc.extend);
-    for (var i = 0; i < doc.sel.ranges.length; i++)
-      { out[i] = extendRange(doc.sel.ranges[i], heads[i], null, extend); }
-    var newSel = normalizeSelection(doc.cm, out, doc.sel.primIndex);
-    setSelection(doc, newSel, options);
-  }
-
-  // Updates a single range in the selection.
-  function replaceOneSelection(doc, i, range, options) {
-    var ranges = doc.sel.ranges.slice(0);
-    ranges[i] = range;
-    setSelection(doc, normalizeSelection(doc.cm, ranges, doc.sel.primIndex), options);
-  }
-
-  // Reset the selection to a single range.
-  function setSimpleSelection(doc, anchor, head, options) {
-    setSelection(doc, simpleSelection(anchor, head), options);
-  }
-
-  // Give beforeSelectionChange handlers a change to influence a
-  // selection update.
-  function filterSelectionChange(doc, sel, options) {
-    var obj = {
-      ranges: sel.ranges,
-      update: function(ranges) {
-        var this$1 = this;
-
-        this.ranges = [];
-        for (var i = 0; i < ranges.length; i++)
-          { this$1.ranges[i] = new Range(clipPos(doc, ranges[i].anchor),
-                                     clipPos(doc, ranges[i].head)); }
-      },
-      origin: options && options.origin
-    };
-    signal(doc, "beforeSelectionChange", doc, obj);
-    if (doc.cm) { signal(doc.cm, "beforeSelectionChange", doc.cm, obj); }
-    if (obj.ranges != sel.ranges) { return normalizeSelection(doc.cm, obj.ranges, obj.ranges.length - 1) }
-    else { return sel }
-  }
-
-  function setSelectionReplaceHistory(doc, sel, options) {
-    var done = doc.history.done, last = lst(done);
-    if (last && last.ranges) {
-      done[done.length - 1] = sel;
-      setSelectionNoUndo(doc, sel, options);
-    } else {
-      setSelection(doc, sel, options);
-    }
-  }
-
-  // Set a new selection.
-  function setSelection(doc, sel, options) {
-    setSelectionNoUndo(doc, sel, options);
-    addSelectionToHistory(doc, doc.sel, doc.cm ? doc.cm.curOp.id : NaN, options);
-  }
-
-  function setSelectionNoUndo(doc, sel, options) {
-    if (hasHandler(doc, "beforeSelectionChange") || doc.cm && hasHandler(doc.cm, "beforeSelectionChange"))
-      { sel = filterSelectionChange(doc, sel, options); }
-
-    var bias = options && options.bias ||
-      (cmp(sel.primary().head, doc.sel.primary().head) < 0 ? -1 : 1);
-    setSelectionInner(doc, skipAtomicInSelection(doc, sel, bias, true));
-
-    if (!(options && options.scroll === false) && doc.cm)
-      { ensureCursorVisible(doc.cm); }
-  }
-
-  function setSelectionInner(doc, sel) {
-    if (sel.equals(doc.sel)) { return }
-
-    doc.sel = sel;
-
-    if (doc.cm) {
-      doc.cm.curOp.updateInput = 1;
-      doc.cm.curOp.selectionChanged = true;
-      signalCursorActivity(doc.cm);
-    }
-    signalLater(doc, "cursorActivity", doc);
-  }
-
-  // Verify that the selection does not partially select any atomic
-  // marked ranges.
-  function reCheckSelection(doc) {
-    setSelectionInner(doc, skipAtomicInSelection(doc, doc.sel, null, false));
-  }
-
-  // Return a selection that does not partially select any atomic
-  // ranges.
-  function skipAtomicInSelection(doc, sel, bias, mayClear) {
-    var out;
-    for (var i = 0; i < sel.ranges.length; i++) {
-      var range = sel.ranges[i];
-      var old = sel.ranges.length == doc.sel.ranges.length && doc.sel.ranges[i];
-      var newAnchor = skipAtomic(doc, range.anchor, old && old.anchor, bias, mayClear);
-      var newHead = skipAtomic(doc, range.head, old && old.head, bias, mayClear);
-      if (out || newAnchor != range.anchor || newHead != range.head) {
-        if (!out) { out = sel.ranges.slice(0, i); }
-        out[i] = new Range(newAnchor, newHead);
-      }
-    }
-    return out ? normalizeSelection(doc.cm, out, sel.primIndex) : sel
-  }
-
-  function skipAtomicInner(doc, pos, oldPos, dir, mayClear) {
-    var line = getLine(doc, pos.line);
-    if (line.markedSpans) { for (var i = 0; i < line.markedSpans.length; ++i) {
-      var sp = line.markedSpans[i], m = sp.marker;
-
-      // Determine if we should prevent the cursor being placed to the left/right of an atomic marker
-      // Historically this was determined using the inclusiveLeft/Right option, but the new way to control it
-      // is with selectLeft/Right
-      var preventCursorLeft = ("selectLeft" in m) ? !m.selectLeft : m.inclusiveLeft;
-      var preventCursorRight = ("selectRight" in m) ? !m.selectRight : m.inclusiveRight;
-
-      if ((sp.from == null || (preventCursorLeft ? sp.from <= pos.ch : sp.from < pos.ch)) &&
-          (sp.to == null || (preventCursorRight ? sp.to >= pos.ch : sp.to > pos.ch))) {
-        if (mayClear) {
-          signal(m, "beforeCursorEnter");
-          if (m.explicitlyCleared) {
-            if (!line.markedSpans) { break }
-            else {--i; continue}
-          }
-        }
-        if (!m.atomic) { continue }
-
-        if (oldPos) {
-          var near = m.find(dir < 0 ? 1 : -1), diff = (void 0);
-          if (dir < 0 ? preventCursorRight : preventCursorLeft)
-            { near = movePos(doc, near, -dir, near && near.line == pos.line ? line : null); }
-          if (near && near.line == pos.line && (diff = cmp(near, oldPos)) && (dir < 0 ? diff < 0 : diff > 0))
-            { return skipAtomicInner(doc, near, pos, dir, mayClear) }
-        }
-
-        var far = m.find(dir < 0 ? -1 : 1);
-        if (dir < 0 ? preventCursorLeft : preventCursorRight)
-          { far = movePos(doc, far, dir, far.line == pos.line ? line : null); }
-        return far ? skipAtomicInner(doc, far, pos, dir, mayClear) : null
-      }
-    } }
-    return pos
-  }
-
-  // Ensure a given position is not inside an atomic range.
-  function skipAtomic(doc, pos, oldPos, bias, mayClear) {
-    var dir = bias || 1;
-    var found = skipAtomicInner(doc, pos, oldPos, dir, mayClear) ||
-        (!mayClear && skipAtomicInner(doc, pos, oldPos, dir, true)) ||
-        skipAtomicInner(doc, pos, oldPos, -dir, mayClear) ||
-        (!mayClear && skipAtomicInner(doc, pos, oldPos, -dir, true));
-    if (!found) {
-      doc.cantEdit = true;
-      return Pos(doc.first, 0)
-    }
-    return found
-  }
-
-  function movePos(doc, pos, dir, line) {
-    if (dir < 0 && pos.ch == 0) {
-      if (pos.line > doc.first) { return clipPos(doc, Pos(pos.line - 1)) }
-      else { return null }
-    } else if (dir > 0 && pos.ch == (line || getLine(doc, pos.line)).text.length) {
-      if (pos.line < doc.first + doc.size - 1) { return Pos(pos.line + 1, 0) }
-      else { return null }
-    } else {
-      return new Pos(pos.line, pos.ch + dir)
-    }
-  }
-
-  function selectAll(cm) {
-    cm.setSelection(Pos(cm.firstLine(), 0), Pos(cm.lastLine()), sel_dontScroll);
-  }
-
-  // UPDATING
-
-  // Allow "beforeChange" event handlers to influence a change
-  function filterChange(doc, change, update) {
-    var obj = {
-      canceled: false,
-      from: change.from,
-      to: change.to,
-      text: change.text,
-      origin: change.origin,
-      cancel: function () { return obj.canceled = true; }
-    };
-    if (update) { obj.update = function (from, to, text, origin) {
-      if (from) { obj.from = clipPos(doc, from); }
-      if (to) { obj.to = clipPos(doc, to); }
-      if (text) { obj.text = text; }
-      if (origin !== undefined) { obj.origin = origin; }
-    }; }
-    signal(doc, "beforeChange", doc, obj);
-    if (doc.cm) { signal(doc.cm, "beforeChange", doc.cm, obj); }
-
-    if (obj.canceled) {
-      if (doc.cm) { doc.cm.curOp.updateInput = 2; }
-      return null
-    }
-    return {from: obj.from, to: obj.to, text: obj.text, origin: obj.origin}
-  }
-
-  // Apply a change to a document, and add it to the document's
-  // history, and propagating it to all linked documents.
-  function makeChange(doc, change, ignoreReadOnly) {
-    if (doc.cm) {
-      if (!doc.cm.curOp) { return operation(doc.cm, makeChange)(doc, change, ignoreReadOnly) }
-      if (doc.cm.state.suppressEdits) { return }
-    }
-
-    if (hasHandler(doc, "beforeChange") || doc.cm && hasHandler(doc.cm, "beforeChange")) {
-      change = filterChange(doc, change, true);
-      if (!change) { return }
-    }
-
-    // Possibly split or suppress the update based on the presence
-    // of read-only spans in its range.
-    var split = sawReadOnlySpans && !ignoreReadOnly && removeReadOnlyRanges(doc, change.from, change.to);
-    if (split) {
-      for (var i = split.length - 1; i >= 0; --i)
-        { makeChangeInner(doc, {from: split[i].from, to: split[i].to, text: i ? [""] : change.text, origin: change.origin}); }
-    } else {
-      makeChangeInner(doc, change);
-    }
-  }
-
-  function makeChangeInner(doc, change) {
-    if (change.text.length == 1 && change.text[0] == "" && cmp(change.from, change.to) == 0) { return }
-    var selAfter = computeSelAfterChange(doc, change);
-    addChangeToHistory(doc, change, selAfter, doc.cm ? doc.cm.curOp.id : NaN);
-
-    makeChangeSingleDoc(doc, change, selAfter, stretchSpansOverChange(doc, change));
-    var rebased = [];
-
-    linkedDocs(doc, function (doc, sharedHist) {
-      if (!sharedHist && indexOf(rebased, doc.history) == -1) {
-        rebaseHist(doc.history, change);
-        rebased.push(doc.history);
-      }
-      makeChangeSingleDoc(doc, change, null, stretchSpansOverChange(doc, change));
-    });
-  }
-
-  // Revert a change stored in a document's history.
-  function makeChangeFromHistory(doc, type, allowSelectionOnly) {
-    var suppress = doc.cm && doc.cm.state.suppressEdits;
-    if (suppress && !allowSelectionOnly) { return }
-
-    var hist = doc.history, event, selAfter = doc.sel;
-    var source = type == "undo" ? hist.done : hist.undone, dest = type == "undo" ? hist.undone : hist.done;
-
-    // Verify that there is a useable event (so that ctrl-z won't
-    // needlessly clear selection events)
-    var i = 0;
-    for (; i < source.length; i++) {
-      event = source[i];
-      if (allowSelectionOnly ? event.ranges && !event.equals(doc.sel) : !event.ranges)
-        { break }
-    }
-    if (i == source.length) { return }
-    hist.lastOrigin = hist.lastSelOrigin = null;
-
-    for (;;) {
-      event = source.pop();
-      if (event.ranges) {
-        pushSelectionToHistory(event, dest);
-        if (allowSelectionOnly && !event.equals(doc.sel)) {
-          setSelection(doc, event, {clearRedo: false});
-          return
-        }
-        selAfter = event;
-      } else if (suppress) {
-        source.push(event);
-        return
-      } else { break }
-    }
-
-    // Build up a reverse change object to add to the opposite history
-    // stack (redo when undoing, and vice versa).
-    var antiChanges = [];
-    pushSelectionToHistory(selAfter, dest);
-    dest.push({changes: antiChanges, generation: hist.generation});
-    hist.generation = event.generation || ++hist.maxGeneration;
-
-    var filter = hasHandler(doc, "beforeChange") || doc.cm && hasHandler(doc.cm, "beforeChange");
-
-    var loop = function ( i ) {
-      var change = event.changes[i];
-      change.origin = type;
-      if (filter && !filterChange(doc, change, false)) {
-        source.length = 0;
-        return {}
-      }
-
-      antiChanges.push(historyChangeFromChange(doc, change));
-
-      var after = i ? computeSelAfterChange(doc, change) : lst(source);
-      makeChangeSingleDoc(doc, change, after, mergeOldSpans(doc, change));
-      if (!i && doc.cm) { doc.cm.scrollIntoView({from: change.from, to: changeEnd(change)}); }
-      var rebased = [];
-
-      // Propagate to the linked documents
-      linkedDocs(doc, function (doc, sharedHist) {
-        if (!sharedHist && indexOf(rebased, doc.history) == -1) {
-          rebaseHist(doc.history, change);
-          rebased.push(doc.history);
-        }
-        makeChangeSingleDoc(doc, change, null, mergeOldSpans(doc, change));
-      });
-    };
-
-    for (var i$1 = event.changes.length - 1; i$1 >= 0; --i$1) {
-      var returned = loop( i$1 );
-
-      if ( returned ) return returned.v;
-    }
-  }
-
-  // Sub-views need their line numbers shifted when text is added
-  // above or below them in the parent document.
-  function shiftDoc(doc, distance) {
-    if (distance == 0) { return }
-    doc.first += distance;
-    doc.sel = new Selection(map(doc.sel.ranges, function (range) { return new Range(
-      Pos(range.anchor.line + distance, range.anchor.ch),
-      Pos(range.head.line + distance, range.head.ch)
-    ); }), doc.sel.primIndex);
-    if (doc.cm) {
-      regChange(doc.cm, doc.first, doc.first - distance, distance);
-      for (var d = doc.cm.display, l = d.viewFrom; l < d.viewTo; l++)
-        { regLineChange(doc.cm, l, "gutter"); }
-    }
-  }
-
-  // More lower-level change function, handling only a single document
-  // (not linked ones).
-  function makeChangeSingleDoc(doc, change, selAfter, spans) {
-    if (doc.cm && !doc.cm.curOp)
-      { return operation(doc.cm, makeChangeSingleDoc)(doc, change, selAfter, spans) }
-
-    if (change.to.line < doc.first) {
-      shiftDoc(doc, change.text.length - 1 - (change.to.line - change.from.line));
-      return
-    }
-    if (change.from.line > doc.lastLine()) { return }
-
-    // Clip the change to the size of this doc
-    if (change.from.line < doc.first) {
-      var shift = change.text.length - 1 - (doc.first - change.from.line);
-      shiftDoc(doc, shift);
-      change = {from: Pos(doc.first, 0), to: Pos(change.to.line + shift, change.to.ch),
-                text: [lst(change.text)], origin: change.origin};
-    }
-    var last = doc.lastLine();
-    if (change.to.line > last) {
-      change = {from: change.from, to: Pos(last, getLine(doc, last).text.length),
-                text: [change.text[0]], origin: change.origin};
-    }
-
-    change.removed = getBetween(doc, change.from, change.to);
-
-    if (!selAfter) { selAfter = computeSelAfterChange(doc, change); }
-    if (doc.cm) { makeChangeSingleDocInEditor(doc.cm, change, spans); }
-    else { updateDoc(doc, change, spans); }
-    setSelectionNoUndo(doc, selAfter, sel_dontScroll);
-  }
-
-  // Handle the interaction of a change to a document with the editor
-  // that this document is part of.
-  function makeChangeSingleDocInEditor(cm, change, spans) {
-    var doc = cm.doc, display = cm.display, from = change.from, to = change.to;
-
-    var recomputeMaxLength = false, checkWidthStart = from.line;
-    if (!cm.options.lineWrapping) {
-      checkWidthStart = lineNo(visualLine(getLine(doc, from.line)));
-      doc.iter(checkWidthStart, to.line + 1, function (line) {
-        if (line == display.maxLine) {
-          recomputeMaxLength = true;
-          return true
-        }
-      });
-    }
-
-    if (doc.sel.contains(change.from, change.to) > -1)
-      { signalCursorActivity(cm); }
-
-    updateDoc(doc, change, spans, estimateHeight(cm));
-
-    if (!cm.options.lineWrapping) {
-      doc.iter(checkWidthStart, from.line + change.text.length, function (line) {
-        var len = lineLength(line);
-        if (len > display.maxLineLength) {
-          display.maxLine = line;
-          display.maxLineLength = len;
-          display.maxLineChanged = true;
-          recomputeMaxLength = false;
-        }
-      });
-      if (recomputeMaxLength) { cm.curOp.updateMaxLine = true; }
-    }
-
-    retreatFrontier(doc, from.line);
-    startWorker(cm, 400);
-
-    var lendiff = change.text.length - (to.line - from.line) - 1;
-    // Remember that these lines changed, for updating the display
-    if (change.full)
-      { regChange(cm); }
-    else if (from.line == to.line && change.text.length == 1 && !isWholeLineUpdate(cm.doc, change))
-      { regLineChange(cm, from.line, "text"); }
-    else
-      { regChange(cm, from.line, to.line + 1, lendiff); }
-
-    var changesHandler = hasHandler(cm, "changes"), changeHandler = hasHandler(cm, "change");
-    if (changeHandler || changesHandler) {
-      var obj = {
-        from: from, to: to,
-        text: change.text,
-        removed: change.removed,
-        origin: change.origin
-      };
-      if (changeHandler) { signalLater(cm, "change", cm, obj); }
-      if (changesHandler) { (cm.curOp.changeObjs || (cm.curOp.changeObjs = [])).push(obj); }
-    }
-    cm.display.selForContextMenu = null;
-  }
-
-  function replaceRange(doc, code, from, to, origin) {
-    var assign;
-
-    if (!to) { to = from; }
-    if (cmp(to, from) < 0) { (assign = [to, from], from = assign[0], to = assign[1]); }
-    if (typeof code == "string") { code = doc.splitLines(code); }
-    makeChange(doc, {from: from, to: to, text: code, origin: origin});
-  }
-
-  // Rebasing/resetting history to deal with externally-sourced changes
-
-  function rebaseHistSelSingle(pos, from, to, diff) {
-    if (to < pos.line) {
-      pos.line += diff;
-    } else if (from < pos.line) {
-      pos.line = from;
-      pos.ch = 0;
-    }
-  }
-
-  // Tries to rebase an array of history events given a change in the
-  // document. If the change touches the same lines as the event, the
-  // event, and everything 'behind' it, is discarded. If the change is
-  // before the event, the event's positions are updated. Uses a
-  // copy-on-write scheme for the positions, to avoid having to
-  // reallocate them all on every rebase, but also avoid problems with
-  // shared position objects being unsafely updated.
-  function rebaseHistArray(array, from, to, diff) {
-    for (var i = 0; i < array.length; ++i) {
-      var sub = array[i], ok = true;
-      if (sub.ranges) {
-        if (!sub.copied) { sub = array[i] = sub.deepCopy(); sub.copied = true; }
-        for (var j = 0; j < sub.ranges.length; j++) {
-          rebaseHistSelSingle(sub.ranges[j].anchor, from, to, diff);
-          rebaseHistSelSingle(sub.ranges[j].head, from, to, diff);
-        }
-        continue
-      }
-      for (var j$1 = 0; j$1 < sub.changes.length; ++j$1) {
-        var cur = sub.changes[j$1];
-        if (to < cur.from.line) {
-          cur.from = Pos(cur.from.line + diff, cur.from.ch);
-          cur.to = Pos(cur.to.line + diff, cur.to.ch);
-        } else if (from <= cur.to.line) {
-          ok = false;
-          break
-        }
-      }
-      if (!ok) {
-        array.splice(0, i + 1);
-        i = 0;
-      }
-    }
-  }
-
-  function rebaseHist(hist, change) {
-    var from = change.from.line, to = change.to.line, diff = change.text.length - (to - from) - 1;
-    rebaseHistArray(hist.done, from, to, diff);
-    rebaseHistArray(hist.undone, from, to, diff);
-  }
-
-  // Utility for applying a change to a line by handle or number,
-  // returning the number and optionally registering the line as
-  // changed.
-  function changeLine(doc, handle, changeType, op) {
-    var no = handle, line = handle;
-    if (typeof handle == "number") { line = getLine(doc, clipLine(doc, handle)); }
-    else { no = lineNo(handle); }
-    if (no == null) { return null }
-    if (op(line, no) && doc.cm) { regLineChange(doc.cm, no, changeType); }
-    return line
-  }
-
-  // The document is represented as a BTree consisting of leaves, with
-  // chunk of lines in them, and branches, with up to ten leaves or
-  // other branch nodes below them. The top node is always a branch
-  // node, and is the document object itself (meaning it has
-  // additional methods and properties).
-  //
-  // All nodes have parent links. The tree is used both to go from
-  // line numbers to line objects, and to go from objects to numbers.
-  // It also indexes by height, and is used to convert between height
-  // and line object, and to find the total height of the document.
-  //
-  // See also http://marijnhaverbeke.nl/blog/codemirror-line-tree.html
-
-  function LeafChunk(lines) {
-    var this$1 = this;
-
-    this.lines = lines;
-    this.parent = null;
-    var height = 0;
-    for (var i = 0; i < lines.length; ++i) {
-      lines[i].parent = this$1;
-      height += lines[i].height;
-    }
-    this.height = height;
-  }
-
-  LeafChunk.prototype = {
-    chunkSize: function() { return this.lines.length },
-
-    // Remove the n lines at offset 'at'.
-    removeInner: function(at, n) {
-      var this$1 = this;
-
-      for (var i = at, e = at + n; i < e; ++i) {
-        var line = this$1.lines[i];
-        this$1.height -= line.height;
-        cleanUpLine(line);
-        signalLater(line, "delete");
-      }
-      this.lines.splice(at, n);
-    },
-
-    // Helper used to collapse a small branch into a single leaf.
-    collapse: function(lines) {
-      lines.push.apply(lines, this.lines);
-    },
-
-    // Insert the given array of lines at offset 'at', count them as
-    // having the given height.
-    insertInner: function(at, lines, height) {
-      var this$1 = this;
-
-      this.height += height;
-      this.lines = this.lines.slice(0, at).concat(lines).concat(this.lines.slice(at));
-      for (var i = 0; i < lines.length; ++i) { lines[i].parent = this$1; }
-    },
-
-    // Used to iterate over a part of the tree.
-    iterN: function(at, n, op) {
-      var this$1 = this;
-
-      for (var e = at + n; at < e; ++at)
-        { if (op(this$1.lines[at])) { return true } }
-    }
-  };
-
-  function BranchChunk(children) {
-    var this$1 = this;
-
-    this.children = children;
-    var size = 0, height = 0;
-    for (var i = 0; i < children.length; ++i) {
-      var ch = children[i];
-      size += ch.chunkSize(); height += ch.height;
-      ch.parent = this$1;
-    }
-    this.size = size;
-    this.height = height;
-    this.parent = null;
-  }
-
-  BranchChunk.prototype = {
-    chunkSize: function() { return this.size },
-
-    removeInner: function(at, n) {
-      var this$1 = this;
-
-      this.size -= n;
-      for (var i = 0; i < this.children.length; ++i) {
-        var child = this$1.children[i], sz = child.chunkSize();
-        if (at < sz) {
-          var rm = Math.min(n, sz - at), oldHeight = child.height;
-          child.removeInner(at, rm);
-          this$1.height -= oldHeight - child.height;
-          if (sz == rm) { this$1.children.splice(i--, 1); child.parent = null; }
-          if ((n -= rm) == 0) { break }
-          at = 0;
-        } else { at -= sz; }
-      }
-      // If the result is smaller than 25 lines, ensure that it is a
-      // single leaf node.
-      if (this.size - n < 25 &&
-          (this.children.length > 1 || !(this.children[0] instanceof LeafChunk))) {
-        var lines = [];
-        this.collapse(lines);
-        this.children = [new LeafChunk(lines)];
-        this.children[0].parent = this;
-      }
-    },
-
-    collapse: function(lines) {
-      var this$1 = this;
-
-      for (var i = 0; i < this.children.length; ++i) { this$1.children[i].collapse(lines); }
-    },
-
-    insertInner: function(at, lines, height) {
-      var this$1 = this;
-
-      this.size += lines.length;
-      this.height += height;
-      for (var i = 0; i < this.children.length; ++i) {
-        var child = this$1.children[i], sz = child.chunkSize();
-        if (at <= sz) {
-          child.insertInner(at, lines, height);
-          if (child.lines && child.lines.length > 50) {
-            // To avoid memory thrashing when child.lines is huge (e.g. first view of a large file), it's never spliced.
-            // Instead, small slices are taken. They're taken in order because sequential memory accesses are fastest.
-            var remaining = child.lines.length % 25 + 25;
-            for (var pos = remaining; pos < child.lines.length;) {
-              var leaf = new LeafChunk(child.lines.slice(pos, pos += 25));
-              child.height -= leaf.height;
-              this$1.children.splice(++i, 0, leaf);
-              leaf.parent = this$1;
-            }
-            child.lines = child.lines.slice(0, remaining);
-            this$1.maybeSpill();
-          }
-          break
-        }
-        at -= sz;
-      }
-    },
-
-    // When a node has grown, check whether it should be split.
-    maybeSpill: function() {
-      if (this.children.length <= 10) { return }
-      var me = this;
-      do {
-        var spilled = me.children.splice(me.children.length - 5, 5);
-        var sibling = new BranchChunk(spilled);
-        if (!me.parent) { // Become the parent node
-          var copy = new BranchChunk(me.children);
-          copy.parent = me;
-          me.children = [copy, sibling];
-          me = copy;
-       } else {
-          me.size -= sibling.size;
-          me.height -= sibling.height;
-          var myIndex = indexOf(me.parent.children, me);
-          me.parent.children.splice(myIndex + 1, 0, sibling);
-        }
-        sibling.parent = me.parent;
-      } while (me.children.length > 10)
-      me.parent.maybeSpill();
-    },
-
-    iterN: function(at, n, op) {
-      var this$1 = this;
-
-      for (var i = 0; i < this.children.length; ++i) {
-        var child = this$1.children[i], sz = child.chunkSize();
-        if (at < sz) {
-          var used = Math.min(n, sz - at);
-          if (child.iterN(at, used, op)) { return true }
-          if ((n -= used) == 0) { break }
-          at = 0;
-        } else { at -= sz; }
-      }
-    }
-  };
-
-  // Line widgets are block elements displayed above or below a line.
-
-  var LineWidget = function(doc, node, options) {
-    var this$1 = this;
-
-    if (options) { for (var opt in options) { if (options.hasOwnProperty(opt))
-      { this$1[opt] = options[opt]; } } }
-    this.doc = doc;
-    this.node = node;
-  };
-
-  LineWidget.prototype.clear = function () {
-      var this$1 = this;
-
-    var cm = this.doc.cm, ws = this.line.widgets, line = this.line, no = lineNo(line);
-    if (no == null || !ws) { return }
-    for (var i = 0; i < ws.length; ++i) { if (ws[i] == this$1) { ws.splice(i--, 1); } }
-    if (!ws.length) { line.widgets = null; }
-    var height = widgetHeight(this);
-    updateLineHeight(line, Math.max(0, line.height - height));
-    if (cm) {
-      runInOp(cm, function () {
-        adjustScrollWhenAboveVisible(cm, line, -height);
-        regLineChange(cm, no, "widget");
-      });
-      signalLater(cm, "lineWidgetCleared", cm, this, no);
-    }
-  };
-
-  LineWidget.prototype.changed = function () {
-      var this$1 = this;
-
-    var oldH = this.height, cm = this.doc.cm, line = this.line;
-    this.height = null;
-    var diff = widgetHeight(this) - oldH;
-    if (!diff) { return }
-    if (!lineIsHidden(this.doc, line)) { updateLineHeight(line, line.height + diff); }
-    if (cm) {
-      runInOp(cm, function () {
-        cm.curOp.forceUpdate = true;
-        adjustScrollWhenAboveVisible(cm, line, diff);
-        signalLater(cm, "lineWidgetChanged", cm, this$1, lineNo(line));
-      });
-    }
-  };
-  eventMixin(LineWidget);
-
-  function adjustScrollWhenAboveVisible(cm, line, diff) {
-    if (heightAtLine(line) < ((cm.curOp && cm.curOp.scrollTop) || cm.doc.scrollTop))
-      { addToScrollTop(cm, diff); }
-  }
-
-  function addLineWidget(doc, handle, node, options) {
-    var widget = new LineWidget(doc, node, options);
-    var cm = doc.cm;
-    if (cm && widget.noHScroll) { cm.display.alignWidgets = true; }
-    changeLine(doc, handle, "widget", function (line) {
-      var widgets = line.widgets || (line.widgets = []);
-      if (widget.insertAt == null) { widgets.push(widget); }
-      else { widgets.splice(Math.min(widgets.length - 1, Math.max(0, widget.insertAt)), 0, widget); }
-      widget.line = line;
-      if (cm && !lineIsHidden(doc, line)) {
-        var aboveVisible = heightAtLine(line) < doc.scrollTop;
-        updateLineHeight(line, line.height + widgetHeight(widget));
-        if (aboveVisible) { addToScrollTop(cm, widget.height); }
-        cm.curOp.forceUpdate = true;
-      }
-      return true
-    });
-    if (cm) { signalLater(cm, "lineWidgetAdded", cm, widget, typeof handle == "number" ? handle : lineNo(handle)); }
-    return widget
-  }
-
-  // TEXTMARKERS
-
-  // Created with markText and setBookmark methods. A TextMarker is a
-  // handle that can be used to clear or find a marked position in the
-  // document. Line objects hold arrays (markedSpans) containing
-  // {from, to, marker} object pointing to such marker objects, and
-  // indicating that such a marker is present on that line. Multiple
-  // lines may point to the same marker when it spans across lines.
-  // The spans will have null for their from/to properties when the
-  // marker continues beyond the start/end of the line. Markers have
-  // links back to the lines they currently touch.
-
-  // Collapsed markers have unique ids, in order to be able to order
-  // them, which is needed for uniquely determining an outer marker
-  // when they overlap (they may nest, but not partially overlap).
-  var nextMarkerId = 0;
-
-  var TextMarker = function(doc, type) {
-    this.lines = [];
-    this.type = type;
-    this.doc = doc;
-    this.id = ++nextMarkerId;
-  };
-
-  // Clear the marker.
-  TextMarker.prototype.clear = function () {
-      var this$1 = this;
-
-    if (this.explicitlyCleared) { return }
-    var cm = this.doc.cm, withOp = cm && !cm.curOp;
-    if (withOp) { startOperation(cm); }
-    if (hasHandler(this, "clear")) {
-      var found = this.find();
-      if (found) { signalLater(this, "clear", found.from, found.to); }
-    }
-    var min = null, max = null;
-    for (var i = 0; i < this.lines.length; ++i) {
-      var line = this$1.lines[i];
-      var span = getMarkedSpanFor(line.markedSpans, this$1);
-      if (cm && !this$1.collapsed) { regLineChange(cm, lineNo(line), "text"); }
-      else if (cm) {
-        if (span.to != null) { max = lineNo(line); }
-        if (span.from != null) { min = lineNo(line); }
-      }
-      line.markedSpans = removeMarkedSpan(line.markedSpans, span);
-      if (span.from == null && this$1.collapsed && !lineIsHidden(this$1.doc, line) && cm)
-        { updateLineHeight(line, textHeight(cm.display)); }
-    }
-    if (cm && this.collapsed && !cm.options.lineWrapping) { for (var i$1 = 0; i$1 < this.lines.length; ++i$1) {
-      var visual = visualLine(this$1.lines[i$1]), len = lineLength(visual);
-      if (len > cm.display.maxLineLength) {
-        cm.display.maxLine = visual;
-        cm.display.maxLineLength = len;
-        cm.display.maxLineChanged = true;
-      }
-    } }
-
-    if (min != null && cm && this.collapsed) { regChange(cm, min, max + 1); }
-    this.lines.length = 0;
-    this.explicitlyCleared = true;
-    if (this.atomic && this.doc.cantEdit) {
-      this.doc.cantEdit = false;
-      if (cm) { reCheckSelection(cm.doc); }
-    }
-    if (cm) { signalLater(cm, "markerCleared", cm, this, min, max); }
-    if (withOp) { endOperation(cm); }
-    if (this.parent) { this.parent.clear(); }
-  };
-
-  // Find the position of the marker in the document. Returns a {from,
-  // to} object by default. Side can be passed to get a specific side
-  // -- 0 (both), -1 (left), or 1 (right). When lineObj is true, the
-  // Pos objects returned contain a line object, rather than a line
-  // number (used to prevent looking up the same line twice).
-  TextMarker.prototype.find = function (side, lineObj) {
-      var this$1 = this;
-
-    if (side == null && this.type == "bookmark") { side = 1; }
-    var from, to;
-    for (var i = 0; i < this.lines.length; ++i) {
-      var line = this$1.lines[i];
-      var span = getMarkedSpanFor(line.markedSpans, this$1);
-      if (span.from != null) {
-        from = Pos(lineObj ? line : lineNo(line), span.from);
-        if (side == -1) { return from }
-      }
-      if (span.to != null) {
-        to = Pos(lineObj ? line : lineNo(line), span.to);
-        if (side == 1) { return to }
-      }
-    }
-    return from && {from: from, to: to}
-  };
-
-  // Signals that the marker's widget changed, and surrounding layout
-  // should be recomputed.
-  TextMarker.prototype.changed = function () {
-      var this$1 = this;
-
-    var pos = this.find(-1, true), widget = this, cm = this.doc.cm;
-    if (!pos || !cm) { return }
-    runInOp(cm, function () {
-      var line = pos.line, lineN = lineNo(pos.line);
-      var view = findViewForLine(cm, lineN);
-      if (view) {
-        clearLineMeasurementCacheFor(view);
-        cm.curOp.selectionChanged = cm.curOp.forceUpdate = true;
-      }
-      cm.curOp.updateMaxLine = true;
-      if (!lineIsHidden(widget.doc, line) && widget.height != null) {
-        var oldHeight = widget.height;
-        widget.height = null;
-        var dHeight = widgetHeight(widget) - oldHeight;
-        if (dHeight)
-          { updateLineHeight(line, line.height + dHeight); }
-      }
-      signalLater(cm, "markerChanged", cm, this$1);
-    });
-  };
-
-  TextMarker.prototype.attachLine = function (line) {
-    if (!this.lines.length && this.doc.cm) {
-      var op = this.doc.cm.curOp;
-      if (!op.maybeHiddenMarkers || indexOf(op.maybeHiddenMarkers, this) == -1)
-        { (op.maybeUnhiddenMarkers || (op.maybeUnhiddenMarkers = [])).push(this); }
-    }
-    this.lines.push(line);
-  };
-
-  TextMarker.prototype.detachLine = function (line) {
-    this.lines.splice(indexOf(this.lines, line), 1);
-    if (!this.lines.length && this.doc.cm) {
-      var op = this.doc.cm.curOp
-      ;(op.maybeHiddenMarkers || (op.maybeHiddenMarkers = [])).push(this);
-    }
-  };
-  eventMixin(TextMarker);
-
-  // Create a marker, wire it up to the right lines, and
-  function markText(doc, from, to, options, type) {
-    // Shared markers (across linked documents) are handled separately
-    // (markTextShared will call out to this again, once per
-    // document).
-    if (options && options.shared) { return markTextShared(doc, from, to, options, type) }
-    // Ensure we are in an operation.
-    if (doc.cm && !doc.cm.curOp) { return operation(doc.cm, markText)(doc, from, to, options, type) }
-
-    var marker = new TextMarker(doc, type), diff = cmp(from, to);
-    if (options) { copyObj(options, marker, false); }
-    // Don't connect empty markers unless clearWhenEmpty is false
-    if (diff > 0 || diff == 0 && marker.clearWhenEmpty !== false)
-      { return marker }
-    if (marker.replacedWith) {
-      // Showing up as a widget implies collapsed (widget replaces text)
-      marker.collapsed = true;
-      marker.widgetNode = eltP("span", [marker.replacedWith], "CodeMirror-widget");
-      if (!options.handleMouseEvents) { marker.widgetNode.setAttribute("cm-ignore-events", "true"); }
-      if (options.insertLeft) { marker.widgetNode.insertLeft = true; }
-    }
-    if (marker.collapsed) {
-      if (conflictingCollapsedRange(doc, from.line, from, to, marker) ||
-          from.line != to.line && conflictingCollapsedRange(doc, to.line, from, to, marker))
-        { throw new Error("Inserting collapsed marker partially overlapping an existing one") }
-      seeCollapsedSpans();
-    }
-
-    if (marker.addToHistory)
-      { addChangeToHistory(doc, {from: from, to: to, origin: "markText"}, doc.sel, NaN); }
-
-    var curLine = from.line, cm = doc.cm, updateMaxLine;
-    doc.iter(curLine, to.line + 1, function (line) {
-      if (cm && marker.collapsed && !cm.options.lineWrapping && visualLine(line) == cm.display.maxLine)
-        { updateMaxLine = true; }
-      if (marker.collapsed && curLine != from.line) { updateLineHeight(line, 0); }
-      addMarkedSpan(line, new MarkedSpan(marker,
-                                         curLine == from.line ? from.ch : null,
-                                         curLine == to.line ? to.ch : null));
-      ++curLine;
-    });
-    // lineIsHidden depends on the presence of the spans, so needs a second pass
-    if (marker.collapsed) { doc.iter(from.line, to.line + 1, function (line) {
-      if (lineIsHidden(doc, line)) { updateLineHeight(line, 0); }
-    }); }
-
-    if (marker.clearOnEnter) { on(marker, "beforeCursorEnter", function () { return marker.clear(); }); }
-
-    if (marker.readOnly) {
-      seeReadOnlySpans();
-      if (doc.history.done.length || doc.history.undone.length)
-        { doc.clearHistory(); }
-    }
-    if (marker.collapsed) {
-      marker.id = ++nextMarkerId;
-      marker.atomic = true;
-    }
-    if (cm) {
-      // Sync editor state
-      if (updateMaxLine) { cm.curOp.updateMaxLine = true; }
-      if (marker.collapsed)
-        { regChange(cm, from.line, to.line + 1); }
-      else if (marker.className || marker.startStyle || marker.endStyle || marker.css ||
-               marker.attributes || marker.title)
-        { for (var i = from.line; i <= to.line; i++) { regLineChange(cm, i, "text"); } }
-      if (marker.atomic) { reCheckSelection(cm.doc); }
-      signalLater(cm, "markerAdded", cm, marker);
-    }
-    return marker
-  }
-
-  // SHARED TEXTMARKERS
-
-  // A shared marker spans multiple linked documents. It is
-  // implemented as a meta-marker-object controlling multiple normal
-  // markers.
-  var SharedTextMarker = function(markers, primary) {
-    var this$1 = this;
-
-    this.markers = markers;
-    this.primary = primary;
-    for (var i = 0; i < markers.length; ++i)
-      { markers[i].parent = this$1; }
-  };
-
-  SharedTextMarker.prototype.clear = function () {
-      var this$1 = this;
-
-    if (this.explicitlyCleared) { return }
-    this.explicitlyCleared = true;
-    for (var i = 0; i < this.markers.length; ++i)
-      { this$1.markers[i].clear(); }
-    signalLater(this, "clear");
-  };
-
-  SharedTextMarker.prototype.find = function (side, lineObj) {
-    return this.primary.find(side, lineObj)
-  };
-  eventMixin(SharedTextMarker);
-
-  function markTextShared(doc, from, to, options, type) {
-    options = copyObj(options);
-    options.shared = false;
-    var markers = [markText(doc, from, to, options, type)], primary = markers[0];
-    var widget = options.widgetNode;
-    linkedDocs(doc, function (doc) {
-      if (widget) { options.widgetNode = widget.cloneNode(true); }
-      markers.push(markText(doc, clipPos(doc, from), clipPos(doc, to), options, type));
-      for (var i = 0; i < doc.linked.length; ++i)
-        { if (doc.linked[i].isParent) { return } }
-      primary = lst(markers);
-    });
-    return new SharedTextMarker(markers, primary)
-  }
-
-  function findSharedMarkers(doc) {
-    return doc.findMarks(Pos(doc.first, 0), doc.clipPos(Pos(doc.lastLine())), function (m) { return m.parent; })
-  }
-
-  function copySharedMarkers(doc, markers) {
-    for (var i = 0; i < markers.length; i++) {
-      var marker = markers[i], pos = marker.find();
-      var mFrom = doc.clipPos(pos.from), mTo = doc.clipPos(pos.to);
-      if (cmp(mFrom, mTo)) {
-        var subMark = markText(doc, mFrom, mTo, marker.primary, marker.primary.type);
-        marker.markers.push(subMark);
-        subMark.parent = marker;
-      }
-    }
-  }
-
-  function detachSharedMarkers(markers) {
-    var loop = function ( i ) {
-      var marker = markers[i], linked = [marker.primary.doc];
-      linkedDocs(marker.primary.doc, function (d) { return linked.push(d); });
-      for (var j = 0; j < marker.markers.length; j++) {
-        var subMarker = marker.markers[j];
-        if (indexOf(linked, subMarker.doc) == -1) {
-          subMarker.parent = null;
-          marker.markers.splice(j--, 1);
-        }
-      }
-    };
-
-    for (var i = 0; i < markers.length; i++) loop( i );
-  }
-
-  var nextDocId = 0;
-  var Doc = function(text, mode, firstLine, lineSep, direction) {
-    if (!(this instanceof Doc)) { return new Doc(text, mode, firstLine, lineSep, direction) }
-    if (firstLine == null) { firstLine = 0; }
-
-    BranchChunk.call(this, [new LeafChunk([new Line("", null)])]);
-    this.first = firstLine;
-    this.scrollTop = this.scrollLeft = 0;
-    this.cantEdit = false;
-    this.cleanGeneration = 1;
-    this.modeFrontier = this.highlightFrontier = firstLine;
-    var start = Pos(firstLine, 0);
-    this.sel = simpleSelection(start);
-    this.history = new History(null);
-    this.id = ++nextDocId;
-    this.modeOption = mode;
-    this.lineSep = lineSep;
-    this.direction = (direction == "rtl") ? "rtl" : "ltr";
-    this.extend = false;
-
-    if (typeof text == "string") { text = this.splitLines(text); }
-    updateDoc(this, {from: start, to: start, text: text});
-    setSelection(this, simpleSelection(start), sel_dontScroll);
-  };
-
-  Doc.prototype = createObj(BranchChunk.prototype, {
-    constructor: Doc,
-    // Iterate over the document. Supports two forms -- with only one
-    // argument, it calls that for each line in the document. With
-    // three, it iterates over the range given by the first two (with
-    // the second being non-inclusive).
-    iter: function(from, to, op) {
-      if (op) { this.iterN(from - this.first, to - from, op); }
-      else { this.iterN(this.first, this.first + this.size, from); }
-    },
-
-    // Non-public interface for adding and removing lines.
-    insert: function(at, lines) {
-      var height = 0;
-      for (var i = 0; i < lines.length; ++i) { height += lines[i].height; }
-      this.insertInner(at - this.first, lines, height);
-    },
-    remove: function(at, n) { this.removeInner(at - this.first, n); },
-
-    // From here, the methods are part of the public interface. Most
-    // are also available from CodeMirror (editor) instances.
-
-    getValue: function(lineSep) {
-      var lines = getLines(this, this.first, this.first + this.size);
-      if (lineSep === false) { return lines }
-      return lines.join(lineSep || this.lineSeparator())
-    },
-    setValue: docMethodOp(function(code) {
-      var top = Pos(this.first, 0), last = this.first + this.size - 1;
-      makeChange(this, {from: top, to: Pos(last, getLine(this, last).text.length),
-                        text: this.splitLines(code), origin: "setValue", full: true}, true);
-      if (this.cm) { scrollToCoords(this.cm, 0, 0); }
-      setSelection(this, simpleSelection(top), sel_dontScroll);
-    }),
-    replaceRange: function(code, from, to, origin) {
-      from = clipPos(this, from);
-      to = to ? clipPos(this, to) : from;
-      replaceRange(this, code, from, to, origin);
-    },
-    getRange: function(from, to, lineSep) {
-      var lines = getBetween(this, clipPos(this, from), clipPos(this, to));
-      if (lineSep === false) { return lines }
-      return lines.join(lineSep || this.lineSeparator())
-    },
-
-    getLine: function(line) {var l = this.getLineHandle(line); return l && l.text},
-
-    getLineHandle: function(line) {if (isLine(this, line)) { return getLine(this, line) }},
-    getLineNumber: function(line) {return lineNo(line)},
-
-    getLineHandleVisualStart: function(line) {
-      if (typeof line == "number") { line = getLine(this, line); }
-      return visualLine(line)
-    },
-
-    lineCount: function() {return this.size},
-    firstLine: function() {return this.first},
-    lastLine: function() {return this.first + this.size - 1},
-
-    clipPos: function(pos) {return clipPos(this, pos)},
-
-    getCursor: function(start) {
-      var range$$1 = this.sel.primary(), pos;
-      if (start == null || start == "head") { pos = range$$1.head; }
-      else if (start == "anchor") { pos = range$$1.anchor; }
-      else if (start == "end" || start == "to" || start === false) { pos = range$$1.to(); }
-      else { pos = range$$1.from(); }
-      return pos
-    },
-    listSelections: function() { return this.sel.ranges },
-    somethingSelected: function() {return this.sel.somethingSelected()},
-
-    setCursor: docMethodOp(function(line, ch, options) {
-      setSimpleSelection(this, clipPos(this, typeof line == "number" ? Pos(line, ch || 0) : line), null, options);
-    }),
-    setSelection: docMethodOp(function(anchor, head, options) {
-      setSimpleSelection(this, clipPos(this, anchor), clipPos(this, head || anchor), options);
-    }),
-    extendSelection: docMethodOp(function(head, other, options) {
-      extendSelection(this, clipPos(this, head), other && clipPos(this, other), options);
-    }),
-    extendSelections: docMethodOp(function(heads, options) {
-      extendSelections(this, clipPosArray(this, heads), options);
-    }),
-    extendSelectionsBy: docMethodOp(function(f, options) {
-      var heads = map(this.sel.ranges, f);
-      extendSelections(this, clipPosArray(this, heads), options);
-    }),
-    setSelections: docMethodOp(function(ranges, primary, options) {
-      var this$1 = this;
-
-      if (!ranges.length) { return }
-      var out = [];
-      for (var i = 0; i < ranges.length; i++)
-        { out[i] = new Range(clipPos(this$1, ranges[i].anchor),
-                           clipPos(this$1, ranges[i].head)); }
-      if (primary == null) { primary = Math.min(ranges.length - 1, this.sel.primIndex); }
-      setSelection(this, normalizeSelection(this.cm, out, primary), options);
-    }),
-    addSelection: docMethodOp(function(anchor, head, options) {
-      var ranges = this.sel.ranges.slice(0);
-      ranges.push(new Range(clipPos(this, anchor), clipPos(this, head || anchor)));
-      setSelection(this, normalizeSelection(this.cm, ranges, ranges.length - 1), options);
-    }),
-
-    getSelection: function(lineSep) {
-      var this$1 = this;
-
-      var ranges = this.sel.ranges, lines;
-      for (var i = 0; i < ranges.length; i++) {
-        var sel = getBetween(this$1, ranges[i].from(), ranges[i].to());
-        lines = lines ? lines.concat(sel) : sel;
-      }
-      if (lineSep === false) { return lines }
-      else { return lines.join(lineSep || this.lineSeparator()) }
-    },
-    getSelections: function(lineSep) {
-      var this$1 = this;
-
-      var parts = [], ranges = this.sel.ranges;
-      for (var i = 0; i < ranges.length; i++) {
-        var sel = getBetween(this$1, ranges[i].from(), ranges[i].to());
-        if (lineSep !== false) { sel = sel.join(lineSep || this$1.lineSeparator()); }
-        parts[i] = sel;
-      }
-      return parts
-    },
-    replaceSelection: function(code, collapse, origin) {
-      var dup = [];
-      for (var i = 0; i < this.sel.ranges.length; i++)
-        { dup[i] = code; }
-      this.replaceSelections(dup, collapse, origin || "+input");
-    },
-    replaceSelections: docMethodOp(function(code, collapse, origin) {
-      var this$1 = this;
-
-      var changes = [], sel = this.sel;
-      for (var i = 0; i < sel.ranges.length; i++) {
-        var range$$1 = sel.ranges[i];
-        changes[i] = {from: range$$1.from(), to: range$$1.to(), text: this$1.splitLines(code[i]), origin: origin};
-      }
-      var newSel = collapse && collapse != "end" && computeReplacedSel(this, changes, collapse);
-      for (var i$1 = changes.length - 1; i$1 >= 0; i$1--)
-        { makeChange(this$1, changes[i$1]); }
-      if (newSel) { setSelectionReplaceHistory(this, newSel); }
-      else if (this.cm) { ensureCursorVisible(this.cm); }
-    }),
-    undo: docMethodOp(function() {makeChangeFromHistory(this, "undo");}),
-    redo: docMethodOp(function() {makeChangeFromHistory(this, "redo");}),
-    undoSelection: docMethodOp(function() {makeChangeFromHistory(this, "undo", true);}),
-    redoSelection: docMethodOp(function() {makeChangeFromHistory(this, "redo", true);}),
-
-    setExtending: function(val) {this.extend = val;},
-    getExtending: function() {return this.extend},
-
-    historySize: function() {
-      var hist = this.history, done = 0, undone = 0;
-      for (var i = 0; i < hist.done.length; i++) { if (!hist.done[i].ranges) { ++done; } }
-      for (var i$1 = 0; i$1 < hist.undone.length; i$1++) { if (!hist.undone[i$1].ranges) { ++undone; } }
-      return {undo: done, redo: undone}
-    },
-    clearHistory: function() {this.history = new History(this.history.maxGeneration);},
-
-    markClean: function() {
-      this.cleanGeneration = this.changeGeneration(true);
-    },
-    changeGeneration: function(forceSplit) {
-      if (forceSplit)
-        { this.history.lastOp = this.history.lastSelOp = this.history.lastOrigin = null; }
-      return this.history.generation
-    },
-    isClean: function (gen) {
-      return this.history.generation == (gen || this.cleanGeneration)
-    },
-
-    getHistory: function() {
-      return {done: copyHistoryArray(this.history.done),
-              undone: copyHistoryArray(this.history.undone)}
-    },
-    setHistory: function(histData) {
-      var hist = this.history = new History(this.history.maxGeneration);
-      hist.done = copyHistoryArray(histData.done.slice(0), null, true);
-      hist.undone = copyHistoryArray(histData.undone.slice(0), null, true);
-    },
-
-    setGutterMarker: docMethodOp(function(line, gutterID, value) {
-      return changeLine(this, line, "gutter", function (line) {
-        var markers = line.gutterMarkers || (line.gutterMarkers = {});
-        markers[gutterID] = value;
-        if (!value && isEmpty(markers)) { line.gutterMarkers = null; }
-        return true
-      })
-    }),
-
-    clearGutter: docMethodOp(function(gutterID) {
-      var this$1 = this;
-
-      this.iter(function (line) {
-        if (line.gutterMarkers && line.gutterMarkers[gutterID]) {
-          changeLine(this$1, line, "gutter", function () {
-            line.gutterMarkers[gutterID] = null;
-            if (isEmpty(line.gutterMarkers)) { line.gutterMarkers = null; }
-            return true
-          });
-        }
-      });
-    }),
-
-    lineInfo: function(line) {
-      var n;
-      if (typeof line == "number") {
-        if (!isLine(this, line)) { return null }
-        n = line;
-        line = getLine(this, line);
-        if (!line) { return null }
-      } else {
-        n = lineNo(line);
-        if (n == null) { return null }
-      }
-      return {line: n, handle: line, text: line.text, gutterMarkers: line.gutterMarkers,
-              textClass: line.textClass, bgClass: line.bgClass, wrapClass: line.wrapClass,
-              widgets: line.widgets}
-    },
-
-    addLineClass: docMethodOp(function(handle, where, cls) {
-      return changeLine(this, handle, where == "gutter" ? "gutter" : "class", function (line) {
-        var prop = where == "text" ? "textClass"
-                 : where == "background" ? "bgClass"
-                 : where == "gutter" ? "gutterClass" : "wrapClass";
-        if (!line[prop]) { line[prop] = cls; }
-        else if (classTest(cls).test(line[prop])) { return false }
-        else { line[prop] += " " + cls; }
-        return true
-      })
-    }),
-    removeLineClass: docMethodOp(function(handle, where, cls) {
-      return changeLine(this, handle, where == "gutter" ? "gutter" : "class", function (line) {
-        var prop = where == "text" ? "textClass"
-                 : where == "background" ? "bgClass"
-                 : where == "gutter" ? "gutterClass" : "wrapClass";
-        var cur = line[prop];
-        if (!cur) { return false }
-        else if (cls == null) { line[prop] = null; }
-        else {
-          var found = cur.match(classTest(cls));
-          if (!found) { return false }
-          var end = found.index + found[0].length;
-          line[prop] = cur.slice(0, found.index) + (!found.index || end == cur.length ? "" : " ") + cur.slice(end) || null;
-        }
-        return true
-      })
-    }),
-
-    addLineWidget: docMethodOp(function(handle, node, options) {
-      return addLineWidget(this, handle, node, options)
-    }),
-    removeLineWidget: function(widget) { widget.clear(); },
-
-    markText: function(from, to, options) {
-      return markText(this, clipPos(this, from), clipPos(this, to), options, options && options.type || "range")
-    },
-    setBookmark: function(pos, options) {
-      var realOpts = {replacedWith: options && (options.nodeType == null ? options.widget : options),
-                      insertLeft: options && options.insertLeft,
-                      clearWhenEmpty: false, shared: options && options.shared,
-                      handleMouseEvents: options && options.handleMouseEvents};
-      pos = clipPos(this, pos);
-      return markText(this, pos, pos, realOpts, "bookmark")
-    },
-    findMarksAt: function(pos) {
-      pos = clipPos(this, pos);
-      var markers = [], spans = getLine(this, pos.line).markedSpans;
-      if (spans) { for (var i = 0; i < spans.length; ++i) {
-        var span = spans[i];
-        if ((span.from == null || span.from <= pos.ch) &&
-            (span.to == null || span.to >= pos.ch))
-          { markers.push(span.marker.parent || span.marker); }
-      } }
-      return markers
-    },
-    findMarks: function(from, to, filter) {
-      from = clipPos(this, from); to = clipPos(this, to);
-      var found = [], lineNo$$1 = from.line;
-      this.iter(from.line, to.line + 1, function (line) {
-        var spans = line.markedSpans;
-        if (spans) { for (var i = 0; i < spans.length; i++) {
-          var span = spans[i];
-          if (!(span.to != null && lineNo$$1 == from.line && from.ch >= span.to ||
-                span.from == null && lineNo$$1 != from.line ||
-                span.from != null && lineNo$$1 == to.line && span.from >= to.ch) &&
-              (!filter || filter(span.marker)))
-            { found.push(span.marker.parent || span.marker); }
-        } }
-        ++lineNo$$1;
-      });
-      return found
-    },
-    getAllMarks: function() {
-      var markers = [];
-      this.iter(function (line) {
-        var sps = line.markedSpans;
-        if (sps) { for (var i = 0; i < sps.length; ++i)
-          { if (sps[i].from != null) { markers.push(sps[i].marker); } } }
-      });
-      return markers
-    },
-
-    posFromIndex: function(off) {
-      var ch, lineNo$$1 = this.first, sepSize = this.lineSeparator().length;
-      this.iter(function (line) {
-        var sz = line.text.length + sepSize;
-        if (sz > off) { ch = off; return true }
-        off -= sz;
-        ++lineNo$$1;
-      });
-      return clipPos(this, Pos(lineNo$$1, ch))
-    },
-    indexFromPos: function (coords) {
-      coords = clipPos(this, coords);
-      var index = coords.ch;
-      if (coords.line < this.first || coords.ch < 0) { return 0 }
-      var sepSize = this.lineSeparator().length;
-      this.iter(this.first, coords.line, function (line) { // iter aborts when callback returns a truthy value
-        index += line.text.length + sepSize;
-      });
-      return index
-    },
-
-    copy: function(copyHistory) {
-      var doc = new Doc(getLines(this, this.first, this.first + this.size),
-                        this.modeOption, this.first, this.lineSep, this.direction);
-      doc.scrollTop = this.scrollTop; doc.scrollLeft = this.scrollLeft;
-      doc.sel = this.sel;
-      doc.extend = false;
-      if (copyHistory) {
-        doc.history.undoDepth = this.history.undoDepth;
-        doc.setHistory(this.getHistory());
-      }
-      return doc
-    },
-
-    linkedDoc: function(options) {
-      if (!options) { options = {}; }
-      var from = this.first, to = this.first + this.size;
-      if (options.from != null && options.from > from) { from = options.from; }
-      if (options.to != null && options.to < to) { to = options.to; }
-      var copy = new Doc(getLines(this, from, to), options.mode || this.modeOption, from, this.lineSep, this.direction);
-      if (options.sharedHist) { copy.history = this.history
-      ; }(this.linked || (this.linked = [])).push({doc: copy, sharedHist: options.sharedHist});
-      copy.linked = [{doc: this, isParent: true, sharedHist: options.sharedHist}];
-      copySharedMarkers(copy, findSharedMarkers(this));
-      return copy
-    },
-    unlinkDoc: function(other) {
-      var this$1 = this;
-
-      if (other instanceof CodeMirror) { other = other.doc; }
-      if (this.linked) { for (var i = 0; i < this.linked.length; ++i) {
-        var link = this$1.linked[i];
-        if (link.doc != other) { continue }
-        this$1.linked.splice(i, 1);
-        other.unlinkDoc(this$1);
-        detachSharedMarkers(findSharedMarkers(this$1));
-        break
-      } }
-      // If the histories were shared, split them again
-      if (other.history == this.history) {
-        var splitIds = [other.id];
-        linkedDocs(other, function (doc) { return splitIds.push(doc.id); }, true);
-        other.history = new History(null);
-        other.history.done = copyHistoryArray(this.history.done, splitIds);
-        other.history.undone = copyHistoryArray(this.history.undone, splitIds);
-      }
-    },
-    iterLinkedDocs: function(f) {linkedDocs(this, f);},
-
-    getMode: function() {return this.mode},
-    getEditor: function() {return this.cm},
-
-    splitLines: function(str) {
-      if (this.lineSep) { return str.split(this.lineSep) }
-      return splitLinesAuto(str)
-    },
-    lineSeparator: function() { return this.lineSep || "\n" },
-
-    setDirection: docMethodOp(function (dir) {
-      if (dir != "rtl") { dir = "ltr"; }
-      if (dir == this.direction) { return }
-      this.direction = dir;
-      this.iter(function (line) { return line.order = null; });
-      if (this.cm) { directionChanged(this.cm); }
-    })
-  });
-
-  // Public alias.
-  Doc.prototype.eachLine = Doc.prototype.iter;
-
-  // Kludge to work around strange IE behavior where it'll sometimes
-  // re-fire a series of drag-related events right after the drop (#1551)
-  var lastDrop = 0;
-
-  function onDrop(e) {
-    var cm = this;
-    clearDragCursor(cm);
-    if (signalDOMEvent(cm, e) || eventInWidget(cm.display, e))
-      { return }
-    e_preventDefault(e);
-    if (ie) { lastDrop = +new Date; }
-    var pos = posFromMouse(cm, e, true), files = e.dataTransfer.files;
-    if (!pos || cm.isReadOnly()) { return }
-    // Might be a file drop, in which case we simply extract the text
-    // and insert it.
-    if (files && files.length && window.FileReader && window.File) {
-      var n = files.length, text = Array(n), read = 0;
-      var loadFile = function (file, i) {
-        if (cm.options.allowDropFileTypes &&
-            indexOf(cm.options.allowDropFileTypes, file.type) == -1)
-          { return }
-
-        var reader = new FileReader;
-        reader.onload = operation(cm, function () {
-          var content = reader.result;
-          if (/[\x00-\x08\x0e-\x1f]{2}/.test(content)) { content = ""; }
-          text[i] = content;
-          if (++read == n) {
-            pos = clipPos(cm.doc, pos);
-            var change = {from: pos, to: pos,
-                          text: cm.doc.splitLines(text.join(cm.doc.lineSeparator())),
-                          origin: "paste"};
-            makeChange(cm.doc, change);
-            setSelectionReplaceHistory(cm.doc, simpleSelection(pos, changeEnd(change)));
-          }
-        });
-        reader.readAsText(file);
-      };
-      for (var i = 0; i < n; ++i) { loadFile(files[i], i); }
-    } else { // Normal drop
-      // Don't do a replace if the drop happened inside of the selected text.
-      if (cm.state.draggingText && cm.doc.sel.contains(pos) > -1) {
-        cm.state.draggingText(e);
-        // Ensure the editor is re-focused
-        setTimeout(function () { return cm.display.input.focus(); }, 20);
-        return
-      }
-      try {
-        var text$1 = e.dataTransfer.getData("Text");
-        if (text$1) {
-          var selected;
-          if (cm.state.draggingText && !cm.state.draggingText.copy)
-            { selected = cm.listSelections(); }
-          setSelectionNoUndo(cm.doc, simpleSelection(pos, pos));
-          if (selected) { for (var i$1 = 0; i$1 < selected.length; ++i$1)
-            { replaceRange(cm.doc, "", selected[i$1].anchor, selected[i$1].head, "drag"); } }
-          cm.replaceSelection(text$1, "around", "paste");
-          cm.display.input.focus();
-        }
-      }
-      catch(e){}
-    }
-  }
-
-  function onDragStart(cm, e) {
-    if (ie && (!cm.state.draggingText || +new Date - lastDrop < 100)) { e_stop(e); return }
-    if (signalDOMEvent(cm, e) || eventInWidget(cm.display, e)) { return }
-
-    e.dataTransfer.setData("Text", cm.getSelection());
-    e.dataTransfer.effectAllowed = "copyMove";
-
-    // Use dummy image instead of default browsers image.
-    // Recent Safari (~6.0.2) have a tendency to segfault when this happens, so we don't do it there.
-    if (e.dataTransfer.setDragImage && !safari) {
-      var img = elt("img", null, null, "position: fixed; left: 0; top: 0;");
-      img.src = "data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==";
-      if (presto) {
-        img.width = img.height = 1;
-        cm.display.wrapper.appendChild(img);
-        // Force a relayout, or Opera won't use our image for some obscure reason
-        img._top = img.offsetTop;
-      }
-      e.dataTransfer.setDragImage(img, 0, 0);
-      if (presto) { img.parentNode.removeChild(img); }
-    }
-  }
-
-  function onDragOver(cm, e) {
-    var pos = posFromMouse(cm, e);
-    if (!pos) { return }
-    var frag = document.createDocumentFragment();
-    drawSelectionCursor(cm, pos, frag);
-    if (!cm.display.dragCursor) {
-      cm.display.dragCursor = elt("div", null, "CodeMirror-cursors CodeMirror-dragcursors");
-      cm.display.lineSpace.insertBefore(cm.display.dragCursor, cm.display.cursorDiv);
-    }
-    removeChildrenAndAdd(cm.display.dragCursor, frag);
-  }
-
-  function clearDragCursor(cm) {
-    if (cm.display.dragCursor) {
-      cm.display.lineSpace.removeChild(cm.display.dragCursor);
-      cm.display.dragCursor = null;
-    }
-  }
-
-  // These must be handled carefully, because naively registering a
-  // handler for each editor will cause the editors to never be
-  // garbage collected.
-
-  function forEachCodeMirror(f) {
-    if (!document.getElementsByClassName) { return }
-    var byClass = document.getElementsByClassName("CodeMirror"), editors = [];
-    for (var i = 0; i < byClass.length; i++) {
-      var cm = byClass[i].CodeMirror;
-      if (cm) { editors.push(cm); }
-    }
-    if (editors.length) { editors[0].operation(function () {
-      for (var i = 0; i < editors.length; i++) { f(editors[i]); }
-    }); }
-  }
-
-  var globalsRegistered = false;
-  function ensureGlobalHandlers() {
-    if (globalsRegistered) { return }
-    registerGlobalHandlers();
-    globalsRegistered = true;
-  }
-  function registerGlobalHandlers() {
-    // When the window resizes, we need to refresh active editors.
-    var resizeTimer;
-    on(window, "resize", function () {
-      if (resizeTimer == null) { resizeTimer = setTimeout(function () {
-        resizeTimer = null;
-        forEachCodeMirror(onResize);
-      }, 100); }
-    });
-    // When the window loses focus, we want to show the editor as blurred
-    on(window, "blur", function () { return forEachCodeMirror(onBlur); });
-  }
-  // Called when the window resizes
-  function onResize(cm) {
-    var d = cm.display;
-    // Might be a text scaling operation, clear size caches.
-    d.cachedCharWidth = d.cachedTextHeight = d.cachedPaddingH = null;
-    d.scrollbarsClipped = false;
-    cm.setSize();
-  }
-
-  var keyNames = {
-    3: "Pause", 8: "Backspace", 9: "Tab", 13: "Enter", 16: "Shift", 17: "Ctrl", 18: "Alt",
-    19: "Pause", 20: "CapsLock", 27: "Esc", 32: "Space", 33: "PageUp", 34: "PageDown", 35: "End",
-    36: "Home", 37: "Left", 38: "Up", 39: "Right", 40: "Down", 44: "PrintScrn", 45: "Insert",
-    46: "Delete", 59: ";", 61: "=", 91: "Mod", 92: "Mod", 93: "Mod",
-    106: "*", 107: "=", 109: "-", 110: ".", 111: "/", 145: "ScrollLock",
-    173: "-", 186: ";", 187: "=", 188: ",", 189: "-", 190: ".", 191: "/", 192: "`", 219: "[", 220: "\\",
-    221: "]", 222: "'", 63232: "Up", 63233: "Down", 63234: "Left", 63235: "Right", 63272: "Delete",
-    63273: "Home", 63275: "End", 63276: "PageUp", 63277: "PageDown", 63302: "Insert"
-  };
-
-  // Number keys
-  for (var i = 0; i < 10; i++) { keyNames[i + 48] = keyNames[i + 96] = String(i); }
-  // Alphabetic keys
-  for (var i$1 = 65; i$1 <= 90; i$1++) { keyNames[i$1] = String.fromCharCode(i$1); }
-  // Function keys
-  for (var i$2 = 1; i$2 <= 12; i$2++) { keyNames[i$2 + 111] = keyNames[i$2 + 63235] = "F" + i$2; }
-
-  var keyMap = {};
-
-  keyMap.basic = {
-    "Left": "goCharLeft", "Right": "goCharRight", "Up": "goLineUp", "Down": "goLineDown",
-    "End": "goLineEnd", "Home": "goLineStartSmart", "PageUp": "goPageUp", "PageDown": "goPageDown",
-    "Delete": "delCharAfter", "Backspace": "delCharBefore", "Shift-Backspace": "delCharBefore",
-    "Tab": "defaultTab", "Shift-Tab": "indentAuto",
-    "Enter": "newlineAndIndent", "Insert": "toggleOverwrite",
-    "Esc": "singleSelection"
-  };
-  // Note that the save and find-related commands aren't defined by
-  // default. User code or addons can define them. Unknown commands
-  // are simply ignored.
-  keyMap.pcDefault = {
-    "Ctrl-A": "selectAll", "Ctrl-D": "deleteLine", "Ctrl-Z": "undo", "Shift-Ctrl-Z": "redo", "Ctrl-Y": "redo",
-    "Ctrl-Home": "goDocStart", "Ctrl-End": "goDocEnd", "Ctrl-Up": "goLineUp", "Ctrl-Down": "goLineDown",
-    "Ctrl-Left": "goGroupLeft", "Ctrl-Right": "goGroupRight", "Alt-Left": "goLineStart", "Alt-Right": "goLineEnd",
-    "Ctrl-Backspace": "delGroupBefore", "Ctrl-Delete": "delGroupAfter", "Ctrl-S": "save", "Ctrl-F": "find",
-    "Ctrl-G": "findNext", "Shift-Ctrl-G": "findPrev", "Shift-Ctrl-F": "replace", "Shift-Ctrl-R": "replaceAll",
-    "Ctrl-[": "indentLess", "Ctrl-]": "indentMore",
-    "Ctrl-U": "undoSelection", "Shift-Ctrl-U": "redoSelection", "Alt-U": "redoSelection",
-    "fallthrough": "basic"
-  };
-  // Very basic readline/emacs-style bindings, which are standard on Mac.
-  keyMap.emacsy = {
-    "Ctrl-F": "goCharRight", "Ctrl-B": "goCharLeft", "Ctrl-P": "goLineUp", "Ctrl-N": "goLineDown",
-    "Alt-F": "goWordRight", "Alt-B": "goWordLeft", "Ctrl-A": "goLineStart", "Ctrl-E": "goLineEnd",
-    "Ctrl-V": "goPageDown", "Shift-Ctrl-V": "goPageUp", "Ctrl-D": "delCharAfter", "Ctrl-H": "delCharBefore",
-    "Alt-D": "delWordAfter", "Alt-Backspace": "delWordBefore", "Ctrl-K": "killLine", "Ctrl-T": "transposeChars",
-    "Ctrl-O": "openLine"
-  };
-  keyMap.macDefault = {
-    "Cmd-A": "selectAll", "Cmd-D": "deleteLine", "Cmd-Z": "undo", "Shift-Cmd-Z": "redo", "Cmd-Y": "redo",
-    "Cmd-Home": "goDocStart", "Cmd-Up": "goDocStart", "Cmd-End": "goDocEnd", "Cmd-Down": "goDocEnd", "Alt-Left": "goGroupLeft",
-    "Alt-Right": "goGroupRight", "Cmd-Left": "goLineLeft", "Cmd-Right": "goLineRight", "Alt-Backspace": "delGroupBefore",
-    "Ctrl-Alt-Backspace": "delGroupAfter", "Alt-Delete": "delGroupAfter", "Cmd-S": "save", "Cmd-F": "find",
-    "Cmd-G": "findNext", "Shift-Cmd-G": "findPrev", "Cmd-Alt-F": "replace", "Shift-Cmd-Alt-F": "replaceAll",
-    "Cmd-[": "indentLess", "Cmd-]": "indentMore", "Cmd-Backspace": "delWrappedLineLeft", "Cmd-Delete": "delWrappedLineRight",
-    "Cmd-U": "undoSelection", "Shift-Cmd-U": "redoSelection", "Ctrl-Up": "goDocStart", "Ctrl-Down": "goDocEnd",
-    "fallthrough": ["basic", "emacsy"]
-  };
-  keyMap["default"] = mac ? keyMap.macDefault : keyMap.pcDefault;
-
-  // KEYMAP DISPATCH
-
-  function normalizeKeyName(name) {
-    var parts = name.split(/-(?!$)/);
-    name = parts[parts.length - 1];
-    var alt, ctrl, shift, cmd;
-    for (var i = 0; i < parts.length - 1; i++) {
-      var mod = parts[i];
-      if (/^(cmd|meta|m)$/i.test(mod)) { cmd = true; }
-      else if (/^a(lt)?$/i.test(mod)) { alt = true; }
-      else if (/^(c|ctrl|control)$/i.test(mod)) { ctrl = true; }
-      else if (/^s(hift)?$/i.test(mod)) { shift = true; }
-      else { throw new Error("Unrecognized modifier name: " + mod) }
-    }
-    if (alt) { name = "Alt-" + name; }
-    if (ctrl) { name = "Ctrl-" + name; }
-    if (cmd) { name = "Cmd-" + name; }
-    if (shift) { name = "Shift-" + name; }
-    return name
-  }
-
-  // This is a kludge to keep keymaps mostly working as raw objects
-  // (backwards compatibility) while at the same time support features
-  // like normalization and multi-stroke key bindings. It compiles a
-  // new normalized keymap, and then updates the old object to reflect
-  // this.
-  function normalizeKeyMap(keymap) {
-    var copy = {};
-    for (var keyname in keymap) { if (keymap.hasOwnProperty(keyname)) {
-      var value = keymap[keyname];
-      if (/^(name|fallthrough|(de|at)tach)$/.test(keyname)) { continue }
-      if (value == "...") { delete keymap[keyname]; continue }
-
-      var keys = map(keyname.split(" "), normalizeKeyName);
-      for (var i = 0; i < keys.length; i++) {
-        var val = (void 0), name = (void 0);
-        if (i == keys.length - 1) {
-          name = keys.join(" ");
-          val = value;
-        } else {
-          name = keys.slice(0, i + 1).join(" ");
-          val = "...";
-        }
-        var prev = copy[name];
-        if (!prev) { copy[name] = val; }
-        else if (prev != val) { throw new Error("Inconsistent bindings for " + name) }
-      }
-      delete keymap[keyname];
-    } }
-    for (var prop in copy) { keymap[prop] = copy[prop]; }
-    return keymap
-  }
-
-  function lookupKey(key, map$$1, handle, context) {
-    map$$1 = getKeyMap(map$$1);
-    var found = map$$1.call ? map$$1.call(key, context) : map$$1[key];
-    if (found === false) { return "nothing" }
-    if (found === "...") { return "multi" }
-    if (found != null && handle(found)) { return "handled" }
-
-    if (map$$1.fallthrough) {
-      if (Object.prototype.toString.call(map$$1.fallthrough) != "[object Array]")
-        { return lookupKey(key, map$$1.fallthrough, handle, context) }
-      for (var i = 0; i < map$$1.fallthrough.length; i++) {
-        var result = lookupKey(key, map$$1.fallthrough[i], handle, context);
-        if (result) { return result }
-      }
-    }
-  }
-
-  // Modifier key presses don't count as 'real' key presses for the
-  // purpose of keymap fallthrough.
-  function isModifierKey(value) {
-    var name = typeof value == "string" ? value : keyNames[value.keyCode];
-    return name == "Ctrl" || name == "Alt" || name == "Shift" || name == "Mod"
-  }
-
-  function addModifierNames(name, event, noShift) {
-    var base = name;
-    if (event.altKey && base != "Alt") { name = "Alt-" + name; }
-    if ((flipCtrlCmd ? event.metaKey : event.ctrlKey) && base != "Ctrl") { name = "Ctrl-" + name; }
-    if ((flipCtrlCmd ? event.ctrlKey : event.metaKey) && base != "Cmd") { name = "Cmd-" + name; }
-    if (!noShift && event.shiftKey && base != "Shift") { name = "Shift-" + name; }
-    return name
-  }
-
-  // Look up the name of a key as indicated by an event object.
-  function keyName(event, noShift) {
-    if (presto && event.keyCode == 34 && event["char"]) { return false }
-    var name = keyNames[event.keyCode];
-    if (name == null || event.altGraphKey) { return false }
-    // Ctrl-ScrollLock has keyCode 3, same as Ctrl-Pause,
-    // so we'll use event.code when available (Chrome 48+, FF 38+, Safari 10.1+)
-    if (event.keyCode == 3 && event.code) { name = event.code; }
-    return addModifierNames(name, event, noShift)
-  }
-
-  function getKeyMap(val) {
-    return typeof val == "string" ? keyMap[val] : val
-  }
-
-  // Helper for deleting text near the selection(s), used to implement
-  // backspace, delete, and similar functionality.
-  function deleteNearSelection(cm, compute) {
-    var ranges = cm.doc.sel.ranges, kill = [];
-    // Build up a set of ranges to kill first, merging overlapping
-    // ranges.
-    for (var i = 0; i < ranges.length; i++) {
-      var toKill = compute(ranges[i]);
-      while (kill.length && cmp(toKill.from, lst(kill).to) <= 0) {
-        var replaced = kill.pop();
-        if (cmp(replaced.from, toKill.from) < 0) {
-          toKill.from = replaced.from;
-          break
-        }
-      }
-      kill.push(toKill);
-    }
-    // Next, remove those actual ranges.
-    runInOp(cm, function () {
-      for (var i = kill.length - 1; i >= 0; i--)
-        { replaceRange(cm.doc, "", kill[i].from, kill[i].to, "+delete"); }
-      ensureCursorVisible(cm);
-    });
-  }
-
-  function moveCharLogically(line, ch, dir) {
-    var target = skipExtendingChars(line.text, ch + dir, dir);
-    return target < 0 || target > line.text.length ? null : target
-  }
-
-  function moveLogically(line, start, dir) {
-    var ch = moveCharLogically(line, start.ch, dir);
-    return ch == null ? null : new Pos(start.line, ch, dir < 0 ? "after" : "before")
-  }
-
-  function endOfLine(visually, cm, lineObj, lineNo, dir) {
-    if (visually) {
-      var order = getOrder(lineObj, cm.doc.direction);
-      if (order) {
-        var part = dir < 0 ? lst(order) : order[0];
-        var moveInStorageOrder = (dir < 0) == (part.level == 1);
-        var sticky = moveInStorageOrder ? "after" : "before";
-        var ch;
-        // With a wrapped rtl chunk (possibly spanning multiple bidi parts),
-        // it could be that the last bidi part is not on the last visual line,
-        // since visual lines contain content order-consecutive chunks.
-        // Thus, in rtl, we are looking for the first (content-order) character
-        // in the rtl chunk that is on the last line (that is, the same line
-        // as the last (content-order) character).
-        if (part.level > 0 || cm.doc.direction == "rtl") {
-          var prep = prepareMeasureForLine(cm, lineObj);
-          ch = dir < 0 ? lineObj.text.length - 1 : 0;
-          var targetTop = measureCharPrepared(cm, prep, ch).top;
-          ch = findFirst(function (ch) { return measureCharPrepared(cm, prep, ch).top == targetTop; }, (dir < 0) == (part.level == 1) ? part.from : part.to - 1, ch);
-          if (sticky == "before") { ch = moveCharLogically(lineObj, ch, 1); }
-        } else { ch = dir < 0 ? part.to : part.from; }
-        return new Pos(lineNo, ch, sticky)
-      }
-    }
-    return new Pos(lineNo, dir < 0 ? lineObj.text.length : 0, dir < 0 ? "before" : "after")
-  }
-
-  function moveVisually(cm, line, start, dir) {
-    var bidi = getOrder(line, cm.doc.direction);
-    if (!bidi) { return moveLogically(line, start, dir) }
-    if (start.ch >= line.text.length) {
-      start.ch = line.text.length;
-      start.sticky = "before";
-    } else if (start.ch <= 0) {
-      start.ch = 0;
-      start.sticky = "after";
-    }
-    var partPos = getBidiPartAt(bidi, start.ch, start.sticky), part = bidi[partPos];
-    if (cm.doc.direction == "ltr" && part.level % 2 == 0 && (dir > 0 ? part.to > start.ch : part.from < start.ch)) {
-      // Case 1: We move within an ltr part in an ltr editor. Even with wrapped lines,
-      // nothing interesting happens.
-      return moveLogically(line, start, dir)
-    }
-
-    var mv = function (pos, dir) { return moveCharLogically(line, pos instanceof Pos ? pos.ch : pos, dir); };
-    var prep;
-    var getWrappedLineExtent = function (ch) {
-      if (!cm.options.lineWrapping) { return {begin: 0, end: line.text.length} }
-      prep = prep || prepareMeasureForLine(cm, line);
-      return wrappedLineExtentChar(cm, line, prep, ch)
-    };
-    var wrappedLineExtent = getWrappedLineExtent(start.sticky == "before" ? mv(start, -1) : start.ch);
-
-    if (cm.doc.direction == "rtl" || part.level == 1) {
-      var moveInStorageOrder = (part.level == 1) == (dir < 0);
-      var ch = mv(start, moveInStorageOrder ? 1 : -1);
-      if (ch != null && (!moveInStorageOrder ? ch >= part.from && ch >= wrappedLineExtent.begin : ch <= part.to && ch <= wrappedLineExtent.end)) {
-        // Case 2: We move within an rtl part or in an rtl editor on the same visual line
-        var sticky = moveInStorageOrder ? "before" : "after";
-        return new Pos(start.line, ch, sticky)
-      }
-    }
-
-    // Case 3: Could not move within this bidi part in this visual line, so leave
-    // the current bidi part
-
-    var searchInVisualLine = function (partPos, dir, wrappedLineExtent) {
-      var getRes = function (ch, moveInStorageOrder) { return moveInStorageOrder
-        ? new Pos(start.line, mv(ch, 1), "before")
-        : new Pos(start.line, ch, "after"); };
-
-      for (; partPos >= 0 && partPos < bidi.length; partPos += dir) {
-        var part = bidi[partPos];
-        var moveInStorageOrder = (dir > 0) == (part.level != 1);
-        var ch = moveInStorageOrder ? wrappedLineExtent.begin : mv(wrappedLineExtent.end, -1);
-        if (part.from <= ch && ch < part.to) { return getRes(ch, moveInStorageOrder) }
-        ch = moveInStorageOrder ? part.from : mv(part.to, -1);
-        if (wrappedLineExtent.begin <= ch && ch < wrappedLineExtent.end) { return getRes(ch, moveInStorageOrder) }
-      }
-    };
-
-    // Case 3a: Look for other bidi parts on the same visual line
-    var res = searchInVisualLine(partPos + dir, dir, wrappedLineExtent);
-    if (res) { return res }
-
-    // Case 3b: Look for other bidi parts on the next visual line
-    var nextCh = dir > 0 ? wrappedLineExtent.end : mv(wrappedLineExtent.begin, -1);
-    if (nextCh != null && !(dir > 0 && nextCh == line.text.length)) {
-      res = searchInVisualLine(dir > 0 ? 0 : bidi.length - 1, dir, getWrappedLineExtent(nextCh));
-      if (res) { return res }
-    }
-
-    // Case 4: Nowhere to move
-    return null
-  }
-
-  // Commands are parameter-less actions that can be performed on an
-  // editor, mostly used for keybindings.
-  var commands = {
-    selectAll: selectAll,
-    singleSelection: function (cm) { return cm.setSelection(cm.getCursor("anchor"), cm.getCursor("head"), sel_dontScroll); },
-    killLine: function (cm) { return deleteNearSelection(cm, function (range) {
-      if (range.empty()) {
-        var len = getLine(cm.doc, range.head.line).text.length;
-        if (range.head.ch == len && range.head.line < cm.lastLine())
-          { return {from: range.head, to: Pos(range.head.line + 1, 0)} }
-        else
-          { return {from: range.head, to: Pos(range.head.line, len)} }
-      } else {
-        return {from: range.from(), to: range.to()}
-      }
-    }); },
-    deleteLine: function (cm) { return deleteNearSelection(cm, function (range) { return ({
-      from: Pos(range.from().line, 0),
-      to: clipPos(cm.doc, Pos(range.to().line + 1, 0))
-    }); }); },
-    delLineLeft: function (cm) { return deleteNearSelection(cm, function (range) { return ({
-      from: Pos(range.from().line, 0), to: range.from()
-    }); }); },
-    delWrappedLineLeft: function (cm) { return deleteNearSelection(cm, function (range) {
-      var top = cm.charCoords(range.head, "div").top + 5;
-      var leftPos = cm.coordsChar({left: 0, top: top}, "div");
-      return {from: leftPos, to: range.from()}
-    }); },
-    delWrappedLineRight: function (cm) { return deleteNearSelection(cm, function (range) {
-      var top = cm.charCoords(range.head, "div").top + 5;
-      var rightPos = cm.coordsChar({left: cm.display.lineDiv.offsetWidth + 100, top: top}, "div");
-      return {from: range.from(), to: rightPos }
-    }); },
-    undo: function (cm) { return cm.undo(); },
-    redo: function (cm) { return cm.redo(); },
-    undoSelection: function (cm) { return cm.undoSelection(); },
-    redoSelection: function (cm) { return cm.redoSelection(); },
-    goDocStart: function (cm) { return cm.extendSelection(Pos(cm.firstLine(), 0)); },
-    goDocEnd: function (cm) { return cm.extendSelection(Pos(cm.lastLine())); },
-    goLineStart: function (cm) { return cm.extendSelectionsBy(function (range) { return lineStart(cm, range.head.line); },
-      {origin: "+move", bias: 1}
-    ); },
-    goLineStartSmart: function (cm) { return cm.extendSelectionsBy(function (range) { return lineStartSmart(cm, range.head); },
-      {origin: "+move", bias: 1}
-    ); },
-    goLineEnd: function (cm) { return cm.extendSelectionsBy(function (range) { return lineEnd(cm, range.head.line); },
-      {origin: "+move", bias: -1}
-    ); },
-    goLineRight: function (cm) { return cm.extendSelectionsBy(function (range) {
-      var top = cm.cursorCoords(range.head, "div").top + 5;
-      return cm.coordsChar({left: cm.display.lineDiv.offsetWidth + 100, top: top}, "div")
-    }, sel_move); },
-    goLineLeft: function (cm) { return cm.extendSelectionsBy(function (range) {
-      var top = cm.cursorCoords(range.head, "div").top + 5;
-      return cm.coordsChar({left: 0, top: top}, "div")
-    }, sel_move); },
-    goLineLeftSmart: function (cm) { return cm.extendSelectionsBy(function (range) {
-      var top = cm.cursorCoords(range.head, "div").top + 5;
-      var pos = cm.coordsChar({left: 0, top: top}, "div");
-      if (pos.ch < cm.getLine(pos.line).search(/\S/)) { return lineStartSmart(cm, range.head) }
-      return pos
-    }, sel_move); },
-    goLineUp: function (cm) { return cm.moveV(-1, "line"); },
-    goLineDown: function (cm) { return cm.moveV(1, "line"); },
-    goPageUp: function (cm) { return cm.moveV(-1, "page"); },
-    goPageDown: function (cm) { return cm.moveV(1, "page"); },
-    goCharLeft: function (cm) { return cm.moveH(-1, "char"); },
-    goCharRight: function (cm) { return cm.moveH(1, "char"); },
-    goColumnLeft: function (cm) { return cm.moveH(-1, "column"); },
-    goColumnRight: function (cm) { return cm.moveH(1, "column"); },
-    goWordLeft: function (cm) { return cm.moveH(-1, "word"); },
-    goGroupRight: function (cm) { return cm.moveH(1, "group"); },
-    goGroupLeft: function (cm) { return cm.moveH(-1, "group"); },
-    goWordRight: function (cm) { return cm.moveH(1, "word"); },
-    delCharBefore: function (cm) { return cm.deleteH(-1, "char"); },
-    delCharAfter: function (cm) { return cm.deleteH(1, "char"); },
-    delWordBefore: function (cm) { return cm.deleteH(-1, "word"); },
-    delWordAfter: function (cm) { return cm.deleteH(1, "word"); },
-    delGroupBefore: function (cm) { return cm.deleteH(-1, "group"); },
-    delGroupAfter: function (cm) { return cm.deleteH(1, "group"); },
-    indentAuto: function (cm) { return cm.indentSelection("smart"); },
-    indentMore: function (cm) { return cm.indentSelection("add"); },
-    indentLess: function (cm) { return cm.indentSelection("subtract"); },
-    insertTab: function (cm) { return cm.replaceSelection("\t"); },
-    insertSoftTab: function (cm) {
-      var spaces = [], ranges = cm.listSelections(), tabSize = cm.options.tabSize;
-      for (var i = 0; i < ranges.length; i++) {
-        var pos = ranges[i].from();
-        var col = countColumn(cm.getLine(pos.line), pos.ch, tabSize);
-        spaces.push(spaceStr(tabSize - col % tabSize));
-      }
-      cm.replaceSelections(spaces);
-    },
-    defaultTab: function (cm) {
-      if (cm.somethingSelected()) { cm.indentSelection("add"); }
-      else { cm.execCommand("insertTab"); }
-    },
-    // Swap the two chars left and right of each selection's head.
-    // Move cursor behind the two swapped characters afterwards.
-    //
-    // Doesn't consider line feeds a character.
-    // Doesn't scan more than one line above to find a character.
-    // Doesn't do anything on an empty line.
-    // Doesn't do anything with non-empty selections.
-    transposeChars: function (cm) { return runInOp(cm, function () {
-      var ranges = cm.listSelections(), newSel = [];
-      for (var i = 0; i < ranges.length; i++) {
-        if (!ranges[i].empty()) { continue }
-        var cur = ranges[i].head, line = getLine(cm.doc, cur.line).text;
-        if (line) {
-          if (cur.ch == line.length) { cur = new Pos(cur.line, cur.ch - 1); }
-          if (cur.ch > 0) {
-            cur = new Pos(cur.line, cur.ch + 1);
-            cm.replaceRange(line.charAt(cur.ch - 1) + line.charAt(cur.ch - 2),
-                            Pos(cur.line, cur.ch - 2), cur, "+transpose");
-          } else if (cur.line > cm.doc.first) {
-            var prev = getLine(cm.doc, cur.line - 1).text;
-            if (prev) {
-              cur = new Pos(cur.line, 1);
-              cm.replaceRange(line.charAt(0) + cm.doc.lineSeparator() +
-                              prev.charAt(prev.length - 1),
-                              Pos(cur.line - 1, prev.length - 1), cur, "+transpose");
-            }
-          }
-        }
-        newSel.push(new Range(cur, cur));
-      }
-      cm.setSelections(newSel);
-    }); },
-    newlineAndIndent: function (cm) { return runInOp(cm, function () {
-      var sels = cm.listSelections();
-      for (var i = sels.length - 1; i >= 0; i--)
-        { cm.replaceRange(cm.doc.lineSeparator(), sels[i].anchor, sels[i].head, "+input"); }
-      sels = cm.listSelections();
-      for (var i$1 = 0; i$1 < sels.length; i$1++)
-        { cm.indentLine(sels[i$1].from().line, null, true); }
-      ensureCursorVisible(cm);
-    }); },
-    openLine: function (cm) { return cm.replaceSelection("\n", "start"); },
-    toggleOverwrite: function (cm) { return cm.toggleOverwrite(); }
-  };
-
-
-  function lineStart(cm, lineN) {
-    var line = getLine(cm.doc, lineN);
-    var visual = visualLine(line);
-    if (visual != line) { lineN = lineNo(visual); }
-    return endOfLine(true, cm, visual, lineN, 1)
-  }
-  function lineEnd(cm, lineN) {
-    var line = getLine(cm.doc, lineN);
-    var visual = visualLineEnd(line);
-    if (visual != line) { lineN = lineNo(visual); }
-    return endOfLine(true, cm, line, lineN, -1)
-  }
-  function lineStartSmart(cm, pos) {
-    var start = lineStart(cm, pos.line);
-    var line = getLine(cm.doc, start.line);
-    var order = getOrder(line, cm.doc.direction);
-    if (!order || order[0].level == 0) {
-      var firstNonWS = Math.max(0, line.text.search(/\S/));
-      var inWS = pos.line == start.line && pos.ch <= firstNonWS && pos.ch;
-      return Pos(start.line, inWS ? 0 : firstNonWS, start.sticky)
-    }
-    return start
-  }
-
-  // Run a handler that was bound to a key.
-  function doHandleBinding(cm, bound, dropShift) {
-    if (typeof bound == "string") {
-      bound = commands[bound];
-      if (!bound) { return false }
-    }
-    // Ensure previous input has been read, so that the handler sees a
-    // consistent view of the document
-    cm.display.input.ensurePolled();
-    var prevShift = cm.display.shift, done = false;
-    try {
-      if (cm.isReadOnly()) { cm.state.suppressEdits = true; }
-      if (dropShift) { cm.display.shift = false; }
-      done = bound(cm) != Pass;
-    } finally {
-      cm.display.shift = prevShift;
-      cm.state.suppressEdits = false;
-    }
-    return done
-  }
-
-  function lookupKeyForEditor(cm, name, handle) {
-    for (var i = 0; i < cm.state.keyMaps.length; i++) {
-      var result = lookupKey(name, cm.state.keyMaps[i], handle, cm);
-      if (result) { return result }
-    }
-    return (cm.options.extraKeys && lookupKey(name, cm.options.extraKeys, handle, cm))
-      || lookupKey(name, cm.options.keyMap, handle, cm)
-  }
-
-  // Note that, despite the name, this function is also used to check
-  // for bound mouse clicks.
-
-  var stopSeq = new Delayed;
-
-  function dispatchKey(cm, name, e, handle) {
-    var seq = cm.state.keySeq;
-    if (seq) {
-      if (isModifierKey(name)) { return "handled" }
-      if (/\'$/.test(name))
-        { cm.state.keySeq = null; }
-      else
-        { stopSeq.set(50, function () {
-          if (cm.state.keySeq == seq) {
-            cm.state.keySeq = null;
-            cm.display.input.reset();
-          }
-        }); }
-      if (dispatchKeyInner(cm, seq + " " + name, e, handle)) { return true }
-    }
-    return dispatchKeyInner(cm, name, e, handle)
-  }
-
-  function dispatchKeyInner(cm, name, e, handle) {
-    var result = lookupKeyForEditor(cm, name, handle);
-
-    if (result == "multi")
-      { cm.state.keySeq = name; }
-    if (result == "handled")
-      { signalLater(cm, "keyHandled", cm, name, e); }
-
-    if (result == "handled" || result == "multi") {
-      e_preventDefault(e);
-      restartBlink(cm);
-    }
-
-    return !!result
-  }
-
-  // Handle a key from the keydown event.
-  function handleKeyBinding(cm, e) {
-    var name = keyName(e, true);
-    if (!name) { return false }
-
-    if (e.shiftKey && !cm.state.keySeq) {
-      // First try to resolve full name (including 'Shift-'). Failing
-      // that, see if there is a cursor-motion command (starting with
-      // 'go') bound to the keyname without 'Shift-'.
-      return dispatchKey(cm, "Shift-" + name, e, function (b) { return doHandleBinding(cm, b, true); })
-          || dispatchKey(cm, name, e, function (b) {
-               if (typeof b == "string" ? /^go[A-Z]/.test(b) : b.motion)
-                 { return doHandleBinding(cm, b) }
-             })
-    } else {
-      return dispatchKey(cm, name, e, function (b) { return doHandleBinding(cm, b); })
-    }
-  }
-
-  // Handle a key from the keypress event
-  function handleCharBinding(cm, e, ch) {
-    return dispatchKey(cm, "'" + ch + "'", e, function (b) { return doHandleBinding(cm, b, true); })
-  }
-
-  var lastStoppedKey = null;
-  function onKeyDown(e) {
-    var cm = this;
-    cm.curOp.focus = activeElt();
-    if (signalDOMEvent(cm, e)) { return }
-    // IE does strange things with escape.
-    if (ie && ie_version < 11 && e.keyCode == 27) { e.returnValue = false; }
-    var code = e.keyCode;
-    cm.display.shift = code == 16 || e.shiftKey;
-    var handled = handleKeyBinding(cm, e);
-    if (presto) {
-      lastStoppedKey = handled ? code : null;
-      // Opera has no cut event... we try to at least catch the key combo
-      if (!handled && code == 88 && !hasCopyEvent && (mac ? e.metaKey : e.ctrlKey))
-        { cm.replaceSelection("", null, "cut"); }
-    }
-
-    // Turn mouse into crosshair when Alt is held on Mac.
-    if (code == 18 && !/\bCodeMirror-crosshair\b/.test(cm.display.lineDiv.className))
-      { showCrossHair(cm); }
-  }
-
-  function showCrossHair(cm) {
-    var lineDiv = cm.display.lineDiv;
-    addClass(lineDiv, "CodeMirror-crosshair");
-
-    function up(e) {
-      if (e.keyCode == 18 || !e.altKey) {
-        rmClass(lineDiv, "CodeMirror-crosshair");
-        off(document, "keyup", up);
-        off(document, "mouseover", up);
-      }
-    }
-    on(document, "keyup", up);
-    on(document, "mouseover", up);
-  }
-
-  function onKeyUp(e) {
-    if (e.keyCode == 16) { this.doc.sel.shift = false; }
-    signalDOMEvent(this, e);
-  }
-
-  function onKeyPress(e) {
-    var cm = this;
-    if (eventInWidget(cm.display, e) || signalDOMEvent(cm, e) || e.ctrlKey && !e.altKey || mac && e.metaKey) { return }
-    var keyCode = e.keyCode, charCode = e.charCode;
-    if (presto && keyCode == lastStoppedKey) {lastStoppedKey = null; e_preventDefault(e); return}
-    if ((presto && (!e.which || e.which < 10)) && handleKeyBinding(cm, e)) { return }
-    var ch = String.fromCharCode(charCode == null ? keyCode : charCode);
-    // Some browsers fire keypress events for backspace
-    if (ch == "\x08") { return }
-    if (handleCharBinding(cm, e, ch)) { return }
-    cm.display.input.onKeyPress(e);
-  }
-
-  var DOUBLECLICK_DELAY = 400;
-
-  var PastClick = function(time, pos, button) {
-    this.time = time;
-    this.pos = pos;
-    this.button = button;
-  };
-
-  PastClick.prototype.compare = function (time, pos, button) {
-    return this.time + DOUBLECLICK_DELAY > time &&
-      cmp(pos, this.pos) == 0 && button == this.button
-  };
-
-  var lastClick, lastDoubleClick;
-  function clickRepeat(pos, button) {
-    var now = +new Date;
-    if (lastDoubleClick && lastDoubleClick.compare(now, pos, button)) {
-      lastClick = lastDoubleClick = null;
-      return "triple"
-    } else if (lastClick && lastClick.compare(now, pos, button)) {
-      lastDoubleClick = new PastClick(now, pos, button);
-      lastClick = null;
-      return "double"
-    } else {
-      lastClick = new PastClick(now, pos, button);
-      lastDoubleClick = null;
-      return "single"
-    }
-  }
-
-  // A mouse down can be a single click, double click, triple click,
-  // start of selection drag, start of text drag, new cursor
-  // (ctrl-click), rectangle drag (alt-drag), or xwin
-  // middle-click-paste. Or it might be a click on something we should
-  // not interfere with, such as a scrollbar or widget.
-  function onMouseDown(e) {
-    var cm = this, display = cm.display;
-    if (signalDOMEvent(cm, e) || display.activeTouch && display.input.supportsTouch()) { return }
-    display.input.ensurePolled();
-    display.shift = e.shiftKey;
-
-    if (eventInWidget(display, e)) {
-      if (!webkit) {
-        // Briefly turn off draggability, to allow widgets to do
-        // normal dragging things.
-        display.scroller.draggable = false;
-        setTimeout(function () { return display.scroller.draggable = true; }, 100);
-      }
-      return
-    }
-    if (clickInGutter(cm, e)) { return }
-    var pos = posFromMouse(cm, e), button = e_button(e), repeat = pos ? clickRepeat(pos, button) : "single";
-    window.focus();
-
-    // #3261: make sure, that we're not starting a second selection
-    if (button == 1 && cm.state.selectingText)
-      { cm.state.selectingText(e); }
-
-    if (pos && handleMappedButton(cm, button, pos, repeat, e)) { return }
-
-    if (button == 1) {
-      if (pos) { leftButtonDown(cm, pos, repeat, e); }
-      else if (e_target(e) == display.scroller) { e_preventDefault(e); }
-    } else if (button == 2) {
-      if (pos) { extendSelection(cm.doc, pos); }
-      setTimeout(function () { return display.input.focus(); }, 20);
-    } else if (button == 3) {
-      if (captureRightClick) { cm.display.input.onContextMenu(e); }
-      else { delayBlurEvent(cm); }
-    }
-  }
-
-  function handleMappedButton(cm, button, pos, repeat, event) {
-    var name = "Click";
-    if (repeat == "double") { name = "Double" + name; }
-    else if (repeat == "triple") { name = "Triple" + name; }
-    name = (button == 1 ? "Left" : button == 2 ? "Middle" : "Right") + name;
-
-    return dispatchKey(cm,  addModifierNames(name, event), event, function (bound) {
-      if (typeof bound == "string") { bound = commands[bound]; }
-      if (!bound) { return false }
-      var done = false;
-      try {
-        if (cm.isReadOnly()) { cm.state.suppressEdits = true; }
-        done = bound(cm, pos) != Pass;
-      } finally {
-        cm.state.suppressEdits = false;
-      }
-      return done
-    })
-  }
-
-  function configureMouse(cm, repeat, event) {
-    var option = cm.getOption("configureMouse");
-    var value = option ? option(cm, repeat, event) : {};
-    if (value.unit == null) {
-      var rect = chromeOS ? event.shiftKey && event.metaKey : event.altKey;
-      value.unit = rect ? "rectangle" : repeat == "single" ? "char" : repeat == "double" ? "word" : "line";
-    }
-    if (value.extend == null || cm.doc.extend) { value.extend = cm.doc.extend || event.shiftKey; }
-    if (value.addNew == null) { value.addNew = mac ? event.metaKey : event.ctrlKey; }
-    if (value.moveOnDrag == null) { value.moveOnDrag = !(mac ? event.altKey : event.ctrlKey); }
-    return value
-  }
-
-  function leftButtonDown(cm, pos, repeat, event) {
-    if (ie) { setTimeout(bind(ensureFocus, cm), 0); }
-    else { cm.curOp.focus = activeElt(); }
-
-    var behavior = configureMouse(cm, repeat, event);
-
-    var sel = cm.doc.sel, contained;
-    if (cm.options.dragDrop && dragAndDrop && !cm.isReadOnly() &&
-        repeat == "single" && (contained = sel.contains(pos)) > -1 &&
-        (cmp((contained = sel.ranges[contained]).from(), pos) < 0 || pos.xRel > 0) &&
-        (cmp(contained.to(), pos) > 0 || pos.xRel < 0))
-      { leftButtonStartDrag(cm, event, pos, behavior); }
-    else
-      { leftButtonSelect(cm, event, pos, behavior); }
-  }
-
-  // Start a text drag. When it ends, see if any dragging actually
-  // happen, and treat as a click if it didn't.
-  function leftButtonStartDrag(cm, event, pos, behavior) {
-    var display = cm.display, moved = false;
-    var dragEnd = operation(cm, function (e) {
-      if (webkit) { display.scroller.draggable = false; }
-      cm.state.draggingText = false;
-      off(display.wrapper.ownerDocument, "mouseup", dragEnd);
-      off(display.wrapper.ownerDocument, "mousemove", mouseMove);
-      off(display.scroller, "dragstart", dragStart);
-      off(display.scroller, "drop", dragEnd);
-      if (!moved) {
-        e_preventDefault(e);
-        if (!behavior.addNew)
-          { extendSelection(cm.doc, pos, null, null, behavior.extend); }
-        // Work around unexplainable focus problem in IE9 (#2127) and Chrome (#3081)
-        if (webkit || ie && ie_version == 9)
-          { setTimeout(function () {display.wrapper.ownerDocument.body.focus(); display.input.focus();}, 20); }
-        else
-          { display.input.focus(); }
-      }
-    });
-    var mouseMove = function(e2) {
-      moved = moved || Math.abs(event.clientX - e2.clientX) + Math.abs(event.clientY - e2.clientY) >= 10;
-    };
-    var dragStart = function () { return moved = true; };
-    // Let the drag handler handle this.
-    if (webkit) { display.scroller.draggable = true; }
-    cm.state.draggingText = dragEnd;
-    dragEnd.copy = !behavior.moveOnDrag;
-    // IE's approach to draggable
-    if (display.scroller.dragDrop) { display.scroller.dragDrop(); }
-    on(display.wrapper.ownerDocument, "mouseup", dragEnd);
-    on(display.wrapper.ownerDocument, "mousemove", mouseMove);
-    on(display.scroller, "dragstart", dragStart);
-    on(display.scroller, "drop", dragEnd);
-
-    delayBlurEvent(cm);
-    setTimeout(function () { return display.input.focus(); }, 20);
-  }
-
-  function rangeForUnit(cm, pos, unit) {
-    if (unit == "char") { return new Range(pos, pos) }
-    if (unit == "word") { return cm.findWordAt(pos) }
-    if (unit == "line") { return new Range(Pos(pos.line, 0), clipPos(cm.doc, Pos(pos.line + 1, 0))) }
-    var result = unit(cm, pos);
-    return new Range(result.from, result.to)
-  }
-
-  // Normal selection, as opposed to text dragging.
-  function leftButtonSelect(cm, event, start, behavior) {
-    var display = cm.display, doc = cm.doc;
-    e_preventDefault(event);
-
-    var ourRange, ourIndex, startSel = doc.sel, ranges = startSel.ranges;
-    if (behavior.addNew && !behavior.extend) {
-      ourIndex = doc.sel.contains(start);
-      if (ourIndex > -1)
-        { ourRange = ranges[ourIndex]; }
-      else
-        { ourRange = new Range(start, start); }
-    } else {
-      ourRange = doc.sel.primary();
-      ourIndex = doc.sel.primIndex;
-    }
-
-    if (behavior.unit == "rectangle") {
-      if (!behavior.addNew) { ourRange = new Range(start, start); }
-      start = posFromMouse(cm, event, true, true);
-      ourIndex = -1;
-    } else {
-      var range$$1 = rangeForUnit(cm, start, behavior.unit);
-      if (behavior.extend)
-        { ourRange = extendRange(ourRange, range$$1.anchor, range$$1.head, behavior.extend); }
-      else
-        { ourRange = range$$1; }
-    }
-
-    if (!behavior.addNew) {
-      ourIndex = 0;
-      setSelection(doc, new Selection([ourRange], 0), sel_mouse);
-      startSel = doc.sel;
-    } else if (ourIndex == -1) {
-      ourIndex = ranges.length;
-      setSelection(doc, normalizeSelection(cm, ranges.concat([ourRange]), ourIndex),
-                   {scroll: false, origin: "*mouse"});
-    } else if (ranges.length > 1 && ranges[ourIndex].empty() && behavior.unit == "char" && !behavior.extend) {
-      setSelection(doc, normalizeSelection(cm, ranges.slice(0, ourIndex).concat(ranges.slice(ourIndex + 1)), 0),
-                   {scroll: false, origin: "*mouse"});
-      startSel = doc.sel;
-    } else {
-      replaceOneSelection(doc, ourIndex, ourRange, sel_mouse);
-    }
-
-    var lastPos = start;
-    function extendTo(pos) {
-      if (cmp(lastPos, pos) == 0) { return }
-      lastPos = pos;
-
-      if (behavior.unit == "rectangle") {
-        var ranges = [], tabSize = cm.options.tabSize;
-        var startCol = countColumn(getLine(doc, start.line).text, start.ch, tabSize);
-        var posCol = countColumn(getLine(doc, pos.line).text, pos.ch, tabSize);
-        var left = Math.min(startCol, posCol), right = Math.max(startCol, posCol);
-        for (var line = Math.min(start.line, pos.line), end = Math.min(cm.lastLine(), Math.max(start.line, pos.line));
-             line <= end; line++) {
-          var text = getLine(doc, line).text, leftPos = findColumn(text, left, tabSize);
-          if (left == right)
-            { ranges.push(new Range(Pos(line, leftPos), Pos(line, leftPos))); }
-          else if (text.length > leftPos)
-            { ranges.push(new Range(Pos(line, leftPos), Pos(line, findColumn(text, right, tabSize)))); }
-        }
-        if (!ranges.length) { ranges.push(new Range(start, start)); }
-        setSelection(doc, normalizeSelection(cm, startSel.ranges.slice(0, ourIndex).concat(ranges), ourIndex),
-                     {origin: "*mouse", scroll: false});
-        cm.scrollIntoView(pos);
-      } else {
-        var oldRange = ourRange;
-        var range$$1 = rangeForUnit(cm, pos, behavior.unit);
-        var anchor = oldRange.anchor, head;
-        if (cmp(range$$1.anchor, anchor) > 0) {
-          head = range$$1.head;
-          anchor = minPos(oldRange.from(), range$$1.anchor);
-        } else {
-          head = range$$1.anchor;
-          anchor = maxPos(oldRange.to(), range$$1.head);
-        }
-        var ranges$1 = startSel.ranges.slice(0);
-        ranges$1[ourIndex] = bidiSimplify(cm, new Range(clipPos(doc, anchor), head));
-        setSelection(doc, normalizeSelection(cm, ranges$1, ourIndex), sel_mouse);
-      }
-    }
-
-    var editorSize = display.wrapper.getBoundingClientRect();
-    // Used to ensure timeout re-tries don't fire when another extend
-    // happened in the meantime (clearTimeout isn't reliable -- at
-    // least on Chrome, the timeouts still happen even when cleared,
-    // if the clear happens after their scheduled firing time).
-    var counter = 0;
-
-    function extend(e) {
-      var curCount = ++counter;
-      var cur = posFromMouse(cm, e, true, behavior.unit == "rectangle");
-      if (!cur) { return }
-      if (cmp(cur, lastPos) != 0) {
-        cm.curOp.focus = activeElt();
-        extendTo(cur);
-        var visible = visibleLines(display, doc);
-        if (cur.line >= visible.to || cur.line < visible.from)
-          { setTimeout(operation(cm, function () {if (counter == curCount) { extend(e); }}), 150); }
-      } else {
-        var outside = e.clientY < editorSize.top ? -20 : e.clientY > editorSize.bottom ? 20 : 0;
-        if (outside) { setTimeout(operation(cm, function () {
-          if (counter != curCount) { return }
-          display.scroller.scrollTop += outside;
-          extend(e);
-        }), 50); }
-      }
-    }
-
-    function done(e) {
-      cm.state.selectingText = false;
-      counter = Infinity;
-      // If e is null or undefined we interpret this as someone trying
-      // to explicitly cancel the selection rather than the user
-      // letting go of the mouse button.
-      if (e) {
-        e_preventDefault(e);
-        display.input.focus();
-      }
-      off(display.wrapper.ownerDocument, "mousemove", move);
-      off(display.wrapper.ownerDocument, "mouseup", up);
-      doc.history.lastSelOrigin = null;
-    }
-
-    var move = operation(cm, function (e) {
-      if (e.buttons === 0 || !e_button(e)) { done(e); }
-      else { extend(e); }
-    });
-    var up = operation(cm, done);
-    cm.state.selectingText = up;
-    on(display.wrapper.ownerDocument, "mousemove", move);
-    on(display.wrapper.ownerDocument, "mouseup", up);
-  }
-
-  // Used when mouse-selecting to adjust the anchor to the proper side
-  // of a bidi jump depending on the visual position of the head.
-  function bidiSimplify(cm, range$$1) {
-    var anchor = range$$1.anchor;
-    var head = range$$1.head;
-    var anchorLine = getLine(cm.doc, anchor.line);
-    if (cmp(anchor, head) == 0 && anchor.sticky == head.sticky) { return range$$1 }
-    var order = getOrder(anchorLine);
-    if (!order) { return range$$1 }
-    var index = getBidiPartAt(order, anchor.ch, anchor.sticky), part = order[index];
-    if (part.from != anchor.ch && part.to != anchor.ch) { return range$$1 }
-    var boundary = index + ((part.from == anchor.ch) == (part.level != 1) ? 0 : 1);
-    if (boundary == 0 || boundary == order.length) { return range$$1 }
-
-    // Compute the relative visual position of the head compared to the
-    // anchor (<0 is to the left, >0 to the right)
-    var leftSide;
-    if (head.line != anchor.line) {
-      leftSide = (head.line - anchor.line) * (cm.doc.direction == "ltr" ? 1 : -1) > 0;
-    } else {
-      var headIndex = getBidiPartAt(order, head.ch, head.sticky);
-      var dir = headIndex - index || (head.ch - anchor.ch) * (part.level == 1 ? -1 : 1);
-      if (headIndex == boundary - 1 || headIndex == boundary)
-        { leftSide = dir < 0; }
-      else
-        { leftSide = dir > 0; }
-    }
-
-    var usePart = order[boundary + (leftSide ? -1 : 0)];
-    var from = leftSide == (usePart.level == 1);
-    var ch = from ? usePart.from : usePart.to, sticky = from ? "after" : "before";
-    return anchor.ch == ch && anchor.sticky == sticky ? range$$1 : new Range(new Pos(anchor.line, ch, sticky), head)
-  }
-
-
-  // Determines whether an event happened in the gutter, and fires the
-  // handlers for the corresponding event.
-  function gutterEvent(cm, e, type, prevent) {
-    var mX, mY;
-    if (e.touches) {
-      mX = e.touches[0].clientX;
-      mY = e.touches[0].clientY;
-    } else {
-      try { mX = e.clientX; mY = e.clientY; }
-      catch(e) { return false }
-    }
-    if (mX >= Math.floor(cm.display.gutters.getBoundingClientRect().right)) { return false }
-    if (prevent) { e_preventDefault(e); }
-
-    var display = cm.display;
-    var lineBox = display.lineDiv.getBoundingClientRect();
-
-    if (mY > lineBox.bottom || !hasHandler(cm, type)) { return e_defaultPrevented(e) }
-    mY -= lineBox.top - display.viewOffset;
-
-    for (var i = 0; i < cm.display.gutterSpecs.length; ++i) {
-      var g = display.gutters.childNodes[i];
-      if (g && g.getBoundingClientRect().right >= mX) {
-        var line = lineAtHeight(cm.doc, mY);
-        var gutter = cm.display.gutterSpecs[i];
-        signal(cm, type, cm, line, gutter.className, e);
-        return e_defaultPrevented(e)
-      }
-    }
-  }
-
-  function clickInGutter(cm, e) {
-    return gutterEvent(cm, e, "gutterClick", true)
-  }
-
-  // CONTEXT MENU HANDLING
-
-  // To make the context menu work, we need to briefly unhide the
-  // textarea (making it as unobtrusive as possible) to let the
-  // right-click take effect on it.
-  function onContextMenu(cm, e) {
-    if (eventInWidget(cm.display, e) || contextMenuInGutter(cm, e)) { return }
-    if (signalDOMEvent(cm, e, "contextmenu")) { return }
-    if (!captureRightClick) { cm.display.input.onContextMenu(e); }
-  }
-
-  function contextMenuInGutter(cm, e) {
-    if (!hasHandler(cm, "gutterContextMenu")) { return false }
-    return gutterEvent(cm, e, "gutterContextMenu", false)
-  }
-
-  function themeChanged(cm) {
-    cm.display.wrapper.className = cm.display.wrapper.className.replace(/\s*cm-s-\S+/g, "") +
-      cm.options.theme.replace(/(^|\s)\s*/g, " cm-s-");
-    clearCaches(cm);
-  }
-
-  var Init = {toString: function(){return "CodeMirror.Init"}};
-
-  var defaults = {};
-  var optionHandlers = {};
-
-  function defineOptions(CodeMirror) {
-    var optionHandlers = CodeMirror.optionHandlers;
-
-    function option(name, deflt, handle, notOnInit) {
-      CodeMirror.defaults[name] = deflt;
-      if (handle) { optionHandlers[name] =
-        notOnInit ? function (cm, val, old) {if (old != Init) { handle(cm, val, old); }} : handle; }
-    }
-
-    CodeMirror.defineOption = option;
-
-    // Passed to option handlers when there is no old value.
-    CodeMirror.Init = Init;
-
-    // These two are, on init, called from the constructor because they
-    // have to be initialized before the editor can start at all.
-    option("value", "", function (cm, val) { return cm.setValue(val); }, true);
-    option("mode", null, function (cm, val) {
-      cm.doc.modeOption = val;
-      loadMode(cm);
-    }, true);
-
-    option("indentUnit", 2, loadMode, true);
-    option("indentWithTabs", false);
-    option("smartIndent", true);
-    option("tabSize", 4, function (cm) {
-      resetModeState(cm);
-      clearCaches(cm);
-      regChange(cm);
-    }, true);
-
-    option("lineSeparator", null, function (cm, val) {
-      cm.doc.lineSep = val;
-      if (!val) { return }
-      var newBreaks = [], lineNo = cm.doc.first;
-      cm.doc.iter(function (line) {
-        for (var pos = 0;;) {
-          var found = line.text.indexOf(val, pos);
-          if (found == -1) { break }
-          pos = found + val.length;
-          newBreaks.push(Pos(lineNo, found));
-        }
-        lineNo++;
-      });
-      for (var i = newBreaks.length - 1; i >= 0; i--)
-        { replaceRange(cm.doc, val, newBreaks[i], Pos(newBreaks[i].line, newBreaks[i].ch + val.length)); }
-    });
-    option("specialChars", /[\u0000-\u001f\u007f-\u009f\u00ad\u061c\u200b-\u200f\u2028\u2029\ufeff\ufff9-\ufffc]/g, function (cm, val, old) {
-      cm.state.specialChars = new RegExp(val.source + (val.test("\t") ? "" : "|\t"), "g");
-      if (old != Init) { cm.refresh(); }
-    });
-    option("specialCharPlaceholder", defaultSpecialCharPlaceholder, function (cm) { return cm.refresh(); }, true);
-    option("electricChars", true);
-    option("inputStyle", mobile ? "contenteditable" : "textarea", function () {
-      throw new Error("inputStyle can not (yet) be changed in a running editor") // FIXME
-    }, true);
-    option("spellcheck", false, function (cm, val) { return cm.getInputField().spellcheck = val; }, true);
-    option("autocorrect", false, function (cm, val) { return cm.getInputField().autocorrect = val; }, true);
-    option("autocapitalize", false, function (cm, val) { return cm.getInputField().autocapitalize = val; }, true);
-    option("rtlMoveVisually", !windows);
-    option("wholeLineUpdateBefore", true);
-
-    option("theme", "default", function (cm) {
-      themeChanged(cm);
-      updateGutters(cm);
-    }, true);
-    option("keyMap", "default", function (cm, val, old) {
-      var next = getKeyMap(val);
-      var prev = old != Init && getKeyMap(old);
-      if (prev && prev.detach) { prev.detach(cm, next); }
-      if (next.attach) { next.attach(cm, prev || null); }
-    });
-    option("extraKeys", null);
-    option("configureMouse", null);
-
-    option("lineWrapping", false, wrappingChanged, true);
-    option("gutters", [], function (cm, val) {
-      cm.display.gutterSpecs = getGutters(val, cm.options.lineNumbers);
-      updateGutters(cm);
-    }, true);
-    option("fixedGutter", true, function (cm, val) {
-      cm.display.gutters.style.left = val ? compensateForHScroll(cm.display) + "px" : "0";
-      cm.refresh();
-    }, true);
-    option("coverGutterNextToScrollbar", false, function (cm) { return updateScrollbars(cm); }, true);
-    option("scrollbarStyle", "native", function (cm) {
-      initScrollbars(cm);
-      updateScrollbars(cm);
-      cm.display.scrollbars.setScrollTop(cm.doc.scrollTop);
-      cm.display.scrollbars.setScrollLeft(cm.doc.scrollLeft);
-    }, true);
-    option("lineNumbers", false, function (cm, val) {
-      cm.display.gutterSpecs = getGutters(cm.options.gutters, val);
-      updateGutters(cm);
-    }, true);
-    option("firstLineNumber", 1, updateGutters, true);
-    option("lineNumberFormatter", function (integer) { return integer; }, updateGutters, true);
-    option("showCursorWhenSelecting", false, updateSelection, true);
-
-    option("resetSelectionOnContextMenu", true);
-    option("lineWiseCopyCut", true);
-    option("pasteLinesPerSelection", true);
-    option("selectionsMayTouch", false);
-
-    option("readOnly", false, function (cm, val) {
-      if (val == "nocursor") {
-        onBlur(cm);
-        cm.display.input.blur();
-      }
-      cm.display.input.readOnlyChanged(val);
-    });
-    option("disableInput", false, function (cm, val) {if (!val) { cm.display.input.reset(); }}, true);
-    option("dragDrop", true, dragDropChanged);
-    option("allowDropFileTypes", null);
-
-    option("cursorBlinkRate", 530);
-    option("cursorScrollMargin", 0);
-    option("cursorHeight", 1, updateSelection, true);
-    option("singleCursorHeightPerLine", true, updateSelection, true);
-    option("workTime", 100);
-    option("workDelay", 100);
-    option("flattenSpans", true, resetModeState, true);
-    option("addModeClass", false, resetModeState, true);
-    option("pollInterval", 100);
-    option("undoDepth", 200, function (cm, val) { return cm.doc.history.undoDepth = val; });
-    option("historyEventDelay", 1250);
-    option("viewportMargin", 10, function (cm) { return cm.refresh(); }, true);
-    option("maxHighlightLength", 10000, resetModeState, true);
-    option("moveInputWithCursor", true, function (cm, val) {
-      if (!val) { cm.display.input.resetPosition(); }
-    });
-
-    option("tabindex", null, function (cm, val) { return cm.display.input.getField().tabIndex = val || ""; });
-    option("autofocus", null);
-    option("direction", "ltr", function (cm, val) { return cm.doc.setDirection(val); }, true);
-    option("phrases", null);
-  }
-
-  function dragDropChanged(cm, value, old) {
-    var wasOn = old && old != Init;
-    if (!value != !wasOn) {
-      var funcs = cm.display.dragFunctions;
-      var toggle = value ? on : off;
-      toggle(cm.display.scroller, "dragstart", funcs.start);
-      toggle(cm.display.scroller, "dragenter", funcs.enter);
-      toggle(cm.display.scroller, "dragover", funcs.over);
-      toggle(cm.display.scroller, "dragleave", funcs.leave);
-      toggle(cm.display.scroller, "drop", funcs.drop);
-    }
-  }
-
-  function wrappingChanged(cm) {
-    if (cm.options.lineWrapping) {
-      addClass(cm.display.wrapper, "CodeMirror-wrap");
-      cm.display.sizer.style.minWidth = "";
-      cm.display.sizerWidth = null;
-    } else {
-      rmClass(cm.display.wrapper, "CodeMirror-wrap");
-      findMaxLine(cm);
-    }
-    estimateLineHeights(cm);
-    regChange(cm);
-    clearCaches(cm);
-    setTimeout(function () { return updateScrollbars(cm); }, 100);
-  }
-
-  // A CodeMirror instance represents an editor. This is the object
-  // that user code is usually dealing with.
-
-  function CodeMirror(place, options) {
-    var this$1 = this;
-
-    if (!(this instanceof CodeMirror)) { return new CodeMirror(place, options) }
-
-    this.options = options = options ? copyObj(options) : {};
-    // Determine effective options based on given values and defaults.
-    copyObj(defaults, options, false);
-
-    var doc = options.value;
-    if (typeof doc == "string") { doc = new Doc(doc, options.mode, null, options.lineSeparator, options.direction); }
-    else if (options.mode) { doc.modeOption = options.mode; }
-    this.doc = doc;
-
-    var input = new CodeMirror.inputStyles[options.inputStyle](this);
-    var display = this.display = new Display(place, doc, input, options);
-    display.wrapper.CodeMirror = this;
-    themeChanged(this);
-    if (options.lineWrapping)
-      { this.display.wrapper.className += " CodeMirror-wrap"; }
-    initScrollbars(this);
-
-    this.state = {
-      keyMaps: [],  // stores maps added by addKeyMap
-      overlays: [], // highlighting overlays, as added by addOverlay
-      modeGen: 0,   // bumped when mode/overlay changes, used to invalidate highlighting info
-      overwrite: false,
-      delayingBlurEvent: false,
-      focused: false,
-      suppressEdits: false, // used to disable editing during key handlers when in readOnly mode
-      pasteIncoming: -1, cutIncoming: -1, // help recognize paste/cut edits in input.poll
-      selectingText: false,
-      draggingText: false,
-      highlight: new Delayed(), // stores highlight worker timeout
-      keySeq: null,  // Unfinished key sequence
-      specialChars: null
-    };
-
-    if (options.autofocus && !mobile) { display.input.focus(); }
-
-    // Override magic textarea content restore that IE sometimes does
-    // on our hidden textarea on reload
-    if (ie && ie_version < 11) { setTimeout(function () { return this$1.display.input.reset(true); }, 20); }
-
-    registerEventHandlers(this);
-    ensureGlobalHandlers();
-
-    startOperation(this);
-    this.curOp.forceUpdate = true;
-    attachDoc(this, doc);
-
-    if ((options.autofocus && !mobile) || this.hasFocus())
-      { setTimeout(bind(onFocus, this), 20); }
-    else
-      { onBlur(this); }
-
-    for (var opt in optionHandlers) { if (optionHandlers.hasOwnProperty(opt))
-      { optionHandlers[opt](this$1, options[opt], Init); } }
-    maybeUpdateLineNumberWidth(this);
-    if (options.finishInit) { options.finishInit(this); }
-    for (var i = 0; i < initHooks.length; ++i) { initHooks[i](this$1); }
-    endOperation(this);
-    // Suppress optimizelegibility in Webkit, since it breaks text
-    // measuring on line wrapping boundaries.
-    if (webkit && options.lineWrapping &&
-        getComputedStyle(display.lineDiv).textRendering == "optimizelegibility")
-      { display.lineDiv.style.textRendering = "auto"; }
-  }
-
-  // The default configuration options.
-  CodeMirror.defaults = defaults;
-  // Functions to run when options are changed.
-  CodeMirror.optionHandlers = optionHandlers;
-
-  // Attach the necessary event handlers when initializing the editor
-  function registerEventHandlers(cm) {
-    var d = cm.display;
-    on(d.scroller, "mousedown", operation(cm, onMouseDown));
-    // Older IE's will not fire a second mousedown for a double click
-    if (ie && ie_version < 11)
-      { on(d.scroller, "dblclick", operation(cm, function (e) {
-        if (signalDOMEvent(cm, e)) { return }
-        var pos = posFromMouse(cm, e);
-        if (!pos || clickInGutter(cm, e) || eventInWidget(cm.display, e)) { return }
-        e_preventDefault(e);
-        var word = cm.findWordAt(pos);
-        extendSelection(cm.doc, word.anchor, word.head);
-      })); }
-    else
-      { on(d.scroller, "dblclick", function (e) { return signalDOMEvent(cm, e) || e_preventDefault(e); }); }
-    // Some browsers fire contextmenu *after* opening the menu, at
-    // which point we can't mess with it anymore. Context menu is
-    // handled in onMouseDown for these browsers.
-    on(d.scroller, "contextmenu", function (e) { return onContextMenu(cm, e); });
-
-    // Used to suppress mouse event handling when a touch happens
-    var touchFinished, prevTouch = {end: 0};
-    function finishTouch() {
-      if (d.activeTouch) {
-        touchFinished = setTimeout(function () { return d.activeTouch = null; }, 1000);
-        prevTouch = d.activeTouch;
-        prevTouch.end = +new Date;
-      }
-    }
-    function isMouseLikeTouchEvent(e) {
-      if (e.touches.length != 1) { return false }
-      var touch = e.touches[0];
-      return touch.radiusX <= 1 && touch.radiusY <= 1
-    }
-    function farAway(touch, other) {
-      if (other.left == null) { return true }
-      var dx = other.left - touch.left, dy = other.top - touch.top;
-      return dx * dx + dy * dy > 20 * 20
-    }
-    on(d.scroller, "touchstart", function (e) {
-      if (!signalDOMEvent(cm, e) && !isMouseLikeTouchEvent(e) && !clickInGutter(cm, e)) {
-        d.input.ensurePolled();
-        clearTimeout(touchFinished);
-        var now = +new Date;
-        d.activeTouch = {start: now, moved: false,
-                         prev: now - prevTouch.end <= 300 ? prevTouch : null};
-        if (e.touches.length == 1) {
-          d.activeTouch.left = e.touches[0].pageX;
-          d.activeTouch.top = e.touches[0].pageY;
-        }
-      }
-    });
-    on(d.scroller, "touchmove", function () {
-      if (d.activeTouch) { d.activeTouch.moved = true; }
-    });
-    on(d.scroller, "touchend", function (e) {
-      var touch = d.activeTouch;
-      if (touch && !eventInWidget(d, e) && touch.left != null &&
-          !touch.moved && new Date - touch.start < 300) {
-        var pos = cm.coordsChar(d.activeTouch, "page"), range;
-        if (!touch.prev || farAway(touch, touch.prev)) // Single tap
-          { range = new Range(pos, pos); }
-        else if (!touch.prev.prev || farAway(touch, touch.prev.prev)) // Double tap
-          { range = cm.findWordAt(pos); }
-        else // Triple tap
-          { range = new Range(Pos(pos.line, 0), clipPos(cm.doc, Pos(pos.line + 1, 0))); }
-        cm.setSelection(range.anchor, range.head);
-        cm.focus();
-        e_preventDefault(e);
-      }
-      finishTouch();
-    });
-    on(d.scroller, "touchcancel", finishTouch);
-
-    // Sync scrolling between fake scrollbars and real scrollable
-    // area, ensure viewport is updated when scrolling.
-    on(d.scroller, "scroll", function () {
-      if (d.scroller.clientHeight) {
-        updateScrollTop(cm, d.scroller.scrollTop);
-        setScrollLeft(cm, d.scroller.scrollLeft, true);
-        signal(cm, "scroll", cm);
-      }
-    });
-
-    // Listen to wheel events in order to try and update the viewport on time.
-    on(d.scroller, "mousewheel", function (e) { return onScrollWheel(cm, e); });
-    on(d.scroller, "DOMMouseScroll", function (e) { return onScrollWheel(cm, e); });
-
-    // Prevent wrapper from ever scrolling
-    on(d.wrapper, "scroll", function () { return d.wrapper.scrollTop = d.wrapper.scrollLeft = 0; });
-
-    d.dragFunctions = {
-      enter: function (e) {if (!signalDOMEvent(cm, e)) { e_stop(e); }},
-      over: function (e) {if (!signalDOMEvent(cm, e)) { onDragOver(cm, e); e_stop(e); }},
-      start: function (e) { return onDragStart(cm, e); },
-      drop: operation(cm, onDrop),
-      leave: function (e) {if (!signalDOMEvent(cm, e)) { clearDragCursor(cm); }}
-    };
-
-    var inp = d.input.getField();
-    on(inp, "keyup", function (e) { return onKeyUp.call(cm, e); });
-    on(inp, "keydown", operation(cm, onKeyDown));
-    on(inp, "keypress", operation(cm, onKeyPress));
-    on(inp, "focus", function (e) { return onFocus(cm, e); });
-    on(inp, "blur", function (e) { return onBlur(cm, e); });
-  }
-
-  var initHooks = [];
-  CodeMirror.defineInitHook = function (f) { return initHooks.push(f); };
-
-  // Indent the given line. The how parameter can be "smart",
-  // "add"/null, "subtract", or "prev". When aggressive is false
-  // (typically set to true for forced single-line indents), empty
-  // lines are not indented, and places where the mode returns Pass
-  // are left alone.
-  function indentLine(cm, n, how, aggressive) {
-    var doc = cm.doc, state;
-    if (how == null) { how = "add"; }
-    if (how == "smart") {
-      // Fall back to "prev" when the mode doesn't have an indentation
-      // method.
-      if (!doc.mode.indent) { how = "prev"; }
-      else { state = getContextBefore(cm, n).state; }
-    }
-
-    var tabSize = cm.options.tabSize;
-    var line = getLine(doc, n), curSpace = countColumn(line.text, null, tabSize);
-    if (line.stateAfter) { line.stateAfter = null; }
-    var curSpaceString = line.text.match(/^\s*/)[0], indentation;
-    if (!aggressive && !/\S/.test(line.text)) {
-      indentation = 0;
-      how = "not";
-    } else if (how == "smart") {
-      indentation = doc.mode.indent(state, line.text.slice(curSpaceString.length), line.text);
-      if (indentation == Pass || indentation > 150) {
-        if (!aggressive) { return }
-        how = "prev";
-      }
-    }
-    if (how == "prev") {
-      if (n > doc.first) { indentation = countColumn(getLine(doc, n-1).text, null, tabSize); }
-      else { indentation = 0; }
-    } else if (how == "add") {
-      indentation = curSpace + cm.options.indentUnit;
-    } else if (how == "subtract") {
-      indentation = curSpace - cm.options.indentUnit;
-    } else if (typeof how == "number") {
-      indentation = curSpace + how;
-    }
-    indentation = Math.max(0, indentation);
-
-    var indentString = "", pos = 0;
-    if (cm.options.indentWithTabs)
-      { for (var i = Math.floor(indentation / tabSize); i; --i) {pos += tabSize; indentString += "\t";} }
-    if (pos < indentation) { indentString += spaceStr(indentation - pos); }
-
-    if (indentString != curSpaceString) {
-      replaceRange(doc, indentString, Pos(n, 0), Pos(n, curSpaceString.length), "+input");
-      line.stateAfter = null;
-      return true
-    } else {
-      // Ensure that, if the cursor was in the whitespace at the start
-      // of the line, it is moved to the end of that space.
-      for (var i$1 = 0; i$1 < doc.sel.ranges.length; i$1++) {
-        var range = doc.sel.ranges[i$1];
-        if (range.head.line == n && range.head.ch < curSpaceString.length) {
-          var pos$1 = Pos(n, curSpaceString.length);
-          replaceOneSelection(doc, i$1, new Range(pos$1, pos$1));
-          break
-        }
-      }
-    }
-  }
-
-  // This will be set to a {lineWise: bool, text: [string]} object, so
-  // that, when pasting, we know what kind of selections the copied
-  // text was made out of.
-  var lastCopied = null;
-
-  function setLastCopied(newLastCopied) {
-    lastCopied = newLastCopied;
-  }
-
-  function applyTextInput(cm, inserted, deleted, sel, origin) {
-    var doc = cm.doc;
-    cm.display.shift = false;
-    if (!sel) { sel = doc.sel; }
-
-    var recent = +new Date - 200;
-    var paste = origin == "paste" || cm.state.pasteIncoming > recent;
-    var textLines = splitLinesAuto(inserted), multiPaste = null;
-    // When pasting N lines into N selections, insert one line per selection
-    if (paste && sel.ranges.length > 1) {
-      if (lastCopied && lastCopied.text.join("\n") == inserted) {
-        if (sel.ranges.length % lastCopied.text.length == 0) {
-          multiPaste = [];
-          for (var i = 0; i < lastCopied.text.length; i++)
-            { multiPaste.push(doc.splitLines(lastCopied.text[i])); }
-        }
-      } else if (textLines.length == sel.ranges.length && cm.options.pasteLinesPerSelection) {
-        multiPaste = map(textLines, function (l) { return [l]; });
-      }
-    }
-
-    var updateInput = cm.curOp.updateInput;
-    // Normal behavior is to insert the new text into every selection
-    for (var i$1 = sel.ranges.length - 1; i$1 >= 0; i$1--) {
-      var range$$1 = sel.ranges[i$1];
-      var from = range$$1.from(), to = range$$1.to();
-      if (range$$1.empty()) {
-        if (deleted && deleted > 0) // Handle deletion
-          { from = Pos(from.line, from.ch - deleted); }
-        else if (cm.state.overwrite && !paste) // Handle overwrite
-          { to = Pos(to.line, Math.min(getLine(doc, to.line).text.length, to.ch + lst(textLines).length)); }
-        else if (paste && lastCopied && lastCopied.lineWise && lastCopied.text.join("\n") == inserted)
-          { from = to = Pos(from.line, 0); }
-      }
-      var changeEvent = {from: from, to: to, text: multiPaste ? multiPaste[i$1 % multiPaste.length] : textLines,
-                         origin: origin || (paste ? "paste" : cm.state.cutIncoming > recent ? "cut" : "+input")};
-      makeChange(cm.doc, changeEvent);
-      signalLater(cm, "inputRead", cm, changeEvent);
-    }
-    if (inserted && !paste)
-      { triggerElectric(cm, inserted); }
-
-    ensureCursorVisible(cm);
-    if (cm.curOp.updateInput < 2) { cm.curOp.updateInput = updateInput; }
-    cm.curOp.typing = true;
-    cm.state.pasteIncoming = cm.state.cutIncoming = -1;
-  }
-
-  function handlePaste(e, cm) {
-    var pasted = e.clipboardData && e.clipboardData.getData("Text");
-    if (pasted) {
-      e.preventDefault();
-      if (!cm.isReadOnly() && !cm.options.disableInput)
-        { runInOp(cm, function () { return applyTextInput(cm, pasted, 0, null, "paste"); }); }
-      return true
-    }
-  }
-
-  function triggerElectric(cm, inserted) {
-    // When an 'electric' character is inserted, immediately trigger a reindent
-    if (!cm.options.electricChars || !cm.options.smartIndent) { return }
-    var sel = cm.doc.sel;
-
-    for (var i = sel.ranges.length - 1; i >= 0; i--) {
-      var range$$1 = sel.ranges[i];
-      if (range$$1.head.ch > 100 || (i && sel.ranges[i - 1].head.line == range$$1.head.line)) { continue }
-      var mode = cm.getModeAt(range$$1.head);
-      var indented = false;
-      if (mode.electricChars) {
-        for (var j = 0; j < mode.electricChars.length; j++)
-          { if (inserted.indexOf(mode.electricChars.charAt(j)) > -1) {
-            indented = indentLine(cm, range$$1.head.line, "smart");
-            break
-          } }
-      } else if (mode.electricInput) {
-        if (mode.electricInput.test(getLine(cm.doc, range$$1.head.line).text.slice(0, range$$1.head.ch)))
-          { indented = indentLine(cm, range$$1.head.line, "smart"); }
-      }
-      if (indented) { signalLater(cm, "electricInput", cm, range$$1.head.line); }
-    }
-  }
-
-  function copyableRanges(cm) {
-    var text = [], ranges = [];
-    for (var i = 0; i < cm.doc.sel.ranges.length; i++) {
-      var line = cm.doc.sel.ranges[i].head.line;
-      var lineRange = {anchor: Pos(line, 0), head: Pos(line + 1, 0)};
-      ranges.push(lineRange);
-      text.push(cm.getRange(lineRange.anchor, lineRange.head));
-    }
-    return {text: text, ranges: ranges}
-  }
-
-  function disableBrowserMagic(field, spellcheck, autocorrect, autocapitalize) {
-    field.setAttribute("autocorrect", autocorrect ? "" : "off");
-    field.setAttribute("autocapitalize", autocapitalize ? "" : "off");
-    field.setAttribute("spellcheck", !!spellcheck);
-  }
-
-  function hiddenTextarea() {
-    var te = elt("textarea", null, null, "position: absolute; bottom: -1em; padding: 0; width: 1px; height: 1em; outline: none");
-    var div = elt("div", [te], null, "overflow: hidden; position: relative; width: 3px; height: 0px;");
-    // The textarea is kept positioned near the cursor to prevent the
-    // fact that it'll be scrolled into view on input from scrolling
-    // our fake cursor out of view. On webkit, when wrap=off, paste is
-    // very slow. So make the area wide instead.
-    if (webkit) { te.style.width = "1000px"; }
-    else { te.setAttribute("wrap", "off"); }
-    // If border: 0; -- iOS fails to open keyboard (issue #1287)
-    if (ios) { te.style.border = "1px solid black"; }
-    disableBrowserMagic(te);
-    return div
-  }
-
-  // The publicly visible API. Note that methodOp(f) means
-  // 'wrap f in an operation, performed on its `this` parameter'.
-
-  // This is not the complete set of editor methods. Most of the
-  // methods defined on the Doc type are also injected into
-  // CodeMirror.prototype, for backwards compatibility and
-  // convenience.
-
-  function addEditorMethods(CodeMirror) {
-    var optionHandlers = CodeMirror.optionHandlers;
-
-    var helpers = CodeMirror.helpers = {};
-
-    CodeMirror.prototype = {
-      constructor: CodeMirror,
-      focus: function(){window.focus(); this.display.input.focus();},
-
-      setOption: function(option, value) {
-        var options = this.options, old = options[option];
-        if (options[option] == value && option != "mode") { return }
-        options[option] = value;
-        if (optionHandlers.hasOwnProperty(option))
-          { operation(this, optionHandlers[option])(this, value, old); }
-        signal(this, "optionChange", this, option);
-      },
-
-      getOption: function(option) {return this.options[option]},
-      getDoc: function() {return this.doc},
-
-      addKeyMap: function(map$$1, bottom) {
-        this.state.keyMaps[bottom ? "push" : "unshift"](getKeyMap(map$$1));
-      },
-      removeKeyMap: function(map$$1) {
-        var maps = this.state.keyMaps;
-        for (var i = 0; i < maps.length; ++i)
-          { if (maps[i] == map$$1 || maps[i].name == map$$1) {
-            maps.splice(i, 1);
-            return true
-          } }
-      },
-
-      addOverlay: methodOp(function(spec, options) {
-        var mode = spec.token ? spec : CodeMirror.getMode(this.options, spec);
-        if (mode.startState) { throw new Error("Overlays may not be stateful.") }
-        insertSorted(this.state.overlays,
-                     {mode: mode, modeSpec: spec, opaque: options && options.opaque,
-                      priority: (options && options.priority) || 0},
-                     function (overlay) { return overlay.priority; });
-        this.state.modeGen++;
-        regChange(this);
-      }),
-      removeOverlay: methodOp(function(spec) {
-        var this$1 = this;
-
-        var overlays = this.state.overlays;
-        for (var i = 0; i < overlays.length; ++i) {
-          var cur = overlays[i].modeSpec;
-          if (cur == spec || typeof spec == "string" && cur.name == spec) {
-            overlays.splice(i, 1);
-            this$1.state.modeGen++;
-            regChange(this$1);
-            return
-          }
-        }
-      }),
-
-      indentLine: methodOp(function(n, dir, aggressive) {
-        if (typeof dir != "string" && typeof dir != "number") {
-          if (dir == null) { dir = this.options.smartIndent ? "smart" : "prev"; }
-          else { dir = dir ? "add" : "subtract"; }
-        }
-        if (isLine(this.doc, n)) { indentLine(this, n, dir, aggressive); }
-      }),
-      indentSelection: methodOp(function(how) {
-        var this$1 = this;
-
-        var ranges = this.doc.sel.ranges, end = -1;
-        for (var i = 0; i < ranges.length; i++) {
-          var range$$1 = ranges[i];
-          if (!range$$1.empty()) {
-            var from = range$$1.from(), to = range$$1.to();
-            var start = Math.max(end, from.line);
-            end = Math.min(this$1.lastLine(), to.line - (to.ch ? 0 : 1)) + 1;
-            for (var j = start; j < end; ++j)
-              { indentLine(this$1, j, how); }
-            var newRanges = this$1.doc.sel.ranges;
-            if (from.ch == 0 && ranges.length == newRanges.length && newRanges[i].from().ch > 0)
-              { replaceOneSelection(this$1.doc, i, new Range(from, newRanges[i].to()), sel_dontScroll); }
-          } else if (range$$1.head.line > end) {
-            indentLine(this$1, range$$1.head.line, how, true);
-            end = range$$1.head.line;
-            if (i == this$1.doc.sel.primIndex) { ensureCursorVisible(this$1); }
-          }
-        }
-      }),
-
-      // Fetch the parser token for a given character. Useful for hacks
-      // that want to inspect the mode state (say, for completion).
-      getTokenAt: function(pos, precise) {
-        return takeToken(this, pos, precise)
-      },
-
-      getLineTokens: function(line, precise) {
-        return takeToken(this, Pos(line), precise, true)
-      },
-
-      getTokenTypeAt: function(pos) {
-        pos = clipPos(this.doc, pos);
-        var styles = getLineStyles(this, getLine(this.doc, pos.line));
-        var before = 0, after = (styles.length - 1) / 2, ch = pos.ch;
-        var type;
-        if (ch == 0) { type = styles[2]; }
-        else { for (;;) {
-          var mid = (before + after) >> 1;
-          if ((mid ? styles[mid * 2 - 1] : 0) >= ch) { after = mid; }
-          else if (styles[mid * 2 + 1] < ch) { before = mid + 1; }
-          else { type = styles[mid * 2 + 2]; break }
-        } }
-        var cut = type ? type.indexOf("overlay ") : -1;
-        return cut < 0 ? type : cut == 0 ? null : type.slice(0, cut - 1)
-      },
-
-      getModeAt: function(pos) {
-        var mode = this.doc.mode;
-        if (!mode.innerMode) { return mode }
-        return CodeMirror.innerMode(mode, this.getTokenAt(pos).state).mode
-      },
-
-      getHelper: function(pos, type) {
-        return this.getHelpers(pos, type)[0]
-      },
-
-      getHelpers: function(pos, type) {
-        var this$1 = this;
-
-        var found = [];
-        if (!helpers.hasOwnProperty(type)) { return found }
-        var help = helpers[type], mode = this.getModeAt(pos);
-        if (typeof mode[type] == "string") {
-          if (help[mode[type]]) { found.push(help[mode[type]]); }
-        } else if (mode[type]) {
-          for (var i = 0; i < mode[type].length; i++) {
-            var val = help[mode[type][i]];
-            if (val) { found.push(val); }
-          }
-        } else if (mode.helperType && help[mode.helperType]) {
-          found.push(help[mode.helperType]);
-        } else if (help[mode.name]) {
-          found.push(help[mode.name]);
-        }
-        for (var i$1 = 0; i$1 < help._global.length; i$1++) {
-          var cur = help._global[i$1];
-          if (cur.pred(mode, this$1) && indexOf(found, cur.val) == -1)
-            { found.push(cur.val); }
-        }
-        return found
-      },
-
-      getStateAfter: function(line, precise) {
-        var doc = this.doc;
-        line = clipLine(doc, line == null ? doc.first + doc.size - 1: line);
-        return getContextBefore(this, line + 1, precise).state
-      },
-
-      cursorCoords: function(start, mode) {
-        var pos, range$$1 = this.doc.sel.primary();
-        if (start == null) { pos = range$$1.head; }
-        else if (typeof start == "object") { pos = clipPos(this.doc, start); }
-        else { pos = start ? range$$1.from() : range$$1.to(); }
-        return cursorCoords(this, pos, mode || "page")
-      },
-
-      charCoords: function(pos, mode) {
-        return charCoords(this, clipPos(this.doc, pos), mode || "page")
-      },
-
-      coordsChar: function(coords, mode) {
-        coords = fromCoordSystem(this, coords, mode || "page");
-        return coordsChar(this, coords.left, coords.top)
-      },
-
-      lineAtHeight: function(height, mode) {
-        height = fromCoordSystem(this, {top: height, left: 0}, mode || "page").top;
-        return lineAtHeight(this.doc, height + this.display.viewOffset)
-      },
-      heightAtLine: function(line, mode, includeWidgets) {
-        var end = false, lineObj;
-        if (typeof line == "number") {
-          var last = this.doc.first + this.doc.size - 1;
-          if (line < this.doc.first) { line = this.doc.first; }
-          else if (line > last) { line = last; end = true; }
-          lineObj = getLine(this.doc, line);
-        } else {
-          lineObj = line;
-        }
-        return intoCoordSystem(this, lineObj, {top: 0, left: 0}, mode || "page", includeWidgets || end).top +
-          (end ? this.doc.height - heightAtLine(lineObj) : 0)
-      },
-
-      defaultTextHeight: function() { return textHeight(this.display) },
-      defaultCharWidth: function() { return charWidth(this.display) },
-
-      getViewport: function() { return {from: this.display.viewFrom, to: this.display.viewTo}},
-
-      addWidget: function(pos, node, scroll, vert, horiz) {
-        var display = this.display;
-        pos = cursorCoords(this, clipPos(this.doc, pos));
-        var top = pos.bottom, left = pos.left;
-        node.style.position = "absolute";
-        node.setAttribute("cm-ignore-events", "true");
-        this.display.input.setUneditable(node);
-        display.sizer.appendChild(node);
-        if (vert == "over") {
-          top = pos.top;
-        } else if (vert == "above" || vert == "near") {
-          var vspace = Math.max(display.wrapper.clientHeight, this.doc.height),
-          hspace = Math.max(display.sizer.clientWidth, display.lineSpace.clientWidth);
-          // Default to positioning above (if specified and possible); otherwise default to positioning below
-          if ((vert == 'above' || pos.bottom + node.offsetHeight > vspace) && pos.top > node.offsetHeight)
-            { top = pos.top - node.offsetHeight; }
-          else if (pos.bottom + node.offsetHeight <= vspace)
-            { top = pos.bottom; }
-          if (left + node.offsetWidth > hspace)
-            { left = hspace - node.offsetWidth; }
-        }
-        node.style.top = top + "px";
-        node.style.left = node.style.right = "";
-        if (horiz == "right") {
-          left = display.sizer.clientWidth - node.offsetWidth;
-          node.style.right = "0px";
-        } else {
-          if (horiz == "left") { left = 0; }
-          else if (horiz == "middle") { left = (display.sizer.clientWidth - node.offsetWidth) / 2; }
-          node.style.left = left + "px";
-        }
-        if (scroll)
-          { scrollIntoView(this, {left: left, top: top, right: left + node.offsetWidth, bottom: top + node.offsetHeight}); }
-      },
-
-      triggerOnKeyDown: methodOp(onKeyDown),
-      triggerOnKeyPress: methodOp(onKeyPress),
-      triggerOnKeyUp: onKeyUp,
-      triggerOnMouseDown: methodOp(onMouseDown),
-
-      execCommand: function(cmd) {
-        if (commands.hasOwnProperty(cmd))
-          { return commands[cmd].call(null, this) }
-      },
-
-      triggerElectric: methodOp(function(text) { triggerElectric(this, text); }),
-
-      findPosH: function(from, amount, unit, visually) {
-        var this$1 = this;
-
-        var dir = 1;
-        if (amount < 0) { dir = -1; amount = -amount; }
-        var cur = clipPos(this.doc, from);
-        for (var i = 0; i < amount; ++i) {
-          cur = findPosH(this$1.doc, cur, dir, unit, visually);
-          if (cur.hitSide) { break }
-        }
-        return cur
-      },
-
-      moveH: methodOp(function(dir, unit) {
-        var this$1 = this;
-
-        this.extendSelectionsBy(function (range$$1) {
-          if (this$1.display.shift || this$1.doc.extend || range$$1.empty())
-            { return findPosH(this$1.doc, range$$1.head, dir, unit, this$1.options.rtlMoveVisually) }
-          else
-            { return dir < 0 ? range$$1.from() : range$$1.to() }
-        }, sel_move);
-      }),
-
-      deleteH: methodOp(function(dir, unit) {
-        var sel = this.doc.sel, doc = this.doc;
-        if (sel.somethingSelected())
-          { doc.replaceSelection("", null, "+delete"); }
-        else
-          { deleteNearSelection(this, function (range$$1) {
-            var other = findPosH(doc, range$$1.head, dir, unit, false);
-            return dir < 0 ? {from: other, to: range$$1.head} : {from: range$$1.head, to: other}
-          }); }
-      }),
-
-      findPosV: function(from, amount, unit, goalColumn) {
-        var this$1 = this;
-
-        var dir = 1, x = goalColumn;
-        if (amount < 0) { dir = -1; amount = -amount; }
-        var cur = clipPos(this.doc, from);
-        for (var i = 0; i < amount; ++i) {
-          var coords = cursorCoords(this$1, cur, "div");
-          if (x == null) { x = coords.left; }
-          else { coords.left = x; }
-          cur = findPosV(this$1, coords, dir, unit);
-          if (cur.hitSide) { break }
-        }
-        return cur
-      },
-
-      moveV: methodOp(function(dir, unit) {
-        var this$1 = this;
-
-        var doc = this.doc, goals = [];
-        var collapse = !this.display.shift && !doc.extend && doc.sel.somethingSelected();
-        doc.extendSelectionsBy(function (range$$1) {
-          if (collapse)
-            { return dir < 0 ? range$$1.from() : range$$1.to() }
-          var headPos = cursorCoords(this$1, range$$1.head, "div");
-          if (range$$1.goalColumn != null) { headPos.left = range$$1.goalColumn; }
-          goals.push(headPos.left);
-          var pos = findPosV(this$1, headPos, dir, unit);
-          if (unit == "page" && range$$1 == doc.sel.primary())
-            { addToScrollTop(this$1, charCoords(this$1, pos, "div").top - headPos.top); }
-          return pos
-        }, sel_move);
-        if (goals.length) { for (var i = 0; i < doc.sel.ranges.length; i++)
-          { doc.sel.ranges[i].goalColumn = goals[i]; } }
-      }),
-
-      // Find the word at the given position (as returned by coordsChar).
-      findWordAt: function(pos) {
-        var doc = this.doc, line = getLine(doc, pos.line).text;
-        var start = pos.ch, end = pos.ch;
-        if (line) {
-          var helper = this.getHelper(pos, "wordChars");
-          if ((pos.sticky == "before" || end == line.length) && start) { --start; } else { ++end; }
-          var startChar = line.charAt(start);
-          var check = isWordChar(startChar, helper)
-            ? function (ch) { return isWordChar(ch, helper); }
-            : /\s/.test(startChar) ? function (ch) { return /\s/.test(ch); }
-            : function (ch) { return (!/\s/.test(ch) && !isWordChar(ch)); };
-          while (start > 0 && check(line.charAt(start - 1))) { --start; }
-          while (end < line.length && check(line.charAt(end))) { ++end; }
-        }
-        return new Range(Pos(pos.line, start), Pos(pos.line, end))
-      },
-
-      toggleOverwrite: function(value) {
-        if (value != null && value == this.state.overwrite) { return }
-        if (this.state.overwrite = !this.state.overwrite)
-          { addClass(this.display.cursorDiv, "CodeMirror-overwrite"); }
-        else
-          { rmClass(this.display.cursorDiv, "CodeMirror-overwrite"); }
-
-        signal(this, "overwriteToggle", this, this.state.overwrite);
-      },
-      hasFocus: function() { return this.display.input.getField() == activeElt() },
-      isReadOnly: function() { return !!(this.options.readOnly || this.doc.cantEdit) },
-
-      scrollTo: methodOp(function (x, y) { scrollToCoords(this, x, y); }),
-      getScrollInfo: function() {
-        var scroller = this.display.scroller;
-        return {left: scroller.scrollLeft, top: scroller.scrollTop,
-                height: scroller.scrollHeight - scrollGap(this) - this.display.barHeight,
-                width: scroller.scrollWidth - scrollGap(this) - this.display.barWidth,
-                clientHeight: displayHeight(this), clientWidth: displayWidth(this)}
-      },
-
-      scrollIntoView: methodOp(function(range$$1, margin) {
-        if (range$$1 == null) {
-          range$$1 = {from: this.doc.sel.primary().head, to: null};
-          if (margin == null) { margin = this.options.cursorScrollMargin; }
-        } else if (typeof range$$1 == "number") {
-          range$$1 = {from: Pos(range$$1, 0), to: null};
-        } else if (range$$1.from == null) {
-          range$$1 = {from: range$$1, to: null};
-        }
-        if (!range$$1.to) { range$$1.to = range$$1.from; }
-        range$$1.margin = margin || 0;
-
-        if (range$$1.from.line != null) {
-          scrollToRange(this, range$$1);
-        } else {
-          scrollToCoordsRange(this, range$$1.from, range$$1.to, range$$1.margin);
-        }
-      }),
-
-      setSize: methodOp(function(width, height) {
-        var this$1 = this;
-
-        var interpret = function (val) { return typeof val == "number" || /^\d+$/.test(String(val)) ? val + "px" : val; };
-        if (width != null) { this.display.wrapper.style.width = interpret(width); }
-        if (height != null) { this.display.wrapper.style.height = interpret(height); }
-        if (this.options.lineWrapping) { clearLineMeasurementCache(this); }
-        var lineNo$$1 = this.display.viewFrom;
-        this.doc.iter(lineNo$$1, this.display.viewTo, function (line) {
-          if (line.widgets) { for (var i = 0; i < line.widgets.length; i++)
-            { if (line.widgets[i].noHScroll) { regLineChange(this$1, lineNo$$1, "widget"); break } } }
-          ++lineNo$$1;
-        });
-        this.curOp.forceUpdate = true;
-        signal(this, "refresh", this);
-      }),
-
-      operation: function(f){return runInOp(this, f)},
-      startOperation: function(){return startOperation(this)},
-      endOperation: function(){return endOperation(this)},
-
-      refresh: methodOp(function() {
-        var oldHeight = this.display.cachedTextHeight;
-        regChange(this);
-        this.curOp.forceUpdate = true;
-        clearCaches(this);
-        scrollToCoords(this, this.doc.scrollLeft, this.doc.scrollTop);
-        updateGutterSpace(this.display);
-        if (oldHeight == null || Math.abs(oldHeight - textHeight(this.display)) > .5)
-          { estimateLineHeights(this); }
-        signal(this, "refresh", this);
-      }),
-
-      swapDoc: methodOp(function(doc) {
-        var old = this.doc;
-        old.cm = null;
-        // Cancel the current text selection if any (#5821)
-        if (this.state.selectingText) { this.state.selectingText(); }
-        attachDoc(this, doc);
-        clearCaches(this);
-        this.display.input.reset();
-        scrollToCoords(this, doc.scrollLeft, doc.scrollTop);
-        this.curOp.forceScroll = true;
-        signalLater(this, "swapDoc", this, old);
-        return old
-      }),
-
-      phrase: function(phraseText) {
-        var phrases = this.options.phrases;
-        return phrases && Object.prototype.hasOwnProperty.call(phrases, phraseText) ? phrases[phraseText] : phraseText
-      },
-
-      getInputField: function(){return this.display.input.getField()},
-      getWrapperElement: function(){return this.display.wrapper},
-      getScrollerElement: function(){return this.display.scroller},
-      getGutterElement: function(){return this.display.gutters}
-    };
-    eventMixin(CodeMirror);
-
-    CodeMirror.registerHelper = function(type, name, value) {
-      if (!helpers.hasOwnProperty(type)) { helpers[type] = CodeMirror[type] = {_global: []}; }
-      helpers[type][name] = value;
-    };
-    CodeMirror.registerGlobalHelper = function(type, name, predicate, value) {
-      CodeMirror.registerHelper(type, name, value);
-      helpers[type]._global.push({pred: predicate, val: value});
-    };
-  }
-
-  // Used for horizontal relative motion. Dir is -1 or 1 (left or
-  // right), unit can be "char", "column" (like char, but doesn't
-  // cross line boundaries), "word" (across next word), or "group" (to
-  // the start of next group of word or non-word-non-whitespace
-  // chars). The visually param controls whether, in right-to-left
-  // text, direction 1 means to move towards the next index in the
-  // string, or towards the character to the right of the current
-  // position. The resulting position will have a hitSide=true
-  // property if it reached the end of the document.
-  function findPosH(doc, pos, dir, unit, visually) {
-    var oldPos = pos;
-    var origDir = dir;
-    var lineObj = getLine(doc, pos.line);
-    function findNextLine() {
-      var l = pos.line + dir;
-      if (l < doc.first || l >= doc.first + doc.size) { return false }
-      pos = new Pos(l, pos.ch, pos.sticky);
-      return lineObj = getLine(doc, l)
-    }
-    function moveOnce(boundToLine) {
-      var next;
-      if (visually) {
-        next = moveVisually(doc.cm, lineObj, pos, dir);
-      } else {
-        next = moveLogically(lineObj, pos, dir);
-      }
-      if (next == null) {
-        if (!boundToLine && findNextLine())
-          { pos = endOfLine(visually, doc.cm, lineObj, pos.line, dir); }
-        else
-          { return false }
-      } else {
-        pos = next;
-      }
-      return true
-    }
-
-    if (unit == "char") {
-      moveOnce();
-    } else if (unit == "column") {
-      moveOnce(true);
-    } else if (unit == "word" || unit == "group") {
-      var sawType = null, group = unit == "group";
-      var helper = doc.cm && doc.cm.getHelper(pos, "wordChars");
-      for (var first = true;; first = false) {
-        if (dir < 0 && !moveOnce(!first)) { break }
-        var cur = lineObj.text.charAt(pos.ch) || "\n";
-        var type = isWordChar(cur, helper) ? "w"
-          : group && cur == "\n" ? "n"
-          : !group || /\s/.test(cur) ? null
-          : "p";
-        if (group && !first && !type) { type = "s"; }
-        if (sawType && sawType != type) {
-          if (dir < 0) {dir = 1; moveOnce(); pos.sticky = "after";}
-          break
-        }
-
-        if (type) { sawType = type; }
-        if (dir > 0 && !moveOnce(!first)) { break }
-      }
-    }
-    var result = skipAtomic(doc, pos, oldPos, origDir, true);
-    if (equalCursorPos(oldPos, result)) { result.hitSide = true; }
-    return result
-  }
-
-  // For relative vertical movement. Dir may be -1 or 1. Unit can be
-  // "page" or "line". The resulting position will have a hitSide=true
-  // property if it reached the end of the document.
-  function findPosV(cm, pos, dir, unit) {
-    var doc = cm.doc, x = pos.left, y;
-    if (unit == "page") {
-      var pageSize = Math.min(cm.display.wrapper.clientHeight, window.innerHeight || document.documentElement.clientHeight);
-      var moveAmount = Math.max(pageSize - .5 * textHeight(cm.display), 3);
-      y = (dir > 0 ? pos.bottom : pos.top) + dir * moveAmount;
-
-    } else if (unit == "line") {
-      y = dir > 0 ? pos.bottom + 3 : pos.top - 3;
-    }
-    var target;
-    for (;;) {
-      target = coordsChar(cm, x, y);
-      if (!target.outside) { break }
-      if (dir < 0 ? y <= 0 : y >= doc.height) { target.hitSide = true; break }
-      y += dir * 5;
-    }
-    return target
-  }
-
-  // CONTENTEDITABLE INPUT STYLE
-
-  var ContentEditableInput = function(cm) {
-    this.cm = cm;
-    this.lastAnchorNode = this.lastAnchorOffset = this.lastFocusNode = this.lastFocusOffset = null;
-    this.polling = new Delayed();
-    this.composing = null;
-    this.gracePeriod = false;
-    this.readDOMTimeout = null;
-  };
-
-  ContentEditableInput.prototype.init = function (display) {
-      var this$1 = this;
-
-    var input = this, cm = input.cm;
-    var div = input.div = display.lineDiv;
-    disableBrowserMagic(div, cm.options.spellcheck, cm.options.autocorrect, cm.options.autocapitalize);
-
-    on(div, "paste", function (e) {
-      if (signalDOMEvent(cm, e) || handlePaste(e, cm)) { return }
-      // IE doesn't fire input events, so we schedule a read for the pasted content in this way
-      if (ie_version <= 11) { setTimeout(operation(cm, function () { return this$1.updateFromDOM(); }), 20); }
-    });
-
-    on(div, "compositionstart", function (e) {
-      this$1.composing = {data: e.data, done: false};
-    });
-    on(div, "compositionupdate", function (e) {
-      if (!this$1.composing) { this$1.composing = {data: e.data, done: false}; }
-    });
-    on(div, "compositionend", function (e) {
-      if (this$1.composing) {
-        if (e.data != this$1.composing.data) { this$1.readFromDOMSoon(); }
-        this$1.composing.done = true;
-      }
-    });
-
-    on(div, "touchstart", function () { return input.forceCompositionEnd(); });
-
-    on(div, "input", function () {
-      if (!this$1.composing) { this$1.readFromDOMSoon(); }
-    });
-
-    function onCopyCut(e) {
-      if (signalDOMEvent(cm, e)) { return }
-      if (cm.somethingSelected()) {
-        setLastCopied({lineWise: false, text: cm.getSelections()});
-        if (e.type == "cut") { cm.replaceSelection("", null, "cut"); }
-      } else if (!cm.options.lineWiseCopyCut) {
-        return
-      } else {
-        var ranges = copyableRanges(cm);
-        setLastCopied({lineWise: true, text: ranges.text});
-        if (e.type == "cut") {
-          cm.operation(function () {
-            cm.setSelections(ranges.ranges, 0, sel_dontScroll);
-            cm.replaceSelection("", null, "cut");
-          });
-        }
-      }
-      if (e.clipboardData) {
-        e.clipboardData.clearData();
-        var content = lastCopied.text.join("\n");
-        // iOS exposes the clipboard API, but seems to discard content inserted into it
-        e.clipboardData.setData("Text", content);
-        if (e.clipboardData.getData("Text") == content) {
-          e.preventDefault();
-          return
-        }
-      }
-      // Old-fashioned briefly-focus-a-textarea hack
-      var kludge = hiddenTextarea(), te = kludge.firstChild;
-      cm.display.lineSpace.insertBefore(kludge, cm.display.lineSpace.firstChild);
-      te.value = lastCopied.text.join("\n");
-      var hadFocus = document.activeElement;
-      selectInput(te);
-      setTimeout(function () {
-        cm.display.lineSpace.removeChild(kludge);
-        hadFocus.focus();
-        if (hadFocus == div) { input.showPrimarySelection(); }
-      }, 50);
-    }
-    on(div, "copy", onCopyCut);
-    on(div, "cut", onCopyCut);
-  };
-
-  ContentEditableInput.prototype.prepareSelection = function () {
-    var result = prepareSelection(this.cm, false);
-    result.focus = this.cm.state.focused;
-    return result
-  };
-
-  ContentEditableInput.prototype.showSelection = function (info, takeFocus) {
-    if (!info || !this.cm.display.view.length) { return }
-    if (info.focus || takeFocus) { this.showPrimarySelection(); }
-    this.showMultipleSelections(info);
-  };
-
-  ContentEditableInput.prototype.getSelection = function () {
-    return this.cm.display.wrapper.ownerDocument.getSelection()
-  };
-
-  ContentEditableInput.prototype.showPrimarySelection = function () {
-    var sel = this.getSelection(), cm = this.cm, prim = cm.doc.sel.primary();
-    var from = prim.from(), to = prim.to();
-
-    if (cm.display.viewTo == cm.display.viewFrom || from.line >= cm.display.viewTo || to.line < cm.display.viewFrom) {
-      sel.removeAllRanges();
-      return
-    }
-
-    var curAnchor = domToPos(cm, sel.anchorNode, sel.anchorOffset);
-    var curFocus = domToPos(cm, sel.focusNode, sel.focusOffset);
-    if (curAnchor && !curAnchor.bad && curFocus && !curFocus.bad &&
-        cmp(minPos(curAnchor, curFocus), from) == 0 &&
-        cmp(maxPos(curAnchor, curFocus), to) == 0)
-      { return }
-
-    var view = cm.display.view;
-    var start = (from.line >= cm.display.viewFrom && posToDOM(cm, from)) ||
-        {node: view[0].measure.map[2], offset: 0};
-    var end = to.line < cm.display.viewTo && posToDOM(cm, to);
-    if (!end) {
-      var measure = view[view.length - 1].measure;
-      var map$$1 = measure.maps ? measure.maps[measure.maps.length - 1] : measure.map;
-      end = {node: map$$1[map$$1.length - 1], offset: map$$1[map$$1.length - 2] - map$$1[map$$1.length - 3]};
-    }
-
-    if (!start || !end) {
-      sel.removeAllRanges();
-      return
-    }
-
-    var old = sel.rangeCount && sel.getRangeAt(0), rng;
-    try { rng = range(start.node, start.offset, end.offset, end.node); }
-    catch(e) {} // Our model of the DOM might be outdated, in which case the range we try to set can be impossible
-    if (rng) {
-      if (!gecko && cm.state.focused) {
-        sel.collapse(start.node, start.offset);
-        if (!rng.collapsed) {
-          sel.removeAllRanges();
-          sel.addRange(rng);
-        }
-      } else {
-        sel.removeAllRanges();
-        sel.addRange(rng);
-      }
-      if (old && sel.anchorNode == null) { sel.addRange(old); }
-      else if (gecko) { this.startGracePeriod(); }
-    }
-    this.rememberSelection();
-  };
-
-  ContentEditableInput.prototype.startGracePeriod = function () {
-      var this$1 = this;
-
-    clearTimeout(this.gracePeriod);
-    this.gracePeriod = setTimeout(function () {
-      this$1.gracePeriod = false;
-      if (this$1.selectionChanged())
-        { this$1.cm.operation(function () { return this$1.cm.curOp.selectionChanged = true; }); }
-    }, 20);
-  };
-
-  ContentEditableInput.prototype.showMultipleSelections = function (info) {
-    removeChildrenAndAdd(this.cm.display.cursorDiv, info.cursors);
-    removeChildrenAndAdd(this.cm.display.selectionDiv, info.selection);
-  };
-
-  ContentEditableInput.prototype.rememberSelection = function () {
-    var sel = this.getSelection();
-    this.lastAnchorNode = sel.anchorNode; this.lastAnchorOffset = sel.anchorOffset;
-    this.lastFocusNode = sel.focusNode; this.lastFocusOffset = sel.focusOffset;
-  };
-
-  ContentEditableInput.prototype.selectionInEditor = function () {
-    var sel = this.getSelection();
-    if (!sel.rangeCount) { return false }
-    var node = sel.getRangeAt(0).commonAncestorContainer;
-    return contains(this.div, node)
-  };
-
-  ContentEditableInput.prototype.focus = function () {
-    if (this.cm.options.readOnly != "nocursor") {
-      if (!this.selectionInEditor())
-        { this.showSelection(this.prepareSelection(), true); }
-      this.div.focus();
-    }
-  };
-  ContentEditableInput.prototype.blur = function () { this.div.blur(); };
-  ContentEditableInput.prototype.getField = function () { return this.div };
-
-  ContentEditableInput.prototype.supportsTouch = function () { return true };
-
-  ContentEditableInput.prototype.receivedFocus = function () {
-    var input = this;
-    if (this.selectionInEditor())
-      { this.pollSelection(); }
-    else
-      { runInOp(this.cm, function () { return input.cm.curOp.selectionChanged = true; }); }
-
-    function poll() {
-      if (input.cm.state.focused) {
-        input.pollSelection();
-        input.polling.set(input.cm.options.pollInterval, poll);
-      }
-    }
-    this.polling.set(this.cm.options.pollInterval, poll);
-  };
-
-  ContentEditableInput.prototype.selectionChanged = function () {
-    var sel = this.getSelection();
-    return sel.anchorNode != this.lastAnchorNode || sel.anchorOffset != this.lastAnchorOffset ||
-      sel.focusNode != this.lastFocusNode || sel.focusOffset != this.lastFocusOffset
-  };
-
-  ContentEditableInput.prototype.pollSelection = function () {
-    if (this.readDOMTimeout != null || this.gracePeriod || !this.selectionChanged()) { return }
-    var sel = this.getSelection(), cm = this.cm;
-    // On Android Chrome (version 56, at least), backspacing into an
-    // uneditable block element will put the cursor in that element,
-    // and then, because it's not editable, hide the virtual keyboard.
-    // Because Android doesn't allow us to actually detect backspace
-    // presses in a sane way, this code checks for when that happens
-    // and simulates a backspace press in this case.
-    if (android && chrome && this.cm.display.gutterSpecs.length && isInGutter(sel.anchorNode)) {
-      this.cm.triggerOnKeyDown({type: "keydown", keyCode: 8, preventDefault: Math.abs});
-      this.blur();
-      this.focus();
-      return
-    }
-    if (this.composing) { return }
-    this.rememberSelection();
-    var anchor = domToPos(cm, sel.anchorNode, sel.anchorOffset);
-    var head = domToPos(cm, sel.focusNode, sel.focusOffset);
-    if (anchor && head) { runInOp(cm, function () {
-      setSelection(cm.doc, simpleSelection(anchor, head), sel_dontScroll);
-      if (anchor.bad || head.bad) { cm.curOp.selectionChanged = true; }
-    }); }
-  };
-
-  ContentEditableInput.prototype.pollContent = function () {
-    if (this.readDOMTimeout != null) {
-      clearTimeout(this.readDOMTimeout);
-      this.readDOMTimeout = null;
-    }
-
-    var cm = this.cm, display = cm.display, sel = cm.doc.sel.primary();
-    var from = sel.from(), to = sel.to();
-    if (from.ch == 0 && from.line > cm.firstLine())
-      { from = Pos(from.line - 1, getLine(cm.doc, from.line - 1).length); }
-    if (to.ch == getLine(cm.doc, to.line).text.length && to.line < cm.lastLine())
-      { to = Pos(to.line + 1, 0); }
-    if (from.line < display.viewFrom || to.line > display.viewTo - 1) { return false }
-
-    var fromIndex, fromLine, fromNode;
-    if (from.line == display.viewFrom || (fromIndex = findViewIndex(cm, from.line)) == 0) {
-      fromLine = lineNo(display.view[0].line);
-      fromNode = display.view[0].node;
-    } else {
-      fromLine = lineNo(display.view[fromIndex].line);
-      fromNode = display.view[fromIndex - 1].node.nextSibling;
-    }
-    var toIndex = findViewIndex(cm, to.line);
-    var toLine, toNode;
-    if (toIndex == display.view.length - 1) {
-      toLine = display.viewTo - 1;
-      toNode = display.lineDiv.lastChild;
-    } else {
-      toLine = lineNo(display.view[toIndex + 1].line) - 1;
-      toNode = display.view[toIndex + 1].node.previousSibling;
-    }
-
-    if (!fromNode) { return false }
-    var newText = cm.doc.splitLines(domTextBetween(cm, fromNode, toNode, fromLine, toLine));
-    var oldText = getBetween(cm.doc, Pos(fromLine, 0), Pos(toLine, getLine(cm.doc, toLine).text.length));
-    while (newText.length > 1 && oldText.length > 1) {
-      if (lst(newText) == lst(oldText)) { newText.pop(); oldText.pop(); toLine--; }
-      else if (newText[0] == oldText[0]) { newText.shift(); oldText.shift(); fromLine++; }
-      else { break }
-    }
-
-    var cutFront = 0, cutEnd = 0;
-    var newTop = newText[0], oldTop = oldText[0], maxCutFront = Math.min(newTop.length, oldTop.length);
-    while (cutFront < maxCutFront && newTop.charCodeAt(cutFront) == oldTop.charCodeAt(cutFront))
-      { ++cutFront; }
-    var newBot = lst(newText), oldBot = lst(oldText);
-    var maxCutEnd = Math.min(newBot.length - (newText.length == 1 ? cutFront : 0),
-                             oldBot.length - (oldText.length == 1 ? cutFront : 0));
-    while (cutEnd < maxCutEnd &&
-           newBot.charCodeAt(newBot.length - cutEnd - 1) == oldBot.charCodeAt(oldBot.length - cutEnd - 1))
-      { ++cutEnd; }
-    // Try to move start of change to start of selection if ambiguous
-    if (newText.length == 1 && oldText.length == 1 && fromLine == from.line) {
-      while (cutFront && cutFront > from.ch &&
-             newBot.charCodeAt(newBot.length - cutEnd - 1) == oldBot.charCodeAt(oldBot.length - cutEnd - 1)) {
-        cutFront--;
-        cutEnd++;
-      }
-    }
-
-    newText[newText.length - 1] = newBot.slice(0, newBot.length - cutEnd).replace(/^\u200b+/, "");
-    newText[0] = newText[0].slice(cutFront).replace(/\u200b+$/, "");
-
-    var chFrom = Pos(fromLine, cutFront);
-    var chTo = Pos(toLine, oldText.length ? lst(oldText).length - cutEnd : 0);
-    if (newText.length > 1 || newText[0] || cmp(chFrom, chTo)) {
-      replaceRange(cm.doc, newText, chFrom, chTo, "+input");
-      return true
-    }
-  };
-
-  ContentEditableInput.prototype.ensurePolled = function () {
-    this.forceCompositionEnd();
-  };
-  ContentEditableInput.prototype.reset = function () {
-    this.forceCompositionEnd();
-  };
-  ContentEditableInput.prototype.forceCompositionEnd = function () {
-    if (!this.composing) { return }
-    clearTimeout(this.readDOMTimeout);
-    this.composing = null;
-    this.updateFromDOM();
-    this.div.blur();
-    this.div.focus();
-  };
-  ContentEditableInput.prototype.readFromDOMSoon = function () {
-      var this$1 = this;
-
-    if (this.readDOMTimeout != null) { return }
-    this.readDOMTimeout = setTimeout(function () {
-      this$1.readDOMTimeout = null;
-      if (this$1.composing) {
-        if (this$1.composing.done) { this$1.composing = null; }
-        else { return }
-      }
-      this$1.updateFromDOM();
-    }, 80);
-  };
-
-  ContentEditableInput.prototype.updateFromDOM = function () {
-      var this$1 = this;
-
-    if (this.cm.isReadOnly() || !this.pollContent())
-      { runInOp(this.cm, function () { return regChange(this$1.cm); }); }
-  };
-
-  ContentEditableInput.prototype.setUneditable = function (node) {
-    node.contentEditable = "false";
-  };
-
-  ContentEditableInput.prototype.onKeyPress = function (e) {
-    if (e.charCode == 0 || this.composing) { return }
-    e.preventDefault();
-    if (!this.cm.isReadOnly())
-      { operation(this.cm, applyTextInput)(this.cm, String.fromCharCode(e.charCode == null ? e.keyCode : e.charCode), 0); }
-  };
-
-  ContentEditableInput.prototype.readOnlyChanged = function (val) {
-    this.div.contentEditable = String(val != "nocursor");
-  };
-
-  ContentEditableInput.prototype.onContextMenu = function () {};
-  ContentEditableInput.prototype.resetPosition = function () {};
-
-  ContentEditableInput.prototype.needsContentAttribute = true;
-
-  function posToDOM(cm, pos) {
-    var view = findViewForLine(cm, pos.line);
-    if (!view || view.hidden) { return null }
-    var line = getLine(cm.doc, pos.line);
-    var info = mapFromLineView(view, line, pos.line);
-
-    var order = getOrder(line, cm.doc.direction), side = "left";
-    if (order) {
-      var partPos = getBidiPartAt(order, pos.ch);
-      side = partPos % 2 ? "right" : "left";
-    }
-    var result = nodeAndOffsetInLineMap(info.map, pos.ch, side);
-    result.offset = result.collapse == "right" ? result.end : result.start;
-    return result
-  }
-
-  function isInGutter(node) {
-    for (var scan = node; scan; scan = scan.parentNode)
-      { if (/CodeMirror-gutter-wrapper/.test(scan.className)) { return true } }
-    return false
-  }
-
-  function badPos(pos, bad) { if (bad) { pos.bad = true; } return pos }
-
-  function domTextBetween(cm, from, to, fromLine, toLine) {
-    var text = "", closing = false, lineSep = cm.doc.lineSeparator(), extraLinebreak = false;
-    function recognizeMarker(id) { return function (marker) { return marker.id == id; } }
-    function close() {
-      if (closing) {
-        text += lineSep;
-        if (extraLinebreak) { text += lineSep; }
-        closing = extraLinebreak = false;
-      }
-    }
-    function addText(str) {
-      if (str) {
-        close();
-        text += str;
-      }
-    }
-    function walk(node) {
-      if (node.nodeType == 1) {
-        var cmText = node.getAttribute("cm-text");
-        if (cmText) {
-          addText(cmText);
-          return
-        }
-        var markerID = node.getAttribute("cm-marker"), range$$1;
-        if (markerID) {
-          var found = cm.findMarks(Pos(fromLine, 0), Pos(toLine + 1, 0), recognizeMarker(+markerID));
-          if (found.length && (range$$1 = found[0].find(0)))
-            { addText(getBetween(cm.doc, range$$1.from, range$$1.to).join(lineSep)); }
-          return
-        }
-        if (node.getAttribute("contenteditable") == "false") { return }
-        var isBlock = /^(pre|div|p|li|table|br)$/i.test(node.nodeName);
-        if (!/^br$/i.test(node.nodeName) && node.textContent.length == 0) { return }
-
-        if (isBlock) { close(); }
-        for (var i = 0; i < node.childNodes.length; i++)
-          { walk(node.childNodes[i]); }
-
-        if (/^(pre|p)$/i.test(node.nodeName)) { extraLinebreak = true; }
-        if (isBlock) { closing = true; }
-      } else if (node.nodeType == 3) {
-        addText(node.nodeValue.replace(/\u200b/g, "").replace(/\u00a0/g, " "));
-      }
-    }
-    for (;;) {
-      walk(from);
-      if (from == to) { break }
-      from = from.nextSibling;
-      extraLinebreak = false;
-    }
-    return text
-  }
-
-  function domToPos(cm, node, offset) {
-    var lineNode;
-    if (node == cm.display.lineDiv) {
-      lineNode = cm.display.lineDiv.childNodes[offset];
-      if (!lineNode) { return badPos(cm.clipPos(Pos(cm.display.viewTo - 1)), true) }
-      node = null; offset = 0;
-    } else {
-      for (lineNode = node;; lineNode = lineNode.parentNode) {
-        if (!lineNode || lineNode == cm.display.lineDiv) { return null }
-        if (lineNode.parentNode && lineNode.parentNode == cm.display.lineDiv) { break }
-      }
-    }
-    for (var i = 0; i < cm.display.view.length; i++) {
-      var lineView = cm.display.view[i];
-      if (lineView.node == lineNode)
-        { return locateNodeInLineView(lineView, node, offset) }
-    }
-  }
-
-  function locateNodeInLineView(lineView, node, offset) {
-    var wrapper = lineView.text.firstChild, bad = false;
-    if (!node || !contains(wrapper, node)) { return badPos(Pos(lineNo(lineView.line), 0), true) }
-    if (node == wrapper) {
-      bad = true;
-      node = wrapper.childNodes[offset];
-      offset = 0;
-      if (!node) {
-        var line = lineView.rest ? lst(lineView.rest) : lineView.line;
-        return badPos(Pos(lineNo(line), line.text.length), bad)
-      }
-    }
-
-    var textNode = node.nodeType == 3 ? node : null, topNode = node;
-    if (!textNode && node.childNodes.length == 1 && node.firstChild.nodeType == 3) {
-      textNode = node.firstChild;
-      if (offset) { offset = textNode.nodeValue.length; }
-    }
-    while (topNode.parentNode != wrapper) { topNode = topNode.parentNode; }
-    var measure = lineView.measure, maps = measure.maps;
-
-    function find(textNode, topNode, offset) {
-      for (var i = -1; i < (maps ? maps.length : 0); i++) {
-        var map$$1 = i < 0 ? measure.map : maps[i];
-        for (var j = 0; j < map$$1.length; j += 3) {
-          var curNode = map$$1[j + 2];
-          if (curNode == textNode || curNode == topNode) {
-            var line = lineNo(i < 0 ? lineView.line : lineView.rest[i]);
-            var ch = map$$1[j] + offset;
-            if (offset < 0 || curNode != textNode) { ch = map$$1[j + (offset ? 1 : 0)]; }
-            return Pos(line, ch)
-          }
-        }
-      }
-    }
-    var found = find(textNode, topNode, offset);
-    if (found) { return badPos(found, bad) }
-
-    // FIXME this is all really shaky. might handle the few cases it needs to handle, but likely to cause problems
-    for (var after = topNode.nextSibling, dist = textNode ? textNode.nodeValue.length - offset : 0; after; after = after.nextSibling) {
-      found = find(after, after.firstChild, 0);
-      if (found)
-        { return badPos(Pos(found.line, found.ch - dist), bad) }
-      else
-        { dist += after.textContent.length; }
-    }
-    for (var before = topNode.previousSibling, dist$1 = offset; before; before = before.previousSibling) {
-      found = find(before, before.firstChild, -1);
-      if (found)
-        { return badPos(Pos(found.line, found.ch + dist$1), bad) }
-      else
-        { dist$1 += before.textContent.length; }
-    }
-  }
-
-  // TEXTAREA INPUT STYLE
-
-  var TextareaInput = function(cm) {
-    this.cm = cm;
-    // See input.poll and input.reset
-    this.prevInput = "";
-
-    // Flag that indicates whether we expect input to appear real soon
-    // now (after some event like 'keypress' or 'input') and are
-    // polling intensively.
-    this.pollingFast = false;
-    // Self-resetting timeout for the poller
-    this.polling = new Delayed();
-    // Used to work around IE issue with selection being forgotten when focus moves away from textarea
-    this.hasSelection = false;
-    this.composing = null;
-  };
-
-  TextareaInput.prototype.init = function (display) {
-      var this$1 = this;
-
-    var input = this, cm = this.cm;
-    this.createField(display);
-    var te = this.textarea;
-
-    display.wrapper.insertBefore(this.wrapper, display.wrapper.firstChild);
-
-    // Needed to hide big blue blinking cursor on Mobile Safari (doesn't seem to work in iOS 8 anymore)
-    if (ios) { te.style.width = "0px"; }
-
-    on(te, "input", function () {
-      if (ie && ie_version >= 9 && this$1.hasSelection) { this$1.hasSelection = null; }
-      input.poll();
-    });
-
-    on(te, "paste", function (e) {
-      if (signalDOMEvent(cm, e) || handlePaste(e, cm)) { return }
-
-      cm.state.pasteIncoming = +new Date;
-      input.fastPoll();
-    });
-
-    function prepareCopyCut(e) {
-      if (signalDOMEvent(cm, e)) { return }
-      if (cm.somethingSelected()) {
-        setLastCopied({lineWise: false, text: cm.getSelections()});
-      } else if (!cm.options.lineWiseCopyCut) {
-        return
-      } else {
-        var ranges = copyableRanges(cm);
-        setLastCopied({lineWise: true, text: ranges.text});
-        if (e.type == "cut") {
-          cm.setSelections(ranges.ranges, null, sel_dontScroll);
-        } else {
-          input.prevInput = "";
-          te.value = ranges.text.join("\n");
-          selectInput(te);
-        }
-      }
-      if (e.type == "cut") { cm.state.cutIncoming = +new Date; }
-    }
-    on(te, "cut", prepareCopyCut);
-    on(te, "copy", prepareCopyCut);
-
-    on(display.scroller, "paste", function (e) {
-      if (eventInWidget(display, e) || signalDOMEvent(cm, e)) { return }
-      if (!te.dispatchEvent) {
-        cm.state.pasteIncoming = +new Date;
-        input.focus();
-        return
-      }
-
-      // Pass the `paste` event to the textarea so it's handled by its event listener.
-      var event = new Event("paste");
-      event.clipboardData = e.clipboardData;
-      te.dispatchEvent(event);
-    });
-
-    // Prevent normal selection in the editor (we handle our own)
-    on(display.lineSpace, "selectstart", function (e) {
-      if (!eventInWidget(display, e)) { e_preventDefault(e); }
-    });
-
-    on(te, "compositionstart", function () {
-      var start = cm.getCursor("from");
-      if (input.composing) { input.composing.range.clear(); }
-      input.composing = {
-        start: start,
-        range: cm.markText(start, cm.getCursor("to"), {className: "CodeMirror-composing"})
-      };
-    });
-    on(te, "compositionend", function () {
-      if (input.composing) {
-        input.poll();
-        input.composing.range.clear();
-        input.composing = null;
-      }
-    });
-  };
-
-  TextareaInput.prototype.createField = function (_display) {
-    // Wraps and hides input textarea
-    this.wrapper = hiddenTextarea();
-    // The semihidden textarea that is focused when the editor is
-    // focused, and receives input.
-    this.textarea = this.wrapper.firstChild;
-  };
-
-  TextareaInput.prototype.prepareSelection = function () {
-    // Redraw the selection and/or cursor
-    var cm = this.cm, display = cm.display, doc = cm.doc;
-    var result = prepareSelection(cm);
-
-    // Move the hidden textarea near the cursor to prevent scrolling artifacts
-    if (cm.options.moveInputWithCursor) {
-      var headPos = cursorCoords(cm, doc.sel.primary().head, "div");
-      var wrapOff = display.wrapper.getBoundingClientRect(), lineOff = display.lineDiv.getBoundingClientRect();
-      result.teTop = Math.max(0, Math.min(display.wrapper.clientHeight - 10,
-                                          headPos.top + lineOff.top - wrapOff.top));
-      result.teLeft = Math.max(0, Math.min(display.wrapper.clientWidth - 10,
-                                           headPos.left + lineOff.left - wrapOff.left));
-    }
-
-    return result
-  };
-
-  TextareaInput.prototype.showSelection = function (drawn) {
-    var cm = this.cm, display = cm.display;
-    removeChildrenAndAdd(display.cursorDiv, drawn.cursors);
-    removeChildrenAndAdd(display.selectionDiv, drawn.selection);
-    if (drawn.teTop != null) {
-      this.wrapper.style.top = drawn.teTop + "px";
-      this.wrapper.style.left = drawn.teLeft + "px";
-    }
-  };
-
-  // Reset the input to correspond to the selection (or to be empty,
-  // when not typing and nothing is selected)
-  TextareaInput.prototype.reset = function (typing) {
-    if (this.contextMenuPending || this.composing) { return }
-    var cm = this.cm;
-    if (cm.somethingSelected()) {
-      this.prevInput = "";
-      var content = cm.getSelection();
-      this.textarea.value = content;
-      if (cm.state.focused) { selectInput(this.textarea); }
-      if (ie && ie_version >= 9) { this.hasSelection = content; }
-    } else if (!typing) {
-      this.prevInput = this.textarea.value = "";
-      if (ie && ie_version >= 9) { this.hasSelection = null; }
-    }
-  };
-
-  TextareaInput.prototype.getField = function () { return this.textarea };
-
-  TextareaInput.prototype.supportsTouch = function () { return false };
-
-  TextareaInput.prototype.focus = function () {
-    if (this.cm.options.readOnly != "nocursor" && (!mobile || activeElt() != this.textarea)) {
-      try { this.textarea.focus(); }
-      catch (e) {} // IE8 will throw if the textarea is display: none or not in DOM
-    }
-  };
-
-  TextareaInput.prototype.blur = function () { this.textarea.blur(); };
-
-  TextareaInput.prototype.resetPosition = function () {
-    this.wrapper.style.top = this.wrapper.style.left = 0;
-  };
-
-  TextareaInput.prototype.receivedFocus = function () { this.slowPoll(); };
-
-  // Poll for input changes, using the normal rate of polling. This
-  // runs as long as the editor is focused.
-  TextareaInput.prototype.slowPoll = function () {
-      var this$1 = this;
-
-    if (this.pollingFast) { return }
-    this.polling.set(this.cm.options.pollInterval, function () {
-      this$1.poll();
-      if (this$1.cm.state.focused) { this$1.slowPoll(); }
-    });
-  };
-
-  // When an event has just come in that is likely to add or change
-  // something in the input textarea, we poll faster, to ensure that
-  // the change appears on the screen quickly.
-  TextareaInput.prototype.fastPoll = function () {
-    var missed = false, input = this;
-    input.pollingFast = true;
-    function p() {
-      var changed = input.poll();
-      if (!changed && !missed) {missed = true; input.polling.set(60, p);}
-      else {input.pollingFast = false; input.slowPoll();}
-    }
-    input.polling.set(20, p);
-  };
-
-  // Read input from the textarea, and update the document to match.
-  // When something is selected, it is present in the textarea, and
-  // selected (unless it is huge, in which case a placeholder is
-  // used). When nothing is selected, the cursor sits after previously
-  // seen text (can be empty), which is stored in prevInput (we must
-  // not reset the textarea when typing, because that breaks IME).
-  TextareaInput.prototype.poll = function () {
-      var this$1 = this;
-
-    var cm = this.cm, input = this.textarea, prevInput = this.prevInput;
-    // Since this is called a *lot*, try to bail out as cheaply as
-    // possible when it is clear that nothing happened. hasSelection
-    // will be the case when there is a lot of text in the textarea,
-    // in which case reading its value would be expensive.
-    if (this.contextMenuPending || !cm.state.focused ||
-        (hasSelection(input) && !prevInput && !this.composing) ||
-        cm.isReadOnly() || cm.options.disableInput || cm.state.keySeq)
-      { return false }
-
-    var text = input.value;
-    // If nothing changed, bail.
-    if (text == prevInput && !cm.somethingSelected()) { return false }
-    // Work around nonsensical selection resetting in IE9/10, and
-    // inexplicable appearance of private area unicode characters on
-    // some key combos in Mac (#2689).
-    if (ie && ie_version >= 9 && this.hasSelection === text ||
-        mac && /[\uf700-\uf7ff]/.test(text)) {
-      cm.display.input.reset();
-      return false
-    }
-
-    if (cm.doc.sel == cm.display.selForContextMenu) {
-      var first = text.charCodeAt(0);
-      if (first == 0x200b && !prevInput) { prevInput = "\u200b"; }
-      if (first == 0x21da) { this.reset(); return this.cm.execCommand("undo") }
-    }
-    // Find the part of the input that is actually new
-    var same = 0, l = Math.min(prevInput.length, text.length);
-    while (same < l && prevInput.charCodeAt(same) == text.charCodeAt(same)) { ++same; }
-
-    runInOp(cm, function () {
-      applyTextInput(cm, text.slice(same), prevInput.length - same,
-                     null, this$1.composing ? "*compose" : null);
-
-      // Don't leave long text in the textarea, since it makes further polling slow
-      if (text.length > 1000 || text.indexOf("\n") > -1) { input.value = this$1.prevInput = ""; }
-      else { this$1.prevInput = text; }
-
-      if (this$1.composing) {
-        this$1.composing.range.clear();
-        this$1.composing.range = cm.markText(this$1.composing.start, cm.getCursor("to"),
-                                           {className: "CodeMirror-composing"});
-      }
-    });
-    return true
-  };
-
-  TextareaInput.prototype.ensurePolled = function () {
-    if (this.pollingFast && this.poll()) { this.pollingFast = false; }
-  };
-
-  TextareaInput.prototype.onKeyPress = function () {
-    if (ie && ie_version >= 9) { this.hasSelection = null; }
-    this.fastPoll();
-  };
-
-  TextareaInput.prototype.onContextMenu = function (e) {
-    var input = this, cm = input.cm, display = cm.display, te = input.textarea;
-    if (input.contextMenuPending) { input.contextMenuPending(); }
-    var pos = posFromMouse(cm, e), scrollPos = display.scroller.scrollTop;
-    if (!pos || presto) { return } // Opera is difficult.
-
-    // Reset the current text selection only if the click is done outside of the selection
-    // and 'resetSelectionOnContextMenu' option is true.
-    var reset = cm.options.resetSelectionOnContextMenu;
-    if (reset && cm.doc.sel.contains(pos) == -1)
-      { operation(cm, setSelection)(cm.doc, simpleSelection(pos), sel_dontScroll); }
-
-    var oldCSS = te.style.cssText, oldWrapperCSS = input.wrapper.style.cssText;
-    var wrapperBox = input.wrapper.offsetParent.getBoundingClientRect();
-    input.wrapper.style.cssText = "position: static";
-    te.style.cssText = "position: absolute; width: 30px; height: 30px;\n      top: " + (e.clientY - wrapperBox.top - 5) + "px; left: " + (e.clientX - wrapperBox.left - 5) + "px;\n      z-index: 1000; background: " + (ie ? "rgba(255, 255, 255, .05)" : "transparent") + ";\n      outline: none; border-width: 0; outline: none; overflow: hidden; opacity: .05; filter: alpha(opacity=5);";
-    var oldScrollY;
-    if (webkit) { oldScrollY = window.scrollY; } // Work around Chrome issue (#2712)
-    display.input.focus();
-    if (webkit) { window.scrollTo(null, oldScrollY); }
-    display.input.reset();
-    // Adds "Select all" to context menu in FF
-    if (!cm.somethingSelected()) { te.value = input.prevInput = " "; }
-    input.contextMenuPending = rehide;
-    display.selForContextMenu = cm.doc.sel;
-    clearTimeout(display.detectingSelectAll);
-
-    // Select-all will be greyed out if there's nothing to select, so
-    // this adds a zero-width space so that we can later check whether
-    // it got selected.
-    function prepareSelectAllHack() {
-      if (te.selectionStart != null) {
-        var selected = cm.somethingSelected();
-        var extval = "\u200b" + (selected ? te.value : "");
-        te.value = "\u21da"; // Used to catch context-menu undo
-        te.value = extval;
-        input.prevInput = selected ? "" : "\u200b";
-        te.selectionStart = 1; te.selectionEnd = extval.length;
-        // Re-set this, in case some other handler touched the
-        // selection in the meantime.
-        display.selForContextMenu = cm.doc.sel;
-      }
-    }
-    function rehide() {
-      if (input.contextMenuPending != rehide) { return }
-      input.contextMenuPending = false;
-      input.wrapper.style.cssText = oldWrapperCSS;
-      te.style.cssText = oldCSS;
-      if (ie && ie_version < 9) { display.scrollbars.setScrollTop(display.scroller.scrollTop = scrollPos); }
-
-      // Try to detect the user choosing select-all
-      if (te.selectionStart != null) {
-        if (!ie || (ie && ie_version < 9)) { prepareSelectAllHack(); }
-        var i = 0, poll = function () {
-          if (display.selForContextMenu == cm.doc.sel && te.selectionStart == 0 &&
-              te.selectionEnd > 0 && input.prevInput == "\u200b") {
-            operation(cm, selectAll)(cm);
-          } else if (i++ < 10) {
-            display.detectingSelectAll = setTimeout(poll, 500);
-          } else {
-            display.selForContextMenu = null;
-            display.input.reset();
-          }
-        };
-        display.detectingSelectAll = setTimeout(poll, 200);
-      }
-    }
-
-    if (ie && ie_version >= 9) { prepareSelectAllHack(); }
-    if (captureRightClick) {
-      e_stop(e);
-      var mouseup = function () {
-        off(window, "mouseup", mouseup);
-        setTimeout(rehide, 20);
-      };
-      on(window, "mouseup", mouseup);
-    } else {
-      setTimeout(rehide, 50);
-    }
-  };
-
-  TextareaInput.prototype.readOnlyChanged = function (val) {
-    if (!val) { this.reset(); }
-    this.textarea.disabled = val == "nocursor";
-  };
-
-  TextareaInput.prototype.setUneditable = function () {};
-
-  TextareaInput.prototype.needsContentAttribute = false;
-
-  function fromTextArea(textarea, options) {
-    options = options ? copyObj(options) : {};
-    options.value = textarea.value;
-    if (!options.tabindex && textarea.tabIndex)
-      { options.tabindex = textarea.tabIndex; }
-    if (!options.placeholder && textarea.placeholder)
-      { options.placeholder = textarea.placeholder; }
-    // Set autofocus to true if this textarea is focused, or if it has
-    // autofocus and no other element is focused.
-    if (options.autofocus == null) {
-      var hasFocus = activeElt();
-      options.autofocus = hasFocus == textarea ||
-        textarea.getAttribute("autofocus") != null && hasFocus == document.body;
-    }
-
-    function save() {textarea.value = cm.getValue();}
-
-    var realSubmit;
-    if (textarea.form) {
-      on(textarea.form, "submit", save);
-      // Deplorable hack to make the submit method do the right thing.
-      if (!options.leaveSubmitMethodAlone) {
-        var form = textarea.form;
-        realSubmit = form.submit;
-        try {
-          var wrappedSubmit = form.submit = function () {
-            save();
-            form.submit = realSubmit;
-            form.submit();
-            form.submit = wrappedSubmit;
-          };
-        } catch(e) {}
-      }
-    }
-
-    options.finishInit = function (cm) {
-      cm.save = save;
-      cm.getTextArea = function () { return textarea; };
-      cm.toTextArea = function () {
-        cm.toTextArea = isNaN; // Prevent this from being ran twice
-        save();
-        textarea.parentNode.removeChild(cm.getWrapperElement());
-        textarea.style.display = "";
-        if (textarea.form) {
-          off(textarea.form, "submit", save);
-          if (typeof textarea.form.submit == "function")
-            { textarea.form.submit = realSubmit; }
-        }
-      };
-    };
-
-    textarea.style.display = "none";
-    var cm = CodeMirror(function (node) { return textarea.parentNode.insertBefore(node, textarea.nextSibling); },
-      options);
-    return cm
-  }
-
-  function addLegacyProps(CodeMirror) {
-    CodeMirror.off = off;
-    CodeMirror.on = on;
-    CodeMirror.wheelEventPixels = wheelEventPixels;
-    CodeMirror.Doc = Doc;
-    CodeMirror.splitLines = splitLinesAuto;
-    CodeMirror.countColumn = countColumn;
-    CodeMirror.findColumn = findColumn;
-    CodeMirror.isWordChar = isWordCharBasic;
-    CodeMirror.Pass = Pass;
-    CodeMirror.signal = signal;
-    CodeMirror.Line = Line;
-    CodeMirror.changeEnd = changeEnd;
-    CodeMirror.scrollbarModel = scrollbarModel;
-    CodeMirror.Pos = Pos;
-    CodeMirror.cmpPos = cmp;
-    CodeMirror.modes = modes;
-    CodeMirror.mimeModes = mimeModes;
-    CodeMirror.resolveMode = resolveMode;
-    CodeMirror.getMode = getMode;
-    CodeMirror.modeExtensions = modeExtensions;
-    CodeMirror.extendMode = extendMode;
-    CodeMirror.copyState = copyState;
-    CodeMirror.startState = startState;
-    CodeMirror.innerMode = innerMode;
-    CodeMirror.commands = commands;
-    CodeMirror.keyMap = keyMap;
-    CodeMirror.keyName = keyName;
-    CodeMirror.isModifierKey = isModifierKey;
-    CodeMirror.lookupKey = lookupKey;
-    CodeMirror.normalizeKeyMap = normalizeKeyMap;
-    CodeMirror.StringStream = StringStream;
-    CodeMirror.SharedTextMarker = SharedTextMarker;
-    CodeMirror.TextMarker = TextMarker;
-    CodeMirror.LineWidget = LineWidget;
-    CodeMirror.e_preventDefault = e_preventDefault;
-    CodeMirror.e_stopPropagation = e_stopPropagation;
-    CodeMirror.e_stop = e_stop;
-    CodeMirror.addClass = addClass;
-    CodeMirror.contains = contains;
-    CodeMirror.rmClass = rmClass;
-    CodeMirror.keyNames = keyNames;
-  }
-
-  // EDITOR CONSTRUCTOR
-
-  defineOptions(CodeMirror);
-
-  addEditorMethods(CodeMirror);
-
-  // Set up methods on CodeMirror's prototype to redirect to the editor's document.
-  var dontDelegate = "iter insert remove copy getEditor constructor".split(" ");
-  for (var prop in Doc.prototype) { if (Doc.prototype.hasOwnProperty(prop) && indexOf(dontDelegate, prop) < 0)
-    { CodeMirror.prototype[prop] = (function(method) {
-      return function() {return method.apply(this.doc, arguments)}
-    })(Doc.prototype[prop]); } }
-
-  eventMixin(Doc);
-  CodeMirror.inputStyles = {"textarea": TextareaInput, "contenteditable": ContentEditableInput};
-
-  // Extra arguments are stored as the mode's dependencies, which is
-  // used by (legacy) mechanisms like loadmode.js to automatically
-  // load a mode. (Preferred mechanism is the require/define calls.)
-  CodeMirror.defineMode = function(name/*, mode, …*/) {
-    if (!CodeMirror.defaults.mode && name != "null") { CodeMirror.defaults.mode = name; }
-    defineMode.apply(this, arguments);
-  };
-
-  CodeMirror.defineMIME = defineMIME;
-
-  // Minimal default mode.
-  CodeMirror.defineMode("null", function () { return ({token: function (stream) { return stream.skipToEnd(); }}); });
-  CodeMirror.defineMIME("text/plain", "null");
-
-  // EXTENSIONS
-
-  CodeMirror.defineExtension = function (name, func) {
-    CodeMirror.prototype[name] = func;
-  };
-  CodeMirror.defineDocExtension = function (name, func) {
-    Doc.prototype[name] = func;
-  };
-
-  CodeMirror.fromTextArea = fromTextArea;
-
-  addLegacyProps(CodeMirror);
-
-  CodeMirror.version = "5.48.0";
-
-  return CodeMirror;
-
-})));
Index: admin/js/codemirror/mode/css/css.js
===================================================================
--- admin/js/codemirror/mode/css/css.js	(revision 3979)
+++ 	(revision )
@@ -1,831 +1,0 @@
-// CodeMirror, copyright (c) by Marijn Haverbeke and others
-// Distributed under an MIT license: https://codemirror.net/LICENSE
-
-(function(mod) {
-  if (typeof exports == "object" && typeof module == "object") // CommonJS
-    mod(require("../../lib/codemirror"));
-  else if (typeof define == "function" && define.amd) // AMD
-    define(["../../lib/codemirror"], mod);
-  else // Plain browser env
-    mod(CodeMirror);
-})(function(CodeMirror) {
-"use strict";
-
-CodeMirror.defineMode("css", function(config, parserConfig) {
-  var inline = parserConfig.inline
-  if (!parserConfig.propertyKeywords) parserConfig = CodeMirror.resolveMode("text/css");
-
-  var indentUnit = config.indentUnit,
-      tokenHooks = parserConfig.tokenHooks,
-      documentTypes = parserConfig.documentTypes || {},
-      mediaTypes = parserConfig.mediaTypes || {},
-      mediaFeatures = parserConfig.mediaFeatures || {},
-      mediaValueKeywords = parserConfig.mediaValueKeywords || {},
-      propertyKeywords = parserConfig.propertyKeywords || {},
-      nonStandardPropertyKeywords = parserConfig.nonStandardPropertyKeywords || {},
-      fontProperties = parserConfig.fontProperties || {},
-      counterDescriptors = parserConfig.counterDescriptors || {},
-      colorKeywords = parserConfig.colorKeywords || {},
-      valueKeywords = parserConfig.valueKeywords || {},
-      allowNested = parserConfig.allowNested,
-      lineComment = parserConfig.lineComment,
-      supportsAtComponent = parserConfig.supportsAtComponent === true;
-
-  var type, override;
-  function ret(style, tp) { type = tp; return style; }
-
-  // Tokenizers
-
-  function tokenBase(stream, state) {
-    var ch = stream.next();
-    if (tokenHooks[ch]) {
-      var result = tokenHooks[ch](stream, state);
-      if (result !== false) return result;
-    }
-    if (ch == "@") {
-      stream.eatWhile(/[\w\\\-]/);
-      return ret("def", stream.current());
-    } else if (ch == "=" || (ch == "~" || ch == "|") && stream.eat("=")) {
-      return ret(null, "compare");
-    } else if (ch == "\"" || ch == "'") {
-      state.tokenize = tokenString(ch);
-      return state.tokenize(stream, state);
-    } else if (ch == "#") {
-      stream.eatWhile(/[\w\\\-]/);
-      return ret("atom", "hash");
-    } else if (ch == "!") {
-      stream.match(/^\s*\w*/);
-      return ret("keyword", "important");
-    } else if (/\d/.test(ch) || ch == "." && stream.eat(/\d/)) {
-      stream.eatWhile(/[\w.%]/);
-      return ret("number", "unit");
-    } else if (ch === "-") {
-      if (/[\d.]/.test(stream.peek())) {
-        stream.eatWhile(/[\w.%]/);
-        return ret("number", "unit");
-      } else if (stream.match(/^-[\w\\\-]*/)) {
-        stream.eatWhile(/[\w\\\-]/);
-        if (stream.match(/^\s*:/, false))
-          return ret("variable-2", "variable-definition");
-        return ret("variable-2", "variable");
-      } else if (stream.match(/^\w+-/)) {
-        return ret("meta", "meta");
-      }
-    } else if (/[,+>*\/]/.test(ch)) {
-      return ret(null, "select-op");
-    } else if (ch == "." && stream.match(/^-?[_a-z][_a-z0-9-]*/i)) {
-      return ret("qualifier", "qualifier");
-    } else if (/[:;{}\[\]\(\)]/.test(ch)) {
-      return ret(null, ch);
-    } else if (stream.match(/[\w-.]+(?=\()/)) {
-      if (/^(url(-prefix)?|domain|regexp)$/.test(stream.current().toLowerCase())) {
-        state.tokenize = tokenParenthesized;
-      }
-      return ret("variable callee", "variable");
-    } else if (/[\w\\\-]/.test(ch)) {
-      stream.eatWhile(/[\w\\\-]/);
-      return ret("property", "word");
-    } else {
-      return ret(null, null);
-    }
-  }
-
-  function tokenString(quote) {
-    return function(stream, state) {
-      var escaped = false, ch;
-      while ((ch = stream.next()) != null) {
-        if (ch == quote && !escaped) {
-          if (quote == ")") stream.backUp(1);
-          break;
-        }
-        escaped = !escaped && ch == "\\";
-      }
-      if (ch == quote || !escaped && quote != ")") state.tokenize = null;
-      return ret("string", "string");
-    };
-  }
-
-  function tokenParenthesized(stream, state) {
-    stream.next(); // Must be '('
-    if (!stream.match(/\s*[\"\')]/, false))
-      state.tokenize = tokenString(")");
-    else
-      state.tokenize = null;
-    return ret(null, "(");
-  }
-
-  // Context management
-
-  function Context(type, indent, prev) {
-    this.type = type;
-    this.indent = indent;
-    this.prev = prev;
-  }
-
-  function pushContext(state, stream, type, indent) {
-    state.context = new Context(type, stream.indentation() + (indent === false ? 0 : indentUnit), state.context);
-    return type;
-  }
-
-  function popContext(state) {
-    if (state.context.prev)
-      state.context = state.context.prev;
-    return state.context.type;
-  }
-
-  function pass(type, stream, state) {
-    return states[state.context.type](type, stream, state);
-  }
-  function popAndPass(type, stream, state, n) {
-    for (var i = n || 1; i > 0; i--)
-      state.context = state.context.prev;
-    return pass(type, stream, state);
-  }
-
-  // Parser
-
-  function wordAsValue(stream) {
-    var word = stream.current().toLowerCase();
-    if (valueKeywords.hasOwnProperty(word))
-      override = "atom";
-    else if (colorKeywords.hasOwnProperty(word))
-      override = "keyword";
-    else
-      override = "variable";
-  }
-
-  var states = {};
-
-  states.top = function(type, stream, state) {
-    if (type == "{") {
-      return pushContext(state, stream, "block");
-    } else if (type == "}" && state.context.prev) {
-      return popContext(state);
-    } else if (supportsAtComponent && /@component/i.test(type)) {
-      return pushContext(state, stream, "atComponentBlock");
-    } else if (/^@(-moz-)?document$/i.test(type)) {
-      return pushContext(state, stream, "documentTypes");
-    } else if (/^@(media|supports|(-moz-)?document|import)$/i.test(type)) {
-      return pushContext(state, stream, "atBlock");
-    } else if (/^@(font-face|counter-style)/i.test(type)) {
-      state.stateArg = type;
-      return "restricted_atBlock_before";
-    } else if (/^@(-(moz|ms|o|webkit)-)?keyframes$/i.test(type)) {
-      return "keyframes";
-    } else if (type && type.charAt(0) == "@") {
-      return pushContext(state, stream, "at");
-    } else if (type == "hash") {
-      override = "builtin";
-    } else if (type == "word") {
-      override = "tag";
-    } else if (type == "variable-definition") {
-      return "maybeprop";
-    } else if (type == "interpolation") {
-      return pushContext(state, stream, "interpolation");
-    } else if (type == ":") {
-      return "pseudo";
-    } else if (allowNested && type == "(") {
-      return pushContext(state, stream, "parens");
-    }
-    return state.context.type;
-  };
-
-  states.block = function(type, stream, state) {
-    if (type == "word") {
-      var word = stream.current().toLowerCase();
-      if (propertyKeywords.hasOwnProperty(word)) {
-        override = "property";
-        return "maybeprop";
-      } else if (nonStandardPropertyKeywords.hasOwnProperty(word)) {
-        override = "string-2";
-        return "maybeprop";
-      } else if (allowNested) {
-        override = stream.match(/^\s*:(?:\s|$)/, false) ? "property" : "tag";
-        return "block";
-      } else {
-        override += " error";
-        return "maybeprop";
-      }
-    } else if (type == "meta") {
-      return "block";
-    } else if (!allowNested && (type == "hash" || type == "qualifier")) {
-      override = "error";
-      return "block";
-    } else {
-      return states.top(type, stream, state);
-    }
-  };
-
-  states.maybeprop = function(type, stream, state) {
-    if (type == ":") return pushContext(state, stream, "prop");
-    return pass(type, stream, state);
-  };
-
-  states.prop = function(type, stream, state) {
-    if (type == ";") return popContext(state);
-    if (type == "{" && allowNested) return pushContext(state, stream, "propBlock");
-    if (type == "}" || type == "{") return popAndPass(type, stream, state);
-    if (type == "(") return pushContext(state, stream, "parens");
-
-    if (type == "hash" && !/^#([0-9a-fA-f]{3,4}|[0-9a-fA-f]{6}|[0-9a-fA-f]{8})$/.test(stream.current())) {
-      override += " error";
-    } else if (type == "word") {
-      wordAsValue(stream);
-    } else if (type == "interpolation") {
-      return pushContext(state, stream, "interpolation");
-    }
-    return "prop";
-  };
-
-  states.propBlock = function(type, _stream, state) {
-    if (type == "}") return popContext(state);
-    if (type == "word") { override = "property"; return "maybeprop"; }
-    return state.context.type;
-  };
-
-  states.parens = function(type, stream, state) {
-    if (type == "{" || type == "}") return popAndPass(type, stream, state);
-    if (type == ")") return popContext(state);
-    if (type == "(") return pushContext(state, stream, "parens");
-    if (type == "interpolation") return pushContext(state, stream, "interpolation");
-    if (type == "word") wordAsValue(stream);
-    return "parens";
-  };
-
-  states.pseudo = function(type, stream, state) {
-    if (type == "meta") return "pseudo";
-
-    if (type == "word") {
-      override = "variable-3";
-      return state.context.type;
-    }
-    return pass(type, stream, state);
-  };
-
-  states.documentTypes = function(type, stream, state) {
-    if (type == "word" && documentTypes.hasOwnProperty(stream.current())) {
-      override = "tag";
-      return state.context.type;
-    } else {
-      return states.atBlock(type, stream, state);
-    }
-  };
-
-  states.atBlock = function(type, stream, state) {
-    if (type == "(") return pushContext(state, stream, "atBlock_parens");
-    if (type == "}" || type == ";") return popAndPass(type, stream, state);
-    if (type == "{") return popContext(state) && pushContext(state, stream, allowNested ? "block" : "top");
-
-    if (type == "interpolation") return pushContext(state, stream, "interpolation");
-
-    if (type == "word") {
-      var word = stream.current().toLowerCase();
-      if (word == "only" || word == "not" || word == "and" || word == "or")
-        override = "keyword";
-      else if (mediaTypes.hasOwnProperty(word))
-        override = "attribute";
-      else if (mediaFeatures.hasOwnProperty(word))
-        override = "property";
-      else if (mediaValueKeywords.hasOwnProperty(word))
-        override = "keyword";
-      else if (propertyKeywords.hasOwnProperty(word))
-        override = "property";
-      else if (nonStandardPropertyKeywords.hasOwnProperty(word))
-        override = "string-2";
-      else if (valueKeywords.hasOwnProperty(word))
-        override = "atom";
-      else if (colorKeywords.hasOwnProperty(word))
-        override = "keyword";
-      else
-        override = "error";
-    }
-    return state.context.type;
-  };
-
-  states.atComponentBlock = function(type, stream, state) {
-    if (type == "}")
-      return popAndPass(type, stream, state);
-    if (type == "{")
-      return popContext(state) && pushContext(state, stream, allowNested ? "block" : "top", false);
-    if (type == "word")
-      override = "error";
-    return state.context.type;
-  };
-
-  states.atBlock_parens = function(type, stream, state) {
-    if (type == ")") return popContext(state);
-    if (type == "{" || type == "}") return popAndPass(type, stream, state, 2);
-    return states.atBlock(type, stream, state);
-  };
-
-  states.restricted_atBlock_before = function(type, stream, state) {
-    if (type == "{")
-      return pushContext(state, stream, "restricted_atBlock");
-    if (type == "word" && state.stateArg == "@counter-style") {
-      override = "variable";
-      return "restricted_atBlock_before";
-    }
-    return pass(type, stream, state);
-  };
-
-  states.restricted_atBlock = function(type, stream, state) {
-    if (type == "}") {
-      state.stateArg = null;
-      return popContext(state);
-    }
-    if (type == "word") {
-      if ((state.stateArg == "@font-face" && !fontProperties.hasOwnProperty(stream.current().toLowerCase())) ||
-          (state.stateArg == "@counter-style" && !counterDescriptors.hasOwnProperty(stream.current().toLowerCase())))
-        override = "error";
-      else
-        override = "property";
-      return "maybeprop";
-    }
-    return "restricted_atBlock";
-  };
-
-  states.keyframes = function(type, stream, state) {
-    if (type == "word") { override = "variable"; return "keyframes"; }
-    if (type == "{") return pushContext(state, stream, "top");
-    return pass(type, stream, state);
-  };
-
-  states.at = function(type, stream, state) {
-    if (type == ";") return popContext(state);
-    if (type == "{" || type == "}") return popAndPass(type, stream, state);
-    if (type == "word") override = "tag";
-    else if (type == "hash") override = "builtin";
-    return "at";
-  };
-
-  states.interpolation = function(type, stream, state) {
-    if (type == "}") return popContext(state);
-    if (type == "{" || type == ";") return popAndPass(type, stream, state);
-    if (type == "word") override = "variable";
-    else if (type != "variable" && type != "(" && type != ")") override = "error";
-    return "interpolation";
-  };
-
-  return {
-    startState: function(base) {
-      return {tokenize: null,
-              state: inline ? "block" : "top",
-              stateArg: null,
-              context: new Context(inline ? "block" : "top", base || 0, null)};
-    },
-
-    token: function(stream, state) {
-      if (!state.tokenize && stream.eatSpace()) return null;
-      var style = (state.tokenize || tokenBase)(stream, state);
-      if (style && typeof style == "object") {
-        type = style[1];
-        style = style[0];
-      }
-      override = style;
-      if (type != "comment")
-        state.state = states[state.state](type, stream, state);
-      return override;
-    },
-
-    indent: function(state, textAfter) {
-      var cx = state.context, ch = textAfter && textAfter.charAt(0);
-      var indent = cx.indent;
-      if (cx.type == "prop" && (ch == "}" || ch == ")")) cx = cx.prev;
-      if (cx.prev) {
-        if (ch == "}" && (cx.type == "block" || cx.type == "top" ||
-                          cx.type == "interpolation" || cx.type == "restricted_atBlock")) {
-          // Resume indentation from parent context.
-          cx = cx.prev;
-          indent = cx.indent;
-        } else if (ch == ")" && (cx.type == "parens" || cx.type == "atBlock_parens") ||
-            ch == "{" && (cx.type == "at" || cx.type == "atBlock")) {
-          // Dedent relative to current context.
-          indent = Math.max(0, cx.indent - indentUnit);
-        }
-      }
-      return indent;
-    },
-
-    electricChars: "}",
-    blockCommentStart: "/*",
-    blockCommentEnd: "*/",
-    blockCommentContinue: " * ",
-    lineComment: lineComment,
-    fold: "brace"
-  };
-});
-
-  function keySet(array) {
-    var keys = {};
-    for (var i = 0; i < array.length; ++i) {
-      keys[array[i].toLowerCase()] = true;
-    }
-    return keys;
-  }
-
-  var documentTypes_ = [
-    "domain", "regexp", "url", "url-prefix"
-  ], documentTypes = keySet(documentTypes_);
-
-  var mediaTypes_ = [
-    "all", "aural", "braille", "handheld", "print", "projection", "screen",
-    "tty", "tv", "embossed"
-  ], mediaTypes = keySet(mediaTypes_);
-
-  var mediaFeatures_ = [
-    "width", "min-width", "max-width", "height", "min-height", "max-height",
-    "device-width", "min-device-width", "max-device-width", "device-height",
-    "min-device-height", "max-device-height", "aspect-ratio",
-    "min-aspect-ratio", "max-aspect-ratio", "device-aspect-ratio",
-    "min-device-aspect-ratio", "max-device-aspect-ratio", "color", "min-color",
-    "max-color", "color-index", "min-color-index", "max-color-index",
-    "monochrome", "min-monochrome", "max-monochrome", "resolution",
-    "min-resolution", "max-resolution", "scan", "grid", "orientation",
-    "device-pixel-ratio", "min-device-pixel-ratio", "max-device-pixel-ratio",
-    "pointer", "any-pointer", "hover", "any-hover"
-  ], mediaFeatures = keySet(mediaFeatures_);
-
-  var mediaValueKeywords_ = [
-    "landscape", "portrait", "none", "coarse", "fine", "on-demand", "hover",
-    "interlace", "progressive"
-  ], mediaValueKeywords = keySet(mediaValueKeywords_);
-
-  var propertyKeywords_ = [
-    "align-content", "align-items", "align-self", "alignment-adjust",
-    "alignment-baseline", "anchor-point", "animation", "animation-delay",
-    "animation-direction", "animation-duration", "animation-fill-mode",
-    "animation-iteration-count", "animation-name", "animation-play-state",
-    "animation-timing-function", "appearance", "azimuth", "backface-visibility",
-    "background", "background-attachment", "background-blend-mode", "background-clip",
-    "background-color", "background-image", "background-origin", "background-position",
-    "background-repeat", "background-size", "baseline-shift", "binding",
-    "bleed", "bookmark-label", "bookmark-level", "bookmark-state",
-    "bookmark-target", "border", "border-bottom", "border-bottom-color",
-    "border-bottom-left-radius", "border-bottom-right-radius",
-    "border-bottom-style", "border-bottom-width", "border-collapse",
-    "border-color", "border-image", "border-image-outset",
-    "border-image-repeat", "border-image-slice", "border-image-source",
-    "border-image-width", "border-left", "border-left-color",
-    "border-left-style", "border-left-width", "border-radius", "border-right",
-    "border-right-color", "border-right-style", "border-right-width",
-    "border-spacing", "border-style", "border-top", "border-top-color",
-    "border-top-left-radius", "border-top-right-radius", "border-top-style",
-    "border-top-width", "border-width", "bottom", "box-decoration-break",
-    "box-shadow", "box-sizing", "break-after", "break-before", "break-inside",
-    "caption-side", "caret-color", "clear", "clip", "color", "color-profile", "column-count",
-    "column-fill", "column-gap", "column-rule", "column-rule-color",
-    "column-rule-style", "column-rule-width", "column-span", "column-width",
-    "columns", "content", "counter-increment", "counter-reset", "crop", "cue",
-    "cue-after", "cue-before", "cursor", "direction", "display",
-    "dominant-baseline", "drop-initial-after-adjust",
-    "drop-initial-after-align", "drop-initial-before-adjust",
-    "drop-initial-before-align", "drop-initial-size", "drop-initial-value",
-    "elevation", "empty-cells", "fit", "fit-position", "flex", "flex-basis",
-    "flex-direction", "flex-flow", "flex-grow", "flex-shrink", "flex-wrap",
-    "float", "float-offset", "flow-from", "flow-into", "font", "font-feature-settings",
-    "font-family", "font-kerning", "font-language-override", "font-size", "font-size-adjust",
-    "font-stretch", "font-style", "font-synthesis", "font-variant",
-    "font-variant-alternates", "font-variant-caps", "font-variant-east-asian",
-    "font-variant-ligatures", "font-variant-numeric", "font-variant-position",
-    "font-weight", "grid", "grid-area", "grid-auto-columns", "grid-auto-flow",
-    "grid-auto-rows", "grid-column", "grid-column-end", "grid-column-gap",
-    "grid-column-start", "grid-gap", "grid-row", "grid-row-end", "grid-row-gap",
-    "grid-row-start", "grid-template", "grid-template-areas", "grid-template-columns",
-    "grid-template-rows", "hanging-punctuation", "height", "hyphens",
-    "icon", "image-orientation", "image-rendering", "image-resolution",
-    "inline-box-align", "justify-content", "justify-items", "justify-self", "left", "letter-spacing",
-    "line-break", "line-height", "line-stacking", "line-stacking-ruby",
-    "line-stacking-shift", "line-stacking-strategy", "list-style",
-    "list-style-image", "list-style-position", "list-style-type", "margin",
-    "margin-bottom", "margin-left", "margin-right", "margin-top",
-    "marks", "marquee-direction", "marquee-loop",
-    "marquee-play-count", "marquee-speed", "marquee-style", "max-height",
-    "max-width", "min-height", "min-width", "mix-blend-mode", "move-to", "nav-down", "nav-index",
-    "nav-left", "nav-right", "nav-up", "object-fit", "object-position",
-    "opacity", "order", "orphans", "outline",
-    "outline-color", "outline-offset", "outline-style", "outline-width",
-    "overflow", "overflow-style", "overflow-wrap", "overflow-x", "overflow-y",
-    "padding", "padding-bottom", "padding-left", "padding-right", "padding-top",
-    "page", "page-break-after", "page-break-before", "page-break-inside",
-    "page-policy", "pause", "pause-after", "pause-before", "perspective",
-    "perspective-origin", "pitch", "pitch-range", "place-content", "place-items", "place-self", "play-during", "position",
-    "presentation-level", "punctuation-trim", "quotes", "region-break-after",
-    "region-break-before", "region-break-inside", "region-fragment",
-    "rendering-intent", "resize", "rest", "rest-after", "rest-before", "richness",
-    "right", "rotation", "rotation-point", "ruby-align", "ruby-overhang",
-    "ruby-position", "ruby-span", "shape-image-threshold", "shape-inside", "shape-margin",
-    "shape-outside", "size", "speak", "speak-as", "speak-header",
-    "speak-numeral", "speak-punctuation", "speech-rate", "stress", "string-set",
-    "tab-size", "table-layout", "target", "target-name", "target-new",
-    "target-position", "text-align", "text-align-last", "text-decoration",
-    "text-decoration-color", "text-decoration-line", "text-decoration-skip",
-    "text-decoration-style", "text-emphasis", "text-emphasis-color",
-    "text-emphasis-position", "text-emphasis-style", "text-height",
-    "text-indent", "text-justify", "text-outline", "text-overflow", "text-shadow",
-    "text-size-adjust", "text-space-collapse", "text-transform", "text-underline-position",
-    "text-wrap", "top", "transform", "transform-origin", "transform-style",
-    "transition", "transition-delay", "transition-duration",
-    "transition-property", "transition-timing-function", "unicode-bidi",
-    "user-select", "vertical-align", "visibility", "voice-balance", "voice-duration",
-    "voice-family", "voice-pitch", "voice-range", "voice-rate", "voice-stress",
-    "voice-volume", "volume", "white-space", "widows", "width", "will-change", "word-break",
-    "word-spacing", "word-wrap", "z-index",
-    // SVG-specific
-    "clip-path", "clip-rule", "mask", "enable-background", "filter", "flood-color",
-    "flood-opacity", "lighting-color", "stop-color", "stop-opacity", "pointer-events",
-    "color-interpolation", "color-interpolation-filters",
-    "color-rendering", "fill", "fill-opacity", "fill-rule", "image-rendering",
-    "marker", "marker-end", "marker-mid", "marker-start", "shape-rendering", "stroke",
-    "stroke-dasharray", "stroke-dashoffset", "stroke-linecap", "stroke-linejoin",
-    "stroke-miterlimit", "stroke-opacity", "stroke-width", "text-rendering",
-    "baseline-shift", "dominant-baseline", "glyph-orientation-horizontal",
-    "glyph-orientation-vertical", "text-anchor", "writing-mode"
-  ], propertyKeywords = keySet(propertyKeywords_);
-
-  var nonStandardPropertyKeywords_ = [
-    "scrollbar-arrow-color", "scrollbar-base-color", "scrollbar-dark-shadow-color",
-    "scrollbar-face-color", "scrollbar-highlight-color", "scrollbar-shadow-color",
-    "scrollbar-3d-light-color", "scrollbar-track-color", "shape-inside",
-    "searchfield-cancel-button", "searchfield-decoration", "searchfield-results-button",
-    "searchfield-results-decoration", "zoom"
-  ], nonStandardPropertyKeywords = keySet(nonStandardPropertyKeywords_);
-
-  var fontProperties_ = [
-    "font-family", "src", "unicode-range", "font-variant", "font-feature-settings",
-    "font-stretch", "font-weight", "font-style"
-  ], fontProperties = keySet(fontProperties_);
-
-  var counterDescriptors_ = [
-    "additive-symbols", "fallback", "negative", "pad", "prefix", "range",
-    "speak-as", "suffix", "symbols", "system"
-  ], counterDescriptors = keySet(counterDescriptors_);
-
-  var colorKeywords_ = [
-    "aliceblue", "antiquewhite", "aqua", "aquamarine", "azure", "beige",
-    "bisque", "black", "blanchedalmond", "blue", "blueviolet", "brown",
-    "burlywood", "cadetblue", "chartreuse", "chocolate", "coral", "cornflowerblue",
-    "cornsilk", "crimson", "cyan", "darkblue", "darkcyan", "darkgoldenrod",
-    "darkgray", "darkgreen", "darkkhaki", "darkmagenta", "darkolivegreen",
-    "darkorange", "darkorchid", "darkred", "darksalmon", "darkseagreen",
-    "darkslateblue", "darkslategray", "darkturquoise", "darkviolet",
-    "deeppink", "deepskyblue", "dimgray", "dodgerblue", "firebrick",
-    "floralwhite", "forestgreen", "fuchsia", "gainsboro", "ghostwhite",
-    "gold", "goldenrod", "gray", "grey", "green", "greenyellow", "honeydew",
-    "hotpink", "indianred", "indigo", "ivory", "khaki", "lavender",
-    "lavenderblush", "lawngreen", "lemonchiffon", "lightblue", "lightcoral",
-    "lightcyan", "lightgoldenrodyellow", "lightgray", "lightgreen", "lightpink",
-    "lightsalmon", "lightseagreen", "lightskyblue", "lightslategray",
-    "lightsteelblue", "lightyellow", "lime", "limegreen", "linen", "magenta",
-    "maroon", "mediumaquamarine", "mediumblue", "mediumorchid", "mediumpurple",
-    "mediumseagreen", "mediumslateblue", "mediumspringgreen", "mediumturquoise",
-    "mediumvioletred", "midnightblue", "mintcream", "mistyrose", "moccasin",
-    "navajowhite", "navy", "oldlace", "olive", "olivedrab", "orange", "orangered",
-    "orchid", "palegoldenrod", "palegreen", "paleturquoise", "palevioletred",
-    "papayawhip", "peachpuff", "peru", "pink", "plum", "powderblue",
-    "purple", "rebeccapurple", "red", "rosybrown", "royalblue", "saddlebrown",
-    "salmon", "sandybrown", "seagreen", "seashell", "sienna", "silver", "skyblue",
-    "slateblue", "slategray", "snow", "springgreen", "steelblue", "tan",
-    "teal", "thistle", "tomato", "turquoise", "violet", "wheat", "white",
-    "whitesmoke", "yellow", "yellowgreen"
-  ], colorKeywords = keySet(colorKeywords_);
-
-  var valueKeywords_ = [
-    "above", "absolute", "activeborder", "additive", "activecaption", "afar",
-    "after-white-space", "ahead", "alias", "all", "all-scroll", "alphabetic", "alternate",
-    "always", "amharic", "amharic-abegede", "antialiased", "appworkspace",
-    "arabic-indic", "armenian", "asterisks", "attr", "auto", "auto-flow", "avoid", "avoid-column", "avoid-page",
-    "avoid-region", "background", "backwards", "baseline", "below", "bidi-override", "binary",
-    "bengali", "blink", "block", "block-axis", "bold", "bolder", "border", "border-box",
-    "both", "bottom", "break", "break-all", "break-word", "bullets", "button", "button-bevel",
-    "buttonface", "buttonhighlight", "buttonshadow", "buttontext", "calc", "cambodian",
-    "capitalize", "caps-lock-indicator", "caption", "captiontext", "caret",
-    "cell", "center", "checkbox", "circle", "cjk-decimal", "cjk-earthly-branch",
-    "cjk-heavenly-stem", "cjk-ideographic", "clear", "clip", "close-quote",
-    "col-resize", "collapse", "color", "color-burn", "color-dodge", "column", "column-reverse",
-    "compact", "condensed", "contain", "content", "contents",
-    "content-box", "context-menu", "continuous", "copy", "counter", "counters", "cover", "crop",
-    "cross", "crosshair", "currentcolor", "cursive", "cyclic", "darken", "dashed", "decimal",
-    "decimal-leading-zero", "default", "default-button", "dense", "destination-atop",
-    "destination-in", "destination-out", "destination-over", "devanagari", "difference",
-    "disc", "discard", "disclosure-closed", "disclosure-open", "document",
-    "dot-dash", "dot-dot-dash",
-    "dotted", "double", "down", "e-resize", "ease", "ease-in", "ease-in-out", "ease-out",
-    "element", "ellipse", "ellipsis", "embed", "end", "ethiopic", "ethiopic-abegede",
-    "ethiopic-abegede-am-et", "ethiopic-abegede-gez", "ethiopic-abegede-ti-er",
-    "ethiopic-abegede-ti-et", "ethiopic-halehame-aa-er",
-    "ethiopic-halehame-aa-et", "ethiopic-halehame-am-et",
-    "ethiopic-halehame-gez", "ethiopic-halehame-om-et",
-    "ethiopic-halehame-sid-et", "ethiopic-halehame-so-et",
-    "ethiopic-halehame-ti-er", "ethiopic-halehame-ti-et", "ethiopic-halehame-tig",
-    "ethiopic-numeric", "ew-resize", "exclusion", "expanded", "extends", "extra-condensed",
-    "extra-expanded", "fantasy", "fast", "fill", "fixed", "flat", "flex", "flex-end", "flex-start", "footnotes",
-    "forwards", "from", "geometricPrecision", "georgian", "graytext", "grid", "groove",
-    "gujarati", "gurmukhi", "hand", "hangul", "hangul-consonant", "hard-light", "hebrew",
-    "help", "hidden", "hide", "higher", "highlight", "highlighttext",
-    "hiragana", "hiragana-iroha", "horizontal", "hsl", "hsla", "hue", "icon", "ignore",
-    "inactiveborder", "inactivecaption", "inactivecaptiontext", "infinite",
-    "infobackground", "infotext", "inherit", "initial", "inline", "inline-axis",
-    "inline-block", "inline-flex", "inline-grid", "inline-table", "inset", "inside", "intrinsic", "invert",
-    "italic", "japanese-formal", "japanese-informal", "justify", "kannada",
-    "katakana", "katakana-iroha", "keep-all", "khmer",
-    "korean-hangul-formal", "korean-hanja-formal", "korean-hanja-informal",
-    "landscape", "lao", "large", "larger", "left", "level", "lighter", "lighten",
-    "line-through", "linear", "linear-gradient", "lines", "list-item", "listbox", "listitem",
-    "local", "logical", "loud", "lower", "lower-alpha", "lower-armenian",
-    "lower-greek", "lower-hexadecimal", "lower-latin", "lower-norwegian",
-    "lower-roman", "lowercase", "ltr", "luminosity", "malayalam", "match", "matrix", "matrix3d",
-    "media-controls-background", "media-current-time-display",
-    "media-fullscreen-button", "media-mute-button", "media-play-button",
-    "media-return-to-realtime-button", "media-rewind-button",
-    "media-seek-back-button", "media-seek-forward-button", "media-slider",
-    "media-sliderthumb", "media-time-remaining-display", "media-volume-slider",
-    "media-volume-slider-container", "media-volume-sliderthumb", "medium",
-    "menu", "menulist", "menulist-button", "menulist-text",
-    "menulist-textfield", "menutext", "message-box", "middle", "min-intrinsic",
-    "mix", "mongolian", "monospace", "move", "multiple", "multiply", "myanmar", "n-resize",
-    "narrower", "ne-resize", "nesw-resize", "no-close-quote", "no-drop",
-    "no-open-quote", "no-repeat", "none", "normal", "not-allowed", "nowrap",
-    "ns-resize", "numbers", "numeric", "nw-resize", "nwse-resize", "oblique", "octal", "opacity", "open-quote",
-    "optimizeLegibility", "optimizeSpeed", "oriya", "oromo", "outset",
-    "outside", "outside-shape", "overlay", "overline", "padding", "padding-box",
-    "painted", "page", "paused", "persian", "perspective", "plus-darker", "plus-lighter",
-    "pointer", "polygon", "portrait", "pre", "pre-line", "pre-wrap", "preserve-3d",
-    "progress", "push-button", "radial-gradient", "radio", "read-only",
-    "read-write", "read-write-plaintext-only", "rectangle", "region",
-    "relative", "repeat", "repeating-linear-gradient",
-    "repeating-radial-gradient", "repeat-x", "repeat-y", "reset", "reverse",
-    "rgb", "rgba", "ridge", "right", "rotate", "rotate3d", "rotateX", "rotateY",
-    "rotateZ", "round", "row", "row-resize", "row-reverse", "rtl", "run-in", "running",
-    "s-resize", "sans-serif", "saturation", "scale", "scale3d", "scaleX", "scaleY", "scaleZ", "screen",
-    "scroll", "scrollbar", "scroll-position", "se-resize", "searchfield",
-    "searchfield-cancel-button", "searchfield-decoration",
-    "searchfield-results-button", "searchfield-results-decoration", "self-start", "self-end",
-    "semi-condensed", "semi-expanded", "separate", "serif", "show", "sidama",
-    "simp-chinese-formal", "simp-chinese-informal", "single",
-    "skew", "skewX", "skewY", "skip-white-space", "slide", "slider-horizontal",
-    "slider-vertical", "sliderthumb-horizontal", "sliderthumb-vertical", "slow",
-    "small", "small-caps", "small-caption", "smaller", "soft-light", "solid", "somali",
-    "source-atop", "source-in", "source-out", "source-over", "space", "space-around", "space-between", "space-evenly", "spell-out", "square",
-    "square-button", "start", "static", "status-bar", "stretch", "stroke", "sub",
-    "subpixel-antialiased", "super", "sw-resize", "symbolic", "symbols", "system-ui", "table",
-    "table-caption", "table-cell", "table-column", "table-column-group",
-    "table-footer-group", "table-header-group", "table-row", "table-row-group",
-    "tamil",
-    "telugu", "text", "text-bottom", "text-top", "textarea", "textfield", "thai",
-    "thick", "thin", "threeddarkshadow", "threedface", "threedhighlight",
-    "threedlightshadow", "threedshadow", "tibetan", "tigre", "tigrinya-er",
-    "tigrinya-er-abegede", "tigrinya-et", "tigrinya-et-abegede", "to", "top",
-    "trad-chinese-formal", "trad-chinese-informal", "transform",
-    "translate", "translate3d", "translateX", "translateY", "translateZ",
-    "transparent", "ultra-condensed", "ultra-expanded", "underline", "unset", "up",
-    "upper-alpha", "upper-armenian", "upper-greek", "upper-hexadecimal",
-    "upper-latin", "upper-norwegian", "upper-roman", "uppercase", "urdu", "url",
-    "var", "vertical", "vertical-text", "visible", "visibleFill", "visiblePainted",
-    "visibleStroke", "visual", "w-resize", "wait", "wave", "wider",
-    "window", "windowframe", "windowtext", "words", "wrap", "wrap-reverse", "x-large", "x-small", "xor",
-    "xx-large", "xx-small"
-  ], valueKeywords = keySet(valueKeywords_);
-
-  var allWords = documentTypes_.concat(mediaTypes_).concat(mediaFeatures_).concat(mediaValueKeywords_)
-    .concat(propertyKeywords_).concat(nonStandardPropertyKeywords_).concat(colorKeywords_)
-    .concat(valueKeywords_);
-  CodeMirror.registerHelper("hintWords", "css", allWords);
-
-  function tokenCComment(stream, state) {
-    var maybeEnd = false, ch;
-    while ((ch = stream.next()) != null) {
-      if (maybeEnd && ch == "/") {
-        state.tokenize = null;
-        break;
-      }
-      maybeEnd = (ch == "*");
-    }
-    return ["comment", "comment"];
-  }
-
-  CodeMirror.defineMIME("text/css", {
-    documentTypes: documentTypes,
-    mediaTypes: mediaTypes,
-    mediaFeatures: mediaFeatures,
-    mediaValueKeywords: mediaValueKeywords,
-    propertyKeywords: propertyKeywords,
-    nonStandardPropertyKeywords: nonStandardPropertyKeywords,
-    fontProperties: fontProperties,
-    counterDescriptors: counterDescriptors,
-    colorKeywords: colorKeywords,
-    valueKeywords: valueKeywords,
-    tokenHooks: {
-      "/": function(stream, state) {
-        if (!stream.eat("*")) return false;
-        state.tokenize = tokenCComment;
-        return tokenCComment(stream, state);
-      }
-    },
-    name: "css"
-  });
-
-  CodeMirror.defineMIME("text/x-scss", {
-    mediaTypes: mediaTypes,
-    mediaFeatures: mediaFeatures,
-    mediaValueKeywords: mediaValueKeywords,
-    propertyKeywords: propertyKeywords,
-    nonStandardPropertyKeywords: nonStandardPropertyKeywords,
-    colorKeywords: colorKeywords,
-    valueKeywords: valueKeywords,
-    fontProperties: fontProperties,
-    allowNested: true,
-    lineComment: "//",
-    tokenHooks: {
-      "/": function(stream, state) {
-        if (stream.eat("/")) {
-          stream.skipToEnd();
-          return ["comment", "comment"];
-        } else if (stream.eat("*")) {
-          state.tokenize = tokenCComment;
-          return tokenCComment(stream, state);
-        } else {
-          return ["operator", "operator"];
-        }
-      },
-      ":": function(stream) {
-        if (stream.match(/\s*\{/, false))
-          return [null, null]
-        return false;
-      },
-      "$": function(stream) {
-        stream.match(/^[\w-]+/);
-        if (stream.match(/^\s*:/, false))
-          return ["variable-2", "variable-definition"];
-        return ["variable-2", "variable"];
-      },
-      "#": function(stream) {
-        if (!stream.eat("{")) return false;
-        return [null, "interpolation"];
-      }
-    },
-    name: "css",
-    helperType: "scss"
-  });
-
-  CodeMirror.defineMIME("text/x-less", {
-    mediaTypes: mediaTypes,
-    mediaFeatures: mediaFeatures,
-    mediaValueKeywords: mediaValueKeywords,
-    propertyKeywords: propertyKeywords,
-    nonStandardPropertyKeywords: nonStandardPropertyKeywords,
-    colorKeywords: colorKeywords,
-    valueKeywords: valueKeywords,
-    fontProperties: fontProperties,
-    allowNested: true,
-    lineComment: "//",
-    tokenHooks: {
-      "/": function(stream, state) {
-        if (stream.eat("/")) {
-          stream.skipToEnd();
-          return ["comment", "comment"];
-        } else if (stream.eat("*")) {
-          state.tokenize = tokenCComment;
-          return tokenCComment(stream, state);
-        } else {
-          return ["operator", "operator"];
-        }
-      },
-      "@": function(stream) {
-        if (stream.eat("{")) return [null, "interpolation"];
-        if (stream.match(/^(charset|document|font-face|import|(-(moz|ms|o|webkit)-)?keyframes|media|namespace|page|supports)\b/i, false)) return false;
-        stream.eatWhile(/[\w\\\-]/);
-        if (stream.match(/^\s*:/, false))
-          return ["variable-2", "variable-definition"];
-        return ["variable-2", "variable"];
-      },
-      "&": function() {
-        return ["atom", "atom"];
-      }
-    },
-    name: "css",
-    helperType: "less"
-  });
-
-  CodeMirror.defineMIME("text/x-gss", {
-    documentTypes: documentTypes,
-    mediaTypes: mediaTypes,
-    mediaFeatures: mediaFeatures,
-    propertyKeywords: propertyKeywords,
-    nonStandardPropertyKeywords: nonStandardPropertyKeywords,
-    fontProperties: fontProperties,
-    counterDescriptors: counterDescriptors,
-    colorKeywords: colorKeywords,
-    valueKeywords: valueKeywords,
-    supportsAtComponent: true,
-    tokenHooks: {
-      "/": function(stream, state) {
-        if (!stream.eat("*")) return false;
-        state.tokenize = tokenCComment;
-        return tokenCComment(stream, state);
-      }
-    },
-    name: "css",
-    helperType: "gss"
-  });
-
-});
Index: admin/js/codemirror/mode/htmlmixed/htmlmixed.js
===================================================================
--- admin/js/codemirror/mode/htmlmixed/htmlmixed.js	(revision 3979)
+++ 	(revision )
@@ -1,152 +1,0 @@
-// CodeMirror, copyright (c) by Marijn Haverbeke and others
-// Distributed under an MIT license: https://codemirror.net/LICENSE
-
-(function(mod) {
-  if (typeof exports == "object" && typeof module == "object") // CommonJS
-    mod(require("../../lib/codemirror"), require("../xml/xml"), require("../javascript/javascript"), require("../css/css"));
-  else if (typeof define == "function" && define.amd) // AMD
-    define(["../../lib/codemirror", "../xml/xml", "../javascript/javascript", "../css/css"], mod);
-  else // Plain browser env
-    mod(CodeMirror);
-})(function(CodeMirror) {
-  "use strict";
-
-  var defaultTags = {
-    script: [
-      ["lang", /(javascript|babel)/i, "javascript"],
-      ["type", /^(?:text|application)\/(?:x-)?(?:java|ecma)script$|^module$|^$/i, "javascript"],
-      ["type", /./, "text/plain"],
-      [null, null, "javascript"]
-    ],
-    style:  [
-      ["lang", /^css$/i, "css"],
-      ["type", /^(text\/)?(x-)?(stylesheet|css)$/i, "css"],
-      ["type", /./, "text/plain"],
-      [null, null, "css"]
-    ]
-  };
-
-  function maybeBackup(stream, pat, style) {
-    var cur = stream.current(), close = cur.search(pat);
-    if (close > -1) {
-      stream.backUp(cur.length - close);
-    } else if (cur.match(/<\/?$/)) {
-      stream.backUp(cur.length);
-      if (!stream.match(pat, false)) stream.match(cur);
-    }
-    return style;
-  }
-
-  var attrRegexpCache = {};
-  function getAttrRegexp(attr) {
-    var regexp = attrRegexpCache[attr];
-    if (regexp) return regexp;
-    return attrRegexpCache[attr] = new RegExp("\\s+" + attr + "\\s*=\\s*('|\")?([^'\"]+)('|\")?\\s*");
-  }
-
-  function getAttrValue(text, attr) {
-    var match = text.match(getAttrRegexp(attr))
-    return match ? /^\s*(.*?)\s*$/.exec(match[2])[1] : ""
-  }
-
-  function getTagRegexp(tagName, anchored) {
-    return new RegExp((anchored ? "^" : "") + "<\/\s*" + tagName + "\s*>", "i");
-  }
-
-  function addTags(from, to) {
-    for (var tag in from) {
-      var dest = to[tag] || (to[tag] = []);
-      var source = from[tag];
-      for (var i = source.length - 1; i >= 0; i--)
-        dest.unshift(source[i])
-    }
-  }
-
-  function findMatchingMode(tagInfo, tagText) {
-    for (var i = 0; i < tagInfo.length; i++) {
-      var spec = tagInfo[i];
-      if (!spec[0] || spec[1].test(getAttrValue(tagText, spec[0]))) return spec[2];
-    }
-  }
-
-  CodeMirror.defineMode("htmlmixed", function (config, parserConfig) {
-    var htmlMode = CodeMirror.getMode(config, {
-      name: "xml",
-      htmlMode: true,
-      multilineTagIndentFactor: parserConfig.multilineTagIndentFactor,
-      multilineTagIndentPastTag: parserConfig.multilineTagIndentPastTag
-    });
-
-    var tags = {};
-    var configTags = parserConfig && parserConfig.tags, configScript = parserConfig && parserConfig.scriptTypes;
-    addTags(defaultTags, tags);
-    if (configTags) addTags(configTags, tags);
-    if (configScript) for (var i = configScript.length - 1; i >= 0; i--)
-      tags.script.unshift(["type", configScript[i].matches, configScript[i].mode])
-
-    function html(stream, state) {
-      var style = htmlMode.token(stream, state.htmlState), tag = /\btag\b/.test(style), tagName
-      if (tag && !/[<>\s\/]/.test(stream.current()) &&
-          (tagName = state.htmlState.tagName && state.htmlState.tagName.toLowerCase()) &&
-          tags.hasOwnProperty(tagName)) {
-        state.inTag = tagName + " "
-      } else if (state.inTag && tag && />$/.test(stream.current())) {
-        var inTag = /^([\S]+) (.*)/.exec(state.inTag)
-        state.inTag = null
-        var modeSpec = stream.current() == ">" && findMatchingMode(tags[inTag[1]], inTag[2])
-        var mode = CodeMirror.getMode(config, modeSpec)
-        var endTagA = getTagRegexp(inTag[1], true), endTag = getTagRegexp(inTag[1], false);
-        state.token = function (stream, state) {
-          if (stream.match(endTagA, false)) {
-            state.token = html;
-            state.localState = state.localMode = null;
-            return null;
-          }
-          return maybeBackup(stream, endTag, state.localMode.token(stream, state.localState));
-        };
-        state.localMode = mode;
-        state.localState = CodeMirror.startState(mode, htmlMode.indent(state.htmlState, "", ""));
-      } else if (state.inTag) {
-        state.inTag += stream.current()
-        if (stream.eol()) state.inTag += " "
-      }
-      return style;
-    };
-
-    return {
-      startState: function () {
-        var state = CodeMirror.startState(htmlMode);
-        return {token: html, inTag: null, localMode: null, localState: null, htmlState: state};
-      },
-
-      copyState: function (state) {
-        var local;
-        if (state.localState) {
-          local = CodeMirror.copyState(state.localMode, state.localState);
-        }
-        return {token: state.token, inTag: state.inTag,
-                localMode: state.localMode, localState: local,
-                htmlState: CodeMirror.copyState(htmlMode, state.htmlState)};
-      },
-
-      token: function (stream, state) {
-        return state.token(stream, state);
-      },
-
-      indent: function (state, textAfter, line) {
-        if (!state.localMode || /^\s*<\//.test(textAfter))
-          return htmlMode.indent(state.htmlState, textAfter, line);
-        else if (state.localMode.indent)
-          return state.localMode.indent(state.localState, textAfter, line);
-        else
-          return CodeMirror.Pass;
-      },
-
-      innerMode: function (state) {
-        return {state: state.localState || state.htmlState, mode: state.localMode || htmlMode};
-      }
-    };
-  }, "xml", "javascript", "css");
-
-  CodeMirror.defineMIME("text/html", "htmlmixed");
-});
Index: admin/js/codemirror/mode/javascript/javascript.js
===================================================================
--- admin/js/codemirror/mode/javascript/javascript.js	(revision 3979)
+++ 	(revision )
@@ -1,923 +1,0 @@
-// CodeMirror, copyright (c) by Marijn Haverbeke and others
-// Distributed under an MIT license: https://codemirror.net/LICENSE
-
-(function(mod) {
-  if (typeof exports == "object" && typeof module == "object") // CommonJS
-    mod(require("../../lib/codemirror"));
-  else if (typeof define == "function" && define.amd) // AMD
-    define(["../../lib/codemirror"], mod);
-  else // Plain browser env
-    mod(CodeMirror);
-})(function(CodeMirror) {
-"use strict";
-
-CodeMirror.defineMode("javascript", function(config, parserConfig) {
-  var indentUnit = config.indentUnit;
-  var statementIndent = parserConfig.statementIndent;
-  var jsonldMode = parserConfig.jsonld;
-  var jsonMode = parserConfig.json || jsonldMode;
-  var isTS = parserConfig.typescript;
-  var wordRE = parserConfig.wordCharacters || /[\w$\xa1-\uffff]/;
-
-  // Tokenizer
-
-  var keywords = function(){
-    function kw(type) {return {type: type, style: "keyword"};}
-    var A = kw("keyword a"), B = kw("keyword b"), C = kw("keyword c"), D = kw("keyword d");
-    var operator = kw("operator"), atom = {type: "atom", style: "atom"};
-
-    return {
-      "if": kw("if"), "while": A, "with": A, "else": B, "do": B, "try": B, "finally": B,
-      "return": D, "break": D, "continue": D, "new": kw("new"), "delete": C, "void": C, "throw": C,
-      "debugger": kw("debugger"), "var": kw("var"), "const": kw("var"), "let": kw("var"),
-      "function": kw("function"), "catch": kw("catch"),
-      "for": kw("for"), "switch": kw("switch"), "case": kw("case"), "default": kw("default"),
-      "in": operator, "typeof": operator, "instanceof": operator,
-      "true": atom, "false": atom, "null": atom, "undefined": atom, "NaN": atom, "Infinity": atom,
-      "this": kw("this"), "class": kw("class"), "super": kw("atom"),
-      "yield": C, "export": kw("export"), "import": kw("import"), "extends": C,
-      "await": C
-    };
-  }();
-
-  var isOperatorChar = /[+\-*&%=<>!?|~^@]/;
-  var isJsonldKeyword = /^@(context|id|value|language|type|container|list|set|reverse|index|base|vocab|graph)"/;
-
-  function readRegexp(stream) {
-    var escaped = false, next, inSet = false;
-    while ((next = stream.next()) != null) {
-      if (!escaped) {
-        if (next == "/" && !inSet) return;
-        if (next == "[") inSet = true;
-        else if (inSet && next == "]") inSet = false;
-      }
-      escaped = !escaped && next == "\\";
-    }
-  }
-
-  // Used as scratch variables to communicate multiple values without
-  // consing up tons of objects.
-  var type, content;
-  function ret(tp, style, cont) {
-    type = tp; content = cont;
-    return style;
-  }
-  function tokenBase(stream, state) {
-    var ch = stream.next();
-    if (ch == '"' || ch == "'") {
-      state.tokenize = tokenString(ch);
-      return state.tokenize(stream, state);
-    } else if (ch == "." && stream.match(/^\d+(?:[eE][+\-]?\d+)?/)) {
-      return ret("number", "number");
-    } else if (ch == "." && stream.match("..")) {
-      return ret("spread", "meta");
-    } else if (/[\[\]{}\(\),;\:\.]/.test(ch)) {
-      return ret(ch);
-    } else if (ch == "=" && stream.eat(">")) {
-      return ret("=>", "operator");
-    } else if (ch == "0" && stream.match(/^(?:x[\da-f]+|o[0-7]+|b[01]+)n?/i)) {
-      return ret("number", "number");
-    } else if (/\d/.test(ch)) {
-      stream.match(/^\d*(?:n|(?:\.\d*)?(?:[eE][+\-]?\d+)?)?/);
-      return ret("number", "number");
-    } else if (ch == "/") {
-      if (stream.eat("*")) {
-        state.tokenize = tokenComment;
-        return tokenComment(stream, state);
-      } else if (stream.eat("/")) {
-        stream.skipToEnd();
-        return ret("comment", "comment");
-      } else if (expressionAllowed(stream, state, 1)) {
-        readRegexp(stream);
-        stream.match(/^\b(([gimyus])(?![gimyus]*\2))+\b/);
-        return ret("regexp", "string-2");
-      } else {
-        stream.eat("=");
-        return ret("operator", "operator", stream.current());
-      }
-    } else if (ch == "`") {
-      state.tokenize = tokenQuasi;
-      return tokenQuasi(stream, state);
-    } else if (ch == "#") {
-      stream.skipToEnd();
-      return ret("error", "error");
-    } else if (isOperatorChar.test(ch)) {
-      if (ch != ">" || !state.lexical || state.lexical.type != ">") {
-        if (stream.eat("=")) {
-          if (ch == "!" || ch == "=") stream.eat("=")
-        } else if (/[<>*+\-]/.test(ch)) {
-          stream.eat(ch)
-          if (ch == ">") stream.eat(ch)
-        }
-      }
-      return ret("operator", "operator", stream.current());
-    } else if (wordRE.test(ch)) {
-      stream.eatWhile(wordRE);
-      var word = stream.current()
-      if (state.lastType != ".") {
-        if (keywords.propertyIsEnumerable(word)) {
-          var kw = keywords[word]
-          return ret(kw.type, kw.style, word)
-        }
-        if (word == "async" && stream.match(/^(\s|\/\*.*?\*\/)*[\[\(\w]/, false))
-          return ret("async", "keyword", word)
-      }
-      return ret("variable", "variable", word)
-    }
-  }
-
-  function tokenString(quote) {
-    return function(stream, state) {
-      var escaped = false, next;
-      if (jsonldMode && stream.peek() == "@" && stream.match(isJsonldKeyword)){
-        state.tokenize = tokenBase;
-        return ret("jsonld-keyword", "meta");
-      }
-      while ((next = stream.next()) != null) {
-        if (next == quote && !escaped) break;
-        escaped = !escaped && next == "\\";
-      }
-      if (!escaped) state.tokenize = tokenBase;
-      return ret("string", "string");
-    };
-  }
-
-  function tokenComment(stream, state) {
-    var maybeEnd = false, ch;
-    while (ch = stream.next()) {
-      if (ch == "/" && maybeEnd) {
-        state.tokenize = tokenBase;
-        break;
-      }
-      maybeEnd = (ch == "*");
-    }
-    return ret("comment", "comment");
-  }
-
-  function tokenQuasi(stream, state) {
-    var escaped = false, next;
-    while ((next = stream.next()) != null) {
-      if (!escaped && (next == "`" || next == "$" && stream.eat("{"))) {
-        state.tokenize = tokenBase;
-        break;
-      }
-      escaped = !escaped && next == "\\";
-    }
-    return ret("quasi", "string-2", stream.current());
-  }
-
-  var brackets = "([{}])";
-  // This is a crude lookahead trick to try and notice that we're
-  // parsing the argument patterns for a fat-arrow function before we
-  // actually hit the arrow token. It only works if the arrow is on
-  // the same line as the arguments and there's no strange noise
-  // (comments) in between. Fallback is to only notice when we hit the
-  // arrow, and not declare the arguments as locals for the arrow
-  // body.
-  function findFatArrow(stream, state) {
-    if (state.fatArrowAt) state.fatArrowAt = null;
-    var arrow = stream.string.indexOf("=>", stream.start);
-    if (arrow < 0) return;
-
-    if (isTS) { // Try to skip TypeScript return type declarations after the arguments
-      var m = /:\s*(?:\w+(?:<[^>]*>|\[\])?|\{[^}]*\})\s*$/.exec(stream.string.slice(stream.start, arrow))
-      if (m) arrow = m.index
-    }
-
-    var depth = 0, sawSomething = false;
-    for (var pos = arrow - 1; pos >= 0; --pos) {
-      var ch = stream.string.charAt(pos);
-      var bracket = brackets.indexOf(ch);
-      if (bracket >= 0 && bracket < 3) {
-        if (!depth) { ++pos; break; }
-        if (--depth == 0) { if (ch == "(") sawSomething = true; break; }
-      } else if (bracket >= 3 && bracket < 6) {
-        ++depth;
-      } else if (wordRE.test(ch)) {
-        sawSomething = true;
-      } else if (/["'\/]/.test(ch)) {
-        return;
-      } else if (sawSomething && !depth) {
-        ++pos;
-        break;
-      }
-    }
-    if (sawSomething && !depth) state.fatArrowAt = pos;
-  }
-
-  // Parser
-
-  var atomicTypes = {"atom": true, "number": true, "variable": true, "string": true, "regexp": true, "this": true, "jsonld-keyword": true};
-
-  function JSLexical(indented, column, type, align, prev, info) {
-    this.indented = indented;
-    this.column = column;
-    this.type = type;
-    this.prev = prev;
-    this.info = info;
-    if (align != null) this.align = align;
-  }
-
-  function inScope(state, varname) {
-    for (var v = state.localVars; v; v = v.next)
-      if (v.name == varname) return true;
-    for (var cx = state.context; cx; cx = cx.prev) {
-      for (var v = cx.vars; v; v = v.next)
-        if (v.name == varname) return true;
-    }
-  }
-
-  function parseJS(state, style, type, content, stream) {
-    var cc = state.cc;
-    // Communicate our context to the combinators.
-    // (Less wasteful than consing up a hundred closures on every call.)
-    cx.state = state; cx.stream = stream; cx.marked = null, cx.cc = cc; cx.style = style;
-
-    if (!state.lexical.hasOwnProperty("align"))
-      state.lexical.align = true;
-
-    while(true) {
-      var combinator = cc.length ? cc.pop() : jsonMode ? expression : statement;
-      if (combinator(type, content)) {
-        while(cc.length && cc[cc.length - 1].lex)
-          cc.pop()();
-        if (cx.marked) return cx.marked;
-        if (type == "variable" && inScope(state, content)) return "variable-2";
-        return style;
-      }
-    }
-  }
-
-  // Combinator utils
-
-  var cx = {state: null, column: null, marked: null, cc: null};
-  function pass() {
-    for (var i = arguments.length - 1; i >= 0; i--) cx.cc.push(arguments[i]);
-  }
-  function cont() {
-    pass.apply(null, arguments);
-    return true;
-  }
-  function inList(name, list) {
-    for (var v = list; v; v = v.next) if (v.name == name) return true
-    return false;
-  }
-  function register(varname) {
-    var state = cx.state;
-    cx.marked = "def";
-    if (state.context) {
-      if (state.lexical.info == "var" && state.context && state.context.block) {
-        // FIXME function decls are also not block scoped
-        var newContext = registerVarScoped(varname, state.context)
-        if (newContext != null) {
-          state.context = newContext
-          return
-        }
-      } else if (!inList(varname, state.localVars)) {
-        state.localVars = new Var(varname, state.localVars)
-        return
-      }
-    }
-    // Fall through means this is global
-    if (parserConfig.globalVars && !inList(varname, state.globalVars))
-      state.globalVars = new Var(varname, state.globalVars)
-  }
-  function registerVarScoped(varname, context) {
-    if (!context) {
-      return null
-    } else if (context.block) {
-      var inner = registerVarScoped(varname, context.prev)
-      if (!inner) return null
-      if (inner == context.prev) return context
-      return new Context(inner, context.vars, true)
-    } else if (inList(varname, context.vars)) {
-      return context
-    } else {
-      return new Context(context.prev, new Var(varname, context.vars), false)
-    }
-  }
-
-  function isModifier(name) {
-    return name == "public" || name == "private" || name == "protected" || name == "abstract" || name == "readonly"
-  }
-
-  // Combinators
-
-  function Context(prev, vars, block) { this.prev = prev; this.vars = vars; this.block = block }
-  function Var(name, next) { this.name = name; this.next = next }
-
-  var defaultVars = new Var("this", new Var("arguments", null))
-  function pushcontext() {
-    cx.state.context = new Context(cx.state.context, cx.state.localVars, false)
-    cx.state.localVars = defaultVars
-  }
-  function pushblockcontext() {
-    cx.state.context = new Context(cx.state.context, cx.state.localVars, true)
-    cx.state.localVars = null
-  }
-  function popcontext() {
-    cx.state.localVars = cx.state.context.vars
-    cx.state.context = cx.state.context.prev
-  }
-  popcontext.lex = true
-  function pushlex(type, info) {
-    var result = function() {
-      var state = cx.state, indent = state.indented;
-      if (state.lexical.type == "stat") indent = state.lexical.indented;
-      else for (var outer = state.lexical; outer && outer.type == ")" && outer.align; outer = outer.prev)
-        indent = outer.indented;
-      state.lexical = new JSLexical(indent, cx.stream.column(), type, null, state.lexical, info);
-    };
-    result.lex = true;
-    return result;
-  }
-  function poplex() {
-    var state = cx.state;
-    if (state.lexical.prev) {
-      if (state.lexical.type == ")")
-        state.indented = state.lexical.indented;
-      state.lexical = state.lexical.prev;
-    }
-  }
-  poplex.lex = true;
-
-  function expect(wanted) {
-    function exp(type) {
-      if (type == wanted) return cont();
-      else if (wanted == ";" || type == "}" || type == ")" || type == "]") return pass();
-      else return cont(exp);
-    };
-    return exp;
-  }
-
-  function statement(type, value) {
-    if (type == "var") return cont(pushlex("vardef", value), vardef, expect(";"), poplex);
-    if (type == "keyword a") return cont(pushlex("form"), parenExpr, statement, poplex);
-    if (type == "keyword b") return cont(pushlex("form"), statement, poplex);
-    if (type == "keyword d") return cx.stream.match(/^\s*$/, false) ? cont() : cont(pushlex("stat"), maybeexpression, expect(";"), poplex);
-    if (type == "debugger") return cont(expect(";"));
-    if (type == "{") return cont(pushlex("}"), pushblockcontext, block, poplex, popcontext);
-    if (type == ";") return cont();
-    if (type == "if") {
-      if (cx.state.lexical.info == "else" && cx.state.cc[cx.state.cc.length - 1] == poplex)
-        cx.state.cc.pop()();
-      return cont(pushlex("form"), parenExpr, statement, poplex, maybeelse);
-    }
-    if (type == "function") return cont(functiondef);
-    if (type == "for") return cont(pushlex("form"), forspec, statement, poplex);
-    if (type == "class" || (isTS && value == "interface")) {
-      cx.marked = "keyword"
-      return cont(pushlex("form", type == "class" ? type : value), className, poplex)
-    }
-    if (type == "variable") {
-      if (isTS && value == "declare") {
-        cx.marked = "keyword"
-        return cont(statement)
-      } else if (isTS && (value == "module" || value == "enum" || value == "type") && cx.stream.match(/^\s*\w/, false)) {
-        cx.marked = "keyword"
-        if (value == "enum") return cont(enumdef);
-        else if (value == "type") return cont(typename, expect("operator"), typeexpr, expect(";"));
-        else return cont(pushlex("form"), pattern, expect("{"), pushlex("}"), block, poplex, poplex)
-      } else if (isTS && value == "namespace") {
-        cx.marked = "keyword"
-        return cont(pushlex("form"), expression, statement, poplex)
-      } else if (isTS && value == "abstract") {
-        cx.marked = "keyword"
-        return cont(statement)
-      } else {
-        return cont(pushlex("stat"), maybelabel);
-      }
-    }
-    if (type == "switch") return cont(pushlex("form"), parenExpr, expect("{"), pushlex("}", "switch"), pushblockcontext,
-                                      block, poplex, poplex, popcontext);
-    if (type == "case") return cont(expression, expect(":"));
-    if (type == "default") return cont(expect(":"));
-    if (type == "catch") return cont(pushlex("form"), pushcontext, maybeCatchBinding, statement, poplex, popcontext);
-    if (type == "export") return cont(pushlex("stat"), afterExport, poplex);
-    if (type == "import") return cont(pushlex("stat"), afterImport, poplex);
-    if (type == "async") return cont(statement)
-    if (value == "@") return cont(expression, statement)
-    return pass(pushlex("stat"), expression, expect(";"), poplex);
-  }
-  function maybeCatchBinding(type) {
-    if (type == "(") return cont(funarg, expect(")"))
-  }
-  function expression(type, value) {
-    return expressionInner(type, value, false);
-  }
-  function expressionNoComma(type, value) {
-    return expressionInner(type, value, true);
-  }
-  function parenExpr(type) {
-    if (type != "(") return pass()
-    return cont(pushlex(")"), expression, expect(")"), poplex)
-  }
-  function expressionInner(type, value, noComma) {
-    if (cx.state.fatArrowAt == cx.stream.start) {
-      var body = noComma ? arrowBodyNoComma : arrowBody;
-      if (type == "(") return cont(pushcontext, pushlex(")"), commasep(funarg, ")"), poplex, expect("=>"), body, popcontext);
-      else if (type == "variable") return pass(pushcontext, pattern, expect("=>"), body, popcontext);
-    }
-
-    var maybeop = noComma ? maybeoperatorNoComma : maybeoperatorComma;
-    if (atomicTypes.hasOwnProperty(type)) return cont(maybeop);
-    if (type == "function") return cont(functiondef, maybeop);
-    if (type == "class" || (isTS && value == "interface")) { cx.marked = "keyword"; return cont(pushlex("form"), classExpression, poplex); }
-    if (type == "keyword c" || type == "async") return cont(noComma ? expressionNoComma : expression);
-    if (type == "(") return cont(pushlex(")"), maybeexpression, expect(")"), poplex, maybeop);
-    if (type == "operator" || type == "spread") return cont(noComma ? expressionNoComma : expression);
-    if (type == "[") return cont(pushlex("]"), arrayLiteral, poplex, maybeop);
-    if (type == "{") return contCommasep(objprop, "}", null, maybeop);
-    if (type == "quasi") return pass(quasi, maybeop);
-    if (type == "new") return cont(maybeTarget(noComma));
-    if (type == "import") return cont(expression);
-    return cont();
-  }
-  function maybeexpression(type) {
-    if (type.match(/[;\}\)\],]/)) return pass();
-    return pass(expression);
-  }
-
-  function maybeoperatorComma(type, value) {
-    if (type == ",") return cont(expression);
-    return maybeoperatorNoComma(type, value, false);
-  }
-  function maybeoperatorNoComma(type, value, noComma) {
-    var me = noComma == false ? maybeoperatorComma : maybeoperatorNoComma;
-    var expr = noComma == false ? expression : expressionNoComma;
-    if (type == "=>") return cont(pushcontext, noComma ? arrowBodyNoComma : arrowBody, popcontext);
-    if (type == "operator") {
-      if (/\+\+|--/.test(value) || isTS && value == "!") return cont(me);
-      if (isTS && value == "<" && cx.stream.match(/^([^>]|<.*?>)*>\s*\(/, false))
-        return cont(pushlex(">"), commasep(typeexpr, ">"), poplex, me);
-      if (value == "?") return cont(expression, expect(":"), expr);
-      return cont(expr);
-    }
-    if (type == "quasi") { return pass(quasi, me); }
-    if (type == ";") return;
-    if (type == "(") return contCommasep(expressionNoComma, ")", "call", me);
-    if (type == ".") return cont(property, me);
-    if (type == "[") return cont(pushlex("]"), maybeexpression, expect("]"), poplex, me);
-    if (isTS && value == "as") { cx.marked = "keyword"; return cont(typeexpr, me) }
-    if (type == "regexp") {
-      cx.state.lastType = cx.marked = "operator"
-      cx.stream.backUp(cx.stream.pos - cx.stream.start - 1)
-      return cont(expr)
-    }
-  }
-  function quasi(type, value) {
-    if (type != "quasi") return pass();
-    if (value.slice(value.length - 2) != "${") return cont(quasi);
-    return cont(expression, continueQuasi);
-  }
-  function continueQuasi(type) {
-    if (type == "}") {
-      cx.marked = "string-2";
-      cx.state.tokenize = tokenQuasi;
-      return cont(quasi);
-    }
-  }
-  function arrowBody(type) {
-    findFatArrow(cx.stream, cx.state);
-    return pass(type == "{" ? statement : expression);
-  }
-  function arrowBodyNoComma(type) {
-    findFatArrow(cx.stream, cx.state);
-    return pass(type == "{" ? statement : expressionNoComma);
-  }
-  function maybeTarget(noComma) {
-    return function(type) {
-      if (type == ".") return cont(noComma ? targetNoComma : target);
-      else if (type == "variable" && isTS) return cont(maybeTypeArgs, noComma ? maybeoperatorNoComma : maybeoperatorComma)
-      else return pass(noComma ? expressionNoComma : expression);
-    };
-  }
-  function target(_, value) {
-    if (value == "target") { cx.marked = "keyword"; return cont(maybeoperatorComma); }
-  }
-  function targetNoComma(_, value) {
-    if (value == "target") { cx.marked = "keyword"; return cont(maybeoperatorNoComma); }
-  }
-  function maybelabel(type) {
-    if (type == ":") return cont(poplex, statement);
-    return pass(maybeoperatorComma, expect(";"), poplex);
-  }
-  function property(type) {
-    if (type == "variable") {cx.marked = "property"; return cont();}
-  }
-  function objprop(type, value) {
-    if (type == "async") {
-      cx.marked = "property";
-      return cont(objprop);
-    } else if (type == "variable" || cx.style == "keyword") {
-      cx.marked = "property";
-      if (value == "get" || value == "set") return cont(getterSetter);
-      var m // Work around fat-arrow-detection complication for detecting typescript typed arrow params
-      if (isTS && cx.state.fatArrowAt == cx.stream.start && (m = cx.stream.match(/^\s*:\s*/, false)))
-        cx.state.fatArrowAt = cx.stream.pos + m[0].length
-      return cont(afterprop);
-    } else if (type == "number" || type == "string") {
-      cx.marked = jsonldMode ? "property" : (cx.style + " property");
-      return cont(afterprop);
-    } else if (type == "jsonld-keyword") {
-      return cont(afterprop);
-    } else if (isTS && isModifier(value)) {
-      cx.marked = "keyword"
-      return cont(objprop)
-    } else if (type == "[") {
-      return cont(expression, maybetypeOrIn, expect("]"), afterprop);
-    } else if (type == "spread") {
-      return cont(expressionNoComma, afterprop);
-    } else if (value == "*") {
-      cx.marked = "keyword";
-      return cont(objprop);
-    } else if (type == ":") {
-      return pass(afterprop)
-    }
-  }
-  function getterSetter(type) {
-    if (type != "variable") return pass(afterprop);
-    cx.marked = "property";
-    return cont(functiondef);
-  }
-  function afterprop(type) {
-    if (type == ":") return cont(expressionNoComma);
-    if (type == "(") return pass(functiondef);
-  }
-  function commasep(what, end, sep) {
-    function proceed(type, value) {
-      if (sep ? sep.indexOf(type) > -1 : type == ",") {
-        var lex = cx.state.lexical;
-        if (lex.info == "call") lex.pos = (lex.pos || 0) + 1;
-        return cont(function(type, value) {
-          if (type == end || value == end) return pass()
-          return pass(what)
-        }, proceed);
-      }
-      if (type == end || value == end) return cont();
-      if (sep && sep.indexOf(";") > -1) return pass(what)
-      return cont(expect(end));
-    }
-    return function(type, value) {
-      if (type == end || value == end) return cont();
-      return pass(what, proceed);
-    };
-  }
-  function contCommasep(what, end, info) {
-    for (var i = 3; i < arguments.length; i++)
-      cx.cc.push(arguments[i]);
-    return cont(pushlex(end, info), commasep(what, end), poplex);
-  }
-  function block(type) {
-    if (type == "}") return cont();
-    return pass(statement, block);
-  }
-  function maybetype(type, value) {
-    if (isTS) {
-      if (type == ":") return cont(typeexpr);
-      if (value == "?") return cont(maybetype);
-    }
-  }
-  function maybetypeOrIn(type, value) {
-    if (isTS && (type == ":" || value == "in")) return cont(typeexpr)
-  }
-  function mayberettype(type) {
-    if (isTS && type == ":") {
-      if (cx.stream.match(/^\s*\w+\s+is\b/, false)) return cont(expression, isKW, typeexpr)
-      else return cont(typeexpr)
-    }
-  }
-  function isKW(_, value) {
-    if (value == "is") {
-      cx.marked = "keyword"
-      return cont()
-    }
-  }
-  function typeexpr(type, value) {
-    if (value == "keyof" || value == "typeof" || value == "infer") {
-      cx.marked = "keyword"
-      return cont(value == "typeof" ? expressionNoComma : typeexpr)
-    }
-    if (type == "variable" || value == "void") {
-      cx.marked = "type"
-      return cont(afterType)
-    }
-    if (value == "|" || value == "&") return cont(typeexpr)
-    if (type == "string" || type == "number" || type == "atom") return cont(afterType);
-    if (type == "[") return cont(pushlex("]"), commasep(typeexpr, "]", ","), poplex, afterType)
-    if (type == "{") return cont(pushlex("}"), commasep(typeprop, "}", ",;"), poplex, afterType)
-    if (type == "(") return cont(commasep(typearg, ")"), maybeReturnType, afterType)
-    if (type == "<") return cont(commasep(typeexpr, ">"), typeexpr)
-  }
-  function maybeReturnType(type) {
-    if (type == "=>") return cont(typeexpr)
-  }
-  function typeprop(type, value) {
-    if (type == "variable" || cx.style == "keyword") {
-      cx.marked = "property"
-      return cont(typeprop)
-    } else if (value == "?" || type == "number" || type == "string") {
-      return cont(typeprop)
-    } else if (type == ":") {
-      return cont(typeexpr)
-    } else if (type == "[") {
-      return cont(expect("variable"), maybetype, expect("]"), typeprop)
-    } else if (type == "(") {
-      return pass(functiondecl, typeprop)
-    }
-  }
-  function typearg(type, value) {
-    if (type == "variable" && cx.stream.match(/^\s*[?:]/, false) || value == "?") return cont(typearg)
-    if (type == ":") return cont(typeexpr)
-    if (type == "spread") return cont(typearg)
-    return pass(typeexpr)
-  }
-  function afterType(type, value) {
-    if (value == "<") return cont(pushlex(">"), commasep(typeexpr, ">"), poplex, afterType)
-    if (value == "|" || type == "." || value == "&") return cont(typeexpr)
-    if (type == "[") return cont(typeexpr, expect("]"), afterType)
-    if (value == "extends" || value == "implements") { cx.marked = "keyword"; return cont(typeexpr) }
-    if (value == "?") return cont(typeexpr, expect(":"), typeexpr)
-  }
-  function maybeTypeArgs(_, value) {
-    if (value == "<") return cont(pushlex(">"), commasep(typeexpr, ">"), poplex, afterType)
-  }
-  function typeparam() {
-    return pass(typeexpr, maybeTypeDefault)
-  }
-  function maybeTypeDefault(_, value) {
-    if (value == "=") return cont(typeexpr)
-  }
-  function vardef(_, value) {
-    if (value == "enum") {cx.marked = "keyword"; return cont(enumdef)}
-    return pass(pattern, maybetype, maybeAssign, vardefCont);
-  }
-  function pattern(type, value) {
-    if (isTS && isModifier(value)) { cx.marked = "keyword"; return cont(pattern) }
-    if (type == "variable") { register(value); return cont(); }
-    if (type == "spread") return cont(pattern);
-    if (type == "[") return contCommasep(eltpattern, "]");
-    if (type == "{") return contCommasep(proppattern, "}");
-  }
-  function proppattern(type, value) {
-    if (type == "variable" && !cx.stream.match(/^\s*:/, false)) {
-      register(value);
-      return cont(maybeAssign);
-    }
-    if (type == "variable") cx.marked = "property";
-    if (type == "spread") return cont(pattern);
-    if (type == "}") return pass();
-    if (type == "[") return cont(expression, expect(']'), expect(':'), proppattern);
-    return cont(expect(":"), pattern, maybeAssign);
-  }
-  function eltpattern() {
-    return pass(pattern, maybeAssign)
-  }
-  function maybeAssign(_type, value) {
-    if (value == "=") return cont(expressionNoComma);
-  }
-  function vardefCont(type) {
-    if (type == ",") return cont(vardef);
-  }
-  function maybeelse(type, value) {
-    if (type == "keyword b" && value == "else") return cont(pushlex("form", "else"), statement, poplex);
-  }
-  function forspec(type, value) {
-    if (value == "await") return cont(forspec);
-    if (type == "(") return cont(pushlex(")"), forspec1, poplex);
-  }
-  function forspec1(type) {
-    if (type == "var") return cont(vardef, forspec2);
-    if (type == "variable") return cont(forspec2);
-    return pass(forspec2)
-  }
-  function forspec2(type, value) {
-    if (type == ")") return cont()
-    if (type == ";") return cont(forspec2)
-    if (value == "in" || value == "of") { cx.marked = "keyword"; return cont(expression, forspec2) }
-    return pass(expression, forspec2)
-  }
-  function functiondef(type, value) {
-    if (value == "*") {cx.marked = "keyword"; return cont(functiondef);}
-    if (type == "variable") {register(value); return cont(functiondef);}
-    if (type == "(") return cont(pushcontext, pushlex(")"), commasep(funarg, ")"), poplex, mayberettype, statement, popcontext);
-    if (isTS && value == "<") return cont(pushlex(">"), commasep(typeparam, ">"), poplex, functiondef)
-  }
-  function functiondecl(type, value) {
-    if (value == "*") {cx.marked = "keyword"; return cont(functiondecl);}
-    if (type == "variable") {register(value); return cont(functiondecl);}
-    if (type == "(") return cont(pushcontext, pushlex(")"), commasep(funarg, ")"), poplex, mayberettype, popcontext);
-    if (isTS && value == "<") return cont(pushlex(">"), commasep(typeparam, ">"), poplex, functiondecl)
-  }
-  function typename(type, value) {
-    if (type == "keyword" || type == "variable") {
-      cx.marked = "type"
-      return cont(typename)
-    } else if (value == "<") {
-      return cont(pushlex(">"), commasep(typeparam, ">"), poplex)
-    }
-  }
-  function funarg(type, value) {
-    if (value == "@") cont(expression, funarg)
-    if (type == "spread") return cont(funarg);
-    if (isTS && isModifier(value)) { cx.marked = "keyword"; return cont(funarg); }
-    if (isTS && type == "this") return cont(maybetype, maybeAssign)
-    return pass(pattern, maybetype, maybeAssign);
-  }
-  function classExpression(type, value) {
-    // Class expressions may have an optional name.
-    if (type == "variable") return className(type, value);
-    return classNameAfter(type, value);
-  }
-  function className(type, value) {
-    if (type == "variable") {register(value); return cont(classNameAfter);}
-  }
-  function classNameAfter(type, value) {
-    if (value == "<") return cont(pushlex(">"), commasep(typeparam, ">"), poplex, classNameAfter)
-    if (value == "extends" || value == "implements" || (isTS && type == ",")) {
-      if (value == "implements") cx.marked = "keyword";
-      return cont(isTS ? typeexpr : expression, classNameAfter);
-    }
-    if (type == "{") return cont(pushlex("}"), classBody, poplex);
-  }
-  function classBody(type, value) {
-    if (type == "async" ||
-        (type == "variable" &&
-         (value == "static" || value == "get" || value == "set" || (isTS && isModifier(value))) &&
-         cx.stream.match(/^\s+[\w$\xa1-\uffff]/, false))) {
-      cx.marked = "keyword";
-      return cont(classBody);
-    }
-    if (type == "variable" || cx.style == "keyword") {
-      cx.marked = "property";
-      return cont(isTS ? classfield : functiondef, classBody);
-    }
-    if (type == "number" || type == "string") return cont(isTS ? classfield : functiondef, classBody);
-    if (type == "[")
-      return cont(expression, maybetype, expect("]"), isTS ? classfield : functiondef, classBody)
-    if (value == "*") {
-      cx.marked = "keyword";
-      return cont(classBody);
-    }
-    if (isTS && type == "(") return pass(functiondecl, classBody)
-    if (type == ";" || type == ",") return cont(classBody);
-    if (type == "}") return cont();
-    if (value == "@") return cont(expression, classBody)
-  }
-  function classfield(type, value) {
-    if (value == "?") return cont(classfield)
-    if (type == ":") return cont(typeexpr, maybeAssign)
-    if (value == "=") return cont(expressionNoComma)
-    var context = cx.state.lexical.prev, isInterface = context && context.info == "interface"
-    return pass(isInterface ? functiondecl : functiondef)
-  }
-  function afterExport(type, value) {
-    if (value == "*") { cx.marked = "keyword"; return cont(maybeFrom, expect(";")); }
-    if (value == "default") { cx.marked = "keyword"; return cont(expression, expect(";")); }
-    if (type == "{") return cont(commasep(exportField, "}"), maybeFrom, expect(";"));
-    return pass(statement);
-  }
-  function exportField(type, value) {
-    if (value == "as") { cx.marked = "keyword"; return cont(expect("variable")); }
-    if (type == "variable") return pass(expressionNoComma, exportField);
-  }
-  function afterImport(type) {
-    if (type == "string") return cont();
-    if (type == "(") return pass(expression);
-    return pass(importSpec, maybeMoreImports, maybeFrom);
-  }
-  function importSpec(type, value) {
-    if (type == "{") return contCommasep(importSpec, "}");
-    if (type == "variable") register(value);
-    if (value == "*") cx.marked = "keyword";
-    return cont(maybeAs);
-  }
-  function maybeMoreImports(type) {
-    if (type == ",") return cont(importSpec, maybeMoreImports)
-  }
-  function maybeAs(_type, value) {
-    if (value == "as") { cx.marked = "keyword"; return cont(importSpec); }
-  }
-  function maybeFrom(_type, value) {
-    if (value == "from") { cx.marked = "keyword"; return cont(expression); }
-  }
-  function arrayLiteral(type) {
-    if (type == "]") return cont();
-    return pass(commasep(expressionNoComma, "]"));
-  }
-  function enumdef() {
-    return pass(pushlex("form"), pattern, expect("{"), pushlex("}"), commasep(enummember, "}"), poplex, poplex)
-  }
-  function enummember() {
-    return pass(pattern, maybeAssign);
-  }
-
-  function isContinuedStatement(state, textAfter) {
-    return state.lastType == "operator" || state.lastType == "," ||
-      isOperatorChar.test(textAfter.charAt(0)) ||
-      /[,.]/.test(textAfter.charAt(0));
-  }
-
-  function expressionAllowed(stream, state, backUp) {
-    return state.tokenize == tokenBase &&
-      /^(?:operator|sof|keyword [bcd]|case|new|export|default|spread|[\[{}\(,;:]|=>)$/.test(state.lastType) ||
-      (state.lastType == "quasi" && /\{\s*$/.test(stream.string.slice(0, stream.pos - (backUp || 0))))
-  }
-
-  // Interface
-
-  return {
-    startState: function(basecolumn) {
-      var state = {
-        tokenize: tokenBase,
-        lastType: "sof",
-        cc: [],
-        lexical: new JSLexical((basecolumn || 0) - indentUnit, 0, "block", false),
-        localVars: parserConfig.localVars,
-        context: parserConfig.localVars && new Context(null, null, false),
-        indented: basecolumn || 0
-      };
-      if (parserConfig.globalVars && typeof parserConfig.globalVars == "object")
-        state.globalVars = parserConfig.globalVars;
-      return state;
-    },
-
-    token: function(stream, state) {
-      if (stream.sol()) {
-        if (!state.lexical.hasOwnProperty("align"))
-          state.lexical.align = false;
-        state.indented = stream.indentation();
-        findFatArrow(stream, state);
-      }
-      if (state.tokenize != tokenComment && stream.eatSpace()) return null;
-      var style = state.tokenize(stream, state);
-      if (type == "comment") return style;
-      state.lastType = type == "operator" && (content == "++" || content == "--") ? "incdec" : type;
-      return parseJS(state, style, type, content, stream);
-    },
-
-    indent: function(state, textAfter) {
-      if (state.tokenize == tokenComment) return CodeMirror.Pass;
-      if (state.tokenize != tokenBase) return 0;
-      var firstChar = textAfter && textAfter.charAt(0), lexical = state.lexical, top
-      // Kludge to prevent 'maybelse' from blocking lexical scope pops
-      if (!/^\s*else\b/.test(textAfter)) for (var i = state.cc.length - 1; i >= 0; --i) {
-        var c = state.cc[i];
-        if (c == poplex) lexical = lexical.prev;
-        else if (c != maybeelse) break;
-      }
-      while ((lexical.type == "stat" || lexical.type == "form") &&
-             (firstChar == "}" || ((top = state.cc[state.cc.length - 1]) &&
-                                   (top == maybeoperatorComma || top == maybeoperatorNoComma) &&
-                                   !/^[,\.=+\-*:?[\(]/.test(textAfter))))
-        lexical = lexical.prev;
-      if (statementIndent && lexical.type == ")" && lexical.prev.type == "stat")
-        lexical = lexical.prev;
-      var type = lexical.type, closing = firstChar == type;
-
-      if (type == "vardef") return lexical.indented + (state.lastType == "operator" || state.lastType == "," ? lexical.info.length + 1 : 0);
-      else if (type == "form" && firstChar == "{") return lexical.indented;
-      else if (type == "form") return lexical.indented + indentUnit;
-      else if (type == "stat")
-        return lexical.indented + (isContinuedStatement(state, textAfter) ? statementIndent || indentUnit : 0);
-      else if (lexical.info == "switch" && !closing && parserConfig.doubleIndentSwitch != false)
-        return lexical.indented + (/^(?:case|default)\b/.test(textAfter) ? indentUnit : 2 * indentUnit);
-      else if (lexical.align) return lexical.column + (closing ? 0 : 1);
-      else return lexical.indented + (closing ? 0 : indentUnit);
-    },
-
-    electricInput: /^\s*(?:case .*?:|default:|\{|\})$/,
-    blockCommentStart: jsonMode ? null : "/*",
-    blockCommentEnd: jsonMode ? null : "*/",
-    blockCommentContinue: jsonMode ? null : " * ",
-    lineComment: jsonMode ? null : "//",
-    fold: "brace",
-    closeBrackets: "()[]{}''\"\"``",
-
-    helperType: jsonMode ? "json" : "javascript",
-    jsonldMode: jsonldMode,
-    jsonMode: jsonMode,
-
-    expressionAllowed: expressionAllowed,
-
-    skipExpression: function(state) {
-      var top = state.cc[state.cc.length - 1]
-      if (top == expression || top == expressionNoComma) state.cc.pop()
-    }
-  };
-});
-
-CodeMirror.registerHelper("wordChars", "javascript", /[\w$]/);
-
-CodeMirror.defineMIME("text/javascript", "javascript");
-CodeMirror.defineMIME("text/ecmascript", "javascript");
-CodeMirror.defineMIME("application/javascript", "javascript");
-CodeMirror.defineMIME("application/x-javascript", "javascript");
-CodeMirror.defineMIME("application/ecmascript", "javascript");
-CodeMirror.defineMIME("application/json", {name: "javascript", json: true});
-CodeMirror.defineMIME("application/x-json", {name: "javascript", json: true});
-CodeMirror.defineMIME("application/ld+json", {name: "javascript", jsonld: true});
-CodeMirror.defineMIME("text/typescript", { name: "javascript", typescript: true });
-CodeMirror.defineMIME("application/typescript", { name: "javascript", typescript: true });
-
-});
Index: admin/js/codemirror/mode/php/php.js
===================================================================
--- admin/js/codemirror/mode/php/php.js	(revision 3979)
+++ 	(revision )
@@ -1,234 +1,0 @@
-// CodeMirror, copyright (c) by Marijn Haverbeke and others
-// Distributed under an MIT license: https://codemirror.net/LICENSE
-
-(function(mod) {
-  if (typeof exports == "object" && typeof module == "object") // CommonJS
-    mod(require("../../lib/codemirror"), require("../htmlmixed/htmlmixed"), require("../clike/clike"));
-  else if (typeof define == "function" && define.amd) // AMD
-    define(["../../lib/codemirror", "../htmlmixed/htmlmixed", "../clike/clike"], mod);
-  else // Plain browser env
-    mod(CodeMirror);
-})(function(CodeMirror) {
-  "use strict";
-
-  function keywords(str) {
-    var obj = {}, words = str.split(" ");
-    for (var i = 0; i < words.length; ++i) obj[words[i]] = true;
-    return obj;
-  }
-
-  // Helper for phpString
-  function matchSequence(list, end, escapes) {
-    if (list.length == 0) return phpString(end);
-    return function (stream, state) {
-      var patterns = list[0];
-      for (var i = 0; i < patterns.length; i++) if (stream.match(patterns[i][0])) {
-        state.tokenize = matchSequence(list.slice(1), end);
-        return patterns[i][1];
-      }
-      state.tokenize = phpString(end, escapes);
-      return "string";
-    };
-  }
-  function phpString(closing, escapes) {
-    return function(stream, state) { return phpString_(stream, state, closing, escapes); };
-  }
-  function phpString_(stream, state, closing, escapes) {
-    // "Complex" syntax
-    if (escapes !== false && stream.match("${", false) || stream.match("{$", false)) {
-      state.tokenize = null;
-      return "string";
-    }
-
-    // Simple syntax
-    if (escapes !== false && stream.match(/^\$[a-zA-Z_][a-zA-Z0-9_]*/)) {
-      // After the variable name there may appear array or object operator.
-      if (stream.match("[", false)) {
-        // Match array operator
-        state.tokenize = matchSequence([
-          [["[", null]],
-          [[/\d[\w\.]*/, "number"],
-           [/\$[a-zA-Z_][a-zA-Z0-9_]*/, "variable-2"],
-           [/[\w\$]+/, "variable"]],
-          [["]", null]]
-        ], closing, escapes);
-      }
-      if (stream.match(/\-\>\w/, false)) {
-        // Match object operator
-        state.tokenize = matchSequence([
-          [["->", null]],
-          [[/[\w]+/, "variable"]]
-        ], closing, escapes);
-      }
-      return "variable-2";
-    }
-
-    var escaped = false;
-    // Normal string
-    while (!stream.eol() &&
-           (escaped || escapes === false ||
-            (!stream.match("{$", false) &&
-             !stream.match(/^(\$[a-zA-Z_][a-zA-Z0-9_]*|\$\{)/, false)))) {
-      if (!escaped && stream.match(closing)) {
-        state.tokenize = null;
-        state.tokStack.pop(); state.tokStack.pop();
-        break;
-      }
-      escaped = stream.next() == "\\" && !escaped;
-    }
-    return "string";
-  }
-
-  var phpKeywords = "abstract and array as break case catch class clone const continue declare default " +
-    "do else elseif enddeclare endfor endforeach endif endswitch endwhile extends final " +
-    "for foreach function global goto if implements interface instanceof namespace " +
-    "new or private protected public static switch throw trait try use var while xor " +
-    "die echo empty exit eval include include_once isset list require require_once return " +
-    "print unset __halt_compiler self static parent yield insteadof finally";
-  var phpAtoms = "true false null TRUE FALSE NULL __CLASS__ __DIR__ __FILE__ __LINE__ __METHOD__ __FUNCTION__ __NAMESPACE__ __TRAIT__";
-  var phpBuiltin = "func_num_args func_get_arg func_get_args strlen strcmp strncmp strcasecmp strncasecmp each error_reporting define defined trigger_error user_error set_error_handler restore_error_handler get_declared_classes get_loaded_extensions extension_loaded get_extension_funcs debug_backtrace constant bin2hex hex2bin sleep usleep time mktime gmmktime strftime gmstrftime strtotime date gmdate getdate localtime checkdate flush wordwrap htmlspecialchars htmlentities html_entity_decode md5 md5_file crc32 getimagesize image_type_to_mime_type phpinfo phpversion phpcredits strnatcmp strnatcasecmp substr_count strspn strcspn strtok strtoupper strtolower strpos strrpos strrev hebrev hebrevc nl2br basename dirname pathinfo stripslashes stripcslashes strstr stristr strrchr str_shuffle str_word_count strcoll substr substr_replace quotemeta ucfirst ucwords strtr addslashes addcslashes rtrim str_replace str_repeat count_chars chunk_split trim ltrim strip_tags similar_text explode implode setlocale localeconv parse_str str_pad chop strchr sprintf printf vprintf vsprintf sscanf fscanf parse_url urlencode urldecode rawurlencode rawurldecode readlink linkinfo link unlink exec system escapeshellcmd escapeshellarg passthru shell_exec proc_open proc_close rand srand getrandmax mt_rand mt_srand mt_getrandmax base64_decode base64_encode abs ceil floor round is_finite is_nan is_infinite bindec hexdec octdec decbin decoct dechex base_convert number_format fmod ip2long long2ip getenv putenv getopt microtime gettimeofday getrusage uniqid quoted_printable_decode set_time_limit get_cfg_var magic_quotes_runtime set_magic_quotes_runtime get_magic_quotes_gpc get_magic_quotes_runtime import_request_variables error_log serialize unserialize memory_get_usage var_dump var_export debug_zval_dump print_r highlight_file show_source highlight_string ini_get ini_get_all ini_set ini_alter ini_restore get_include_path set_include_path restore_include_path setcookie header headers_sent connection_aborted connection_status ignore_user_abort parse_ini_file is_uploaded_file move_uploaded_file intval floatval doubleval strval gettype settype is_null is_resource is_bool is_long is_float is_int is_integer is_double is_real is_numeric is_string is_array is_object is_scalar ereg ereg_replace eregi eregi_replace split spliti join sql_regcase dl pclose popen readfile rewind rmdir umask fclose feof fgetc fgets fgetss fread fopen fpassthru ftruncate fstat fseek ftell fflush fwrite fputs mkdir rename copy tempnam tmpfile file file_get_contents file_put_contents stream_select stream_context_create stream_context_set_params stream_context_set_option stream_context_get_options stream_filter_prepend stream_filter_append fgetcsv flock get_meta_tags stream_set_write_buffer set_file_buffer set_socket_blocking stream_set_blocking socket_set_blocking stream_get_meta_data stream_register_wrapper stream_wrapper_register stream_set_timeout socket_set_timeout socket_get_status realpath fnmatch fsockopen pfsockopen pack unpack get_browser crypt opendir closedir chdir getcwd rewinddir readdir dir glob fileatime filectime filegroup fileinode filemtime fileowner fileperms filesize filetype file_exists is_writable is_writeable is_readable is_executable is_file is_dir is_link stat lstat chown touch clearstatcache mail ob_start ob_flush ob_clean ob_end_flush ob_end_clean ob_get_flush ob_get_clean ob_get_length ob_get_level ob_get_status ob_get_contents ob_implicit_flush ob_list_handlers ksort krsort natsort natcasesort asort arsort sort rsort usort uasort uksort shuffle array_walk count end prev next reset current key min max in_array array_search extract compact array_fill range array_multisort array_push array_pop array_shift array_unshift array_splice array_slice array_merge array_merge_recursive array_keys array_values array_count_values array_reverse array_reduce array_pad array_flip array_change_key_case array_rand array_unique array_intersect array_intersect_assoc array_diff array_diff_assoc array_sum array_filter array_map array_chunk array_key_exists array_intersect_key array_combine array_column pos sizeof key_exists assert assert_options version_compare ftok str_rot13 aggregate session_name session_module_name session_save_path session_id session_regenerate_id session_decode session_register session_unregister session_is_registered session_encode session_start session_destroy session_unset session_set_save_handler session_cache_limiter session_cache_expire session_set_cookie_params session_get_cookie_params session_write_close preg_match preg_match_all preg_replace preg_replace_callback preg_split preg_quote preg_grep overload ctype_alnum ctype_alpha ctype_cntrl ctype_digit ctype_lower ctype_graph ctype_print ctype_punct ctype_space ctype_upper ctype_xdigit virtual apache_request_headers apache_note apache_lookup_uri apache_child_terminate apache_setenv apache_response_headers apache_get_version getallheaders mysql_connect mysql_pconnect mysql_close mysql_select_db mysql_create_db mysql_drop_db mysql_query mysql_unbuffered_query mysql_db_query mysql_list_dbs mysql_list_tables mysql_list_fields mysql_list_processes mysql_error mysql_errno mysql_affected_rows mysql_insert_id mysql_result mysql_num_rows mysql_num_fields mysql_fetch_row mysql_fetch_array mysql_fetch_assoc mysql_fetch_object mysql_data_seek mysql_fetch_lengths mysql_fetch_field mysql_field_seek mysql_free_result mysql_field_name mysql_field_table mysql_field_len mysql_field_type mysql_field_flags mysql_escape_string mysql_real_escape_string mysql_stat mysql_thread_id mysql_client_encoding mysql_get_client_info mysql_get_host_info mysql_get_proto_info mysql_get_server_info mysql_info mysql mysql_fieldname mysql_fieldtable mysql_fieldlen mysql_fieldtype mysql_fieldflags mysql_selectdb mysql_createdb mysql_dropdb mysql_freeresult mysql_numfields mysql_numrows mysql_listdbs mysql_listtables mysql_listfields mysql_db_name mysql_dbname mysql_tablename mysql_table_name pg_connect pg_pconnect pg_close pg_connection_status pg_connection_busy pg_connection_reset pg_host pg_dbname pg_port pg_tty pg_options pg_ping pg_query pg_send_query pg_cancel_query pg_fetch_result pg_fetch_row pg_fetch_assoc pg_fetch_array pg_fetch_object pg_fetch_all pg_affected_rows pg_get_result pg_result_seek pg_result_status pg_free_result pg_last_oid pg_num_rows pg_num_fields pg_field_name pg_field_num pg_field_size pg_field_type pg_field_prtlen pg_field_is_null pg_get_notify pg_get_pid pg_result_error pg_last_error pg_last_notice pg_put_line pg_end_copy pg_copy_to pg_copy_from pg_trace pg_untrace pg_lo_create pg_lo_unlink pg_lo_open pg_lo_close pg_lo_read pg_lo_write pg_lo_read_all pg_lo_import pg_lo_export pg_lo_seek pg_lo_tell pg_escape_string pg_escape_bytea pg_unescape_bytea pg_client_encoding pg_set_client_encoding pg_meta_data pg_convert pg_insert pg_update pg_delete pg_select pg_exec pg_getlastoid pg_cmdtuples pg_errormessage pg_numrows pg_numfields pg_fieldname pg_fieldsize pg_fieldtype pg_fieldnum pg_fieldprtlen pg_fieldisnull pg_freeresult pg_result pg_loreadall pg_locreate pg_lounlink pg_loopen pg_loclose pg_loread pg_lowrite pg_loimport pg_loexport http_response_code get_declared_traits getimagesizefromstring socket_import_stream stream_set_chunk_size trait_exists header_register_callback class_uses session_status session_register_shutdown echo print global static exit array empty eval isset unset die include require include_once require_once json_decode json_encode json_last_error json_last_error_msg curl_close curl_copy_handle curl_errno curl_error curl_escape curl_exec curl_file_create curl_getinfo curl_init curl_multi_add_handle curl_multi_close curl_multi_exec curl_multi_getcontent curl_multi_info_read curl_multi_init curl_multi_remove_handle curl_multi_select curl_multi_setopt curl_multi_strerror curl_pause curl_reset curl_setopt_array curl_setopt curl_share_close curl_share_init curl_share_setopt curl_strerror curl_unescape curl_version mysqli_affected_rows mysqli_autocommit mysqli_change_user mysqli_character_set_name mysqli_close mysqli_commit mysqli_connect_errno mysqli_connect_error mysqli_connect mysqli_data_seek mysqli_debug mysqli_dump_debug_info mysqli_errno mysqli_error_list mysqli_error mysqli_fetch_all mysqli_fetch_array mysqli_fetch_assoc mysqli_fetch_field_direct mysqli_fetch_field mysqli_fetch_fields mysqli_fetch_lengths mysqli_fetch_object mysqli_fetch_row mysqli_field_count mysqli_field_seek mysqli_field_tell mysqli_free_result mysqli_get_charset mysqli_get_client_info mysqli_get_client_stats mysqli_get_client_version mysqli_get_connection_stats mysqli_get_host_info mysqli_get_proto_info mysqli_get_server_info mysqli_get_server_version mysqli_info mysqli_init mysqli_insert_id mysqli_kill mysqli_more_results mysqli_multi_query mysqli_next_result mysqli_num_fields mysqli_num_rows mysqli_options mysqli_ping mysqli_prepare mysqli_query mysqli_real_connect mysqli_real_escape_string mysqli_real_query mysqli_reap_async_query mysqli_refresh mysqli_rollback mysqli_select_db mysqli_set_charset mysqli_set_local_infile_default mysqli_set_local_infile_handler mysqli_sqlstate mysqli_ssl_set mysqli_stat mysqli_stmt_init mysqli_store_result mysqli_thread_id mysqli_thread_safe mysqli_use_result mysqli_warning_count";
-  CodeMirror.registerHelper("hintWords", "php", [phpKeywords, phpAtoms, phpBuiltin].join(" ").split(" "));
-  CodeMirror.registerHelper("wordChars", "php", /[\w$]/);
-
-  var phpConfig = {
-    name: "clike",
-    helperType: "php",
-    keywords: keywords(phpKeywords),
-    blockKeywords: keywords("catch do else elseif for foreach if switch try while finally"),
-    defKeywords: keywords("class function interface namespace trait"),
-    atoms: keywords(phpAtoms),
-    builtin: keywords(phpBuiltin),
-    multiLineStrings: true,
-    hooks: {
-      "$": function(stream) {
-        stream.eatWhile(/[\w\$_]/);
-        return "variable-2";
-      },
-      "<": function(stream, state) {
-        var before;
-        if (before = stream.match(/<<\s*/)) {
-          var quoted = stream.eat(/['"]/);
-          stream.eatWhile(/[\w\.]/);
-          var delim = stream.current().slice(before[0].length + (quoted ? 2 : 1));
-          if (quoted) stream.eat(quoted);
-          if (delim) {
-            (state.tokStack || (state.tokStack = [])).push(delim, 0);
-            state.tokenize = phpString(delim, quoted != "'");
-            return "string";
-          }
-        }
-        return false;
-      },
-      "#": function(stream) {
-        while (!stream.eol() && !stream.match("?>", false)) stream.next();
-        return "comment";
-      },
-      "/": function(stream) {
-        if (stream.eat("/")) {
-          while (!stream.eol() && !stream.match("?>", false)) stream.next();
-          return "comment";
-        }
-        return false;
-      },
-      '"': function(_stream, state) {
-        (state.tokStack || (state.tokStack = [])).push('"', 0);
-        state.tokenize = phpString('"');
-        return "string";
-      },
-      "{": function(_stream, state) {
-        if (state.tokStack && state.tokStack.length)
-          state.tokStack[state.tokStack.length - 1]++;
-        return false;
-      },
-      "}": function(_stream, state) {
-        if (state.tokStack && state.tokStack.length > 0 &&
-            !--state.tokStack[state.tokStack.length - 1]) {
-          state.tokenize = phpString(state.tokStack[state.tokStack.length - 2]);
-        }
-        return false;
-      }
-    }
-  };
-
-  CodeMirror.defineMode("php", function(config, parserConfig) {
-    var htmlMode = CodeMirror.getMode(config, (parserConfig && parserConfig.htmlMode) || "text/html");
-    var phpMode = CodeMirror.getMode(config, phpConfig);
-
-    function dispatch(stream, state) {
-      var isPHP = state.curMode == phpMode;
-      if (stream.sol() && state.pending && state.pending != '"' && state.pending != "'") state.pending = null;
-      if (!isPHP) {
-        if (stream.match(/^<\?\w*/)) {
-          state.curMode = phpMode;
-          if (!state.php) state.php = CodeMirror.startState(phpMode, htmlMode.indent(state.html, "", ""))
-          state.curState = state.php;
-          return "meta";
-        }
-        if (state.pending == '"' || state.pending == "'") {
-          while (!stream.eol() && stream.next() != state.pending) {}
-          var style = "string";
-        } else if (state.pending && stream.pos < state.pending.end) {
-          stream.pos = state.pending.end;
-          var style = state.pending.style;
-        } else {
-          var style = htmlMode.token(stream, state.curState);
-        }
-        if (state.pending) state.pending = null;
-        var cur = stream.current(), openPHP = cur.search(/<\?/), m;
-        if (openPHP != -1) {
-          if (style == "string" && (m = cur.match(/[\'\"]$/)) && !/\?>/.test(cur)) state.pending = m[0];
-          else state.pending = {end: stream.pos, style: style};
-          stream.backUp(cur.length - openPHP);
-        }
-        return style;
-      } else if (isPHP && state.php.tokenize == null && stream.match("?>")) {
-        state.curMode = htmlMode;
-        state.curState = state.html;
-        if (!state.php.context.prev) state.php = null;
-        return "meta";
-      } else {
-        return phpMode.token(stream, state.curState);
-      }
-    }
-
-    return {
-      startState: function() {
-        var html = CodeMirror.startState(htmlMode)
-        var php = parserConfig.startOpen ? CodeMirror.startState(phpMode) : null
-        return {html: html,
-                php: php,
-                curMode: parserConfig.startOpen ? phpMode : htmlMode,
-                curState: parserConfig.startOpen ? php : html,
-                pending: null};
-      },
-
-      copyState: function(state) {
-        var html = state.html, htmlNew = CodeMirror.copyState(htmlMode, html),
-            php = state.php, phpNew = php && CodeMirror.copyState(phpMode, php), cur;
-        if (state.curMode == htmlMode) cur = htmlNew;
-        else cur = phpNew;
-        return {html: htmlNew, php: phpNew, curMode: state.curMode, curState: cur,
-                pending: state.pending};
-      },
-
-      token: dispatch,
-
-      indent: function(state, textAfter, line) {
-        if ((state.curMode != phpMode && /^\s*<\//.test(textAfter)) ||
-            (state.curMode == phpMode && /^\?>/.test(textAfter)))
-          return htmlMode.indent(state.html, textAfter, line);
-        return state.curMode.indent(state.curState, textAfter, line);
-      },
-
-      blockCommentStart: "/*",
-      blockCommentEnd: "*/",
-      lineComment: "//",
-
-      innerMode: function(state) { return {state: state.curState, mode: state.curMode}; }
-    };
-  }, "htmlmixed", "clike");
-
-  CodeMirror.defineMIME("application/x-httpd-php", "php");
-  CodeMirror.defineMIME("application/x-httpd-php-open", {name: "php", startOpen: true});
-  CodeMirror.defineMIME("text/x-php", phpConfig);
-});
Index: admin/js/codemirror/mode/xml/xml.js
===================================================================
--- admin/js/codemirror/mode/xml/xml.js	(revision 3979)
+++ 	(revision )
@@ -1,402 +1,0 @@
-// CodeMirror, copyright (c) by Marijn Haverbeke and others
-// Distributed under an MIT license: https://codemirror.net/LICENSE
-
-(function(mod) {
-  if (typeof exports == "object" && typeof module == "object") // CommonJS
-    mod(require("../../lib/codemirror"));
-  else if (typeof define == "function" && define.amd) // AMD
-    define(["../../lib/codemirror"], mod);
-  else // Plain browser env
-    mod(CodeMirror);
-})(function(CodeMirror) {
-"use strict";
-
-var htmlConfig = {
-  autoSelfClosers: {'area': true, 'base': true, 'br': true, 'col': true, 'command': true,
-                    'embed': true, 'frame': true, 'hr': true, 'img': true, 'input': true,
-                    'keygen': true, 'link': true, 'meta': true, 'param': true, 'source': true,
-                    'track': true, 'wbr': true, 'menuitem': true},
-  implicitlyClosed: {'dd': true, 'li': true, 'optgroup': true, 'option': true, 'p': true,
-                     'rp': true, 'rt': true, 'tbody': true, 'td': true, 'tfoot': true,
-                     'th': true, 'tr': true},
-  contextGrabbers: {
-    'dd': {'dd': true, 'dt': true},
-    'dt': {'dd': true, 'dt': true},
-    'li': {'li': true},
-    'option': {'option': true, 'optgroup': true},
-    'optgroup': {'optgroup': true},
-    'p': {'address': true, 'article': true, 'aside': true, 'blockquote': true, 'dir': true,
-          'div': true, 'dl': true, 'fieldset': true, 'footer': true, 'form': true,
-          'h1': true, 'h2': true, 'h3': true, 'h4': true, 'h5': true, 'h6': true,
-          'header': true, 'hgroup': true, 'hr': true, 'menu': true, 'nav': true, 'ol': true,
-          'p': true, 'pre': true, 'section': true, 'table': true, 'ul': true},
-    'rp': {'rp': true, 'rt': true},
-    'rt': {'rp': true, 'rt': true},
-    'tbody': {'tbody': true, 'tfoot': true},
-    'td': {'td': true, 'th': true},
-    'tfoot': {'tbody': true},
-    'th': {'td': true, 'th': true},
-    'thead': {'tbody': true, 'tfoot': true},
-    'tr': {'tr': true}
-  },
-  doNotIndent: {"pre": true},
-  allowUnquoted: true,
-  allowMissing: true,
-  caseFold: true
-}
-
-var xmlConfig = {
-  autoSelfClosers: {},
-  implicitlyClosed: {},
-  contextGrabbers: {},
-  doNotIndent: {},
-  allowUnquoted: false,
-  allowMissing: false,
-  allowMissingTagName: false,
-  caseFold: false
-}
-
-CodeMirror.defineMode("xml", function(editorConf, config_) {
-  var indentUnit = editorConf.indentUnit
-  var config = {}
-  var defaults = config_.htmlMode ? htmlConfig : xmlConfig
-  for (var prop in defaults) config[prop] = defaults[prop]
-  for (var prop in config_) config[prop] = config_[prop]
-
-  // Return variables for tokenizers
-  var type, setStyle;
-
-  function inText(stream, state) {
-    function chain(parser) {
-      state.tokenize = parser;
-      return parser(stream, state);
-    }
-
-    var ch = stream.next();
-    if (ch == "<") {
-      if (stream.eat("!")) {
-        if (stream.eat("[")) {
-          if (stream.match("CDATA[")) return chain(inBlock("atom", "]]>"));
-          else return null;
-        } else if (stream.match("--")) {
-          return chain(inBlock("comment", "-->"));
-        } else if (stream.match("DOCTYPE", true, true)) {
-          stream.eatWhile(/[\w\._\-]/);
-          return chain(doctype(1));
-        } else {
-          return null;
-        }
-      } else if (stream.eat("?")) {
-        stream.eatWhile(/[\w\._\-]/);
-        state.tokenize = inBlock("meta", "?>");
-        return "meta";
-      } else {
-        type = stream.eat("/") ? "closeTag" : "openTag";
-        state.tokenize = inTag;
-        return "tag bracket";
-      }
-    } else if (ch == "&") {
-      var ok;
-      if (stream.eat("#")) {
-        if (stream.eat("x")) {
-          ok = stream.eatWhile(/[a-fA-F\d]/) && stream.eat(";");
-        } else {
-          ok = stream.eatWhile(/[\d]/) && stream.eat(";");
-        }
-      } else {
-        ok = stream.eatWhile(/[\w\.\-:]/) && stream.eat(";");
-      }
-      return ok ? "atom" : "error";
-    } else {
-      stream.eatWhile(/[^&<]/);
-      return null;
-    }
-  }
-  inText.isInText = true;
-
-  function inTag(stream, state) {
-    var ch = stream.next();
-    if (ch == ">" || (ch == "/" && stream.eat(">"))) {
-      state.tokenize = inText;
-      type = ch == ">" ? "endTag" : "selfcloseTag";
-      return "tag bracket";
-    } else if (ch == "=") {
-      type = "equals";
-      return null;
-    } else if (ch == "<") {
-      state.tokenize = inText;
-      state.state = baseState;
-      state.tagName = state.tagStart = null;
-      var next = state.tokenize(stream, state);
-      return next ? next + " tag error" : "tag error";
-    } else if (/[\'\"]/.test(ch)) {
-      state.tokenize = inAttribute(ch);
-      state.stringStartCol = stream.column();
-      return state.tokenize(stream, state);
-    } else {
-      stream.match(/^[^\s\u00a0=<>\"\']*[^\s\u00a0=<>\"\'\/]/);
-      return "word";
-    }
-  }
-
-  function inAttribute(quote) {
-    var closure = function(stream, state) {
-      while (!stream.eol()) {
-        if (stream.next() == quote) {
-          state.tokenize = inTag;
-          break;
-        }
-      }
-      return "string";
-    };
-    closure.isInAttribute = true;
-    return closure;
-  }
-
-  function inBlock(style, terminator) {
-    return function(stream, state) {
-      while (!stream.eol()) {
-        if (stream.match(terminator)) {
-          state.tokenize = inText;
-          break;
-        }
-        stream.next();
-      }
-      return style;
-    }
-  }
-
-  function doctype(depth) {
-    return function(stream, state) {
-      var ch;
-      while ((ch = stream.next()) != null) {
-        if (ch == "<") {
-          state.tokenize = doctype(depth + 1);
-          return state.tokenize(stream, state);
-        } else if (ch == ">") {
-          if (depth == 1) {
-            state.tokenize = inText;
-            break;
-          } else {
-            state.tokenize = doctype(depth - 1);
-            return state.tokenize(stream, state);
-          }
-        }
-      }
-      return "meta";
-    };
-  }
-
-  function Context(state, tagName, startOfLine) {
-    this.prev = state.context;
-    this.tagName = tagName;
-    this.indent = state.indented;
-    this.startOfLine = startOfLine;
-    if (config.doNotIndent.hasOwnProperty(tagName) || (state.context && state.context.noIndent))
-      this.noIndent = true;
-  }
-  function popContext(state) {
-    if (state.context) state.context = state.context.prev;
-  }
-  function maybePopContext(state, nextTagName) {
-    var parentTagName;
-    while (true) {
-      if (!state.context) {
-        return;
-      }
-      parentTagName = state.context.tagName;
-      if (!config.contextGrabbers.hasOwnProperty(parentTagName) ||
-          !config.contextGrabbers[parentTagName].hasOwnProperty(nextTagName)) {
-        return;
-      }
-      popContext(state);
-    }
-  }
-
-  function baseState(type, stream, state) {
-    if (type == "openTag") {
-      state.tagStart = stream.column();
-      return tagNameState;
-    } else if (type == "closeTag") {
-      return closeTagNameState;
-    } else {
-      return baseState;
-    }
-  }
-  function tagNameState(type, stream, state) {
-    if (type == "word") {
-      state.tagName = stream.current();
-      setStyle = "tag";
-      return attrState;
-    } else if (config.allowMissingTagName && type == "endTag") {
-      setStyle = "tag bracket";
-      return attrState(type, stream, state);
-    } else {
-      setStyle = "error";
-      return tagNameState;
-    }
-  }
-  function closeTagNameState(type, stream, state) {
-    if (type == "word") {
-      var tagName = stream.current();
-      if (state.context && state.context.tagName != tagName &&
-          config.implicitlyClosed.hasOwnProperty(state.context.tagName))
-        popContext(state);
-      if ((state.context && state.context.tagName == tagName) || config.matchClosing === false) {
-        setStyle = "tag";
-        return closeState;
-      } else {
-        setStyle = "tag error";
-        return closeStateErr;
-      }
-    } else if (config.allowMissingTagName && type == "endTag") {
-      setStyle = "tag bracket";
-      return closeState(type, stream, state);
-    } else {
-      setStyle = "error";
-      return closeStateErr;
-    }
-  }
-
-  function closeState(type, _stream, state) {
-    if (type != "endTag") {
-      setStyle = "error";
-      return closeState;
-    }
-    popContext(state);
-    return baseState;
-  }
-  function closeStateErr(type, stream, state) {
-    setStyle = "error";
-    return closeState(type, stream, state);
-  }
-
-  function attrState(type, _stream, state) {
-    if (type == "word") {
-      setStyle = "attribute";
-      return attrEqState;
-    } else if (type == "endTag" || type == "selfcloseTag") {
-      var tagName = state.tagName, tagStart = state.tagStart;
-      state.tagName = state.tagStart = null;
-      if (type == "selfcloseTag" ||
-          config.autoSelfClosers.hasOwnProperty(tagName)) {
-        maybePopContext(state, tagName);
-      } else {
-        maybePopContext(state, tagName);
-        state.context = new Context(state, tagName, tagStart == state.indented);
-      }
-      return baseState;
-    }
-    setStyle = "error";
-    return attrState;
-  }
-  function attrEqState(type, stream, state) {
-    if (type == "equals") return attrValueState;
-    if (!config.allowMissing) setStyle = "error";
-    return attrState(type, stream, state);
-  }
-  function attrValueState(type, stream, state) {
-    if (type == "string") return attrContinuedState;
-    if (type == "word" && config.allowUnquoted) {setStyle = "string"; return attrState;}
-    setStyle = "error";
-    return attrState(type, stream, state);
-  }
-  function attrContinuedState(type, stream, state) {
-    if (type == "string") return attrContinuedState;
-    return attrState(type, stream, state);
-  }
-
-  return {
-    startState: function(baseIndent) {
-      var state = {tokenize: inText,
-                   state: baseState,
-                   indented: baseIndent || 0,
-                   tagName: null, tagStart: null,
-                   context: null}
-      if (baseIndent != null) state.baseIndent = baseIndent
-      return state
-    },
-
-    token: function(stream, state) {
-      if (!state.tagName && stream.sol())
-        state.indented = stream.indentation();
-
-      if (stream.eatSpace()) return null;
-      type = null;
-      var style = state.tokenize(stream, state);
-      if ((style || type) && style != "comment") {
-        setStyle = null;
-        state.state = state.state(type || style, stream, state);
-        if (setStyle)
-          style = setStyle == "error" ? style + " error" : setStyle;
-      }
-      return style;
-    },
-
-    indent: function(state, textAfter, fullLine) {
-      var context = state.context;
-      // Indent multi-line strings (e.g. css).
-      if (state.tokenize.isInAttribute) {
-        if (state.tagStart == state.indented)
-          return state.stringStartCol + 1;
-        else
-          return state.indented + indentUnit;
-      }
-      if (context && context.noIndent) return CodeMirror.Pass;
-      if (state.tokenize != inTag && state.tokenize != inText)
-        return fullLine ? fullLine.match(/^(\s*)/)[0].length : 0;
-      // Indent the starts of attribute names.
-      if (state.tagName) {
-        if (config.multilineTagIndentPastTag !== false)
-          return state.tagStart + state.tagName.length + 2;
-        else
-          return state.tagStart + indentUnit * (config.multilineTagIndentFactor || 1);
-      }
-      if (config.alignCDATA && /<!\[CDATA\[/.test(textAfter)) return 0;
-      var tagAfter = textAfter && /^<(\/)?([\w_:\.-]*)/.exec(textAfter);
-      if (tagAfter && tagAfter[1]) { // Closing tag spotted
-        while (context) {
-          if (context.tagName == tagAfter[2]) {
-            context = context.prev;
-            break;
-          } else if (config.implicitlyClosed.hasOwnProperty(context.tagName)) {
-            context = context.prev;
-          } else {
-            break;
-          }
-        }
-      } else if (tagAfter) { // Opening tag spotted
-        while (context) {
-          var grabbers = config.contextGrabbers[context.tagName];
-          if (grabbers && grabbers.hasOwnProperty(tagAfter[2]))
-            context = context.prev;
-          else
-            break;
-        }
-      }
-      while (context && context.prev && !context.startOfLine)
-        context = context.prev;
-      if (context) return context.indent + indentUnit;
-      else return state.baseIndent || 0;
-    },
-
-    electricInput: /<\/[\s\w:]+>$/,
-    blockCommentStart: "<!--",
-    blockCommentEnd: "-->",
-
-    configuration: config.htmlMode ? "html" : "xml",
-    helperType: config.htmlMode ? "html" : "xml",
-
-    skipAttribute: function(state) {
-      if (state.state == attrValueState)
-        state.state = attrState
-    }
-  };
-});
-
-CodeMirror.defineMIME("text/xml", "xml");
-CodeMirror.defineMIME("application/xml", "xml");
-if (!CodeMirror.mimeModes.hasOwnProperty("text/html"))
-  CodeMirror.defineMIME("text/html", {name: "xml", htmlMode: true});
-
-});
Index: admin/js/codemirror/theme/3024-day.css
===================================================================
--- admin/js/codemirror/theme/3024-day.css	(revision 3251)
+++ 	(revision )
@@ -1,41 +1,0 @@
-/*
-
-    Name:       3024 day
-    Author:     Jan T. Sott (http://github.com/idleberg)
-
-    CodeMirror template by Jan T. Sott (https://github.com/idleberg/base16-codemirror)
-    Original Base16 color scheme by Chris Kempson (https://github.com/chriskempson/base16)
-
-*/
-
-.cm-s-3024-day.CodeMirror { background: #f7f7f7; color: #3a3432; }
-.cm-s-3024-day div.CodeMirror-selected { background: #d6d5d4; }
-
-.cm-s-3024-day .CodeMirror-line::selection, .cm-s-3024-day .CodeMirror-line > span::selection, .cm-s-3024-day .CodeMirror-line > span > span::selection { background: #d6d5d4; }
-.cm-s-3024-day .CodeMirror-line::-moz-selection, .cm-s-3024-day .CodeMirror-line > span::-moz-selection, .cm-s-3024-day .CodeMirror-line > span > span::selection { background: #d9d9d9; }
-
-.cm-s-3024-day .CodeMirror-gutters { background: #f7f7f7; border-right: 0px; }
-.cm-s-3024-day .CodeMirror-guttermarker { color: #db2d20; }
-.cm-s-3024-day .CodeMirror-guttermarker-subtle { color: #807d7c; }
-.cm-s-3024-day .CodeMirror-linenumber { color: #807d7c; }
-
-.cm-s-3024-day .CodeMirror-cursor { border-left: 1px solid #5c5855; }
-
-.cm-s-3024-day span.cm-comment { color: #cdab53; }
-.cm-s-3024-day span.cm-atom { color: #a16a94; }
-.cm-s-3024-day span.cm-number { color: #a16a94; }
-
-.cm-s-3024-day span.cm-property, .cm-s-3024-day span.cm-attribute { color: #01a252; }
-.cm-s-3024-day span.cm-keyword { color: #db2d20; }
-.cm-s-3024-day span.cm-string { color: #fded02; }
-
-.cm-s-3024-day span.cm-variable { color: #01a252; }
-.cm-s-3024-day span.cm-variable-2 { color: #01a0e4; }
-.cm-s-3024-day span.cm-def { color: #e8bbd0; }
-.cm-s-3024-day span.cm-bracket { color: #3a3432; }
-.cm-s-3024-day span.cm-tag { color: #db2d20; }
-.cm-s-3024-day span.cm-link { color: #a16a94; }
-.cm-s-3024-day span.cm-error { background: #db2d20; color: #5c5855; }
-
-.cm-s-3024-day .CodeMirror-activeline-background { background: #e8f2ff; }
-.cm-s-3024-day .CodeMirror-matchingbracket { text-decoration: underline; color: #a16a94 !important; }
Index: admin/js/codemirror/theme/3024-night.css
===================================================================
--- admin/js/codemirror/theme/3024-night.css	(revision 3251)
+++ 	(revision )
@@ -1,39 +1,0 @@
-/*
-
-    Name:       3024 night
-    Author:     Jan T. Sott (http://github.com/idleberg)
-
-    CodeMirror template by Jan T. Sott (https://github.com/idleberg/base16-codemirror)
-    Original Base16 color scheme by Chris Kempson (https://github.com/chriskempson/base16)
-
-*/
-
-.cm-s-3024-night.CodeMirror { background: #090300; color: #d6d5d4; }
-.cm-s-3024-night div.CodeMirror-selected { background: #3a3432; }
-.cm-s-3024-night .CodeMirror-line::selection, .cm-s-3024-night .CodeMirror-line > span::selection, .cm-s-3024-night .CodeMirror-line > span > span::selection { background: rgba(58, 52, 50, .99); }
-.cm-s-3024-night .CodeMirror-line::-moz-selection, .cm-s-3024-night .CodeMirror-line > span::-moz-selection, .cm-s-3024-night .CodeMirror-line > span > span::-moz-selection { background: rgba(58, 52, 50, .99); }
-.cm-s-3024-night .CodeMirror-gutters { background: #090300; border-right: 0px; }
-.cm-s-3024-night .CodeMirror-guttermarker { color: #db2d20; }
-.cm-s-3024-night .CodeMirror-guttermarker-subtle { color: #5c5855; }
-.cm-s-3024-night .CodeMirror-linenumber { color: #5c5855; }
-
-.cm-s-3024-night .CodeMirror-cursor { border-left: 1px solid #807d7c; }
-
-.cm-s-3024-night span.cm-comment { color: #cdab53; }
-.cm-s-3024-night span.cm-atom { color: #a16a94; }
-.cm-s-3024-night span.cm-number { color: #a16a94; }
-
-.cm-s-3024-night span.cm-property, .cm-s-3024-night span.cm-attribute { color: #01a252; }
-.cm-s-3024-night span.cm-keyword { color: #db2d20; }
-.cm-s-3024-night span.cm-string { color: #fded02; }
-
-.cm-s-3024-night span.cm-variable { color: #01a252; }
-.cm-s-3024-night span.cm-variable-2 { color: #01a0e4; }
-.cm-s-3024-night span.cm-def { color: #e8bbd0; }
-.cm-s-3024-night span.cm-bracket { color: #d6d5d4; }
-.cm-s-3024-night span.cm-tag { color: #db2d20; }
-.cm-s-3024-night span.cm-link { color: #a16a94; }
-.cm-s-3024-night span.cm-error { background: #db2d20; color: #807d7c; }
-
-.cm-s-3024-night .CodeMirror-activeline-background { background: #2F2F2F; }
-.cm-s-3024-night .CodeMirror-matchingbracket { text-decoration: underline; color: white !important; }
Index: admin/js/codemirror/theme/abcdef.css
===================================================================
--- admin/js/codemirror/theme/abcdef.css	(revision 3617)
+++ 	(revision )
@@ -1,32 +1,0 @@
-.cm-s-abcdef.CodeMirror { background: #0f0f0f; color: #defdef; }
-.cm-s-abcdef div.CodeMirror-selected { background: #515151; }
-.cm-s-abcdef .CodeMirror-line::selection, .cm-s-abcdef .CodeMirror-line > span::selection, .cm-s-abcdef .CodeMirror-line > span > span::selection { background: rgba(56, 56, 56, 0.99); }
-.cm-s-abcdef .CodeMirror-line::-moz-selection, .cm-s-abcdef .CodeMirror-line > span::-moz-selection, .cm-s-abcdef .CodeMirror-line > span > span::-moz-selection { background: rgba(56, 56, 56, 0.99); }
-.cm-s-abcdef .CodeMirror-gutters { background: #555; border-right: 2px solid #314151; }
-.cm-s-abcdef .CodeMirror-guttermarker { color: #222; }
-.cm-s-abcdef .CodeMirror-guttermarker-subtle { color: azure; }
-.cm-s-abcdef .CodeMirror-linenumber { color: #FFFFFF; }
-.cm-s-abcdef .CodeMirror-cursor { border-left: 1px solid #00FF00; }
-
-.cm-s-abcdef span.cm-keyword { color: darkgoldenrod; font-weight: bold; }
-.cm-s-abcdef span.cm-atom { color: #77F; }
-.cm-s-abcdef span.cm-number { color: violet; }
-.cm-s-abcdef span.cm-def { color: #fffabc; }
-.cm-s-abcdef span.cm-variable { color: #abcdef; }
-.cm-s-abcdef span.cm-variable-2 { color: #cacbcc; }
-.cm-s-abcdef span.cm-variable-3, .cm-s-abcdef span.cm-type { color: #def; }
-.cm-s-abcdef span.cm-property { color: #fedcba; }
-.cm-s-abcdef span.cm-operator { color: #ff0; }
-.cm-s-abcdef span.cm-comment { color: #7a7b7c; font-style: italic;}
-.cm-s-abcdef span.cm-string { color: #2b4; }
-.cm-s-abcdef span.cm-meta { color: #C9F; }
-.cm-s-abcdef span.cm-qualifier { color: #FFF700; }
-.cm-s-abcdef span.cm-builtin { color: #30aabc; }
-.cm-s-abcdef span.cm-bracket { color: #8a8a8a; }
-.cm-s-abcdef span.cm-tag { color: #FFDD44; }
-.cm-s-abcdef span.cm-attribute { color: #DDFF00; }
-.cm-s-abcdef span.cm-error { color: #FF0000; }
-.cm-s-abcdef span.cm-header { color: aquamarine; font-weight: bold; }
-.cm-s-abcdef span.cm-link { color: blueviolet; }
-
-.cm-s-abcdef .CodeMirror-activeline-background { background: #314151; }
Index: admin/js/codemirror/theme/ambiance-mobile.css
===================================================================
--- admin/js/codemirror/theme/ambiance-mobile.css	(revision 3251)
+++ 	(revision )
@@ -1,5 +1,0 @@
-.cm-s-ambiance.CodeMirror {
-  -webkit-box-shadow: none;
-  -moz-box-shadow: none;
-  box-shadow: none;
-}
Index: admin/js/codemirror/theme/ambiance.css
===================================================================
--- admin/js/codemirror/theme/ambiance.css	(revision 3617)
+++ 	(revision )
@@ -1,74 +1,0 @@
-/* ambiance theme for codemirror */
-
-/* Color scheme */
-
-.cm-s-ambiance .cm-header { color: blue; }
-.cm-s-ambiance .cm-quote { color: #24C2C7; }
-
-.cm-s-ambiance .cm-keyword { color: #cda869; }
-.cm-s-ambiance .cm-atom { color: #CF7EA9; }
-.cm-s-ambiance .cm-number { color: #78CF8A; }
-.cm-s-ambiance .cm-def { color: #aac6e3; }
-.cm-s-ambiance .cm-variable { color: #ffb795; }
-.cm-s-ambiance .cm-variable-2 { color: #eed1b3; }
-.cm-s-ambiance .cm-variable-3, .cm-s-ambiance .cm-type { color: #faded3; }
-.cm-s-ambiance .cm-property { color: #eed1b3; }
-.cm-s-ambiance .cm-operator { color: #fa8d6a; }
-.cm-s-ambiance .cm-comment { color: #555; font-style:italic; }
-.cm-s-ambiance .cm-string { color: #8f9d6a; }
-.cm-s-ambiance .cm-string-2 { color: #9d937c; }
-.cm-s-ambiance .cm-meta { color: #D2A8A1; }
-.cm-s-ambiance .cm-qualifier { color: yellow; }
-.cm-s-ambiance .cm-builtin { color: #9999cc; }
-.cm-s-ambiance .cm-bracket { color: #24C2C7; }
-.cm-s-ambiance .cm-tag { color: #fee4ff; }
-.cm-s-ambiance .cm-attribute { color: #9B859D; }
-.cm-s-ambiance .cm-hr { color: pink; }
-.cm-s-ambiance .cm-link { color: #F4C20B; }
-.cm-s-ambiance .cm-special { color: #FF9D00; }
-.cm-s-ambiance .cm-error { color: #AF2018; }
-
-.cm-s-ambiance .CodeMirror-matchingbracket { color: #0f0; }
-.cm-s-ambiance .CodeMirror-nonmatchingbracket { color: #f22; }
-
-.cm-s-ambiance div.CodeMirror-selected { background: rgba(255, 255, 255, 0.15); }
-.cm-s-ambiance.CodeMirror-focused div.CodeMirror-selected { background: rgba(255, 255, 255, 0.10); }
-.cm-s-ambiance .CodeMirror-line::selection, .cm-s-ambiance .CodeMirror-line > span::selection, .cm-s-ambiance .CodeMirror-line > span > span::selection { background: rgba(255, 255, 255, 0.10); }
-.cm-s-ambiance .CodeMirror-line::-moz-selection, .cm-s-ambiance .CodeMirror-line > span::-moz-selection, .cm-s-ambiance .CodeMirror-line > span > span::-moz-selection { background: rgba(255, 255, 255, 0.10); }
-
-/* Editor styling */
-
-.cm-s-ambiance.CodeMirror {
-  line-height: 1.40em;
-  color: #E6E1DC;
-  background-color: #202020;
-  -webkit-box-shadow: inset 0 0 10px black;
-  -moz-box-shadow: inset 0 0 10px black;
-  box-shadow: inset 0 0 10px black;
-}
-
-.cm-s-ambiance .CodeMirror-gutters {
-  background: #3D3D3D;
-  border-right: 1px solid #4D4D4D;
-  box-shadow: 0 10px 20px black;
-}
-
-.cm-s-ambiance .CodeMirror-linenumber {
-  text-shadow: 0px 1px 1px #4d4d4d;
-  color: #111;
-  padding: 0 5px;
-}
-
-.cm-s-ambiance .CodeMirror-guttermarker { color: #aaa; }
-.cm-s-ambiance .CodeMirror-guttermarker-subtle { color: #111; }
-
-.cm-s-ambiance .CodeMirror-cursor { border-left: 1px solid #7991E8; }
-
-.cm-s-ambiance .CodeMirror-activeline-background {
-  background: none repeat scroll 0% 0% rgba(255, 255, 255, 0.031);
-}
-
-.cm-s-ambiance.CodeMirror,
-.cm-s-ambiance .CodeMirror-gutters {
-  background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAMgAAADICAQAAAAHUWYVAABFFUlEQVQYGbzBCeDVU/74/6fj9HIcx/FRHx9JCFmzMyGRURhLZIkUsoeRfUjS2FNDtr6WkMhO9sm+S8maJfu+Jcsg+/o/c+Z4z/t97/vezy3z+z8ekGlnYICG/o7gdk+wmSHZ1z4pJItqapjoKXWahm8NmV6eOTbWUOp6/6a/XIg6GQqmenJ2lDHyvCFZ2cBDbmtHA043VFhHwXxClWmeYAdLhV00Bd85go8VmaFCkbVkzlQENzfBDZ5gtN7HwF0KDrTwJ0dypSOzpaKCMwQHKTIreYIxlmhXTzTWkVm+LTynZhiSBT3RZQ7aGfjGEd3qyXQ1FDymqbKxpspERQN2MiRjNZlFFQXfCNFm9nM1zpAsoYjmtRTc5ajwuaXc5xrWskT97RaKzAGe5ARHhVUsDbjKklziiX5WROcJwSNCNI+9w1Jwv4Zb2r7lCMZ4oq5C0EdTx+2GzNuKpJ+iFf38JEWkHJn9DNF7mmBDITrWEg0VWL3pHU20tSZnuqWu+R3BtYa8XxV1HO7GyD32UkOpL/yDloINFTmvtId+nmAjxRw40VMwVKiwrKLE4bK5UOVntYwhOcSSXKrJHKPJedocpGjVz/ZMIbnYUPB10/eKCrs5apqpgVmWzBYWpmtKHecJPjaUuEgRDDaU0oZghCJ6zNMQ5ZhDYx05r5v2muQdM0EILtXUsaKiQX9WMEUotagQzFbUNN6NUPC2nm5pxEWGCjMc3GdJHjSU2kORLK/JGSrkfGEIjncU/CYUnOipoYemwj8tST9NsJmB7TUVXtbUtXATJVZXBMvYeTXJfobgJUPmGMP/yFaWonaa6BcFO3nqcIqCozSZoZoSr1g4zJOzuyGnxTEX3lUEJ7WcZgme8ddaWvWJo2AJR9DZU3CUIbhCSG6ybSwN6qtJVnCU2svDTP2ZInOw2cBTrqtQahtNZn9NcJ4l2NaSmSkkP1noZWnVwkLmdUPOwLZEwy2Z3S3R+4rIG9hcbpPXHFVWcQdZkn2FOta3cKWQnNRC5g1LsJah4GCzSVsKnCOY5OAFRTBekyyryeyilhFKva75r4Mc0aWanGEaThcy31s439KKxTzJYY5WTHPU1FtIHjQU3Oip4xlNzj/lBw23dYZVliQa7WAXf4shetcQfatI+jWRDBPmyNeW6A1P5kdDgyYJlba0BIM8BZu1JfrFwItyjcAMR3K0BWOIrtMEXyhyrlVEx3ui5dUBjmB/Q3CXW85R4mBD0s7B+4q5tKUjOlb9qqmhi5AZ6GFIC5HXtOobdYGlVdMVbNJ8toNTFcHxnoL+muBagcctjWnbNMuR00uI7nQESwg5q2qqrKWIfrNUmeQocY6HuyxJV02wj36w00yhpmUFenv4p6fUkZYqLyuinx2RGOjhCXYyJF84oiU00YMOOhhquNdfbOB7gU88pY4xJO8LVdp6/q2voeB4R04vIdhSE40xZObx1HGGJ/ja0LBthFInKaLPPFzuCaYaoj8JjPME8yoyxo6zlBqkiUZYgq00OYMswbWO5NGmq+xhipxHLRW29ARjNKXO0wRnear8XSg4XFPLKEPUS1GqvyLwiuBUoa7zpZ0l5xxFwWmWZC1H5h5FwU8eQ7K+g8UcVY6TMQreVQT/8uQ8Z+ALIXnSEa2pYZQneE9RZbSBNYXfWYJzW/h/4j4Dp1tYVcFIC5019Vyi4ThPqSFCzjGWaHQTBU8q6vrVwgxP9Lkm840imWKpcLCjYTtrKuwvsKSnrvHCXGkSMk9p6lhckfRpIeis+N2PiszT+mFLspyGleUhDwcLrZqmyeylxwjBcKHEapqkmyangyLZRVOijwOtCY5SsG5zL0OwlCJ4y5KznF3EUNDDrinwiyLZRzOXtlBbK5ITHFGLp8Q0R6ab6mS7enI2cFrxOyHvOCFaT1HThS1krjCwqWeurCkk+willhCC+RSZnRXBiZaC5RXRIZYKp2lyfrHwiKPKR0JDzrdU2EFgpidawlFDR6FgXUMNa+g1FY3bUQh2cLCwosRdnuQTS/S+JVrGLeWIvtQUvONJxlqSQYYKpwoN2kaocLjdVsis4Mk80ESF2YpSkzwldjHkjFCUutI/r+EHDU8oCs6yzL3PhWiEooZdFMkymlas4AcI3KmoMMNSQ3tHzjGWCrcJJdYyZC7QFGwjRL9p+MrRkAGWzIaWCn9W0F3TsK01c2ZvQw0byvxuQU0r1lM0qJO7wW0kRIMdDTtXEdzi4VIh+EoIHm0mWtAtpCixlabgn83fKTI7anJe9ST7WIK1DMGpQmYeA58ImV6ezOGOzK2Kgq01pd60cKWiUi9Lievb/0vIDPHQ05Kzt4ddPckQBQtoaurjyHnek/nKzpQLrVgKPjIkh2v4uyezpv+Xoo7fPFXaGFp1vaLKxQ4uUpQQS5VuQs7BCq4xRJv7fwpVvvFEB3j+620haOuocqMhWd6TTPAEx+mdFNGHdranFe95WrWmIvlY4F1Dle2ECgc6cto7SryuqGGGha0tFQ5V53migUKmg6XKAo4qS3mik+0OZpAhOLeZKicacgaYcyx5hypYQE02ZA4xi/pNhOQxR4klNKyqacj+mpxnLTnnGSo85++3ZCZq6lrZkXlGEX3o+C9FieccJbZWVFjC0Yo1FZnJhoYMFoI1hEZ9r6hwg75HwzBNhbZCdJEfJwTPGzJvaKImw1yYX1HDAmpXR+ZJQ/SmgqMNVQb5vgamGwLtt7VwvP7Qk1xpiM5x5Cyv93E06MZmgs0Nya2azIKOYKCGBQQW97RmhKNKF02JZqHEJ4o58qp7X5EcZmc56trXEqzjCBZ1MFGR87Ql2tSTs6CGxS05PTzRQorkbw7aKoKXFDXsYW42VJih/q+FP2BdTzDTwVqOYB13liM50vG7wy28qagyuIXMeQI/Oqq8bcn5wJI50xH00CRntyfpL1T4hydYpoXgNiFzoIUTDZnLNRzh4TBHwbYGDvZkxmlyJloyr6tRihpeUG94GnKtIznREF0tzJG/OOr73JBcrSh1k6WuTprgLU+mnSGnv6Zge0NNz+kTDdH8nuAuTdJDCNb21LCiIuqlYbqGzT3RAoZofQfjFazkqeNWdYaGvYTM001EW2oKPvVk1ldUGSgUtHFwjKM1h9jnFcmy5lChoLNaQMGGDsYbKixlaMBmmsx1QjCfflwTfO/gckW0ruZ3jugKR3R5W9hGUWqCgxuFgsuaCHorotGKzGaeZB9DMsaTnKCpMtwTvOzhYk0rdrArKCqcaWmVk1+F372ur1YkKxgatI8Qfe1gIX9wE9FgS8ESmuABIXnRUbCapcKe+nO7slClSZFzpV/LkLncEb1qiO42fS3R855Su2mCLh62t1SYZZYVmKwIHjREF2uihTzB20JOkz7dkxzYQnK0UOU494wh+VWRc6Un2kpTaVgLDFEkJ/uhzRcI0YKGgpGWOlocBU/a4fKoJ/pEaNV6jip3+Es9VXY078rGnmAdf7t9ylPXS34RBSuYPs1UecZTU78WanhBCHpZ5sAoTz0LGZKjPf9TRypqWEiTvOFglL1fCEY3wY/++rbk7C8bWebA6p6om6PgOL2kp44TFJlVNBXae2rqqdZztOJpT87GQsE9jqCPIe9VReZuQ/CIgacsyZdCpIScSYqcZk8r+nsyCzhyfhOqHGOIvrLknC8wTpFcaYiGC/RU1NRbUeUpocQOnkRpGOrIOcNRx+1uA0UrzhSSt+VyS3SJpnFWkzNDqOFGIWcfR86DnmARTQ1HKIL33ExPiemeOhYSSjzlSUZZuE4TveoJLnBUOFof6KiysCbnAEcZgcUNTDOwkqWu3RWtmGpZwlHhJENdZ3miGz0lJlsKnjbwqSHQjpxnFDlTLLwqJPMZMjd7KrzkSG7VsxXBZE+F8YZkb01Oe00yyRK9psh5SYh29ySPKBo2ylNht7ZkZnsKenjKNJu9PNEyZpaCHv4Kt6RQsLvAVp7M9kIimmCUwGeWqLMmGuIotYMmWNpSahkhZw9FqZsVnKJhsjAHvtHMsTM9fCI06Dx/u3vfUXCqfsKRc4oFY2jMsoo/7DJDwZ1CsIKnJu+J9ldkpmiCxQx1rWjI+T9FwcWWzOuaYH0Hj7klNRVWEQpmaqosakiGNTFHdjS/qnUdmf0NJW5xsL0HhimCCZZSRzmSPTXJQ4aaztAwtZnoabebJ+htCaZ7Cm535ByoqXKbX1WRc4Eh2MkRXWzImVc96Cj4VdOKVxR84VdQsIUM8Psoou2byVHyZFuq7O8otbSQ2UAoeEWTudATLGSpZzVLlXVkPU2Jc+27lsw2jmg5T5VhbeE3BT083K9WsTTkFU/Osi0rC5lRlpwRHUiesNS0sOvmqGML1aRbPAxTJD9ZKtxuob+hhl8cwYGWpJ8nub7t5p6coYbMovZ1BTdaKn1jYD6h4GFDNFyT/Kqe1XCXphXHOKLZmuRSRdBPEfVUXQzJm5YGPGGJdvAEr7hHNdGZnuBvrpciGmopOLf5N0uVMy0FfYToJk90uUCbJupaVpO53UJXR2bVpoU00V2KOo4zMFrBd0Jtz2pa0clT5Q5L8IpQ177mWQejPMEJhuQjS10ref6HHjdEhy1P1EYR7GtO0uSsKJQYLiTnG1rVScj5lyazpqWGl5uBbRWl7m6ixGOOnEsMJR7z8J0n6KMnCdxhiNYQCoZ6CmYLnO8omC3MkW3bktlPmEt/VQQHejL3+dOE5FlPdK/Mq8hZxxJtLyRrepLThYKbLZxkSb5W52vYxNOaOxUF0yxMUPwBTYqCzy01XayYK0sJyWBLqX0MwU5CzoymRzV0EjjeUeLgDpTo6ij42ZAzvD01dHUUTPLU96MdLbBME8nFBn7zJCMtJcZokn8YoqU0FS5WFKyniHobguMcmW8N0XkWZjkyN3hqOMtS08r+/xTBwpZSZ3qiVRX8SzMHHjfUNFjgHEPmY9PL3ykEzxkSre/1ZD6z/NuznuB0RcE1TWTm9zRgfUWVJiG6yrzgmWPXC8EAR4Wxhlad0ZbgQyEz3pG5RVEwwDJH2mgKpjcTiCOzn1lfUWANFbZ2BA8balnEweJC9J0iuaeZoI+ippFCztEKVvckR2iice1JvhVytrQwUAZpgsubCPaU7xUe9vWnaOpaSBEspalykhC9bUlOMpT42ZHca6hyrqKmw/wMR8H5ZmdFoBVJb03O4UL0tSNnvIeRmkrLWqrs78gcrEn2tpcboh0UPOW3UUR9PMk4T4nnNKWmCjlrefhCwxRNztfmIQVdDElvS4m1/WuOujoZCs5XVOjtKPGokJzsYCtFYoWonSPT21DheU/wWhM19FcElwqNGOsp9Q8N/cwXaiND1MmeL1Q5XROtYYgGeFq1aTMsoMmcrKjQrOFQTQ1fmBYhmW6o8Jkjc7iDJRTBIo5kgJD5yMEYA3srCg7VFKwiVJkmRCc5ohGOKhsYMn/XBLdo5taZjlb9YAlGWRimqbCsoY7HFAXLa5I1HPRxMMsQDHFkWtRNniqT9UEeNjcE7RUlrCJ4R2CSJuqlKHWvJXjAUNcITYkenuBRB84TbeepcqTj3zZyFJzgYQdHnqfgI0ddUwS6GqWpsKWhjq9cV0vBAEMN2znq+EBfIWT+pClYw5xsTlJU6GeIBsjGmmANTzJZiIYpgrM0Oa8ZMjd7NP87jxhqGOhJlnQtjuQpB+8aEE00wZFznSJPyHxgH3HkPOsJFvYk8zqCHzTs1BYOa4J3PFU+UVRZxlHDM4YavlNUuMoRveiZA2d7grMNc2g+RbSCEKzmgYsUmWmazFJyoiOZ4KnyhKOGRzWJa0+moyV4TVHDzn51Awtqaphfk/lRQ08FX1iiqxTB/kLwd0VynKfEvI6cd4XMV5bMhZ7gZUWVzYQ6Nm2BYzxJbw3bGthEUUMfgbGeorae6DxHtJoZ6alhZ0+ytiVoK1R4z5PTrOECT/SugseEOlb1MMNR4VRNcJy+V1Hg9ONClSZFZjdHlc6W6FBLdJja2MC5hhpu0DBYEY1TFGwiFAxRRCsYkiM9JRb0JNMVkW6CZYT/2EiTGWmo8k+h4FhDNE7BvppoTSFnmCV5xZKzvcCdDo7VVPnIU+I+Rc68juApC90MwcFCsJ5hDqxgScYKreruyQwTqrzoqDCmhWi4IbhB0Yrt3RGa6GfDv52rKXWhh28dyZaWUvcZeMTBaZoSGyiCtRU5J8iviioHaErs7Jkj61syVzTTgOcUOQ8buFBTYWdL5g3T4qlpe0+wvD63heAXRfCCIed9RbCsp2CiI7raUOYOTU13N8PNHvpaGvayo4a3LLT1lDrVEPT2zLUlheB1R+ZTRfKWJ+dcocLJfi11vyJ51lLqJ0WD7tRwryezjiV5W28uJO9qykzX8JDe2lHl/9oyBwa2UMfOngpXCixvKdXTk3wrsKmiVYdZIqsoWEERjbcUNDuiaQomGoIbFdEHmsyWnuR+IeriKDVLnlawlyNHKwKlSU631PKep8J4Q+ayjkSLKYLhalNHlYvttb6fHm0p6OApsZ4l2VfdqZkjuysy6ysKLlckf1KUutCTs39bmCgEyyoasIWlVaMF7mgmWtBT8Kol5xpH9IGllo8cJdopcvZ2sImlDmMIbtDk3KIpeNiS08lQw11NFPTwVFlPP6pJ2gvRfI7gQUfmNAtf6Gs0wQxDsKGlVBdF8rCa3jzdwMaGHOsItrZk7hAyOzpK9VS06j5F49b0VNGOOfKs3lDToMsMBe9ZWtHFEgxTJLs7qrygKZjUnmCYoeAqeU6jqWuLJup4WghOdvCYJnrSkSzoyRkm5M2StQwVltPkfCAk58tET/CSg+8MUecmotMEnhBKfWBIZsg2ihruMJQaoIm+tkTLKEqspMh00w95gvFCQRtDwTT1gVDDSEVdlwqZfxoQRbK0g+tbiBZxzKlpnpypejdDwTaeOvorMk/IJE10h9CqRe28hhLbe0pMsdSwv4ZbhKivo2BjDWfL8UKJgeavwlwb5KlwhyE4u4XkGE2ytZCznKLCDZZq42VzT8HLCrpruFbIfOIINmh/qCdZ1ZBc65kLHR1Bkyf5zn6pN3SvGKIlFNGplhrO9QSXanLOMQTLCa0YJCRrCZm/CZmrLTm7WzCK4GJDiWUdFeYx1LCFg3NMd0XmCuF3Y5rITLDUsYS9zoHVzwnJoYpSTQoObyEzr4cFBNqYTopoaU/wkyLZ2lPhX/5Y95ulxGTV7KjhWrOZgl8MyUUafjYraNjNU1N3IWcjT5WzWqjwtoarHSUObGYO3GCJZpsBlnJGPd6ZYLyl1GdCA2625IwwJDP8GUKymbzuyPlZlvTUsaUh5zFDhRWFzPKKZLAlWdcQbObgF9tOqOsmB1dqcqYJmWstFbZRRI9poolmqiLnU0POvxScpah2iSL5UJNzgScY5+AuIbpO0YD3NCW+dLMszFSdFCWGqG6eVq2uYVNDdICGD6W7EPRWZEY5gpsE9rUkS3mijzzJnm6UpUFXG1hCUeVoS5WfNcFpblELL2qqrCvMvRfd45oalvKU2tiQ6ePJOVMRXase9iTtLJztPxJKLWpo2CRDcJwn2sWSLKIO1WQWNTCvpVUvOZhgSC40JD0dOctaSqzkCRbXsKlb11Oip6PCJ0IwSJM31j3akRxlP7Rwn6aGaUL0qiLnJkvB3xWZ2+Q1TfCwpQH3G0o92UzmX4o/oJNQMMSQc547wVHhdk+VCw01DFYEnTxzZKAm74QmeNNR1w6WzEhNK15VJzuCdxQ53dRUDws5KvwgBMOEgpcVNe0hZI6RXT1Jd0cyj5nsaEAHgVmGaJIlWdsc5Ui2ElrRR6jrRAttNMEAIWrTDFubkZaok7/AkzfIwfuWVq0jHzuCK4QabtLUMVPB3kJ0oyHTSVFlqMALilJf2Rf8k5aaHtMfayocLBS8L89oKoxpJvnAkDPa0qp5DAUTHKWmCcnthlou8iCKaFFLHWcINd1nyIwXqrSxMNmSs6KmoL2QrKuWtlQ5V0120xQ5vRyZS1rgFkWwhiOwiuQbR0OOVhQM9iS3tiXp4RawRPMp5tDletOOBL95MpM01dZTBM9pkn5qF010rIeHFcFZhmSGpYpTsI6nwhqe5C9ynhlpp5ophuRb6WcJFldkVnVEwwxVfrVkvnWUuNLCg5bgboFHPDlDPDmnK7hUrWiIbjadDclujlZcaokOFup4Ri1kacV6jmrrK1hN9bGwpKEBQ4Q6DvIUXOmo6U5LqQM6EPyiKNjVkPnJkDPNEaxhiFay5ExW1NXVUGqcpYYdPcGiCq7z/TSlbhL4pplWXKd7NZO5QQFrefhRQW/NHOsqcIglc4UhWklR8K0QzbAw08CBDnpbgqXdeD/QUsM4RZXDFBW6WJKe/mFPdH0LtBgiq57wFLzlyQzz82qYx5D5WJP5yVJDW01BfyHnS6HKO/reZqId1WGa4Hkh2kWodJ8i6KoIPlAj2hPt76CzXsVR6koPRzWTfKqIentatYpQw2me4AA3y1Kind3SwoOKZDcFXTwl9tWU6mfgRk9d71sKtlNwrjnYw5tC5n5LdKiGry3JKNlHEd3oaMCFHrazBPMp/uNJ+V7IudcSbeOIdjUEdwl0VHCOZo5t6YluEuaC9mQeMgSfOyKnYGFHcIeQ84yQWbuJYJpZw5CzglDH7gKnWqqM9ZTaXcN0TeYhR84eQtJT76JJ1lREe7WnnvsMmRc9FQ7SBBM9mV3lCUdmHk/S2RAMt0QjFNFqQpWjDPQ01DXWUdDBkXziKPjGEP3VP+zIWU2t7im41FOloyWzn/L6dkUy3VLDaZ6appgDLHPjJEsyvJngWEPUyVBiAaHCTEXwrLvSEbV1e1gKJniicWorC1MUrVjB3uDhJE/wgSOzk1DXpk0k73qCM8xw2UvD5kJmDUfOomqMpWCkJRlvKXGmoeBm18USjVIk04SClxTB6YrgLAPLWYK9HLUt5cmc0vYES8GnTeRc6skZbQkWdxRsIcyBRzx1DbTk9FbU0caTPOgJHhJKnOGIVhQqvKmo0llRw9sabrZkDtdg3PqaKi9oatjY8B+G371paMg6+mZFNNtQ04mWBq3rYLOmtWWQp8KJnpy9DdFensyjdqZ+yY40VJlH8wcdLzC8PZnvHMFUTZUrDTkLyQaGus5X5LzpYAf3i+e/ZlhqGqWhh6Ou6xTR9Z6oi5AZZtp7Mj2EEm8oSpxiYZCHU/1fbGdNNNRRoZMhmilEb2gqHOEJDtXkHK/JnG6IrvbPCwV3NhONVdS1thBMs1T4QOBcTWa2IzhMk2nW5Kyn9tXUtpv9RsG2msxk+ZsQzRQacJncpgke0+T8y5Fzj8BiGo7XlJjaTIlpQs7KFjpqGnKuoyEPeIKnFMkZHvopgh81ySxNFWvJWcKRs70j2FOT012IllEEO1n4pD1513Yg2ssQPOThOkvyrqHUdEXOSEsihmBbTbKX1kLBPWqWkLOqJbjB3GBIZmoa8qWl4CG/iZ7oiA72ZL7TJNeZUY7kFQftDcHHluBzRbCegzMtrRjVQpX2lgoPKKLJAkcbMl01XK2p7yhL8pCBbQ3BN2avJgKvttcrWDK3CiUOVxQ8ZP+pqXKyIxnmBymCg5vJjNfkPK4+c8cIfK8ocVt7kmfd/I5SR1hKvCzUtb+lhgc00ZaO6CyhIQP1Uv4yIZjload72PXX0OIJvnFU+0Zf6MhsJwTfW0r0UwQfW4LNLZl5HK261JCZ4qnBaAreVAS3WrjV0LBnNDUNNDToCEeFfwgcb4gOEqLRhirWkexrCEYKVV711DLYEE1XBEsp5tpTGjorkomKYF9FDXv7fR3BGwbettSxnyL53MBPjsxDZjMh+VUW9NRxq1DhVk+FSxQcaGjV9Pawv6eGByw5qzoy7xk4RsOShqjJwWKe/1pEEfzkobeD/dQJmpqedcyBTy2sr4nGNRH0c0SPWTLrqAc0OQcb/gemKgqucQT7ySWKCn2EUotoCvpZct7RO2sy/QW0IWcXd7pQRQyZVwT2USRO87uhjioTLKV2brpMUcMQRbKH/N2T+UlTpaMls6cmc6CCNy3JdYYSUzzJQ4oSD3oKLncULOiJvjBEC2oqnCJkJluCYy2ZQ5so9YYlZ1VLlQU1mXEW1jZERwj/MUSRc24TdexlqLKfQBtDTScJUV8FszXBEY5ktpD5Ur9hYB4Nb1iikw3JoYpkKX+RodRKFt53MMuRnKSpY31PwYaGaILh3wxJGz9TkTPEETxoCWZrgvOlmyMzxFEwVJE5xZKzvyJ4WxEc16Gd4Xe3Weq4XH2jKRikqOkGQ87hQnC7wBmGYLAnesX3M+S87eFATauuN+Qcrh7xIxXJbUIdMw3JGE3ylCWzrieaqCn4zhGM19TQ3z1oH1AX+pWEqIc7wNGAkULBo/ZxRaV9NNyh4Br3rCHZzbzmSfawBL0dNRwpW1kK9mxPXR9povcdrGSZK9c2k0xwFGzjuniCtRSZCZ6ccZ7gaktmgAOtKbG/JnOkJrjcQTdFMsxRQ2cLY3WTIrlCw1eWKn8R6pvt4GFDso3QoL4a3nLk3G6JrtME3dSenpx7PNFTmga0EaJTLQ061sEeQoWXhSo9LTXsaSjoJQRXeZLtDclbCrYzfzHHeaKjHCVOUkQHO3JeEepr56mhiyaYYKjjNU+Fed1wS5VlhWSqI/hYUdDOkaxiKehoyOnrCV5yBHtbWFqTHCCwtpDcYolesVR5yUzTZBb3RNMd0d6WP+SvhuBmRcGxnuQzT95IC285cr41cLGQ6aJJhmi4TMGempxeimBRQw1tFKV+8jd6KuzoSTqqDxzRtpZkurvKEHxlqXKRIjjfUNNXQsNOsRScoWFLT+YeRZVD3GRN0MdQcKqQjHDMrdGGVu3iYJpQx3WGUvfbmxwFfR20WBq0oYY7LMFhhgYtr8jpaEnaOzjawWWaTP8mMr0t/EPDPoqcnxTBI5o58L7uoWnMrpoqPwgVrlAUWE+V+TQl9rawoyP6QGAlQw2TPRX+YSkxyBC8Z6jhHkXBgQL7WII3DVFnRfCrBfxewv9D6xsyjys4VkhWb9pUU627JllV0YDNHMku/ldNMMXDEo4aFnAkk4U6frNEU4XgZUPmEKHUl44KrzmYamjAbh0JFvGnaTLPu1s9jPCwjFpYiN7z1DTOk/nc07CfDFzmCf7i+bfNHXhDtLeBXzTBT5rkMvWOIxpl4EMh2LGJBu2syDnAEx2naEhHDWMMzPZEhygyS1mS5RTJr5ZkoKbEUoYqr2kqdDUE8ztK7OaIntJkFrIECwv8LJTaVx5XJE86go8dFeZ3FN3rjabCAYpoYEeC9zzJVULBbmZhDyd7ko09ydpNZ3nm2Kee4FPPXHnYEF1nqOFEC08LUVcDvYXkJHW8gTaKCk9YGOeIJhqiE4ToPEepdp7IWFjdwnWaufGMwJJCMtUTTBBK9BGCOy2tGGrJTHIwyEOzp6aPzNMOtlZkDvcEWpP5SVNhfkvDxhmSazTJXYrM9U1E0xwFVwqZQwzJxw6+kGGGUj2FglGGmnb1/G51udRSMNlTw6GGnCcUwVcOpmsqTHa06o72sw1RL02p9z0VbnMLOaIX3QKaYKSCFQzBKEUNHTSc48k53RH9wxGMtpQa5KjjW0W0n6XCCCG4yxNNdhQ4R4l1Ff+2sSd6UFHiIEOyqqFgT01mEUMD+joy75jPhOA+oVVLm309FR4yVOlp4RhLiScNmSmaYF5Pw0STrOIoWMSR2UkRXOMp+M4SHW8o8Zoi6OZgjKOaFar8zZDzkWzvKOjkKBjmCXby8JahhjXULY4KlzgKLvAwxVGhvyd4zxB1d9T0piazmKLCVZY5sKiD0y2ZSYrkUEPUbIk+dlQ4SJHTR50k1DPaUWIdTZW9NJwnJMOECgd7ou/MnppMJ02O1VT4Wsh85MnZzcFTngpXGKo84qmwgKbCL/orR/SzJ2crA+t6Mp94KvxJUeIbT3CQu1uIdlQEOzlKfS3UMcrTiFmOuroocrZrT2AcmamOKg8YomeEKm/rlT2sociMaybaUlFhuqHCM2qIJ+rg4EcDFymiDSxzaHdPcpE62pD5kyM5SBMoA1PaUtfIthS85ig1VPiPPYXgYEMNk4Qq7TXBgo7oT57gPUdwgCHzhIVFPFU6OYJzHAX9m5oNrVjeE61miDrqQ4VSa1oiURTsKHC0IfjNwU2WzK6eqK8jWln4g15TVBnqmDteCJ501PGAocJhhqjZdtBEB6lnhLreFJKxmlKbeGrqLiSThVIbCdGzloasa6lpMQXHCME2boLpJgT7yWaemu6wBONbqGNVRS0PKIL7LckbjmQtR7K8I5qtqel+T/ChJTNIKLjdUMNIRyvOEko9YYl2cwQveBikCNawJKcLBbc7+JM92mysNvd/Fqp8a0k6CNEe7cnZrxlW0wQXaXjaktnRwNOGZKYiONwS7a1JVheq3WgJHlQUGKHKmp4KAxXR/ULURcNgoa4zhKSLpZR3kxRRb0NmD0OFn+UCS7CzI1nbP6+o4x47QZE5xRCt3ZagnYcvmpYQktXdk5YKXTzBC57kKEe0VVuiSYqapssMS3C9p2CKkHOg8B8Pa8p5atrIw3qezIWanMGa5HRDNF6RM9wcacl0N+Q8Z8hsIkSnaIIdHRUOEebAPy1zbCkhM062FCJtif7PU+UtoVXzWKqM1PxXO8cfdruhFQ/a6x3JKYagvVDhQEtNiyiiSQ7OsuRsZUku0CRNDs4Sog6KKjsZgk2bYJqijgsEenoKeniinRXBn/U3lgpPdyDZynQx8IiioMnCep5Ky8mjGs6Wty0l1hUQTcNWswS3WRp2kCNZwJG8omG8JphPUaFbC8lEfabwP7VtM9yoaNCAjpR41VNhrD9LkbN722v0CoZMByFzhaW+MyzRYEWFDQwN2M4/JiT76PuljT3VU/A36eaIThb+R9oZGOAJ9tewkgGvqOMNRWYjT/Cwu99Q8LqDE4TgbLWxJ1jaDDAERsFOFrobgjUsBScaguXU8kKm2RL19tRypSHnHNlHiIZqgufs4opgQdVdwxBNNFBR6kVFqb8ogimOzB6a6HTzrlDHEpYaxjiiA4TMQobkDg2vejjfwJGWmnbVFAw3H3hq2NyQfG7hz4aC+w3BbwbesG0swYayvpAs6++Ri1Vfzx93mFChvyN5xVHTS+0p9aqCAxyZ6ZacZyw5+7uuQkFPR9DDk9NOiE7X1PCYJVjVUqq7JlrHwWALF5nfHNGjApdpqgzx5OwilDhCiDYTgnc9waGW4BdLNNUQvOtpzDOWHDH8D7TR/A/85KljEQu3NREc4Pl/6B1Hhc8Umb5CsKMmGC9EPcxoT2amwHNCmeOEnOPbklnMkbOgIvO5UMOpQrS9UGVdt6iH/fURjhI/WOpaW9OKLYRod6HCUEdOX000wpDZQ6hwg6LgZfOqo1RfT/CrJzjekXOGhpc1VW71ZLbXyyp+93ILbC1kPtIEYx0FIx1VDrLoVzXRKRYWk809yYlC9ImcrinxtabKnzRJk3lAU1OLEN1j2zrYzr2myHRXJFf4h4QKT1qSTzTB5+ZNTzTRkAxX8FcLV2uS8eoQQ2aAkFzvCM72sJIcJET3WPjRk5wi32uSS9rfZajpWEvj9hW42F4o5NytSXYy8IKHay10VYdrcl4SkqscrXpMwyGOgtkajheSxdQqmpxP1L3t4R5PqasFnrQEjytq6qgp9Y09Qx9o4S1FzhUCn1kyHSzBWLemoSGvOqLNhZyBjmCaAUYpMgt4Ck7wBBMMwWKWgjsUwTaGVsxWC1mYoKiyqqeGKYqonSIRQ3KIkHO0pmAxTdBHkbOvfllfr+AA+7gnc50huVKYK393FOyg7rbPO/izI7hE4CnHHHnJ0ogNPRUGeUpsrZZTBJcrovUcJe51BPsr6GkJdhCCsZ6aTtMEb2pqWkqeVtDXE/QVggsU/Nl86d9RMF3DxvZTA58agu810RWawCiSzzXBeU3MMW9oyJUedvNEvQyNu1f10BSMddR1vaLCYpYa/mGocLSiYDcLbQz8aMn5iyF4xBNMs1P0QEOV7o5gaWGuzSeLue4tt3ro7y4Tgm4G/mopdZgl6q0o6KzJWE3mMksNr3r+a6CbT8g5wZNzT9O7fi/zpaOmnz3BRoqos+tv9zMbdpxsqDBOEewtJLt7cg5wtKKbvldpSzRRCD43VFheCI7yZLppggMVBS/KMAdHODJvOwq2NQSbKKKPLdFWQs7Fqo+mpl01JXYRgq8dnGLhTiFzqmWsUMdpllZdbKlyvSdYxhI9YghOtxR8LgSLWHK62mGGVoxzBE8LNWzqH9CUesQzFy5RQzTc56mhi6fgXEWwpKfE5Z7M05ZgZUPmo6auiv8YKzDYwWBLMErIbKHJvOwIrvEdhOBcQ9JdU1NHQ7CXn2XIDFBKU2WAgcX9UAUzDXWd5alwuyJ41Z9rjKLCL4aCp4WarhPm2rH+SaHUYE001JDZ2ZAzXPjdMpZWvC9wmqIB2lLhQ01D5jO06hghWMndbM7yRJMsoCj1vYbnFQVrW9jak3OlEJ3s/96+p33dEPRV5GxiqaGjIthUU6FFEZyqCa5qJrpBdzSw95IUnOPIrCUUjRZQFrbw5PR0R1qiYx3cb6nrWUMrBmmiBQxVHtTew5ICP/ip6g4hed/Akob/32wvBHsIOX83cI8hGeNeNPCIkPmXe8fPKx84OMSRM1MTdXSwjCZ4S30jVGhvqTRak/OVhgGazHuOCud5onEO1lJr6ecVyaOK6H7zqlBlIaHE0oroCgfvGJIdPcmfLNGLjpz7hZwZQpUbFME0A1cIJa7VNORkgfsMBatbKgwwJM9bSvQXeNOvbIjelg6WWvo5kvbKaJJNHexkKNHL9xRyFlH8Ti2riB5wVPhUk7nGkJnoCe428LR/wRGdYIlmWebCyxou1rCk4g/ShugBDX0V0ZQWkh0dOVsagkM0yV6OoLd5ye+pRlsCr0n+KiQrGuq5yJDzrTAXHtLUMduTDBVKrSm3eHL+6ijxhFDX9Z5gVU/wliHYTMiMFpKLNMEywu80wd3meoFmt6VbRMPenhrOc6DVe4pgXU8DnnHakLOIIrlF4FZPIw6R+zxBP0dyq6OOZ4Q5sLKCcz084ok+VsMMyQhNZmmBgX5xIXOEJTmi7VsGTvMTNdHHhpzdbE8Du2oKxgvBqQKdDDnTFOylCFaxR1syz2iqrOI/FEpNc3C6f11/7+ASS6l2inq2ciTrCCzgyemrCL5SVPjQkdPZUmGy2c9Sw9FtR1sS30RmsKPCS4rkIC/2U0MduwucYolGaPjKEyhzmiPYXagyWbYz8LWBDdzRimAXzxx4z8K9hpzlhLq+NiQ97HuKorMUfK/OVvC2JfiHUPCQI/q7J2gjK+tTDNxkCc4TMssqCs4TGtLVwQihyoAWgj9bosU80XGW6Ac9TJGziaUh5+hnFcHOnlaM1iRn29NaqGENTTTSUHCH2tWTeV0osUhH6psuVLjRUmGWhm6OZEshGeNowABHcJ2Bpy2ZszRcKkRXd2QuKVEeXnbfaEq825FguqfgfE2whlChSRMdron+LATTPQ2Z369t4B9C5gs/ylzv+CMmepIDPclFQl13W0rspPd1JOcbghGOEutqCv5qacURQl3dDKyvyJlqKXGPgcM9FfawJAMVmdcspcYKOZc4GjDYkFlK05olNMHyHn4zFNykyOxt99RkHlfwmiHo60l2EKI+mhreEKp080Tbug08BVPcgoqC5zWt+NLDTZ7oNSF51N1qie7Va3uCCwyZbkINf/NED6jzOsBdZjFN8oqG3wxVunqCSYYKf3EdhJyf9YWGf7tRU2oH3VHgPr1fe5J9hOgHd7xQ0y7qBwXr23aGErP0cm64JVjZwsOGqL+mhNgZmhJLW2oY4UhedsyBgzrCKrq7BmcpNVhR6jBPq64Vgi+kn6XE68pp8J5/+0wRHGOpsKenQn9DZntPzjRLZpDAdD2fnSgkG9tmIXnUwQ6WVighs7Yi2MxQ0N3CqYaCXkJ0oyOztMDJjmSSpcpvlrk0RMMOjmArQ04PRV1DO1FwhCVaUVPpKUM03JK5SxPsIWRu8/CGHi8UHChiqGFDTbSRJWeYUDDcH6vJWUxR4k1FXbMUwV6e4AJFXS8oMqsZKqzvYQ9DDQdZckY4aGsIhtlubbd2r3j4QBMoTamdPZk7O/Bf62lacZwneNjQoGcdVU7zJOd7ghsUHOkosagic6cnWc8+4gg285R6zZP5s1/LUbCKIznTwK36PkdwlOrl4U1LwfdCCa+IrvFkmgw1PCAUXKWo0sURXWcI2muKJlgyFzhynCY4RBOsqCjoI1R5zREco0n2Vt09BQtYSizgKNHfUmUrQ5UOCh51BFcLmY7umhYqXKQomOop8bUnWNNQcIiBcYaC6xzMNOS8JQQfeqKBmmglB+97ok/lfk3ygaHSyZaCRTzRxQo6GzLfa2jWBPepw+UmT7SQEJyiyRkhBLMVOfcoMjcK0eZChfUNzFAUzCsEN5vP/X1uP/n/aoMX+K+nw/Hjr/9xOo7j7Pju61tLcgvJpTWXNbfN5jLpi6VfCOviTktKlFusQixdEKWmEBUKNaIpjZRSSOXSgzaaKLdabrm1/9nZ+/f+vd/vz/v9+Xy+zZ7PRorYoZqyLrCwQdEAixxVOEXNNnjX2nUSRlkqGmWowk8lxR50JPy9Bo6qJXaXwNvREBvnThPEPrewryLhcAnj5WE15Fqi8W7R1sAuEu86S4ENikItFN4xkv9Af4nXSnUVcLiA9xzesFpivRRVeFKtsMRaKBhuSbjOELnAUtlSQUpXgdfB4Z1oSbnFEetbQ0IrAe+Y+pqnDcEJFj6S8LDZzZHwY4e3XONNlARraomNEt2bkvGsosA3ioyHm+6jCMbI59wqt4eeara28IzEmyPgoRaUOEDhTVdEJhmCoTWfC0p8aNkCp0oYqih2iqGi4yXeMkOsn4LdLLnmKfh/YogjNsPebeFGR4m9BJHLzB61XQ3BtpISfS2FugsK9FAtLWX1dCRcrCnUp44CNzuCowUZmxSRgYaE6Za0W2u/E7CVXCiI/UOR8aAm1+OSyE3mOUcwyc1zBBeoX1kiKy0Zfxck1Gsyulti11i83QTBF5Kg3pDQThFMVHiPSlK+0cSedng/VaS8bOZbtsBcTcZAR8JP5KeqQ1OYKAi20njdNNRpgnsU//K+JnaXJaGTomr7aYIphoRn9aeShJWKEq9LcozSF7QleEfDI5LYm5bgVkFkRwVDBCVu0DDIkGupo8TZBq+/pMQURYErJQmPKGKjNDkWOLx7Jd5QizdUweIaKrlP7SwJDhZvONjLkOsBBX9UpGxnydhXkfBLQ8IxgojQbLFnJf81JytSljclYYyEFyx0kVBvKWOFJmONpshGAcsduQY5giVNCV51eOdJYo/pLhbvM0uDHSevNKRcrKZIqnCtJeEsO95RoqcgGK4ocZcho1tTYtcZvH41pNQ7vA0WrhIfOSraIIntIAi+NXWCErdbkvrWwjRLrt0NKUdL6KSOscTOdMSOUtBHwL6OLA0vNSdynaWQEnCpIvKaIrJJEbvHkmuNhn6OjM8VkSGSqn1uYJCGHnq9I3aLhNME3t6GjIkO7xrNFumpyTNX/NrwX7CrIRiqqWijI9JO4d1iieykyfiposQIQ8YjjsjlBh6oHWbwRjgYJQn2NgSnNycmJAk3NiXhx44Sxykihxm8ybUwT1OVKySc7vi3OXVkdBJ4AyXBeksDXG0IhgtYY0lY5ahCD0ehborIk5aUWRJviMA7Xt5kyRjonrXENkm8yYqgs8VzgrJmClK20uMM3jRJ0FiQICQF9hdETlLQWRIb5ki6WDfWRPobvO6a4GP5mcOrNzDFELtTkONLh9dXE8xypEg7z8A9jkhrQ6Fhjlg/QVktJXxt4WXzT/03Q8IaQWSqIuEvloQ2mqC9Jfi7wRul4RX3pSPlzpoVlmCtI2jvKHCFhjcM3sN6lqF6HxnKelLjXWbwrpR4xzuCrTUZx2qq9oAh8p6ixCUGr78g8oyjRAtB5CZFwi80VerVpI0h+IeBxa6Zg6kWvpDHaioYYuEsRbDC3eOmC2JvGYLeioxGknL2UATNJN6hmtj1DlpLvDVmocYbrGCVJKOrg4X6DgddLA203BKMFngdJJFtFd7vJLm6KEpc5yjQrkk7M80SGe34X24nSex1Ra5Omgb71JKyg8SrU3i/kARKwWpH0kOGhKkObyfd0ZGjvyXlAkVZ4xRbYJ2irFMkFY1SwyWxr2oo4zlNiV+7zmaweFpT4kR3kaDAFW6xpSqzJay05FtYR4HmZhc9UxKbbfF2V8RG1MBmSaE+kmC6JnaRXK9gsiXhJHl/U0qM0WTcbyhwkYIvFGwjSbjfwhiJt8ZSQU+Bd5+marPMOkVkD0muxYLIfEuhh60x/J92itguihJSEMySVPQnTewnEm+620rTQEMsOfo4/kP/0ARvWjitlpSX7GxBgcMEsd3EEeYWvdytd+Saawi6aCIj1CkGb6Aj9rwhx16Cf3vAwFy5pyLhVonXzy51FDpdEblbkdJbUcEPDEFzQ8qNmhzzLTmmKWKbFCXeEuRabp6rxbvAtLF442QjQ+wEA9eL1xSR7Q0JXzlSHjJ4exq89yR0laScJ/FW6z4a73pFMEfDiRZvuvijIt86RaSFOl01riV2mD1UEvxGk/Geg5aWwGki1zgKPG9J2U8PEg8qYvMsZeytiTRXBMslCU8JSlxi8EabjwUldlDNLfzTUmCgxWsjqWCOHavYAqsknKFIO0yQ61VL5AVFxk6WhEaCAkdJgt9aSkzXlKNX2jEa79waYuc7gq0N3GDJGCBhoiTXUEPsdknCUE1CK0fwsiaylSF2uiDyO4XX3pFhNd7R4itFGc0k/ElBZwWvq+GC6szVeEoS/MZ+qylwpKNKv9Z469UOjqCjwlusicyTxG6VpNxcQ8IncoR4RhLbR+NdpGGmJWOcIzJGUuKPGpQg8rrG21dOMqQssJQ4RxH5jaUqnZuQ0F4Q+cjxLwPtpZbIAk3QTJHQWBE5S1BokoVtDd6lhqr9UpHSUxMcIYl9pojsb8h4SBOsMQcqvOWC2E8EVehqiJ1hrrAEbQxeK0NGZ0Gkq+guSRgniM23bIHVkqwx4hiHd7smaOyglyIyQuM978j4VS08J/A2G1KeMBRo4fBaSNhKUEZfQewVQ/C1I+MgfbEleEzCUw7mKXI0M3hd1EESVji8x5uQ41nxs1q4RMJCCXs7Iq9acpxn22oSDnQ/sJTxsCbHIYZiLyhY05TY0ZLIOQrGaSJDDN4t8pVaIrsqqFdEegtizc1iTew5Q4ayBDMUsQMkXocaYkc0hZua412siZ1rSXlR460zRJ5SlHGe5j801RLMlJTxtaOM3Q1pvxJ45zUlWFD7rsAbpfEm1JHxG0eh8w2R7QQVzBUw28FhFp5QZzq8t2rx2joqulYTWSuJdTYfWwqMFMcovFmSyJPNyLhE4E10pHzYjOC3huArRa571ZsGajQpQx38SBP5pyZB6lMU3khDnp0MBV51BE9o2E+TY5Ml2E8S7C0o6w1xvCZjf0HkVEHCzFoyNmqC+9wdcqN+Tp7jSDheE9ws8Y5V0NJCn2bk2tqSY4okdrEhx1iDN8cSudwepWmAGXKcJXK65H9to8jYQRH7SBF01ESUJdd0TayVInaWhLkOjlXE5irKGOnI6GSWGCJa482zBI9rCr0jyTVcEuzriC1vcr6mwFGSiqy5zMwxBH/TJHwjSPhL8+01kaaSUuMFKTcLEvaUePcrSmwn8DZrgikWb7CGPxkSjhQwrRk57tctmxLsb9sZvL9LSlyuSLlWkqOjwduo8b6Uv1DkmudIeFF2dHCgxVtk8dpIvHpBxhEOdhKk7OLIUSdJ+cSRY57B+0DgGUUlNfpthTfGkauzxrvTsUUaCVhlKeteTXCoJDCa2NOKhOmC4G1H8JBd4OBZReSRGkqcb/CO1PyLJTLB4j1q8JYaIutEjSLX8YKM+a6phdMsdLFUoV5RTm9JSkuDN8WcIon0NZMNZWh1q8C7SJEwV5HxrmnnTrf3KoJBlmCYI2ilSLlfEvlE4011NNgjgthzEua0oKK7JLE7HZHlEl60BLMVFewg4EWNt0ThrVNEVkkiTwpKXSWJzdRENgvKGq4IhjsiezgSFtsfCUq8qki5S1LRQeYQQ4nemmCkImWMw3tFUoUBZk4NOeZYEp4XRKTGa6wJjrWNHBVJR4m3FCnbuD6aak2WsMTh3SZImGCIPKNgsDpVwnsa70K31lCFJZYcwwSMFcQulGTsZuEaSdBXkPGZhu0FsdUO73RHjq8MPGGIfaGIbVTk6iuI3GFgucHrIQkmWSJdBd7BBu+uOryWAhY7+Lki9rK5wtEQzWwvtbqGhIMFwWRJsElsY4m9IIg9L6lCX0VklaPAYkfkZEGDnOWowlBJjtMUkcGK4Lg6EtoZInMUBVYLgn0UsdmCyCz7gIGHFfk+k1QwTh5We7A9x+IdJ6CvIkEagms0hR50eH9UnTQJ+2oiKyVlLFUE+8gBGu8MQ3CppUHesnjTHN4QB/UGPhCTHLFPHMFrCqa73gqObUJGa03wgbhHkrCfpEpzNLE7JDS25FMKhlhKKWKfCgqstLCPu1zBXy0J2ztwjtixBu8UTRn9LVtkmCN2iyFhtME70JHRQ1KVZXqKI/KNIKYMCYs1GUMEKbM1bKOI9LDXC7zbHS+bt+1MTWS9odA9DtrYtpbImQJ2VHh/lisEwaHqUk1kjKTAKknkBEXkbkdMGwq0dnhzLJF3NJH3JVwrqOB4Sca2hti75nmJN0WzxS6UxDYoEpxpa4htVlRjkYE7DZGzJVU72uC9IyhQL4i8YfGWSYLLNcHXloyz7QhNifmKSE9JgfGmuyLhc403Xm9vqcp6gXe3xuuv8F6VJNxkyTHEkHG2g0aKXL0MsXc1bGfgas2//dCONXiNLCX+5mB7eZIl1kHh7ajwpikyzlUUWOVOsjSQlsS+M0R+pPje/dzBXRZGO0rMtgQrLLG9VSu9n6CMXS3BhwYmSoIBhsjNBmZbgusE9BCPCP5triU4VhNbJfE+swSP27aayE8tuTpYYjtrYjMVGZdp2NpS1s6aBnKSHDsbKuplKbHM4a0wMFd/5/DmGyKrJSUaW4IBrqUhx0vyfzTBBLPIUcnZdrAkNsKR0sWRspumSns6Ch0v/qqIbBYUWKvPU/CFoyrDJGwSNFhbA/MlzKqjrO80hRbpKx0Jewsi/STftwGSlKc1JZyAzx05dhLEdnfQvhZOqiHWWEAHC7+30FuRcZUgaO5gpaIK+xsiHRUsqaPElTV40xQZQ107Q9BZE1nryDVGU9ZSQ47bmhBpLcYpUt7S+xuK/FiT8qKjwXYw5ypS2iuCv7q1gtgjhuBuB8LCFY5cUuCNtsQOFcT+4Ih9JX+k8Ea6v0iCIRZOtCT0Et00JW5UeC85Cg0ScK0k411HcG1zKtre3SeITBRk7WfwDhEvaYLTHP9le0m8By0JDwn4TlLW/aJOvGHxdjYUes+ScZigCkYQdNdEOhkiezgShqkx8ueKjI8lDfK2oNiOFvrZH1hS+tk7NV7nOmLHicGWEgubkXKdwdtZknCLJXaCpkrjZBtLZFsDP9CdxWsSr05Sxl6CMmoFbCOgryX40uDtamB7SVmXW4Ihlgpmq+00tBKUUa83WbjLUNkzDmY7cow1JDygyPGlhgGKYKz4vcV7QBNbJIgM11TUqZaMdwTeSguH6rOaw1JRKzaaGyxVm2EJ/uCIrVWUcZUkcp2grMsEjK+DMwS59jQk3Kd6SEq1d0S6uVmO4Bc1lDXTUcHjluCXEq+1OlBDj1pi9zgiXxnKuE0SqTXwhqbETW6RggMEnGl/q49UT2iCzgJvRwVXS2K/d6+ZkyUl7jawSVLit46EwxVljDZwoSQ20sDBihztHfk2yA8NVZghiXwrYHQdfKAOtzsayjhY9bY0yE2CWEeJ9xfzO423xhL5syS2TFJofO2pboHob0nY4GiAgRrvGQEDa/FWSsoaaYl0syRsEt3kWoH3B01shCXhTUWe9w3Bt44SC9QCh3eShQctwbaK2ApLroGCMlZrYqvlY3qYhM0aXpFkPOuoqJ3Dm6fxXrGwVF9gCWZagjPqznfkuMKQ8DPTQRO8ZqG1hPGKEm9IgpGW4DZDgTNriTxvFiq+Lz+0cKfp4wj6OCK9JSnzNSn9LFU7UhKZZMnYwcJ8s8yRsECScK4j5UOB95HFO0CzhY4xJxuCix0lDlEUeMdS6EZBkTsUkZ4K74dugyTXS7aNgL8aqjDfkCE0ZbwkCXpaWCKhl8P7VD5jxykivSyxyZrYERbe168LYu9ZYh86IkscgVLE7tWPKmJv11CgoyJltMEbrohtVAQfO4ImltiHEroYEs7RxAarVpY8AwXMcMReFOTYWe5iiLRQxJ5Q8DtJ8LQhWOhIeFESPGsILhbNDRljNbHzNRlTFbk2S3L0NOS6V1KFJYKUbSTcIIhM0wQ/s2TM0SRMNcQmSap3jCH4yhJZKSkwyRHpYYgsFeQ4U7xoCB7VVOExhXepo9ABBsYbvGWKXPME3lyH95YioZ0gssQRWWbI+FaSMkXijZXwgiTlYdPdkNLaETxlyDVIwqeaEus0aTcYcg0RVOkpR3CSJqIddK+90JCxzsDVloyrFd5ZAr4TBKfaWa6boEA7C7s6EpYaeFPjveooY72mjIccLHJ9HUwVlDhKkmutJDJBwnp1rvulJZggKDRfbXAkvC/4l3ozQOG9a8lxjx0i7nV4jSXc7vhe3OwIxjgSHjdEhhsif9YkPGlus3iLFDnWOFhtCZbJg0UbQcIaR67JjthoCyMEZRwhiXWyxO5QxI6w5NhT4U1WsJvDO60J34fW9hwzwlKij6ZAW9ne4L0s8C6XeBMEkd/LQy1VucBRot6QMlbivaBhoBgjqGiCJNhsqVp/S2SsG6DIONCR0dXhvWbJ+MRRZJkkuEjgDXJjFQW6SSL7GXK8Z2CZg7cVsbWGoKmEpzQ5elpiy8Ryg7dMkLLUEauzeO86CuwlSOlgYLojZWeJ9xM3S1PWfEfKl5ISLQ0MEKR8YOB2QfCxJBjrKPCN4f9MkaSsqoVXJBmP7EpFZ9UQfOoOFwSzBN4MQ8LsGrymlipcJQhmy0GaQjPqCHaXRwuCZwRbqK2Fg9wlClZqYicrIgMdZfxTQ0c7TBIbrChxmuzoKG8XRaSrIhhiyNFJkrC7oIAWMEOQa5aBekPCRknCo4IKPrYkvCDI8aYmY7WFtprgekcJZ3oLIqssCSMtFbQTJKwXYy3BY5oCh2iKPCpJOE+zRdpYgi6O2KmOAgvVCYaU4ySRek1sgyFhJ403QFHiVEmJHwtybO1gs8Hr5+BETQX3War0qZngYGgtVZtoqd6vFSk/UwdZElYqyjrF4HXUeFspIi9IGKf4j92pKGAdCYMVsbcV3kRF0N+R8LUd5PCsIGWoxDtBkCI0nKofdJQxT+LtZflvuc8Q3CjwWkq8KwUpHzkK/NmSsclCL0nseQdj5FRH5CNHSgtLiW80Of5HU9Hhlsga9bnBq3fEVltKfO5IaSTmGjjc4J0otcP7QsJUSQM8pEj5/wCuUuC2DWz8AAAAAElFTkSuQmCC");
-}
Index: admin/js/codemirror/theme/base16-dark.css
===================================================================
--- admin/js/codemirror/theme/base16-dark.css	(revision 3251)
+++ 	(revision )
@@ -1,38 +1,0 @@
-/*
-
-    Name:       Base16 Default Dark
-    Author:     Chris Kempson (http://chriskempson.com)
-
-    CodeMirror template by Jan T. Sott (https://github.com/idleberg/base16-codemirror)
-    Original Base16 color scheme by Chris Kempson (https://github.com/chriskempson/base16)
-
-*/
-
-.cm-s-base16-dark.CodeMirror { background: #151515; color: #e0e0e0; }
-.cm-s-base16-dark div.CodeMirror-selected { background: #303030; }
-.cm-s-base16-dark .CodeMirror-line::selection, .cm-s-base16-dark .CodeMirror-line > span::selection, .cm-s-base16-dark .CodeMirror-line > span > span::selection { background: rgba(48, 48, 48, .99); }
-.cm-s-base16-dark .CodeMirror-line::-moz-selection, .cm-s-base16-dark .CodeMirror-line > span::-moz-selection, .cm-s-base16-dark .CodeMirror-line > span > span::-moz-selection { background: rgba(48, 48, 48, .99); }
-.cm-s-base16-dark .CodeMirror-gutters { background: #151515; border-right: 0px; }
-.cm-s-base16-dark .CodeMirror-guttermarker { color: #ac4142; }
-.cm-s-base16-dark .CodeMirror-guttermarker-subtle { color: #505050; }
-.cm-s-base16-dark .CodeMirror-linenumber { color: #505050; }
-.cm-s-base16-dark .CodeMirror-cursor { border-left: 1px solid #b0b0b0; }
-
-.cm-s-base16-dark span.cm-comment { color: #8f5536; }
-.cm-s-base16-dark span.cm-atom { color: #aa759f; }
-.cm-s-base16-dark span.cm-number { color: #aa759f; }
-
-.cm-s-base16-dark span.cm-property, .cm-s-base16-dark span.cm-attribute { color: #90a959; }
-.cm-s-base16-dark span.cm-keyword { color: #ac4142; }
-.cm-s-base16-dark span.cm-string { color: #f4bf75; }
-
-.cm-s-base16-dark span.cm-variable { color: #90a959; }
-.cm-s-base16-dark span.cm-variable-2 { color: #6a9fb5; }
-.cm-s-base16-dark span.cm-def { color: #d28445; }
-.cm-s-base16-dark span.cm-bracket { color: #e0e0e0; }
-.cm-s-base16-dark span.cm-tag { color: #ac4142; }
-.cm-s-base16-dark span.cm-link { color: #aa759f; }
-.cm-s-base16-dark span.cm-error { background: #ac4142; color: #b0b0b0; }
-
-.cm-s-base16-dark .CodeMirror-activeline-background { background: #202020; }
-.cm-s-base16-dark .CodeMirror-matchingbracket { text-decoration: underline; color: white !important; }
Index: admin/js/codemirror/theme/base16-light.css
===================================================================
--- admin/js/codemirror/theme/base16-light.css	(revision 3979)
+++ 	(revision )
@@ -1,38 +1,0 @@
-/*
-
-    Name:       Base16 Default Light
-    Author:     Chris Kempson (http://chriskempson.com)
-
-    CodeMirror template by Jan T. Sott (https://github.com/idleberg/base16-codemirror)
-    Original Base16 color scheme by Chris Kempson (https://github.com/chriskempson/base16)
-
-*/
-
-.cm-s-base16-light.CodeMirror { background: #f5f5f5; color: #202020; }
-.cm-s-base16-light div.CodeMirror-selected { background: #e0e0e0; }
-.cm-s-base16-light .CodeMirror-line::selection, .cm-s-base16-light .CodeMirror-line > span::selection, .cm-s-base16-light .CodeMirror-line > span > span::selection { background: #e0e0e0; }
-.cm-s-base16-light .CodeMirror-line::-moz-selection, .cm-s-base16-light .CodeMirror-line > span::-moz-selection, .cm-s-base16-light .CodeMirror-line > span > span::-moz-selection { background: #e0e0e0; }
-.cm-s-base16-light .CodeMirror-gutters { background: #f5f5f5; border-right: 0px; }
-.cm-s-base16-light .CodeMirror-guttermarker { color: #ac4142; }
-.cm-s-base16-light .CodeMirror-guttermarker-subtle { color: #b0b0b0; }
-.cm-s-base16-light .CodeMirror-linenumber { color: #b0b0b0; }
-.cm-s-base16-light .CodeMirror-cursor { border-left: 1px solid #505050; }
-
-.cm-s-base16-light span.cm-comment { color: #8f5536; }
-.cm-s-base16-light span.cm-atom { color: #aa759f; }
-.cm-s-base16-light span.cm-number { color: #aa759f; }
-
-.cm-s-base16-light span.cm-property, .cm-s-base16-light span.cm-attribute { color: #90a959; }
-.cm-s-base16-light span.cm-keyword { color: #ac4142; }
-.cm-s-base16-light span.cm-string { color: #f4bf75; }
-
-.cm-s-base16-light span.cm-variable { color: #90a959; }
-.cm-s-base16-light span.cm-variable-2 { color: #6a9fb5; }
-.cm-s-base16-light span.cm-def { color: #d28445; }
-.cm-s-base16-light span.cm-bracket { color: #202020; }
-.cm-s-base16-light span.cm-tag { color: #ac4142; }
-.cm-s-base16-light span.cm-link { color: #aa759f; }
-.cm-s-base16-light span.cm-error { background: #ac4142; color: #505050; }
-
-.cm-s-base16-light .CodeMirror-activeline-background { background: #DDDCDC; }
-.cm-s-base16-light .CodeMirror-matchingbracket { color: #f5f5f5 !important; background-color: #6A9FB5 !important}
Index: admin/js/codemirror/theme/bespin.css
===================================================================
--- admin/js/codemirror/theme/bespin.css	(revision 3251)
+++ 	(revision )
@@ -1,34 +1,0 @@
-/*
-
-    Name:       Bespin
-    Author:     Mozilla / Jan T. Sott
-
-    CodeMirror template by Jan T. Sott (https://github.com/idleberg/base16-codemirror)
-    Original Base16 color scheme by Chris Kempson (https://github.com/chriskempson/base16)
-
-*/
-
-.cm-s-bespin.CodeMirror {background: #28211c; color: #9d9b97;}
-.cm-s-bespin div.CodeMirror-selected {background: #36312e !important;}
-.cm-s-bespin .CodeMirror-gutters {background: #28211c; border-right: 0px;}
-.cm-s-bespin .CodeMirror-linenumber {color: #666666;}
-.cm-s-bespin .CodeMirror-cursor {border-left: 1px solid #797977 !important;}
-
-.cm-s-bespin span.cm-comment {color: #937121;}
-.cm-s-bespin span.cm-atom {color: #9b859d;}
-.cm-s-bespin span.cm-number {color: #9b859d;}
-
-.cm-s-bespin span.cm-property, .cm-s-bespin span.cm-attribute {color: #54be0d;}
-.cm-s-bespin span.cm-keyword {color: #cf6a4c;}
-.cm-s-bespin span.cm-string {color: #f9ee98;}
-
-.cm-s-bespin span.cm-variable {color: #54be0d;}
-.cm-s-bespin span.cm-variable-2 {color: #5ea6ea;}
-.cm-s-bespin span.cm-def {color: #cf7d34;}
-.cm-s-bespin span.cm-error {background: #cf6a4c; color: #797977;}
-.cm-s-bespin span.cm-bracket {color: #9d9b97;}
-.cm-s-bespin span.cm-tag {color: #cf6a4c;}
-.cm-s-bespin span.cm-link {color: #9b859d;}
-
-.cm-s-bespin .CodeMirror-matchingbracket { text-decoration: underline; color: white !important;}
-.cm-s-bespin .CodeMirror-activeline-background { background: #404040; }
Index: admin/js/codemirror/theme/blackboard.css
===================================================================
--- admin/js/codemirror/theme/blackboard.css	(revision 3251)
+++ 	(revision )
@@ -1,32 +1,0 @@
-/* Port of TextMate's Blackboard theme */
-
-.cm-s-blackboard.CodeMirror { background: #0C1021; color: #F8F8F8; }
-.cm-s-blackboard div.CodeMirror-selected { background: #253B76; }
-.cm-s-blackboard .CodeMirror-line::selection, .cm-s-blackboard .CodeMirror-line > span::selection, .cm-s-blackboard .CodeMirror-line > span > span::selection { background: rgba(37, 59, 118, .99); }
-.cm-s-blackboard .CodeMirror-line::-moz-selection, .cm-s-blackboard .CodeMirror-line > span::-moz-selection, .cm-s-blackboard .CodeMirror-line > span > span::-moz-selection { background: rgba(37, 59, 118, .99); }
-.cm-s-blackboard .CodeMirror-gutters { background: #0C1021; border-right: 0; }
-.cm-s-blackboard .CodeMirror-guttermarker { color: #FBDE2D; }
-.cm-s-blackboard .CodeMirror-guttermarker-subtle { color: #888; }
-.cm-s-blackboard .CodeMirror-linenumber { color: #888; }
-.cm-s-blackboard .CodeMirror-cursor { border-left: 1px solid #A7A7A7; }
-
-.cm-s-blackboard .cm-keyword { color: #FBDE2D; }
-.cm-s-blackboard .cm-atom { color: #D8FA3C; }
-.cm-s-blackboard .cm-number { color: #D8FA3C; }
-.cm-s-blackboard .cm-def { color: #8DA6CE; }
-.cm-s-blackboard .cm-variable { color: #FF6400; }
-.cm-s-blackboard .cm-operator { color: #FBDE2D; }
-.cm-s-blackboard .cm-comment { color: #AEAEAE; }
-.cm-s-blackboard .cm-string { color: #61CE3C; }
-.cm-s-blackboard .cm-string-2 { color: #61CE3C; }
-.cm-s-blackboard .cm-meta { color: #D8FA3C; }
-.cm-s-blackboard .cm-builtin { color: #8DA6CE; }
-.cm-s-blackboard .cm-tag { color: #8DA6CE; }
-.cm-s-blackboard .cm-attribute { color: #8DA6CE; }
-.cm-s-blackboard .cm-header { color: #FF6400; }
-.cm-s-blackboard .cm-hr { color: #AEAEAE; }
-.cm-s-blackboard .cm-link { color: #8DA6CE; }
-.cm-s-blackboard .cm-error { background: #9D1E15; color: #F8F8F8; }
-
-.cm-s-blackboard .CodeMirror-activeline-background { background: #3C3636; }
-.cm-s-blackboard .CodeMirror-matchingbracket { outline:1px solid grey;color:white !important; }
Index: admin/js/codemirror/theme/cobalt.css
===================================================================
--- admin/js/codemirror/theme/cobalt.css	(revision 3617)
+++ 	(revision )
@@ -1,25 +1,0 @@
-.cm-s-cobalt.CodeMirror { background: #002240; color: white; }
-.cm-s-cobalt div.CodeMirror-selected { background: #b36539; }
-.cm-s-cobalt .CodeMirror-line::selection, .cm-s-cobalt .CodeMirror-line > span::selection, .cm-s-cobalt .CodeMirror-line > span > span::selection { background: rgba(179, 101, 57, .99); }
-.cm-s-cobalt .CodeMirror-line::-moz-selection, .cm-s-cobalt .CodeMirror-line > span::-moz-selection, .cm-s-cobalt .CodeMirror-line > span > span::-moz-selection { background: rgba(179, 101, 57, .99); }
-.cm-s-cobalt .CodeMirror-gutters { background: #002240; border-right: 1px solid #aaa; }
-.cm-s-cobalt .CodeMirror-guttermarker { color: #ffee80; }
-.cm-s-cobalt .CodeMirror-guttermarker-subtle { color: #d0d0d0; }
-.cm-s-cobalt .CodeMirror-linenumber { color: #d0d0d0; }
-.cm-s-cobalt .CodeMirror-cursor { border-left: 1px solid white; }
-
-.cm-s-cobalt span.cm-comment { color: #08f; }
-.cm-s-cobalt span.cm-atom { color: #845dc4; }
-.cm-s-cobalt span.cm-number, .cm-s-cobalt span.cm-attribute { color: #ff80e1; }
-.cm-s-cobalt span.cm-keyword { color: #ffee80; }
-.cm-s-cobalt span.cm-string { color: #3ad900; }
-.cm-s-cobalt span.cm-meta { color: #ff9d00; }
-.cm-s-cobalt span.cm-variable-2, .cm-s-cobalt span.cm-tag { color: #9effff; }
-.cm-s-cobalt span.cm-variable-3, .cm-s-cobalt span.cm-def, .cm-s-cobalt .cm-type { color: white; }
-.cm-s-cobalt span.cm-bracket { color: #d8d8d8; }
-.cm-s-cobalt span.cm-builtin, .cm-s-cobalt span.cm-special { color: #ff9e59; }
-.cm-s-cobalt span.cm-link { color: #845dc4; }
-.cm-s-cobalt span.cm-error { color: #9d1e15; }
-
-.cm-s-cobalt .CodeMirror-activeline-background { background: #002D57; }
-.cm-s-cobalt .CodeMirror-matchingbracket { outline:1px solid grey;color:white !important; }
Index: admin/js/codemirror/theme/colorforth.css
===================================================================
--- admin/js/codemirror/theme/colorforth.css	(revision 3617)
+++ 	(revision )
@@ -1,33 +1,0 @@
-.cm-s-colorforth.CodeMirror { background: #000000; color: #f8f8f8; }
-.cm-s-colorforth .CodeMirror-gutters { background: #0a001f; border-right: 1px solid #aaa; }
-.cm-s-colorforth .CodeMirror-guttermarker { color: #FFBD40; }
-.cm-s-colorforth .CodeMirror-guttermarker-subtle { color: #78846f; }
-.cm-s-colorforth .CodeMirror-linenumber { color: #bababa; }
-.cm-s-colorforth .CodeMirror-cursor { border-left: 1px solid white; }
-
-.cm-s-colorforth span.cm-comment     { color: #ededed; }
-.cm-s-colorforth span.cm-def         { color: #ff1c1c; font-weight:bold; }
-.cm-s-colorforth span.cm-keyword     { color: #ffd900; }
-.cm-s-colorforth span.cm-builtin     { color: #00d95a; }
-.cm-s-colorforth span.cm-variable    { color: #73ff00; }
-.cm-s-colorforth span.cm-string      { color: #007bff; }
-.cm-s-colorforth span.cm-number      { color: #00c4ff; }
-.cm-s-colorforth span.cm-atom        { color: #606060; }
-
-.cm-s-colorforth span.cm-variable-2  { color: #EEE; }
-.cm-s-colorforth span.cm-variable-3, .cm-s-colorforth span.cm-type { color: #DDD; }
-.cm-s-colorforth span.cm-property    {}
-.cm-s-colorforth span.cm-operator    {}
-
-.cm-s-colorforth span.cm-meta        { color: yellow; }
-.cm-s-colorforth span.cm-qualifier   { color: #FFF700; }
-.cm-s-colorforth span.cm-bracket     { color: #cc7; }
-.cm-s-colorforth span.cm-tag         { color: #FFBD40; }
-.cm-s-colorforth span.cm-attribute   { color: #FFF700; }
-.cm-s-colorforth span.cm-error       { color: #f00; }
-
-.cm-s-colorforth div.CodeMirror-selected { background: #333d53; }
-
-.cm-s-colorforth span.cm-compilation { background: rgba(255, 255, 255, 0.12); }
-
-.cm-s-colorforth .CodeMirror-activeline-background { background: #253540; }
Index: admin/js/codemirror/theme/darcula.css
===================================================================
--- admin/js/codemirror/theme/darcula.css	(revision 3979)
+++ 	(revision )
@@ -1,51 +1,0 @@
-/**
-    Name: IntelliJ IDEA darcula theme
-    From IntelliJ IDEA by JetBrains
- */
-
-.cm-s-darcula  { font-family: Consolas, Menlo, Monaco, 'Lucida Console', 'Liberation Mono', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', 'Courier New', monospace, serif;}
-.cm-s-darcula.CodeMirror { background: #2B2B2B; color: #A9B7C6; } 
-
-.cm-s-darcula span.cm-meta { color: #BBB529; }
-.cm-s-darcula span.cm-number { color: #6897BB; }
-.cm-s-darcula span.cm-keyword { color: #CC7832; line-height: 1em; font-weight: bold; }  
-.cm-s-darcula span.cm-def { color: #A9B7C6; font-style: italic; }
-.cm-s-darcula span.cm-variable { color: #A9B7C6; }
-.cm-s-darcula span.cm-variable-2 { color: #A9B7C6; }
-.cm-s-darcula span.cm-variable-3 { color: #9876AA; }
-.cm-s-darcula span.cm-type { color: #AABBCC; font-weight: bold; }
-.cm-s-darcula span.cm-property { color: #FFC66D; }
-.cm-s-darcula span.cm-operator { color: #A9B7C6; }
-.cm-s-darcula span.cm-string { color: #6A8759; }
-.cm-s-darcula span.cm-string-2 { color: #6A8759; }
-.cm-s-darcula span.cm-comment { color: #61A151; font-style: italic; } 
-.cm-s-darcula span.cm-link { color: #CC7832; }
-.cm-s-darcula span.cm-atom { color: #CC7832; }
-.cm-s-darcula span.cm-error { color: #BC3F3C; }
-.cm-s-darcula span.cm-tag { color: #629755; font-weight: bold; font-style: italic; text-decoration: underline; }
-.cm-s-darcula span.cm-attribute { color: #6897bb; }
-.cm-s-darcula span.cm-qualifier { color: #6A8759; }
-.cm-s-darcula span.cm-bracket { color: #A9B7C6; }
-.cm-s-darcula span.cm-builtin { color: #FF9E59; }
-.cm-s-darcula span.cm-special { color: #FF9E59; }
-
-.cm-s-darcula .CodeMirror-cursor { border-left: 1px solid #A9B7C6; }  
-.cm-s-darcula .CodeMirror-activeline-background { background: #323232; } 
-.cm-s-darcula .CodeMirror-gutters { background: #313335; border-right: 1px solid #313335; } 
-.cm-s-darcula .CodeMirror-guttermarker { color: #FFEE80; }  
-.cm-s-darcula .CodeMirror-guttermarker-subtle { color: #D0D0D0; }  
-.cm-s-darcula .CodeMirrir-linenumber { color: #606366; } 
-.cm-s-darcula .CodeMirror-matchingbracket { background-color: #3B514D; color: #FFEF28 !important; font-weight: bold; } 
-
-.cm-s-darcula div.CodeMirror-selected { background: #214283; }  
-
-.CodeMirror-hints.darcula {
-  font-family: Menlo, Monaco, Consolas, 'Courier New', monospace;
-  color: #9C9E9E;
-  background-color: #3B3E3F !important;
-}
-
-.CodeMirror-hints.darcula .CodeMirror-hint-active {
-  background-color: #494D4E !important;
-  color: #9C9E9E !important;
-}
Index: admin/js/codemirror/theme/dracula.css
===================================================================
--- admin/js/codemirror/theme/dracula.css	(revision 3617)
+++ 	(revision )
@@ -1,40 +1,0 @@
-/*
-
-    Name:       dracula
-    Author:     Michael Kaminsky (http://github.com/mkaminsky11)
-
-    Original dracula color scheme by Zeno Rocha (https://github.com/zenorocha/dracula-theme)
-
-*/
-
-
-.cm-s-dracula.CodeMirror, .cm-s-dracula .CodeMirror-gutters {
-  background-color: #282a36 !important;
-  color: #f8f8f2 !important;
-  border: none;
-}
-.cm-s-dracula .CodeMirror-gutters { color: #282a36; }
-.cm-s-dracula .CodeMirror-cursor { border-left: solid thin #f8f8f0; }
-.cm-s-dracula .CodeMirror-linenumber { color: #6D8A88; }
-.cm-s-dracula .CodeMirror-selected { background: rgba(255, 255, 255, 0.10); }
-.cm-s-dracula .CodeMirror-line::selection, .cm-s-dracula .CodeMirror-line > span::selection, .cm-s-dracula .CodeMirror-line > span > span::selection { background: rgba(255, 255, 255, 0.10); }
-.cm-s-dracula .CodeMirror-line::-moz-selection, .cm-s-dracula .CodeMirror-line > span::-moz-selection, .cm-s-dracula .CodeMirror-line > span > span::-moz-selection { background: rgba(255, 255, 255, 0.10); }
-.cm-s-dracula span.cm-comment { color: #6272a4; }
-.cm-s-dracula span.cm-string, .cm-s-dracula span.cm-string-2 { color: #f1fa8c; }
-.cm-s-dracula span.cm-number { color: #bd93f9; }
-.cm-s-dracula span.cm-variable { color: #50fa7b; }
-.cm-s-dracula span.cm-variable-2 { color: white; }
-.cm-s-dracula span.cm-def { color: #50fa7b; }
-.cm-s-dracula span.cm-operator { color: #ff79c6; }
-.cm-s-dracula span.cm-keyword { color: #ff79c6; }
-.cm-s-dracula span.cm-atom { color: #bd93f9; }
-.cm-s-dracula span.cm-meta { color: #f8f8f2; }
-.cm-s-dracula span.cm-tag { color: #ff79c6; }
-.cm-s-dracula span.cm-attribute { color: #50fa7b; }
-.cm-s-dracula span.cm-qualifier { color: #50fa7b; }
-.cm-s-dracula span.cm-property { color: #66d9ef; }
-.cm-s-dracula span.cm-builtin { color: #50fa7b; }
-.cm-s-dracula span.cm-variable-3, .cm-s-dracula span.cm-type { color: #ffb86c; }
-
-.cm-s-dracula .CodeMirror-activeline-background { background: rgba(255,255,255,0.1); }
-.cm-s-dracula .CodeMirror-matchingbracket { text-decoration: underline; color: white !important; }
Index: admin/js/codemirror/theme/duotone-dark.css
===================================================================
--- admin/js/codemirror/theme/duotone-dark.css	(revision 3617)
+++ 	(revision )
@@ -1,35 +1,0 @@
-/*
-Name:   DuoTone-Dark
-Author: by Bram de Haan, adapted from DuoTone themes by Simurai (http://simurai.com/projects/2016/01/01/duotone-themes)
-
-CodeMirror template by Jan T. Sott (https://github.com/idleberg), adapted by Bram de Haan (https://github.com/atelierbram/)
-*/
-
-.cm-s-duotone-dark.CodeMirror { background: #2a2734; color: #6c6783; }
-.cm-s-duotone-dark div.CodeMirror-selected { background: #545167!important; }
-.cm-s-duotone-dark .CodeMirror-gutters { background: #2a2734; border-right: 0px; }
-.cm-s-duotone-dark .CodeMirror-linenumber { color: #545167; }
-
-/* begin cursor */
-.cm-s-duotone-dark .CodeMirror-cursor { border-left: 1px solid #ffad5c; /* border-left: 1px solid #ffad5c80; */ border-right: .5em solid #ffad5c; /* border-right: .5em solid #ffad5c80; */ opacity: .5; }
-.cm-s-duotone-dark .CodeMirror-activeline-background { background: #363342; /* background: #36334280;  */ opacity: .5;}
-.cm-s-duotone-dark .cm-fat-cursor .CodeMirror-cursor { background: #ffad5c; /* background: #ffad5c80; */ opacity: .5;}
-/* end cursor */
-
-.cm-s-duotone-dark span.cm-atom, .cm-s-duotone-dark span.cm-number, .cm-s-duotone-dark span.cm-keyword, .cm-s-duotone-dark span.cm-variable, .cm-s-duotone-dark span.cm-attribute, .cm-s-duotone-dark span.cm-quote, .cm-s-duotone-dark span.cm-hr, .cm-s-duotone-dark span.cm-link { color: #ffcc99; }
-
-.cm-s-duotone-dark span.cm-property { color: #9a86fd; }
-.cm-s-duotone-dark span.cm-punctuation, .cm-s-duotone-dark span.cm-unit, .cm-s-duotone-dark span.cm-negative { color: #e09142; }
-.cm-s-duotone-dark span.cm-string { color: #ffb870; }
-.cm-s-duotone-dark span.cm-operator { color: #ffad5c; }
-.cm-s-duotone-dark span.cm-positive { color: #6a51e6; }
-
-.cm-s-duotone-dark span.cm-variable-2, .cm-s-duotone-dark span.cm-variable-3, .cm-s-duotone-dark span.cm-type, .cm-s-duotone-dark span.cm-string-2, .cm-s-duotone-dark span.cm-url { color: #7a63ee; }
-.cm-s-duotone-dark span.cm-def, .cm-s-duotone-dark span.cm-tag, .cm-s-duotone-dark span.cm-builtin, .cm-s-duotone-dark span.cm-qualifier, .cm-s-duotone-dark span.cm-header, .cm-s-duotone-dark span.cm-em { color: #eeebff; }
-.cm-s-duotone-dark span.cm-bracket, .cm-s-duotone-dark span.cm-comment { color: #6c6783; }
-
-/* using #f00 red for errors, don't think any of the colorscheme variables will stand out enough, ... maybe by giving it a background-color ... */
-.cm-s-duotone-dark span.cm-error, .cm-s-duotone-dark span.cm-invalidchar { color: #f00; }
-
-.cm-s-duotone-dark span.cm-header { font-weight: normal; }
-.cm-s-duotone-dark .CodeMirror-matchingbracket { text-decoration: underline; color: #eeebff !important; } 
Index: admin/js/codemirror/theme/duotone-light.css
===================================================================
--- admin/js/codemirror/theme/duotone-light.css	(revision 3617)
+++ 	(revision )
@@ -1,36 +1,0 @@
-/*
-Name:   DuoTone-Light
-Author: by Bram de Haan, adapted from DuoTone themes by Simurai (http://simurai.com/projects/2016/01/01/duotone-themes)
-
-CodeMirror template by Jan T. Sott (https://github.com/idleberg), adapted by Bram de Haan (https://github.com/atelierbram/)
-*/
-
-.cm-s-duotone-light.CodeMirror { background: #faf8f5; color: #b29762; }
-.cm-s-duotone-light div.CodeMirror-selected { background: #e3dcce !important; }
-.cm-s-duotone-light .CodeMirror-gutters { background: #faf8f5; border-right: 0px; }
-.cm-s-duotone-light .CodeMirror-linenumber { color: #cdc4b1; }
-
-/* begin cursor */
-.cm-s-duotone-light .CodeMirror-cursor { border-left: 1px solid #93abdc; /* border-left: 1px solid #93abdc80; */ border-right: .5em solid #93abdc; /* border-right: .5em solid #93abdc80; */ opacity: .5; }
-.cm-s-duotone-light .CodeMirror-activeline-background { background: #e3dcce;  /* background: #e3dcce80; */ opacity: .5; }
-.cm-s-duotone-light .cm-fat-cursor .CodeMirror-cursor { background: #93abdc; /* #93abdc80; */ opacity: .5; }
-/* end cursor */
-
-.cm-s-duotone-light span.cm-atom, .cm-s-duotone-light span.cm-number, .cm-s-duotone-light span.cm-keyword, .cm-s-duotone-light span.cm-variable, .cm-s-duotone-light span.cm-attribute, .cm-s-duotone-light span.cm-quote, .cm-s-duotone-light-light span.cm-hr, .cm-s-duotone-light-light span.cm-link { color: #063289; }
-
-.cm-s-duotone-light span.cm-property { color: #b29762; }
-.cm-s-duotone-light span.cm-punctuation, .cm-s-duotone-light span.cm-unit, .cm-s-duotone-light span.cm-negative { color: #063289; }
-.cm-s-duotone-light span.cm-string, .cm-s-duotone-light span.cm-operator { color: #1659df; }
-.cm-s-duotone-light span.cm-positive { color: #896724; }
-
-.cm-s-duotone-light span.cm-variable-2, .cm-s-duotone-light span.cm-variable-3, .cm-s-duotone-light span.cm-type, .cm-s-duotone-light span.cm-string-2, .cm-s-duotone-light span.cm-url { color: #896724; }
-.cm-s-duotone-light span.cm-def, .cm-s-duotone-light span.cm-tag, .cm-s-duotone-light span.cm-builtin, .cm-s-duotone-light span.cm-qualifier, .cm-s-duotone-light span.cm-header, .cm-s-duotone-light span.cm-em { color: #2d2006; }
-.cm-s-duotone-light span.cm-bracket, .cm-s-duotone-light span.cm-comment { color: #b6ad9a; }
-
-/* using #f00 red for errors, don't think any of the colorscheme variables will stand out enough, ... maybe by giving it a background-color ... */
-/* .cm-s-duotone-light span.cm-error { background: #896724; color: #728fcb; } */
-.cm-s-duotone-light span.cm-error, .cm-s-duotone-light span.cm-invalidchar { color: #f00; }
-
-.cm-s-duotone-light span.cm-header { font-weight: normal; }
-.cm-s-duotone-light .CodeMirror-matchingbracket { text-decoration: underline; color: #faf8f5 !important; }
-
Index: admin/js/codemirror/theme/eclipse.css
===================================================================
--- admin/js/codemirror/theme/eclipse.css	(revision 3617)
+++ 	(revision )
@@ -1,23 +1,0 @@
-.cm-s-eclipse span.cm-meta { color: #FF1717; }
-.cm-s-eclipse span.cm-keyword { line-height: 1em; font-weight: bold; color: #7F0055; }
-.cm-s-eclipse span.cm-atom { color: #219; }
-.cm-s-eclipse span.cm-number { color: #164; }
-.cm-s-eclipse span.cm-def { color: #00f; }
-.cm-s-eclipse span.cm-variable { color: black; }
-.cm-s-eclipse span.cm-variable-2 { color: #0000C0; }
-.cm-s-eclipse span.cm-variable-3, .cm-s-eclipse span.cm-type { color: #0000C0; }
-.cm-s-eclipse span.cm-property { color: black; }
-.cm-s-eclipse span.cm-operator { color: black; }
-.cm-s-eclipse span.cm-comment { color: #3F7F5F; }
-.cm-s-eclipse span.cm-string { color: #2A00FF; }
-.cm-s-eclipse span.cm-string-2 { color: #f50; }
-.cm-s-eclipse span.cm-qualifier { color: #555; }
-.cm-s-eclipse span.cm-builtin { color: #30a; }
-.cm-s-eclipse span.cm-bracket { color: #cc7; }
-.cm-s-eclipse span.cm-tag { color: #170; }
-.cm-s-eclipse span.cm-attribute { color: #00c; }
-.cm-s-eclipse span.cm-link { color: #219; }
-.cm-s-eclipse span.cm-error { color: #f00; }
-
-.cm-s-eclipse .CodeMirror-activeline-background { background: #e8f2ff; }
-.cm-s-eclipse .CodeMirror-matchingbracket { outline:1px solid grey; color:black !important; }
Index: admin/js/codemirror/theme/elegant.css
===================================================================
--- admin/js/codemirror/theme/elegant.css	(revision 3251)
+++ 	(revision )
@@ -1,13 +1,0 @@
-.cm-s-elegant span.cm-number, .cm-s-elegant span.cm-string, .cm-s-elegant span.cm-atom { color: #762; }
-.cm-s-elegant span.cm-comment { color: #262; font-style: italic; line-height: 1em; }
-.cm-s-elegant span.cm-meta { color: #555; font-style: italic; line-height: 1em; }
-.cm-s-elegant span.cm-variable { color: black; }
-.cm-s-elegant span.cm-variable-2 { color: #b11; }
-.cm-s-elegant span.cm-qualifier { color: #555; }
-.cm-s-elegant span.cm-keyword { color: #730; }
-.cm-s-elegant span.cm-builtin { color: #30a; }
-.cm-s-elegant span.cm-link { color: #762; }
-.cm-s-elegant span.cm-error { background-color: #fdd; }
-
-.cm-s-elegant .CodeMirror-activeline-background { background: #e8f2ff; }
-.cm-s-elegant .CodeMirror-matchingbracket { outline:1px solid grey; color:black !important; }
Index: admin/js/codemirror/theme/erlang-dark.css
===================================================================
--- admin/js/codemirror/theme/erlang-dark.css	(revision 3617)
+++ 	(revision )
@@ -1,34 +1,0 @@
-.cm-s-erlang-dark.CodeMirror { background: #002240; color: white; }
-.cm-s-erlang-dark div.CodeMirror-selected { background: #b36539; }
-.cm-s-erlang-dark .CodeMirror-line::selection, .cm-s-erlang-dark .CodeMirror-line > span::selection, .cm-s-erlang-dark .CodeMirror-line > span > span::selection { background: rgba(179, 101, 57, .99); }
-.cm-s-erlang-dark .CodeMirror-line::-moz-selection, .cm-s-erlang-dark .CodeMirror-line > span::-moz-selection, .cm-s-erlang-dark .CodeMirror-line > span > span::-moz-selection { background: rgba(179, 101, 57, .99); }
-.cm-s-erlang-dark .CodeMirror-gutters { background: #002240; border-right: 1px solid #aaa; }
-.cm-s-erlang-dark .CodeMirror-guttermarker { color: white; }
-.cm-s-erlang-dark .CodeMirror-guttermarker-subtle { color: #d0d0d0; }
-.cm-s-erlang-dark .CodeMirror-linenumber { color: #d0d0d0; }
-.cm-s-erlang-dark .CodeMirror-cursor { border-left: 1px solid white; }
-
-.cm-s-erlang-dark span.cm-quote      { color: #ccc; }
-.cm-s-erlang-dark span.cm-atom       { color: #f133f1; }
-.cm-s-erlang-dark span.cm-attribute  { color: #ff80e1; }
-.cm-s-erlang-dark span.cm-bracket    { color: #ff9d00; }
-.cm-s-erlang-dark span.cm-builtin    { color: #eaa; }
-.cm-s-erlang-dark span.cm-comment    { color: #77f; }
-.cm-s-erlang-dark span.cm-def        { color: #e7a; }
-.cm-s-erlang-dark span.cm-keyword    { color: #ffee80; }
-.cm-s-erlang-dark span.cm-meta       { color: #50fefe; }
-.cm-s-erlang-dark span.cm-number     { color: #ffd0d0; }
-.cm-s-erlang-dark span.cm-operator   { color: #d55; }
-.cm-s-erlang-dark span.cm-property   { color: #ccc; }
-.cm-s-erlang-dark span.cm-qualifier  { color: #ccc; }
-.cm-s-erlang-dark span.cm-special    { color: #ffbbbb; }
-.cm-s-erlang-dark span.cm-string     { color: #3ad900; }
-.cm-s-erlang-dark span.cm-string-2   { color: #ccc; }
-.cm-s-erlang-dark span.cm-tag        { color: #9effff; }
-.cm-s-erlang-dark span.cm-variable   { color: #50fe50; }
-.cm-s-erlang-dark span.cm-variable-2 { color: #e0e; }
-.cm-s-erlang-dark span.cm-variable-3, .cm-s-erlang-dark span.cm-type { color: #ccc; }
-.cm-s-erlang-dark span.cm-error      { color: #9d1e15; }
-
-.cm-s-erlang-dark .CodeMirror-activeline-background { background: #013461; }
-.cm-s-erlang-dark .CodeMirror-matchingbracket { outline:1px solid grey; color:white !important; }
Index: admin/js/codemirror/theme/gruvbox-dark.css
===================================================================
--- admin/js/codemirror/theme/gruvbox-dark.css	(revision 3979)
+++ 	(revision )
@@ -1,37 +1,0 @@
-/*
-
-    Name:       gruvbox-dark
-    Author:     kRkk (https://github.com/krkk)
-
-    Original gruvbox color scheme by Pavel Pertsev (https://github.com/morhetz/gruvbox)
-
-*/
-
-.cm-s-gruvbox-dark.CodeMirror, .cm-s-gruvbox-dark .CodeMirror-gutters { background-color: #282828; color: #bdae93; }
-.cm-s-gruvbox-dark .CodeMirror-gutters {background: #282828; border-right: 0px;}
-.cm-s-gruvbox-dark .CodeMirror-linenumber {color: #7c6f64;}
-.cm-s-gruvbox-dark .CodeMirror-cursor { border-left: 1px solid #ebdbb2; }
-.cm-s-gruvbox-dark div.CodeMirror-selected { background: #928374; }
-.cm-s-gruvbox-dark span.cm-meta { color: #83a598; }
-
-.cm-s-gruvbox-dark span.cm-comment { color: #928374; }
-.cm-s-gruvbox-dark span.cm-number, span.cm-atom { color: #d3869b; }
-.cm-s-gruvbox-dark span.cm-keyword { color: #f84934; }
-
-.cm-s-gruvbox-dark span.cm-variable { color: #ebdbb2; }
-.cm-s-gruvbox-dark span.cm-variable-2 { color: #ebdbb2; }
-.cm-s-gruvbox-dark span.cm-variable-3, .cm-s-gruvbox-dark span.cm-type { color: #fabd2f; }
-.cm-s-gruvbox-dark span.cm-operator { color: #ebdbb2; }
-.cm-s-gruvbox-dark span.cm-callee { color: #ebdbb2; }
-.cm-s-gruvbox-dark span.cm-def { color: #ebdbb2; }
-.cm-s-gruvbox-dark span.cm-property { color: #ebdbb2; }
-.cm-s-gruvbox-dark span.cm-string { color: #b8bb26; }
-.cm-s-gruvbox-dark span.cm-string-2 { color: #8ec07c; }
-.cm-s-gruvbox-dark span.cm-qualifier { color: #8ec07c; }
-.cm-s-gruvbox-dark span.cm-attribute { color: #8ec07c; }
-
-.cm-s-gruvbox-dark .CodeMirror-activeline-background { background: #3c3836; }
-.cm-s-gruvbox-dark .CodeMirror-matchingbracket { background: #928374; color:#282828 !important; }
-
-.cm-s-gruvbox-dark span.cm-builtin { color: #fe8019; }
-.cm-s-gruvbox-dark span.cm-tag { color: #fe8019; }
Index: admin/js/codemirror/theme/hopscotch.css
===================================================================
--- admin/js/codemirror/theme/hopscotch.css	(revision 3251)
+++ 	(revision )
@@ -1,34 +1,0 @@
-/*
-
-    Name:       Hopscotch
-    Author:     Jan T. Sott
-
-    CodeMirror template by Jan T. Sott (https://github.com/idleberg/base16-codemirror)
-    Original Base16 color scheme by Chris Kempson (https://github.com/chriskempson/base16)
-
-*/
-
-.cm-s-hopscotch.CodeMirror {background: #322931; color: #d5d3d5;}
-.cm-s-hopscotch div.CodeMirror-selected {background: #433b42 !important;}
-.cm-s-hopscotch .CodeMirror-gutters {background: #322931; border-right: 0px;}
-.cm-s-hopscotch .CodeMirror-linenumber {color: #797379;}
-.cm-s-hopscotch .CodeMirror-cursor {border-left: 1px solid #989498 !important;}
-
-.cm-s-hopscotch span.cm-comment {color: #b33508;}
-.cm-s-hopscotch span.cm-atom {color: #c85e7c;}
-.cm-s-hopscotch span.cm-number {color: #c85e7c;}
-
-.cm-s-hopscotch span.cm-property, .cm-s-hopscotch span.cm-attribute {color: #8fc13e;}
-.cm-s-hopscotch span.cm-keyword {color: #dd464c;}
-.cm-s-hopscotch span.cm-string {color: #fdcc59;}
-
-.cm-s-hopscotch span.cm-variable {color: #8fc13e;}
-.cm-s-hopscotch span.cm-variable-2 {color: #1290bf;}
-.cm-s-hopscotch span.cm-def {color: #fd8b19;}
-.cm-s-hopscotch span.cm-error {background: #dd464c; color: #989498;}
-.cm-s-hopscotch span.cm-bracket {color: #d5d3d5;}
-.cm-s-hopscotch span.cm-tag {color: #dd464c;}
-.cm-s-hopscotch span.cm-link {color: #c85e7c;}
-
-.cm-s-hopscotch .CodeMirror-matchingbracket { text-decoration: underline; color: white !important;}
-.cm-s-hopscotch .CodeMirror-activeline-background { background: #302020; }
Index: admin/js/codemirror/theme/icecoder.css
===================================================================
--- admin/js/codemirror/theme/icecoder.css	(revision 3617)
+++ 	(revision )
@@ -1,43 +1,0 @@
-/*
-ICEcoder default theme by Matt Pass, used in code editor available at https://icecoder.net
-*/
-
-.cm-s-icecoder { color: #666; background: #1d1d1b; }
-
-.cm-s-icecoder span.cm-keyword { color: #eee; font-weight:bold; }  /* off-white 1 */
-.cm-s-icecoder span.cm-atom { color: #e1c76e; }                    /* yellow */
-.cm-s-icecoder span.cm-number { color: #6cb5d9; }                  /* blue */
-.cm-s-icecoder span.cm-def { color: #b9ca4a; }                     /* green */
-
-.cm-s-icecoder span.cm-variable { color: #6cb5d9; }                /* blue */
-.cm-s-icecoder span.cm-variable-2 { color: #cc1e5c; }              /* pink */
-.cm-s-icecoder span.cm-variable-3, .cm-s-icecoder span.cm-type { color: #f9602c; } /* orange */
-
-.cm-s-icecoder span.cm-property { color: #eee; }                   /* off-white 1 */
-.cm-s-icecoder span.cm-operator { color: #9179bb; }                /* purple */
-.cm-s-icecoder span.cm-comment { color: #97a3aa; }                 /* grey-blue */
-
-.cm-s-icecoder span.cm-string { color: #b9ca4a; }                  /* green */
-.cm-s-icecoder span.cm-string-2 { color: #6cb5d9; }                /* blue */
-
-.cm-s-icecoder span.cm-meta { color: #555; }                       /* grey */
-
-.cm-s-icecoder span.cm-qualifier { color: #555; }                  /* grey */
-.cm-s-icecoder span.cm-builtin { color: #214e7b; }                 /* bright blue */
-.cm-s-icecoder span.cm-bracket { color: #cc7; }                    /* grey-yellow */
-
-.cm-s-icecoder span.cm-tag { color: #e8e8e8; }                     /* off-white 2 */
-.cm-s-icecoder span.cm-attribute { color: #099; }                  /* teal */
-
-.cm-s-icecoder span.cm-header { color: #6a0d6a; }                  /* purple-pink */
-.cm-s-icecoder span.cm-quote { color: #186718; }                   /* dark green */
-.cm-s-icecoder span.cm-hr { color: #888; }                         /* mid-grey */
-.cm-s-icecoder span.cm-link { color: #e1c76e; }                    /* yellow */
-.cm-s-icecoder span.cm-error { color: #d00; }                      /* red */
-
-.cm-s-icecoder .CodeMirror-cursor { border-left: 1px solid white; }
-.cm-s-icecoder div.CodeMirror-selected { color: #fff; background: #037; }
-.cm-s-icecoder .CodeMirror-gutters { background: #1d1d1b; min-width: 41px; border-right: 0; }
-.cm-s-icecoder .CodeMirror-linenumber { color: #555; cursor: default; }
-.cm-s-icecoder .CodeMirror-matchingbracket { color: #fff !important; background: #555 !important; }
-.cm-s-icecoder .CodeMirror-activeline-background { background: #000; }
Index: admin/js/codemirror/theme/idea.css
===================================================================
--- admin/js/codemirror/theme/idea.css	(revision 3979)
+++ 	(revision )
@@ -1,42 +1,0 @@
-/**
-    Name:       IDEA default theme
-    From IntelliJ IDEA by JetBrains
- */
-
-.cm-s-idea span.cm-meta { color: #808000; }
-.cm-s-idea span.cm-number { color: #0000FF; }
-.cm-s-idea span.cm-keyword { line-height: 1em; font-weight: bold; color: #000080; }
-.cm-s-idea span.cm-atom { font-weight: bold; color: #000080; }
-.cm-s-idea span.cm-def { color: #000000; }
-.cm-s-idea span.cm-variable { color: black; }
-.cm-s-idea span.cm-variable-2 { color: black; }
-.cm-s-idea span.cm-variable-3, .cm-s-idea span.cm-type { color: black; }
-.cm-s-idea span.cm-property { color: black; }
-.cm-s-idea span.cm-operator { color: black; }
-.cm-s-idea span.cm-comment { color: #808080; }
-.cm-s-idea span.cm-string { color: #008000; }
-.cm-s-idea span.cm-string-2 { color: #008000; }
-.cm-s-idea span.cm-qualifier { color: #555; }
-.cm-s-idea span.cm-error { color: #FF0000; }
-.cm-s-idea span.cm-attribute { color: #0000FF; }
-.cm-s-idea span.cm-tag { color: #000080; }
-.cm-s-idea span.cm-link { color: #0000FF; }
-.cm-s-idea .CodeMirror-activeline-background { background: #FFFAE3; }
-
-.cm-s-idea span.cm-builtin { color: #30a; }
-.cm-s-idea span.cm-bracket { color: #cc7; }
-.cm-s-idea  { font-family: Consolas, Menlo, Monaco, Lucida Console, Liberation Mono, DejaVu Sans Mono, Bitstream Vera Sans Mono, Courier New, monospace, serif;}
-
-
-.cm-s-idea .CodeMirror-matchingbracket { outline:1px solid grey; color:black !important; }
-
-.CodeMirror-hints.idea {
-  font-family: Menlo, Monaco, Consolas, 'Courier New', monospace;
-  color: #616569;
-  background-color: #ebf3fd !important;
-}
-
-.CodeMirror-hints.idea .CodeMirror-hint-active {
-  background-color: #a2b8c9 !important;
-  color: #5c6065 !important;
-}
Index: admin/js/codemirror/theme/isotope.css
===================================================================
--- admin/js/codemirror/theme/isotope.css	(revision 3251)
+++ 	(revision )
@@ -1,34 +1,0 @@
-/*
-
-    Name:       Isotope
-    Author:     David Desandro / Jan T. Sott
-
-    CodeMirror template by Jan T. Sott (https://github.com/idleberg/base16-codemirror)
-    Original Base16 color scheme by Chris Kempson (https://github.com/chriskempson/base16)
-
-*/
-
-.cm-s-isotope.CodeMirror {background: #000000; color: #e0e0e0;}
-.cm-s-isotope div.CodeMirror-selected {background: #404040 !important;}
-.cm-s-isotope .CodeMirror-gutters {background: #000000; border-right: 0px;}
-.cm-s-isotope .CodeMirror-linenumber {color: #808080;}
-.cm-s-isotope .CodeMirror-cursor {border-left: 1px solid #c0c0c0 !important;}
-
-.cm-s-isotope span.cm-comment {color: #3300ff;}
-.cm-s-isotope span.cm-atom {color: #cc00ff;}
-.cm-s-isotope span.cm-number {color: #cc00ff;}
-
-.cm-s-isotope span.cm-property, .cm-s-isotope span.cm-attribute {color: #33ff00;}
-.cm-s-isotope span.cm-keyword {color: #ff0000;}
-.cm-s-isotope span.cm-string {color: #ff0099;}
-
-.cm-s-isotope span.cm-variable {color: #33ff00;}
-.cm-s-isotope span.cm-variable-2 {color: #0066ff;}
-.cm-s-isotope span.cm-def {color: #ff9900;}
-.cm-s-isotope span.cm-error {background: #ff0000; color: #c0c0c0;}
-.cm-s-isotope span.cm-bracket {color: #e0e0e0;}
-.cm-s-isotope span.cm-tag {color: #ff0000;}
-.cm-s-isotope span.cm-link {color: #cc00ff;}
-
-.cm-s-isotope .CodeMirror-matchingbracket { text-decoration: underline; color: white !important;}
-.cm-s-isotope .CodeMirror-activeline-background { background: #202020; }
Index: admin/js/codemirror/theme/lesser-dark.css
===================================================================
--- admin/js/codemirror/theme/lesser-dark.css	(revision 3979)
+++ 	(revision )
@@ -1,47 +1,0 @@
-/*
-http://lesscss.org/ dark theme
-Ported to CodeMirror by Peter Kroon
-*/
-.cm-s-lesser-dark {
-  line-height: 1.3em;
-}
-.cm-s-lesser-dark.CodeMirror { background: #262626; color: #EBEFE7; text-shadow: 0 -1px 1px #262626; }
-.cm-s-lesser-dark div.CodeMirror-selected { background: #45443B; } /* 33322B*/
-.cm-s-lesser-dark .CodeMirror-line::selection, .cm-s-lesser-dark .CodeMirror-line > span::selection, .cm-s-lesser-dark .CodeMirror-line > span > span::selection { background: rgba(69, 68, 59, .99); }
-.cm-s-lesser-dark .CodeMirror-line::-moz-selection, .cm-s-lesser-dark .CodeMirror-line > span::-moz-selection, .cm-s-lesser-dark .CodeMirror-line > span > span::-moz-selection { background: rgba(69, 68, 59, .99); }
-.cm-s-lesser-dark .CodeMirror-cursor { border-left: 1px solid white; }
-.cm-s-lesser-dark pre { padding: 0 8px; }/*editable code holder*/
-
-.cm-s-lesser-dark.CodeMirror span.CodeMirror-matchingbracket { color: #7EFC7E; }/*65FC65*/
-
-.cm-s-lesser-dark .CodeMirror-gutters { background: #262626; border-right:1px solid #aaa; }
-.cm-s-lesser-dark .CodeMirror-guttermarker { color: #599eff; }
-.cm-s-lesser-dark .CodeMirror-guttermarker-subtle { color: #777; }
-.cm-s-lesser-dark .CodeMirror-linenumber { color: #777; }
-
-.cm-s-lesser-dark span.cm-header { color: #a0a; }
-.cm-s-lesser-dark span.cm-quote { color: #090; }
-.cm-s-lesser-dark span.cm-keyword { color: #599eff; }
-.cm-s-lesser-dark span.cm-atom { color: #C2B470; }
-.cm-s-lesser-dark span.cm-number { color: #B35E4D; }
-.cm-s-lesser-dark span.cm-def { color: white; }
-.cm-s-lesser-dark span.cm-variable { color:#D9BF8C; }
-.cm-s-lesser-dark span.cm-variable-2 { color: #669199; }
-.cm-s-lesser-dark span.cm-variable-3, .cm-s-lesser-dark span.cm-type { color: white; }
-.cm-s-lesser-dark span.cm-property { color: #92A75C; }
-.cm-s-lesser-dark span.cm-operator { color: #92A75C; }
-.cm-s-lesser-dark span.cm-comment { color: #666; }
-.cm-s-lesser-dark span.cm-string { color: #BCD279; }
-.cm-s-lesser-dark span.cm-string-2 { color: #f50; }
-.cm-s-lesser-dark span.cm-meta { color: #738C73; }
-.cm-s-lesser-dark span.cm-qualifier { color: #555; }
-.cm-s-lesser-dark span.cm-builtin { color: #ff9e59; }
-.cm-s-lesser-dark span.cm-bracket { color: #EBEFE7; }
-.cm-s-lesser-dark span.cm-tag { color: #669199; }
-.cm-s-lesser-dark span.cm-attribute { color: #81a4d5; }
-.cm-s-lesser-dark span.cm-hr { color: #999; }
-.cm-s-lesser-dark span.cm-link { color: #7070E6; }
-.cm-s-lesser-dark span.cm-error { color: #9d1e15; }
-
-.cm-s-lesser-dark .CodeMirror-activeline-background { background: #3C3A3A; }
-.cm-s-lesser-dark .CodeMirror-matchingbracket { outline:1px solid grey; color:white !important; }
Index: admin/js/codemirror/theme/liquibyte.css
===================================================================
--- admin/js/codemirror/theme/liquibyte.css	(revision 3617)
+++ 	(revision )
@@ -1,95 +1,0 @@
-.cm-s-liquibyte.CodeMirror {
-	background-color: #000;
-	color: #fff;
-	line-height: 1.2em;
-	font-size: 1em;
-}
-.cm-s-liquibyte .CodeMirror-focused .cm-matchhighlight {
-	text-decoration: underline;
-	text-decoration-color: #0f0;
-	text-decoration-style: wavy;
-}
-.cm-s-liquibyte .cm-trailingspace {
-	text-decoration: line-through;
-	text-decoration-color: #f00;
-	text-decoration-style: dotted;
-}
-.cm-s-liquibyte .cm-tab {
-	text-decoration: line-through;
-	text-decoration-color: #404040;
-	text-decoration-style: dotted;
-}
-.cm-s-liquibyte .CodeMirror-gutters { background-color: #262626; border-right: 1px solid #505050; padding-right: 0.8em; }
-.cm-s-liquibyte .CodeMirror-gutter-elt div { font-size: 1.2em; }
-.cm-s-liquibyte .CodeMirror-guttermarker {  }
-.cm-s-liquibyte .CodeMirror-guttermarker-subtle {  }
-.cm-s-liquibyte .CodeMirror-linenumber { color: #606060; padding-left: 0; }
-.cm-s-liquibyte .CodeMirror-cursor { border-left: 1px solid #eee; }
-
-.cm-s-liquibyte span.cm-comment     { color: #008000; }
-.cm-s-liquibyte span.cm-def         { color: #ffaf40; font-weight: bold; }
-.cm-s-liquibyte span.cm-keyword     { color: #c080ff; font-weight: bold; }
-.cm-s-liquibyte span.cm-builtin     { color: #ffaf40; font-weight: bold; }
-.cm-s-liquibyte span.cm-variable    { color: #5967ff; font-weight: bold; }
-.cm-s-liquibyte span.cm-string      { color: #ff8000; }
-.cm-s-liquibyte span.cm-number      { color: #0f0; font-weight: bold; }
-.cm-s-liquibyte span.cm-atom        { color: #bf3030; font-weight: bold; }
-
-.cm-s-liquibyte span.cm-variable-2  { color: #007f7f; font-weight: bold; }
-.cm-s-liquibyte span.cm-variable-3, .cm-s-liquibyte span.cm-type { color: #c080ff; font-weight: bold; }
-.cm-s-liquibyte span.cm-property    { color: #999; font-weight: bold; }
-.cm-s-liquibyte span.cm-operator    { color: #fff; }
-
-.cm-s-liquibyte span.cm-meta        { color: #0f0; }
-.cm-s-liquibyte span.cm-qualifier   { color: #fff700; font-weight: bold; }
-.cm-s-liquibyte span.cm-bracket     { color: #cc7; }
-.cm-s-liquibyte span.cm-tag         { color: #ff0; font-weight: bold; }
-.cm-s-liquibyte span.cm-attribute   { color: #c080ff; font-weight: bold; }
-.cm-s-liquibyte span.cm-error       { color: #f00; }
-
-.cm-s-liquibyte div.CodeMirror-selected { background-color: rgba(255, 0, 0, 0.25); }
-
-.cm-s-liquibyte span.cm-compilation { background-color: rgba(255, 255, 255, 0.12); }
-
-.cm-s-liquibyte .CodeMirror-activeline-background { background-color: rgba(0, 255, 0, 0.15); }
-
-/* Default styles for common addons */
-.cm-s-liquibyte .CodeMirror span.CodeMirror-matchingbracket { color: #0f0; font-weight: bold; }
-.cm-s-liquibyte .CodeMirror span.CodeMirror-nonmatchingbracket { color: #f00; font-weight: bold; }
-.CodeMirror-matchingtag { background-color: rgba(150, 255, 0, .3); }
-/* Scrollbars */
-/* Simple */
-.cm-s-liquibyte div.CodeMirror-simplescroll-horizontal div:hover, .cm-s-liquibyte div.CodeMirror-simplescroll-vertical div:hover {
-	background-color: rgba(80, 80, 80, .7);
-}
-.cm-s-liquibyte div.CodeMirror-simplescroll-horizontal div, .cm-s-liquibyte div.CodeMirror-simplescroll-vertical div {
-	background-color: rgba(80, 80, 80, .3);
-	border: 1px solid #404040;
-	border-radius: 5px;
-}
-.cm-s-liquibyte div.CodeMirror-simplescroll-vertical div {
-	border-top: 1px solid #404040;
-	border-bottom: 1px solid #404040;
-}
-.cm-s-liquibyte div.CodeMirror-simplescroll-horizontal div {
-	border-left: 1px solid #404040;
-	border-right: 1px solid #404040;
-}
-.cm-s-liquibyte div.CodeMirror-simplescroll-vertical {
-	background-color: #262626;
-}
-.cm-s-liquibyte div.CodeMirror-simplescroll-horizontal {
-	background-color: #262626;
-	border-top: 1px solid #404040;
-}
-/* Overlay */
-.cm-s-liquibyte div.CodeMirror-overlayscroll-horizontal div, div.CodeMirror-overlayscroll-vertical div {
-	background-color: #404040;
-	border-radius: 5px;
-}
-.cm-s-liquibyte div.CodeMirror-overlayscroll-vertical div {
-	border: 1px solid #404040;
-}
-.cm-s-liquibyte div.CodeMirror-overlayscroll-horizontal div {
-	border: 1px solid #404040;
-}
Index: admin/js/codemirror/theme/lucario.css
===================================================================
--- admin/js/codemirror/theme/lucario.css	(revision 3758)
+++ 	(revision )
@@ -1,37 +1,0 @@
-/*
-  Name:       lucario
-  Author:     Raphael Amorim
-
-  Original Lucario color scheme (https://github.com/raphamorim/lucario)
-*/
-
-.cm-s-lucario.CodeMirror, .cm-s-lucario .CodeMirror-gutters {
-  background-color: #2b3e50 !important;
-  color: #f8f8f2 !important;
-  border: none;
-}
-.cm-s-lucario .CodeMirror-gutters { color: #2b3e50; }
-.cm-s-lucario .CodeMirror-cursor { border-left: solid thin #E6C845; }
-.cm-s-lucario .CodeMirror-linenumber { color: #f8f8f2; }
-.cm-s-lucario .CodeMirror-selected { background: #243443; }
-.cm-s-lucario .CodeMirror-line::selection, .cm-s-lucario .CodeMirror-line > span::selection, .cm-s-lucario .CodeMirror-line > span > span::selection { background: #243443; }
-.cm-s-lucario .CodeMirror-line::-moz-selection, .cm-s-lucario .CodeMirror-line > span::-moz-selection, .cm-s-lucario .CodeMirror-line > span > span::-moz-selection { background: #243443; }
-.cm-s-lucario span.cm-comment { color: #5c98cd; }
-.cm-s-lucario span.cm-string, .cm-s-lucario span.cm-string-2 { color: #E6DB74; }
-.cm-s-lucario span.cm-number { color: #ca94ff; }
-.cm-s-lucario span.cm-variable { color: #f8f8f2; }
-.cm-s-lucario span.cm-variable-2 { color: #f8f8f2; }
-.cm-s-lucario span.cm-def { color: #72C05D; }
-.cm-s-lucario span.cm-operator { color: #66D9EF; }
-.cm-s-lucario span.cm-keyword { color: #ff6541; }
-.cm-s-lucario span.cm-atom { color: #bd93f9; }
-.cm-s-lucario span.cm-meta { color: #f8f8f2; }
-.cm-s-lucario span.cm-tag { color: #ff6541; }
-.cm-s-lucario span.cm-attribute { color: #66D9EF; }
-.cm-s-lucario span.cm-qualifier { color: #72C05D; }
-.cm-s-lucario span.cm-property { color: #f8f8f2; }
-.cm-s-lucario span.cm-builtin { color: #72C05D; }
-.cm-s-lucario span.cm-variable-3, .cm-s-lucario span.cm-type { color: #ffb86c; }
-
-.cm-s-lucario .CodeMirror-activeline-background { background: #243443; }
-.cm-s-lucario .CodeMirror-matchingbracket { text-decoration: underline; color: white !important; }
Index: admin/js/codemirror/theme/material.css
===================================================================
--- admin/js/codemirror/theme/material.css	(revision 3617)
+++ 	(revision )
@@ -1,53 +1,0 @@
-/*
-
-    Name:       material
-    Author:     Michael Kaminsky (http://github.com/mkaminsky11)
-
-    Original material color scheme by Mattia Astorino (https://github.com/equinusocio/material-theme)
-
-*/
-
-.cm-s-material.CodeMirror {
-  background-color: #263238;
-  color: rgba(233, 237, 237, 1);
-}
-.cm-s-material .CodeMirror-gutters {
-  background: #263238;
-  color: rgb(83,127,126);
-  border: none;
-}
-.cm-s-material .CodeMirror-guttermarker, .cm-s-material .CodeMirror-guttermarker-subtle, .cm-s-material .CodeMirror-linenumber { color: rgb(83,127,126); }
-.cm-s-material .CodeMirror-cursor { border-left: 1px solid #f8f8f0; }
-.cm-s-material div.CodeMirror-selected { background: rgba(255, 255, 255, 0.15); }
-.cm-s-material.CodeMirror-focused div.CodeMirror-selected { background: rgba(255, 255, 255, 0.10); }
-.cm-s-material .CodeMirror-line::selection, .cm-s-material .CodeMirror-line > span::selection, .cm-s-material .CodeMirror-line > span > span::selection { background: rgba(255, 255, 255, 0.10); }
-.cm-s-material .CodeMirror-line::-moz-selection, .cm-s-material .CodeMirror-line > span::-moz-selection, .cm-s-material .CodeMirror-line > span > span::-moz-selection { background: rgba(255, 255, 255, 0.10); }
-
-.cm-s-material .CodeMirror-activeline-background { background: rgba(0, 0, 0, 0); }
-.cm-s-material .cm-keyword { color: rgba(199, 146, 234, 1); }
-.cm-s-material .cm-operator { color: rgba(233, 237, 237, 1); }
-.cm-s-material .cm-variable-2 { color: #80CBC4; }
-.cm-s-material .cm-variable-3, .cm-s-material .cm-type { color: #82B1FF; }
-.cm-s-material .cm-builtin { color: #DECB6B; }
-.cm-s-material .cm-atom { color: #F77669; }
-.cm-s-material .cm-number { color: #F77669; }
-.cm-s-material .cm-def { color: rgba(233, 237, 237, 1); }
-.cm-s-material .cm-string { color: #C3E88D; }
-.cm-s-material .cm-string-2 { color: #80CBC4; }
-.cm-s-material .cm-comment { color: #546E7A; }
-.cm-s-material .cm-variable { color: #82B1FF; }
-.cm-s-material .cm-tag { color: #80CBC4; }
-.cm-s-material .cm-meta { color: #80CBC4; }
-.cm-s-material .cm-attribute { color: #FFCB6B; }
-.cm-s-material .cm-property { color: #80CBAE; }
-.cm-s-material .cm-qualifier { color: #DECB6B; }
-.cm-s-material .cm-variable-3, .cm-s-material .cm-type { color: #DECB6B; }
-.cm-s-material .cm-tag { color: rgba(255, 83, 112, 1); }
-.cm-s-material .cm-error {
-  color: rgba(255, 255, 255, 1.0);
-  background-color: #EC5F67;
-}
-.cm-s-material .CodeMirror-matchingbracket {
-  text-decoration: underline;
-  color: white !important;
-}
Index: admin/js/codemirror/theme/mbo.css
===================================================================
--- admin/js/codemirror/theme/mbo.css	(revision 3251)
+++ 	(revision )
@@ -1,37 +1,0 @@
-/****************************************************************/
-/*   Based on mbonaci's Brackets mbo theme                      */
-/*   https://github.com/mbonaci/global/blob/master/Mbo.tmTheme  */
-/*   Create your own: http://tmtheme-editor.herokuapp.com       */
-/****************************************************************/
-
-.cm-s-mbo.CodeMirror { background: #2c2c2c; color: #ffffec; }
-.cm-s-mbo div.CodeMirror-selected { background: #716C62; }
-.cm-s-mbo .CodeMirror-line::selection, .cm-s-mbo .CodeMirror-line > span::selection, .cm-s-mbo .CodeMirror-line > span > span::selection { background: rgba(113, 108, 98, .99); }
-.cm-s-mbo .CodeMirror-line::-moz-selection, .cm-s-mbo .CodeMirror-line > span::-moz-selection, .cm-s-mbo .CodeMirror-line > span > span::-moz-selection { background: rgba(113, 108, 98, .99); }
-.cm-s-mbo .CodeMirror-gutters { background: #4e4e4e; border-right: 0px; }
-.cm-s-mbo .CodeMirror-guttermarker { color: white; }
-.cm-s-mbo .CodeMirror-guttermarker-subtle { color: grey; }
-.cm-s-mbo .CodeMirror-linenumber { color: #dadada; }
-.cm-s-mbo .CodeMirror-cursor { border-left: 1px solid #ffffec; }
-
-.cm-s-mbo span.cm-comment { color: #95958a; }
-.cm-s-mbo span.cm-atom { color: #00a8c6; }
-.cm-s-mbo span.cm-number { color: #00a8c6; }
-
-.cm-s-mbo span.cm-property, .cm-s-mbo span.cm-attribute { color: #9ddfe9; }
-.cm-s-mbo span.cm-keyword { color: #ffb928; }
-.cm-s-mbo span.cm-string { color: #ffcf6c; }
-.cm-s-mbo span.cm-string.cm-property { color: #ffffec; }
-
-.cm-s-mbo span.cm-variable { color: #ffffec; }
-.cm-s-mbo span.cm-variable-2 { color: #00a8c6; }
-.cm-s-mbo span.cm-def { color: #ffffec; }
-.cm-s-mbo span.cm-bracket { color: #fffffc; font-weight: bold; }
-.cm-s-mbo span.cm-tag { color: #9ddfe9; }
-.cm-s-mbo span.cm-link { color: #f54b07; }
-.cm-s-mbo span.cm-error { border-bottom: #636363; color: #ffffec; }
-.cm-s-mbo span.cm-qualifier { color: #ffffec; }
-
-.cm-s-mbo .CodeMirror-activeline-background { background: #494b41; }
-.cm-s-mbo .CodeMirror-matchingbracket { color: #ffb928 !important; }
-.cm-s-mbo .CodeMirror-matchingtag { background: rgba(255, 255, 255, .37); }
Index: admin/js/codemirror/theme/mdn-like.css
===================================================================
--- admin/js/codemirror/theme/mdn-like.css	(revision 3617)
+++ 	(revision )
@@ -1,46 +1,0 @@
-/*
-  MDN-LIKE Theme - Mozilla
-  Ported to CodeMirror by Peter Kroon <plakroon@gmail.com>
-  Report bugs/issues here: https://github.com/codemirror/CodeMirror/issues
-  GitHub: @peterkroon
-
-  The mdn-like theme is inspired on the displayed code examples at: https://developer.mozilla.org/en-US/docs/Web/CSS/animation
-
-*/
-.cm-s-mdn-like.CodeMirror { color: #999; background-color: #fff; }
-.cm-s-mdn-like div.CodeMirror-selected { background: #cfc; }
-.cm-s-mdn-like .CodeMirror-line::selection, .cm-s-mdn-like .CodeMirror-line > span::selection, .cm-s-mdn-like .CodeMirror-line > span > span::selection { background: #cfc; }
-.cm-s-mdn-like .CodeMirror-line::-moz-selection, .cm-s-mdn-like .CodeMirror-line > span::-moz-selection, .cm-s-mdn-like .CodeMirror-line > span > span::-moz-selection { background: #cfc; }
-
-.cm-s-mdn-like .CodeMirror-gutters { background: #f8f8f8; border-left: 6px solid rgba(0,83,159,0.65); color: #333; }
-.cm-s-mdn-like .CodeMirror-linenumber { color: #aaa; padding-left: 8px; }
-.cm-s-mdn-like .CodeMirror-cursor { border-left: 2px solid #222; }
-
-.cm-s-mdn-like .cm-keyword { color: #6262FF; }
-.cm-s-mdn-like .cm-atom { color: #F90; }
-.cm-s-mdn-like .cm-number { color:  #ca7841; }
-.cm-s-mdn-like .cm-def { color: #8DA6CE; }
-.cm-s-mdn-like span.cm-variable-2, .cm-s-mdn-like span.cm-tag { color: #690; }
-.cm-s-mdn-like span.cm-variable-3, .cm-s-mdn-like span.cm-def, .cm-s-mdn-like span.cm-type { color: #07a; }
-
-.cm-s-mdn-like .cm-variable { color: #07a; }
-.cm-s-mdn-like .cm-property { color: #905; }
-.cm-s-mdn-like .cm-qualifier { color: #690; }
-
-.cm-s-mdn-like .cm-operator { color: #cda869; }
-.cm-s-mdn-like .cm-comment { color:#777; font-weight:normal; }
-.cm-s-mdn-like .cm-string { color:#07a; font-style:italic; }
-.cm-s-mdn-like .cm-string-2 { color:#bd6b18; } /*?*/
-.cm-s-mdn-like .cm-meta { color: #000; } /*?*/
-.cm-s-mdn-like .cm-builtin { color: #9B7536; } /*?*/
-.cm-s-mdn-like .cm-tag { color: #997643; }
-.cm-s-mdn-like .cm-attribute { color: #d6bb6d; } /*?*/
-.cm-s-mdn-like .cm-header { color: #FF6400; }
-.cm-s-mdn-like .cm-hr { color: #AEAEAE; }
-.cm-s-mdn-like .cm-link { color:#ad9361; font-style:italic; text-decoration:none; }
-.cm-s-mdn-like .cm-error { border-bottom: 1px solid red; }
-
-div.cm-s-mdn-like .CodeMirror-activeline-background { background: #efefff; }
-div.cm-s-mdn-like span.CodeMirror-matchingbracket { outline:1px solid grey; color: inherit; }
-
-.cm-s-mdn-like.CodeMirror { background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAFcAAAAyCAYAAAAp8UeFAAAHvklEQVR42s2b63bcNgyEQZCSHCdt2vd/0tWF7I+Q6XgMXiTtuvU5Pl57ZQKkKHzEAOtF5KeIJBGJ8uvL599FRFREZhFx8DeXv8trn68RuGaC8TRfo3SNp9dlDDHedyLyTUTeRWStXKPZrjtpZxaRw5hPqozRs1N8/enzIiQRWcCgy4MUA0f+XWliDhyL8Lfyvx7ei/Ae3iQFHyw7U/59pQVIMEEPEz0G7XiwdRjzSfC3UTtz9vchIntxvry5iMgfIhJoEflOz2CQr3F5h/HfeFe+GTdLaKcu9L8LTeQb/R/7GgbsfKedyNdoHsN31uRPWrfZ5wsj/NzzRQHuToIdU3ahwnsKPxXCjJITuOsi7XLc7SG/v5GdALs7wf8JjTFiB5+QvTEfRyGOfX3Lrx8wxyQi3sNq46O7QahQiCsRFgqddjBouVEHOKDgXAQHD9gJCr5sMKkEdjwsarG/ww3BMHBU7OBjXnzdyY7SfCxf5/z6ATccrwlKuwC/jhznnPF4CgVzhhVf4xp2EixcBActO75iZ8/fM9zAs2OMzKdslgXWJ9XG8PQoOAMA5fGcsvORgv0doBXyHrCwfLJAOwo71QLNkb8n2Pl6EWiR7OCibtkPaz4Kc/0NNAze2gju3zOwekALDaCFPI5vjPFmgGY5AZqyGEvH1x7QfIb8YtxMnA/b+QQ0aQDAwc6JMFg8CbQZ4qoYEEHbRwNojuK3EHwd7VALSgq+MNDKzfT58T8qdpADrgW0GmgcAS1lhzztJmkAzcPNOQbsWEALBDSlMKUG0Eq4CLAQWvEVQ9WU57gZJwZtgPO3r9oBTQ9WO8TjqXINx8R0EYpiZEUWOF3FxkbJkgU9B2f41YBrIj5ZfsQa0M5kTgiAAqM3ShXLgu8XMqcrQBvJ0CL5pnTsfMB13oB8athpAq2XOQmcGmoACCLydx7nToa23ATaSIY2ichfOdPTGxlasXMLaL0MLZAOwAKIM+y8CmicobGdCcbbK9DzN+yYGVoNNI5iUKTMyYOjPse4A8SM1MmcXgU0toOq1yO/v8FOxlASyc7TgeYaAMBJHcY1CcCwGI/TK4AmDbDyKYBBtFUkRwto8gygiQEaByFgJ00BH2M8JWwQS1nafDXQCidWyOI8AcjDCSjCLk8ngObuAm3JAHAdubAmOaK06V8MNEsKPJOhobSprwQa6gD7DclRQdqcwL4zxqgBrQcabUiBLclRDKAlWp+etPkBaNMA0AKlrHwTdEByZAA4GM+SNluSY6wAzcMNewxmgig5Ks0nkrSpBvSaQHMdKTBAnLojOdYyGpQ254602ZILPdTD1hdlggdIm74jbTp8vDwF5ZYUeLWGJpWsh6XNyXgcYwVoJQTEhhTYkxzZjiU5npU2TaB979TQehlaAVq4kaGpiPwwwLkYUuBbQwocyQTv1tA0+1UFWoJF3iv1oq+qoSk8EQdJmwHkziIF7oOZk14EGitibAdjLYYK78H5vZOhtWpoI0ATGHs0Q8OMb4Ey+2bU2UYztCtA0wFAs7TplGLRVQCcqaFdGSPCeTI1QNIC52iWNzof6Uib7xjEp07mNNoUYmVosVItHrHzRlLgBn9LFyRHaQCtVUMbtTNhoXWiTOO9k/V8BdAc1Oq0ArSQs6/5SU0hckNy9NnXqQY0PGYo5dWJ7nINaN6o958FWin27aBaWRka1r5myvLOAm0j30eBJqCxHLReVclxhxOEN2JfDWjxBtAC7MIH1fVaGdoOp4qJYDgKtKPSFNID2gSnGldrCqkFZ+5UeQXQBIRrSwocbdZYQT/2LwRahBPBXoHrB8nxaGROST62DKUbQOMMzZIC9abkuELfQzQALWTnDNAm8KHWFOJgJ5+SHIvTPcmx1xQyZRhNL5Qci689aXMEaN/uNIWkEwDAvFpOZmgsBaaGnbs1NPa1Jm32gBZAIh1pCtG7TSH4aE0y1uVY4uqoFPisGlpP2rSA5qTecWn5agK6BzSpgAyD+wFaqhnYoSZ1Vwr8CmlTQbrcO3ZaX0NAEyMbYaAlyquFoLKK3SPby9CeVUPThrSJmkCAE0CrKUQadi4DrdSlWhmah0YL9z9vClH59YGbHx1J8VZTyAjQepJjmXwAKTDQI3omc3p1U4gDUf6RfcdYfrUp5ClAi2J3Ba6UOXGo+K+bQrjjssitG2SJzshaLwMtXgRagUNpYYoVkMSBLM+9GGiJZMvduG6DRZ4qc04DMPtQQxOjEtACmhO7K1AbNbQDEggZyJwscFpAGwENhoBeUwh3bWolhe8BTYVKxQEWrSUn/uhcM5KhvUu/+eQu0Lzhi+VrK0PrZZNDQKs9cpYUuFYgMVpD4/NxenJTiMCNqdUEUf1qZWjppLT5qSkkUZbCwkbZMSuVnu80hfSkzRbQeqCZSAh6huR4VtoM2gHAlLf72smuWgE+VV7XpE25Ab2WFDgyhnSuKbs4GuGzCjR+tIoUuMFg3kgcWKLTwRqanJQ2W00hAsenfaApRC42hbCvK1SlE0HtE9BGgneJO+ELamitD1YjjOYnNYVcraGhtKkW0EqVVeDx733I2NH581k1NNxNLG0i0IJ8/NjVaOZ0tYZ2Vtr0Xv7tPV3hkWp9EFkgS/J0vosngTaSoaG06WHi+xObQkaAdlbanP8B2+2l0f90LmUAAAAASUVORK5CYII=); }
Index: admin/js/codemirror/theme/midnight.css
===================================================================
--- admin/js/codemirror/theme/midnight.css	(revision 3979)
+++ 	(revision )
@@ -1,39 +1,0 @@
-/* Based on the theme at http://bonsaiden.github.com/JavaScript-Garden */
-
-/*<!--activeline-->*/
-.cm-s-midnight .CodeMirror-activeline-background { background: #253540; }
-
-.cm-s-midnight.CodeMirror {
-    background: #0F192A;
-    color: #D1EDFF;
-}
-
-.cm-s-midnight div.CodeMirror-selected { background: #314D67; }
-.cm-s-midnight .CodeMirror-line::selection, .cm-s-midnight .CodeMirror-line > span::selection, .cm-s-midnight .CodeMirror-line > span > span::selection { background: rgba(49, 77, 103, .99); }
-.cm-s-midnight .CodeMirror-line::-moz-selection, .cm-s-midnight .CodeMirror-line > span::-moz-selection, .cm-s-midnight .CodeMirror-line > span > span::-moz-selection { background: rgba(49, 77, 103, .99); }
-.cm-s-midnight .CodeMirror-gutters { background: #0F192A; border-right: 1px solid; }
-.cm-s-midnight .CodeMirror-guttermarker { color: white; }
-.cm-s-midnight .CodeMirror-guttermarker-subtle { color: #d0d0d0; }
-.cm-s-midnight .CodeMirror-linenumber { color: #D0D0D0; }
-.cm-s-midnight .CodeMirror-cursor { border-left: 1px solid #F8F8F0; }
-
-.cm-s-midnight span.cm-comment { color: #428BDD; }
-.cm-s-midnight span.cm-atom { color: #AE81FF; }
-.cm-s-midnight span.cm-number { color: #D1EDFF; }
-
-.cm-s-midnight span.cm-property, .cm-s-midnight span.cm-attribute { color: #A6E22E; }
-.cm-s-midnight span.cm-keyword { color: #E83737; }
-.cm-s-midnight span.cm-string { color: #1DC116; }
-
-.cm-s-midnight span.cm-variable { color: #FFAA3E; }
-.cm-s-midnight span.cm-variable-2 { color: #FFAA3E; }
-.cm-s-midnight span.cm-def { color: #4DD; }
-.cm-s-midnight span.cm-bracket { color: #D1EDFF; }
-.cm-s-midnight span.cm-tag { color: #449; }
-.cm-s-midnight span.cm-link { color: #AE81FF; }
-.cm-s-midnight span.cm-error { background: #F92672; color: #F8F8F0; }
-
-.cm-s-midnight .CodeMirror-matchingbracket {
-  text-decoration: underline;
-  color: white !important;
-}
Index: admin/js/codemirror/theme/monokai.css
===================================================================
--- admin/js/codemirror/theme/monokai.css	(revision 3758)
+++ 	(revision )
@@ -1,41 +1,0 @@
-/* Based on Sublime Text's Monokai theme */
-
-.cm-s-monokai.CodeMirror { background: #272822; color: #f8f8f2; }
-.cm-s-monokai div.CodeMirror-selected { background: #49483E; }
-.cm-s-monokai .CodeMirror-line::selection, .cm-s-monokai .CodeMirror-line > span::selection, .cm-s-monokai .CodeMirror-line > span > span::selection { background: rgba(73, 72, 62, .99); }
-.cm-s-monokai .CodeMirror-line::-moz-selection, .cm-s-monokai .CodeMirror-line > span::-moz-selection, .cm-s-monokai .CodeMirror-line > span > span::-moz-selection { background: rgba(73, 72, 62, .99); }
-.cm-s-monokai .CodeMirror-gutters { background: #272822; border-right: 0px; }
-.cm-s-monokai .CodeMirror-guttermarker { color: white; }
-.cm-s-monokai .CodeMirror-guttermarker-subtle { color: #d0d0d0; }
-.cm-s-monokai .CodeMirror-linenumber { color: #d0d0d0; }
-.cm-s-monokai .CodeMirror-cursor { border-left: 1px solid #f8f8f0; }
-
-.cm-s-monokai span.cm-comment { color: #75715e; }
-.cm-s-monokai span.cm-atom { color: #ae81ff; }
-.cm-s-monokai span.cm-number { color: #ae81ff; }
-
-.cm-s-monokai span.cm-comment.cm-attribute { color: #97b757; }
-.cm-s-monokai span.cm-comment.cm-def { color: #bc9262; }
-.cm-s-monokai span.cm-comment.cm-tag { color: #bc6283; }
-.cm-s-monokai span.cm-comment.cm-type { color: #5998a6; }
-
-.cm-s-monokai span.cm-property, .cm-s-monokai span.cm-attribute { color: #a6e22e; }
-.cm-s-monokai span.cm-keyword { color: #f92672; }
-.cm-s-monokai span.cm-builtin { color: #66d9ef; }
-.cm-s-monokai span.cm-string { color: #e6db74; }
-
-.cm-s-monokai span.cm-variable { color: #f8f8f2; }
-.cm-s-monokai span.cm-variable-2 { color: #9effff; }
-.cm-s-monokai span.cm-variable-3, .cm-s-monokai span.cm-type { color: #66d9ef; }
-.cm-s-monokai span.cm-def { color: #fd971f; }
-.cm-s-monokai span.cm-bracket { color: #f8f8f2; }
-.cm-s-monokai span.cm-tag { color: #f92672; }
-.cm-s-monokai span.cm-header { color: #ae81ff; }
-.cm-s-monokai span.cm-link { color: #ae81ff; }
-.cm-s-monokai span.cm-error { background: #f92672; color: #f8f8f0; }
-
-.cm-s-monokai .CodeMirror-activeline-background { background: #373831; }
-.cm-s-monokai .CodeMirror-matchingbracket {
-  text-decoration: underline;
-  color: white !important;
-}
Index: admin/js/codemirror/theme/neat.css
===================================================================
--- admin/js/codemirror/theme/neat.css	(revision 3251)
+++ 	(revision )
@@ -1,12 +1,0 @@
-.cm-s-neat span.cm-comment { color: #a86; }
-.cm-s-neat span.cm-keyword { line-height: 1em; font-weight: bold; color: blue; }
-.cm-s-neat span.cm-string { color: #a22; }
-.cm-s-neat span.cm-builtin { line-height: 1em; font-weight: bold; color: #077; }
-.cm-s-neat span.cm-special { line-height: 1em; font-weight: bold; color: #0aa; }
-.cm-s-neat span.cm-variable { color: black; }
-.cm-s-neat span.cm-number, .cm-s-neat span.cm-atom { color: #3a3; }
-.cm-s-neat span.cm-meta { color: #555; }
-.cm-s-neat span.cm-link { color: #3a3; }
-
-.cm-s-neat .CodeMirror-activeline-background { background: #e8f2ff; }
-.cm-s-neat .CodeMirror-matchingbracket { outline:1px solid grey; color:black !important; }
Index: admin/js/codemirror/theme/neo.css
===================================================================
--- admin/js/codemirror/theme/neo.css	(revision 3251)
+++ 	(revision )
@@ -1,43 +1,0 @@
-/* neo theme for codemirror */
-
-/* Color scheme */
-
-.cm-s-neo.CodeMirror {
-  background-color:#ffffff;
-  color:#2e383c;
-  line-height:1.4375;
-}
-.cm-s-neo .cm-comment { color:#75787b; }
-.cm-s-neo .cm-keyword, .cm-s-neo .cm-property { color:#1d75b3; }
-.cm-s-neo .cm-atom,.cm-s-neo .cm-number { color:#75438a; }
-.cm-s-neo .cm-node,.cm-s-neo .cm-tag { color:#9c3328; }
-.cm-s-neo .cm-string { color:#b35e14; }
-.cm-s-neo .cm-variable,.cm-s-neo .cm-qualifier { color:#047d65; }
-
-
-/* Editor styling */
-
-.cm-s-neo pre {
-  padding:0;
-}
-
-.cm-s-neo .CodeMirror-gutters {
-  border:none;
-  border-right:10px solid transparent;
-  background-color:transparent;
-}
-
-.cm-s-neo .CodeMirror-linenumber {
-  padding:0;
-  color:#e0e2e5;
-}
-
-.cm-s-neo .CodeMirror-guttermarker { color: #1d75b3; }
-.cm-s-neo .CodeMirror-guttermarker-subtle { color: #e0e2e5; }
-
-.cm-s-neo .CodeMirror-cursor {
-  width: auto;
-  border: 0;
-  background: rgba(155,157,162,0.37);
-  z-index: 1;
-}
Index: admin/js/codemirror/theme/night.css
===================================================================
--- admin/js/codemirror/theme/night.css	(revision 3617)
+++ 	(revision )
@@ -1,27 +1,0 @@
-/* Loosely based on the Midnight Textmate theme */
-
-.cm-s-night.CodeMirror { background: #0a001f; color: #f8f8f8; }
-.cm-s-night div.CodeMirror-selected { background: #447; }
-.cm-s-night .CodeMirror-line::selection, .cm-s-night .CodeMirror-line > span::selection, .cm-s-night .CodeMirror-line > span > span::selection { background: rgba(68, 68, 119, .99); }
-.cm-s-night .CodeMirror-line::-moz-selection, .cm-s-night .CodeMirror-line > span::-moz-selection, .cm-s-night .CodeMirror-line > span > span::-moz-selection { background: rgba(68, 68, 119, .99); }
-.cm-s-night .CodeMirror-gutters { background: #0a001f; border-right: 1px solid #aaa; }
-.cm-s-night .CodeMirror-guttermarker { color: white; }
-.cm-s-night .CodeMirror-guttermarker-subtle { color: #bbb; }
-.cm-s-night .CodeMirror-linenumber { color: #f8f8f8; }
-.cm-s-night .CodeMirror-cursor { border-left: 1px solid white; }
-
-.cm-s-night span.cm-comment { color: #8900d1; }
-.cm-s-night span.cm-atom { color: #845dc4; }
-.cm-s-night span.cm-number, .cm-s-night span.cm-attribute { color: #ffd500; }
-.cm-s-night span.cm-keyword { color: #599eff; }
-.cm-s-night span.cm-string { color: #37f14a; }
-.cm-s-night span.cm-meta { color: #7678e2; }
-.cm-s-night span.cm-variable-2, .cm-s-night span.cm-tag { color: #99b2ff; }
-.cm-s-night span.cm-variable-3, .cm-s-night span.cm-def, .cm-s-night span.cm-type { color: white; }
-.cm-s-night span.cm-bracket { color: #8da6ce; }
-.cm-s-night span.cm-builtin, .cm-s-night span.cm-special { color: #ff9e59; }
-.cm-s-night span.cm-link { color: #845dc4; }
-.cm-s-night span.cm-error { color: #9d1e15; }
-
-.cm-s-night .CodeMirror-activeline-background { background: #1C005A; }
-.cm-s-night .CodeMirror-matchingbracket { outline:1px solid grey; color:white !important; }
Index: admin/js/codemirror/theme/nord.css
===================================================================
--- admin/js/codemirror/theme/nord.css	(revision 3979)
+++ 	(revision )
@@ -1,42 +1,0 @@
-/* Based on arcticicestudio's Nord theme */
-/* https://github.com/arcticicestudio/nord */
-
-.cm-s-nord.CodeMirror { background: #2e3440; color: #d8dee9; }
-.cm-s-nord div.CodeMirror-selected { background: #434c5e; }
-.cm-s-nord .CodeMirror-line::selection, .cm-s-nord .CodeMirror-line > span::selection, .cm-s-nord .CodeMirror-line > span > span::selection { background: #3b4252; }
-.cm-s-nord .CodeMirror-line::-moz-selection, .cm-s-nord .CodeMirror-line > span::-moz-selection, .cm-s-nord .CodeMirror-line > span > span::-moz-selection { background: #3b4252; }
-.cm-s-nord .CodeMirror-gutters { background: #2e3440; border-right: 0px; }
-.cm-s-nord .CodeMirror-guttermarker { color: #4c566a; }
-.cm-s-nord .CodeMirror-guttermarker-subtle { color: #4c566a; }
-.cm-s-nord .CodeMirror-linenumber { color: #4c566a; }
-.cm-s-nord .CodeMirror-cursor { border-left: 1px solid #f8f8f0; }
-
-.cm-s-nord span.cm-comment { color: #4c566a; }
-.cm-s-nord span.cm-atom { color: #b48ead; }
-.cm-s-nord span.cm-number { color: #b48ead; }
-
-.cm-s-nord span.cm-comment.cm-attribute { color: #97b757; }
-.cm-s-nord span.cm-comment.cm-def { color: #bc9262; }
-.cm-s-nord span.cm-comment.cm-tag { color: #bc6283; }
-.cm-s-nord span.cm-comment.cm-type { color: #5998a6; }
-
-.cm-s-nord span.cm-property, .cm-s-nord span.cm-attribute { color: #8FBCBB; }
-.cm-s-nord span.cm-keyword { color: #81A1C1; }
-.cm-s-nord span.cm-builtin { color: #81A1C1; }
-.cm-s-nord span.cm-string { color: #A3BE8C; }
-
-.cm-s-nord span.cm-variable { color: #d8dee9; }
-.cm-s-nord span.cm-variable-2 { color: #d8dee9; }
-.cm-s-nord span.cm-variable-3, .cm-s-nord span.cm-type { color: #d8dee9; }
-.cm-s-nord span.cm-def { color: #8FBCBB; }
-.cm-s-nord span.cm-bracket { color: #81A1C1; }
-.cm-s-nord span.cm-tag { color: #bf616a; }
-.cm-s-nord span.cm-header { color: #b48ead; }
-.cm-s-nord span.cm-link { color: #b48ead; }
-.cm-s-nord span.cm-error { background: #bf616a; color: #f8f8f0; }
-
-.cm-s-nord .CodeMirror-activeline-background { background: #3b4252; }
-.cm-s-nord .CodeMirror-matchingbracket {
-  text-decoration: underline;
-  color: white !important;
-}
Index: admin/js/codemirror/theme/oceanic-next.css
===================================================================
--- admin/js/codemirror/theme/oceanic-next.css	(revision 3758)
+++ 	(revision )
@@ -1,44 +1,0 @@
-/*
-
-    Name:       oceanic-next
-    Author:     Filype Pereira (https://github.com/fpereira1)
-
-    Original oceanic-next color scheme by Dmitri Voronianski (https://github.com/voronianski/oceanic-next-color-scheme)
-
-*/
-
-.cm-s-oceanic-next.CodeMirror { background: #304148; color: #f8f8f2; }
-.cm-s-oceanic-next div.CodeMirror-selected { background: rgba(101, 115, 126, 0.33); }
-.cm-s-oceanic-next .CodeMirror-line::selection, .cm-s-oceanic-next .CodeMirror-line > span::selection, .cm-s-oceanic-next .CodeMirror-line > span > span::selection { background: rgba(101, 115, 126, 0.33); }
-.cm-s-oceanic-next .CodeMirror-line::-moz-selection, .cm-s-oceanic-next .CodeMirror-line > span::-moz-selection, .cm-s-oceanic-next .CodeMirror-line > span > span::-moz-selection { background: rgba(101, 115, 126, 0.33); }
-.cm-s-oceanic-next .CodeMirror-gutters { background: #304148; border-right: 10px; }
-.cm-s-oceanic-next .CodeMirror-guttermarker { color: white; }
-.cm-s-oceanic-next .CodeMirror-guttermarker-subtle { color: #d0d0d0; }
-.cm-s-oceanic-next .CodeMirror-linenumber { color: #d0d0d0; }
-.cm-s-oceanic-next .CodeMirror-cursor { border-left: 1px solid #f8f8f0; }
-
-.cm-s-oceanic-next span.cm-comment { color: #65737E; }
-.cm-s-oceanic-next span.cm-atom { color: #C594C5; }
-.cm-s-oceanic-next span.cm-number { color: #F99157; }
-
-.cm-s-oceanic-next span.cm-property { color: #99C794; }
-.cm-s-oceanic-next span.cm-attribute,
-.cm-s-oceanic-next span.cm-keyword { color: #C594C5; }
-.cm-s-oceanic-next span.cm-builtin { color: #66d9ef; }
-.cm-s-oceanic-next span.cm-string { color: #99C794; }
-
-.cm-s-oceanic-next span.cm-variable,
-.cm-s-oceanic-next span.cm-variable-2,
-.cm-s-oceanic-next span.cm-variable-3 { color: #f8f8f2; }
-.cm-s-oceanic-next span.cm-def { color: #6699CC; }
-.cm-s-oceanic-next span.cm-bracket { color: #5FB3B3; }
-.cm-s-oceanic-next span.cm-tag { color: #C594C5; }
-.cm-s-oceanic-next span.cm-header { color: #C594C5; }
-.cm-s-oceanic-next span.cm-link { color: #C594C5; }
-.cm-s-oceanic-next span.cm-error { background: #C594C5; color: #f8f8f0; }
-
-.cm-s-oceanic-next .CodeMirror-activeline-background { background: rgba(101, 115, 126, 0.33); }
-.cm-s-oceanic-next .CodeMirror-matchingbracket {
-  text-decoration: underline;
-  color: white !important;
-}
Index: admin/js/codemirror/theme/panda-syntax.css
===================================================================
--- admin/js/codemirror/theme/panda-syntax.css	(revision 3979)
+++ 	(revision )
@@ -1,85 +1,0 @@
-/*
-	Name:       Panda Syntax
-	Author:     Siamak Mokhtari (http://github.com/siamak/)
-	CodeMirror template by Siamak Mokhtari (https://github.com/siamak/atom-panda-syntax)
-*/
-.cm-s-panda-syntax {
-	background: #292A2B;
-	color: #E6E6E6;
-	line-height: 1.5;
-	font-family: 'Operator Mono', 'Source Code Pro', Menlo, Monaco, Consolas, Courier New, monospace;
-}
-.cm-s-panda-syntax .CodeMirror-cursor { border-color: #ff2c6d; }
-.cm-s-panda-syntax .CodeMirror-activeline-background {
-	background: rgba(99, 123, 156, 0.1);
-}
-.cm-s-panda-syntax .CodeMirror-selected {
-	background: #FFF;
-}
-.cm-s-panda-syntax .cm-comment {
-	font-style: italic;
-	color: #676B79;
-}
-.cm-s-panda-syntax .cm-operator {
-	color: #f3f3f3;
-}
-.cm-s-panda-syntax .cm-string {
-	color: #19F9D8;
-}
-.cm-s-panda-syntax .cm-string-2 {
-    color: #FFB86C;
-}
-
-.cm-s-panda-syntax .cm-tag {
-	color: #ff2c6d;
-}
-.cm-s-panda-syntax .cm-meta {
-	color: #b084eb;
-}
-
-.cm-s-panda-syntax .cm-number {
-	color: #FFB86C;
-}
-.cm-s-panda-syntax .cm-atom {
-	color: #ff2c6d;
-}
-.cm-s-panda-syntax .cm-keyword {
-	color: #FF75B5;
-}
-.cm-s-panda-syntax .cm-variable {
-	color: #ffb86c;
-}
-.cm-s-panda-syntax .cm-variable-2 {
-	color: #ff9ac1;
-}
-.cm-s-panda-syntax .cm-variable-3, .cm-s-panda-syntax .cm-type {
-	color: #ff9ac1;
-}
-
-.cm-s-panda-syntax .cm-def {
-	color: #e6e6e6;
-}
-.cm-s-panda-syntax .cm-property {
-	color: #f3f3f3;
-}
-.cm-s-panda-syntax .cm-unit {
-    color: #ffb86c;
-}
-
-.cm-s-panda-syntax .cm-attribute {
-    color: #ffb86c;
-}
-
-.cm-s-panda-syntax .CodeMirror-matchingbracket {
-    border-bottom: 1px dotted #19F9D8;
-    padding-bottom: 2px;
-    color: #e6e6e6;
-}
-.cm-s-panda-syntax .CodeMirror-gutters {
-    background: #292a2b;
-    border-right-color: rgba(255, 255, 255, 0.1);
-}
-.cm-s-panda-syntax .CodeMirror-linenumber {
-    color: #e6e6e6;
-    opacity: 0.6;
-}
Index: admin/js/codemirror/theme/paraiso-dark.css
===================================================================
--- admin/js/codemirror/theme/paraiso-dark.css	(revision 3251)
+++ 	(revision )
@@ -1,38 +1,0 @@
-/*
-
-    Name:       Paraíso (Dark)
-    Author:     Jan T. Sott
-
-    Color scheme by Jan T. Sott (https://github.com/idleberg/Paraiso-CodeMirror)
-    Inspired by the art of Rubens LP (http://www.rubenslp.com.br)
-
-*/
-
-.cm-s-paraiso-dark.CodeMirror { background: #2f1e2e; color: #b9b6b0; }
-.cm-s-paraiso-dark div.CodeMirror-selected { background: #41323f; }
-.cm-s-paraiso-dark .CodeMirror-line::selection, .cm-s-paraiso-dark .CodeMirror-line > span::selection, .cm-s-paraiso-dark .CodeMirror-line > span > span::selection { background: rgba(65, 50, 63, .99); }
-.cm-s-paraiso-dark .CodeMirror-line::-moz-selection, .cm-s-paraiso-dark .CodeMirror-line > span::-moz-selection, .cm-s-paraiso-dark .CodeMirror-line > span > span::-moz-selection { background: rgba(65, 50, 63, .99); }
-.cm-s-paraiso-dark .CodeMirror-gutters { background: #2f1e2e; border-right: 0px; }
-.cm-s-paraiso-dark .CodeMirror-guttermarker { color: #ef6155; }
-.cm-s-paraiso-dark .CodeMirror-guttermarker-subtle { color: #776e71; }
-.cm-s-paraiso-dark .CodeMirror-linenumber { color: #776e71; }
-.cm-s-paraiso-dark .CodeMirror-cursor { border-left: 1px solid #8d8687; }
-
-.cm-s-paraiso-dark span.cm-comment { color: #e96ba8; }
-.cm-s-paraiso-dark span.cm-atom { color: #815ba4; }
-.cm-s-paraiso-dark span.cm-number { color: #815ba4; }
-
-.cm-s-paraiso-dark span.cm-property, .cm-s-paraiso-dark span.cm-attribute { color: #48b685; }
-.cm-s-paraiso-dark span.cm-keyword { color: #ef6155; }
-.cm-s-paraiso-dark span.cm-string { color: #fec418; }
-
-.cm-s-paraiso-dark span.cm-variable { color: #48b685; }
-.cm-s-paraiso-dark span.cm-variable-2 { color: #06b6ef; }
-.cm-s-paraiso-dark span.cm-def { color: #f99b15; }
-.cm-s-paraiso-dark span.cm-bracket { color: #b9b6b0; }
-.cm-s-paraiso-dark span.cm-tag { color: #ef6155; }
-.cm-s-paraiso-dark span.cm-link { color: #815ba4; }
-.cm-s-paraiso-dark span.cm-error { background: #ef6155; color: #8d8687; }
-
-.cm-s-paraiso-dark .CodeMirror-activeline-background { background: #4D344A; }
-.cm-s-paraiso-dark .CodeMirror-matchingbracket { text-decoration: underline; color: white !important; }
Index: admin/js/codemirror/theme/paraiso-light.css
===================================================================
--- admin/js/codemirror/theme/paraiso-light.css	(revision 3251)
+++ 	(revision )
@@ -1,38 +1,0 @@
-/*
-
-    Name:       Paraíso (Light)
-    Author:     Jan T. Sott
-
-    Color scheme by Jan T. Sott (https://github.com/idleberg/Paraiso-CodeMirror)
-    Inspired by the art of Rubens LP (http://www.rubenslp.com.br)
-
-*/
-
-.cm-s-paraiso-light.CodeMirror { background: #e7e9db; color: #41323f; }
-.cm-s-paraiso-light div.CodeMirror-selected { background: #b9b6b0; }
-.cm-s-paraiso-light .CodeMirror-line::selection, .cm-s-paraiso-light .CodeMirror-line > span::selection, .cm-s-paraiso-light .CodeMirror-line > span > span::selection { background: #b9b6b0; }
-.cm-s-paraiso-light .CodeMirror-line::-moz-selection, .cm-s-paraiso-light .CodeMirror-line > span::-moz-selection, .cm-s-paraiso-light .CodeMirror-line > span > span::-moz-selection { background: #b9b6b0; }
-.cm-s-paraiso-light .CodeMirror-gutters { background: #e7e9db; border-right: 0px; }
-.cm-s-paraiso-light .CodeMirror-guttermarker { color: black; }
-.cm-s-paraiso-light .CodeMirror-guttermarker-subtle { color: #8d8687; }
-.cm-s-paraiso-light .CodeMirror-linenumber { color: #8d8687; }
-.cm-s-paraiso-light .CodeMirror-cursor { border-left: 1px solid #776e71; }
-
-.cm-s-paraiso-light span.cm-comment { color: #e96ba8; }
-.cm-s-paraiso-light span.cm-atom { color: #815ba4; }
-.cm-s-paraiso-light span.cm-number { color: #815ba4; }
-
-.cm-s-paraiso-light span.cm-property, .cm-s-paraiso-light span.cm-attribute { color: #48b685; }
-.cm-s-paraiso-light span.cm-keyword { color: #ef6155; }
-.cm-s-paraiso-light span.cm-string { color: #fec418; }
-
-.cm-s-paraiso-light span.cm-variable { color: #48b685; }
-.cm-s-paraiso-light span.cm-variable-2 { color: #06b6ef; }
-.cm-s-paraiso-light span.cm-def { color: #f99b15; }
-.cm-s-paraiso-light span.cm-bracket { color: #41323f; }
-.cm-s-paraiso-light span.cm-tag { color: #ef6155; }
-.cm-s-paraiso-light span.cm-link { color: #815ba4; }
-.cm-s-paraiso-light span.cm-error { background: #ef6155; color: #776e71; }
-
-.cm-s-paraiso-light .CodeMirror-activeline-background { background: #CFD1C4; }
-.cm-s-paraiso-light .CodeMirror-matchingbracket { text-decoration: underline; color: white !important; }
Index: admin/js/codemirror/theme/pastel-on-dark.css
===================================================================
--- admin/js/codemirror/theme/pastel-on-dark.css	(revision 3617)
+++ 	(revision )
@@ -1,52 +1,0 @@
-/**
- * Pastel On Dark theme ported from ACE editor
- * @license MIT
- * @copyright AtomicPages LLC 2014
- * @author Dennis Thompson, AtomicPages LLC
- * @version 1.1
- * @source https://github.com/atomicpages/codemirror-pastel-on-dark-theme
- */
-
-.cm-s-pastel-on-dark.CodeMirror {
-	background: #2c2827;
-	color: #8F938F;
-	line-height: 1.5;
-}
-.cm-s-pastel-on-dark div.CodeMirror-selected { background: rgba(221,240,255,0.2); }
-.cm-s-pastel-on-dark .CodeMirror-line::selection, .cm-s-pastel-on-dark .CodeMirror-line > span::selection, .cm-s-pastel-on-dark .CodeMirror-line > span > span::selection { background: rgba(221,240,255,0.2); }
-.cm-s-pastel-on-dark .CodeMirror-line::-moz-selection, .cm-s-pastel-on-dark .CodeMirror-line > span::-moz-selection, .cm-s-pastel-on-dark .CodeMirror-line > span > span::-moz-selection { background: rgba(221,240,255,0.2); }
-
-.cm-s-pastel-on-dark .CodeMirror-gutters {
-	background: #34302f;
-	border-right: 0px;
-	padding: 0 3px;
-}
-.cm-s-pastel-on-dark .CodeMirror-guttermarker { color: white; }
-.cm-s-pastel-on-dark .CodeMirror-guttermarker-subtle { color: #8F938F; }
-.cm-s-pastel-on-dark .CodeMirror-linenumber { color: #8F938F; }
-.cm-s-pastel-on-dark .CodeMirror-cursor { border-left: 1px solid #A7A7A7; }
-.cm-s-pastel-on-dark span.cm-comment { color: #A6C6FF; }
-.cm-s-pastel-on-dark span.cm-atom { color: #DE8E30; }
-.cm-s-pastel-on-dark span.cm-number { color: #CCCCCC; }
-.cm-s-pastel-on-dark span.cm-property { color: #8F938F; }
-.cm-s-pastel-on-dark span.cm-attribute { color: #a6e22e; }
-.cm-s-pastel-on-dark span.cm-keyword { color: #AEB2F8; }
-.cm-s-pastel-on-dark span.cm-string { color: #66A968; }
-.cm-s-pastel-on-dark span.cm-variable { color: #AEB2F8; }
-.cm-s-pastel-on-dark span.cm-variable-2 { color: #BEBF55; }
-.cm-s-pastel-on-dark span.cm-variable-3, .cm-s-pastel-on-dark span.cm-type { color: #DE8E30; }
-.cm-s-pastel-on-dark span.cm-def { color: #757aD8; }
-.cm-s-pastel-on-dark span.cm-bracket { color: #f8f8f2; }
-.cm-s-pastel-on-dark span.cm-tag { color: #C1C144; }
-.cm-s-pastel-on-dark span.cm-link { color: #ae81ff; }
-.cm-s-pastel-on-dark span.cm-qualifier,.cm-s-pastel-on-dark span.cm-builtin { color: #C1C144; }
-.cm-s-pastel-on-dark span.cm-error {
-	background: #757aD8;
-	color: #f8f8f0;
-}
-.cm-s-pastel-on-dark .CodeMirror-activeline-background { background: rgba(255, 255, 255, 0.031); }
-.cm-s-pastel-on-dark .CodeMirror-matchingbracket {
-	border: 1px solid rgba(255,255,255,0.25);
-	color: #8F938F !important;
-	margin: -1px -1px 0 -1px;
-}
Index: admin/js/codemirror/theme/railscasts.css
===================================================================
--- admin/js/codemirror/theme/railscasts.css	(revision 3251)
+++ 	(revision )
@@ -1,34 +1,0 @@
-/*
-
-    Name:       Railscasts
-    Author:     Ryan Bates (http://railscasts.com)
-
-    CodeMirror template by Jan T. Sott (https://github.com/idleberg/base16-codemirror)
-    Original Base16 color scheme by Chris Kempson (https://github.com/chriskempson/base16)
-
-*/
-
-.cm-s-railscasts.CodeMirror {background: #2b2b2b; color: #f4f1ed;}
-.cm-s-railscasts div.CodeMirror-selected {background: #272935 !important;}
-.cm-s-railscasts .CodeMirror-gutters {background: #2b2b2b; border-right: 0px;}
-.cm-s-railscasts .CodeMirror-linenumber {color: #5a647e;}
-.cm-s-railscasts .CodeMirror-cursor {border-left: 1px solid #d4cfc9 !important;}
-
-.cm-s-railscasts span.cm-comment {color: #bc9458;}
-.cm-s-railscasts span.cm-atom {color: #b6b3eb;}
-.cm-s-railscasts span.cm-number {color: #b6b3eb;}
-
-.cm-s-railscasts span.cm-property, .cm-s-railscasts span.cm-attribute {color: #a5c261;}
-.cm-s-railscasts span.cm-keyword {color: #da4939;}
-.cm-s-railscasts span.cm-string {color: #ffc66d;}
-
-.cm-s-railscasts span.cm-variable {color: #a5c261;}
-.cm-s-railscasts span.cm-variable-2 {color: #6d9cbe;}
-.cm-s-railscasts span.cm-def {color: #cc7833;}
-.cm-s-railscasts span.cm-error {background: #da4939; color: #d4cfc9;}
-.cm-s-railscasts span.cm-bracket {color: #f4f1ed;}
-.cm-s-railscasts span.cm-tag {color: #da4939;}
-.cm-s-railscasts span.cm-link {color: #b6b3eb;}
-
-.cm-s-railscasts .CodeMirror-matchingbracket { text-decoration: underline; color: white !important;}
-.cm-s-railscasts .CodeMirror-activeline-background { background: #303040; }
Index: admin/js/codemirror/theme/rubyblue.css
===================================================================
--- admin/js/codemirror/theme/rubyblue.css	(revision 3617)
+++ 	(revision )
@@ -1,25 +1,0 @@
-.cm-s-rubyblue.CodeMirror { background: #112435; color: white; }
-.cm-s-rubyblue div.CodeMirror-selected { background: #38566F; }
-.cm-s-rubyblue .CodeMirror-line::selection, .cm-s-rubyblue .CodeMirror-line > span::selection, .cm-s-rubyblue .CodeMirror-line > span > span::selection { background: rgba(56, 86, 111, 0.99); }
-.cm-s-rubyblue .CodeMirror-line::-moz-selection, .cm-s-rubyblue .CodeMirror-line > span::-moz-selection, .cm-s-rubyblue .CodeMirror-line > span > span::-moz-selection { background: rgba(56, 86, 111, 0.99); }
-.cm-s-rubyblue .CodeMirror-gutters { background: #1F4661; border-right: 7px solid #3E7087; }
-.cm-s-rubyblue .CodeMirror-guttermarker { color: white; }
-.cm-s-rubyblue .CodeMirror-guttermarker-subtle { color: #3E7087; }
-.cm-s-rubyblue .CodeMirror-linenumber { color: white; }
-.cm-s-rubyblue .CodeMirror-cursor { border-left: 1px solid white; }
-
-.cm-s-rubyblue span.cm-comment { color: #999; font-style:italic; line-height: 1em; }
-.cm-s-rubyblue span.cm-atom { color: #F4C20B; }
-.cm-s-rubyblue span.cm-number, .cm-s-rubyblue span.cm-attribute { color: #82C6E0; }
-.cm-s-rubyblue span.cm-keyword { color: #F0F; }
-.cm-s-rubyblue span.cm-string { color: #F08047; }
-.cm-s-rubyblue span.cm-meta { color: #F0F; }
-.cm-s-rubyblue span.cm-variable-2, .cm-s-rubyblue span.cm-tag { color: #7BD827; }
-.cm-s-rubyblue span.cm-variable-3, .cm-s-rubyblue span.cm-def, .cm-s-rubyblue span.cm-type { color: white; }
-.cm-s-rubyblue span.cm-bracket { color: #F0F; }
-.cm-s-rubyblue span.cm-link { color: #F4C20B; }
-.cm-s-rubyblue span.CodeMirror-matchingbracket { color:#F0F !important; }
-.cm-s-rubyblue span.cm-builtin, .cm-s-rubyblue span.cm-special { color: #FF9D00; }
-.cm-s-rubyblue span.cm-error { color: #AF2018; }
-
-.cm-s-rubyblue .CodeMirror-activeline-background { background: #173047; }
Index: admin/js/codemirror/theme/seti.css
===================================================================
--- admin/js/codemirror/theme/seti.css	(revision 3617)
+++ 	(revision )
@@ -1,44 +1,0 @@
-/*
-
-    Name:       seti
-    Author:     Michael Kaminsky (http://github.com/mkaminsky11)
-
-    Original seti color scheme by Jesse Weed (https://github.com/jesseweed/seti-syntax)
-
-*/
-
-
-.cm-s-seti.CodeMirror {
-  background-color: #151718 !important;
-  color: #CFD2D1 !important;
-  border: none;
-}
-.cm-s-seti .CodeMirror-gutters {
-  color: #404b53;
-  background-color: #0E1112;
-  border: none;
-}
-.cm-s-seti .CodeMirror-cursor { border-left: solid thin #f8f8f0; }
-.cm-s-seti .CodeMirror-linenumber { color: #6D8A88; }
-.cm-s-seti.CodeMirror-focused div.CodeMirror-selected { background: rgba(255, 255, 255, 0.10); }
-.cm-s-seti .CodeMirror-line::selection, .cm-s-seti .CodeMirror-line > span::selection, .cm-s-seti .CodeMirror-line > span > span::selection { background: rgba(255, 255, 255, 0.10); }
-.cm-s-seti .CodeMirror-line::-moz-selection, .cm-s-seti .CodeMirror-line > span::-moz-selection, .cm-s-seti .CodeMirror-line > span > span::-moz-selection { background: rgba(255, 255, 255, 0.10); }
-.cm-s-seti span.cm-comment { color: #41535b; }
-.cm-s-seti span.cm-string, .cm-s-seti span.cm-string-2 { color: #55b5db; }
-.cm-s-seti span.cm-number { color: #cd3f45; }
-.cm-s-seti span.cm-variable { color: #55b5db; }
-.cm-s-seti span.cm-variable-2 { color: #a074c4; }
-.cm-s-seti span.cm-def { color: #55b5db; }
-.cm-s-seti span.cm-keyword { color: #ff79c6; }
-.cm-s-seti span.cm-operator { color: #9fca56; }
-.cm-s-seti span.cm-keyword { color: #e6cd69; }
-.cm-s-seti span.cm-atom { color: #cd3f45; }
-.cm-s-seti span.cm-meta { color: #55b5db; }
-.cm-s-seti span.cm-tag { color: #55b5db; }
-.cm-s-seti span.cm-attribute { color: #9fca56; }
-.cm-s-seti span.cm-qualifier { color: #9fca56; }
-.cm-s-seti span.cm-property { color: #a074c4; }
-.cm-s-seti span.cm-variable-3, .cm-s-seti span.cm-type { color: #9fca56; }
-.cm-s-seti span.cm-builtin { color: #9fca56; }
-.cm-s-seti .CodeMirror-activeline-background { background: #101213; }
-.cm-s-seti .CodeMirror-matchingbracket { text-decoration: underline; color: white !important; }
Index: admin/js/codemirror/theme/shadowfox.css
===================================================================
--- admin/js/codemirror/theme/shadowfox.css	(revision 3758)
+++ 	(revision )
@@ -1,52 +1,0 @@
-/*
-
-    Name:       shadowfox
-    Author:     overdodactyl (http://github.com/overdodactyl)
-
-    Original shadowfox color scheme by Firefox
-
-*/
-
-.cm-s-shadowfox.CodeMirror { background: #2a2a2e; color: #b1b1b3; }
-.cm-s-shadowfox div.CodeMirror-selected { background: #353B48; }
-.cm-s-shadowfox .CodeMirror-line::selection, .cm-s-shadowfox .CodeMirror-line > span::selection, .cm-s-shadowfox .CodeMirror-line > span > span::selection { background: #353B48; }
-.cm-s-shadowfox .CodeMirror-line::-moz-selection, .cm-s-shadowfox .CodeMirror-line > span::-moz-selection, .cm-s-shadowfox .CodeMirror-line > span > span::-moz-selection { background: #353B48; }
-.cm-s-shadowfox .CodeMirror-gutters { background: #0c0c0d ; border-right: 1px solid #0c0c0d; }
-.cm-s-shadowfox .CodeMirror-guttermarker { color: #555; }
-.cm-s-shadowfox .CodeMirror-linenumber { color: #939393; }
-.cm-s-shadowfox .CodeMirror-cursor { border-left: 1px solid #fff; }
-
-.cm-s-shadowfox span.cm-comment { color: #939393; }
-.cm-s-shadowfox span.cm-atom { color: #FF7DE9; }
-.cm-s-shadowfox span.cm-quote { color: #FF7DE9; }
-.cm-s-shadowfox span.cm-builtin { color: #FF7DE9; }
-.cm-s-shadowfox span.cm-attribute { color: #FF7DE9; }
-.cm-s-shadowfox span.cm-keyword { color: #FF7DE9; }
-.cm-s-shadowfox span.cm-error { color: #FF7DE9; }
-
-.cm-s-shadowfox span.cm-number { color: #6B89FF; }
-.cm-s-shadowfox span.cm-string { color: #6B89FF; }
-.cm-s-shadowfox span.cm-string-2 { color: #6B89FF; }
-
-.cm-s-shadowfox span.cm-meta { color: #939393; }
-.cm-s-shadowfox span.cm-hr { color: #939393; }
-
-.cm-s-shadowfox span.cm-header { color: #75BFFF; }
-.cm-s-shadowfox span.cm-qualifier { color: #75BFFF; }
-.cm-s-shadowfox span.cm-variable-2 { color: #75BFFF; }
-
-.cm-s-shadowfox span.cm-property { color: #86DE74; }
-
-.cm-s-shadowfox span.cm-def { color: #75BFFF; }
-.cm-s-shadowfox span.cm-bracket { color: #75BFFF; }
-.cm-s-shadowfox span.cm-tag { color: #75BFFF; }
-.cm-s-shadowfox span.cm-link:visited { color: #75BFFF; }
-
-.cm-s-shadowfox span.cm-variable { color: #B98EFF; }
-.cm-s-shadowfox span.cm-variable-3 { color: #d7d7db; }
-.cm-s-shadowfox span.cm-link { color: #737373; }
-.cm-s-shadowfox span.cm-operator { color: #b1b1b3; }
-.cm-s-shadowfox span.cm-special { color: #d7d7db; }
-
-.cm-s-shadowfox .CodeMirror-activeline-background { background: rgba(185, 215, 253, .15) }
-.cm-s-shadowfox .CodeMirror-matchingbracket { outline: solid 1px rgba(255, 255, 255, .25); color: white !important; }
Index: admin/js/codemirror/theme/solarized.css
===================================================================
--- admin/js/codemirror/theme/solarized.css	(revision 3617)
+++ 	(revision )
@@ -1,168 +1,0 @@
-/*
-Solarized theme for code-mirror
-http://ethanschoonover.com/solarized
-*/
-
-/*
-Solarized color palette
-http://ethanschoonover.com/solarized/img/solarized-palette.png
-*/
-
-.solarized.base03 { color: #002b36; }
-.solarized.base02 { color: #073642; }
-.solarized.base01 { color: #586e75; }
-.solarized.base00 { color: #657b83; }
-.solarized.base0 { color: #839496; }
-.solarized.base1 { color: #93a1a1; }
-.solarized.base2 { color: #eee8d5; }
-.solarized.base3  { color: #fdf6e3; }
-.solarized.solar-yellow  { color: #b58900; }
-.solarized.solar-orange  { color: #cb4b16; }
-.solarized.solar-red { color: #dc322f; }
-.solarized.solar-magenta { color: #d33682; }
-.solarized.solar-violet  { color: #6c71c4; }
-.solarized.solar-blue { color: #268bd2; }
-.solarized.solar-cyan { color: #2aa198; }
-.solarized.solar-green { color: #859900; }
-
-/* Color scheme for code-mirror */
-
-.cm-s-solarized {
-  line-height: 1.45em;
-  color-profile: sRGB;
-  rendering-intent: auto;
-}
-.cm-s-solarized.cm-s-dark {
-  color: #839496;
-  background-color: #002b36;
-  text-shadow: #002b36 0 1px;
-}
-.cm-s-solarized.cm-s-light {
-  background-color: #fdf6e3;
-  color: #657b83;
-  text-shadow: #eee8d5 0 1px;
-}
-
-.cm-s-solarized .CodeMirror-widget {
-  text-shadow: none;
-}
-
-.cm-s-solarized .cm-header { color: #586e75; }
-.cm-s-solarized .cm-quote { color: #93a1a1; }
-
-.cm-s-solarized .cm-keyword { color: #cb4b16; }
-.cm-s-solarized .cm-atom { color: #d33682; }
-.cm-s-solarized .cm-number { color: #d33682; }
-.cm-s-solarized .cm-def { color: #2aa198; }
-
-.cm-s-solarized .cm-variable { color: #839496; }
-.cm-s-solarized .cm-variable-2 { color: #b58900; }
-.cm-s-solarized .cm-variable-3, .cm-s-solarized .cm-type { color: #6c71c4; }
-
-.cm-s-solarized .cm-property { color: #2aa198; }
-.cm-s-solarized .cm-operator { color: #6c71c4; }
-
-.cm-s-solarized .cm-comment { color: #586e75; font-style:italic; }
-
-.cm-s-solarized .cm-string { color: #859900; }
-.cm-s-solarized .cm-string-2 { color: #b58900; }
-
-.cm-s-solarized .cm-meta { color: #859900; }
-.cm-s-solarized .cm-qualifier { color: #b58900; }
-.cm-s-solarized .cm-builtin { color: #d33682; }
-.cm-s-solarized .cm-bracket { color: #cb4b16; }
-.cm-s-solarized .CodeMirror-matchingbracket { color: #859900; }
-.cm-s-solarized .CodeMirror-nonmatchingbracket { color: #dc322f; }
-.cm-s-solarized .cm-tag { color: #93a1a1; }
-.cm-s-solarized .cm-attribute { color: #2aa198; }
-.cm-s-solarized .cm-hr {
-  color: transparent;
-  border-top: 1px solid #586e75;
-  display: block;
-}
-.cm-s-solarized .cm-link { color: #93a1a1; cursor: pointer; }
-.cm-s-solarized .cm-special { color: #6c71c4; }
-.cm-s-solarized .cm-em {
-  color: #999;
-  text-decoration: underline;
-  text-decoration-style: dotted;
-}
-.cm-s-solarized .cm-error,
-.cm-s-solarized .cm-invalidchar {
-  color: #586e75;
-  border-bottom: 1px dotted #dc322f;
-}
-
-.cm-s-solarized.cm-s-dark div.CodeMirror-selected { background: #073642; }
-.cm-s-solarized.cm-s-dark.CodeMirror ::selection { background: rgba(7, 54, 66, 0.99); }
-.cm-s-solarized.cm-s-dark .CodeMirror-line::-moz-selection, .cm-s-dark .CodeMirror-line > span::-moz-selection, .cm-s-dark .CodeMirror-line > span > span::-moz-selection { background: rgba(7, 54, 66, 0.99); }
-
-.cm-s-solarized.cm-s-light div.CodeMirror-selected { background: #eee8d5; }
-.cm-s-solarized.cm-s-light .CodeMirror-line::selection, .cm-s-light .CodeMirror-line > span::selection, .cm-s-light .CodeMirror-line > span > span::selection { background: #eee8d5; }
-.cm-s-solarized.cm-s-light .CodeMirror-line::-moz-selection, .cm-s-ligh .CodeMirror-line > span::-moz-selection, .cm-s-ligh .CodeMirror-line > span > span::-moz-selection { background: #eee8d5; }
-
-/* Editor styling */
-
-
-
-/* Little shadow on the view-port of the buffer view */
-.cm-s-solarized.CodeMirror {
-  -moz-box-shadow: inset 7px 0 12px -6px #000;
-  -webkit-box-shadow: inset 7px 0 12px -6px #000;
-  box-shadow: inset 7px 0 12px -6px #000;
-}
-
-/* Remove gutter border */
-.cm-s-solarized .CodeMirror-gutters {
-  border-right: 0;
-}
-
-/* Gutter colors and line number styling based of color scheme (dark / light) */
-
-/* Dark */
-.cm-s-solarized.cm-s-dark .CodeMirror-gutters {
-  background-color: #073642;
-}
-
-.cm-s-solarized.cm-s-dark .CodeMirror-linenumber {
-  color: #586e75;
-  text-shadow: #021014 0 -1px;
-}
-
-/* Light */
-.cm-s-solarized.cm-s-light .CodeMirror-gutters {
-  background-color: #eee8d5;
-}
-
-.cm-s-solarized.cm-s-light .CodeMirror-linenumber {
-  color: #839496;
-}
-
-/* Common */
-.cm-s-solarized .CodeMirror-linenumber {
-  padding: 0 5px;
-}
-.cm-s-solarized .CodeMirror-guttermarker-subtle { color: #586e75; }
-.cm-s-solarized.cm-s-dark .CodeMirror-guttermarker { color: #ddd; }
-.cm-s-solarized.cm-s-light .CodeMirror-guttermarker { color: #cb4b16; }
-
-.cm-s-solarized .CodeMirror-gutter .CodeMirror-gutter-text {
-  color: #586e75;
-}
-
-/* Cursor */
-.cm-s-solarized .CodeMirror-cursor { border-left: 1px solid #819090; }
-
-/* Fat cursor */
-.cm-s-solarized.cm-s-light.cm-fat-cursor .CodeMirror-cursor { background: #77ee77; }
-.cm-s-solarized.cm-s-light .cm-animate-fat-cursor { background-color: #77ee77; }
-.cm-s-solarized.cm-s-dark.cm-fat-cursor .CodeMirror-cursor { background: #586e75; }
-.cm-s-solarized.cm-s-dark .cm-animate-fat-cursor { background-color: #586e75; }
-
-/* Active line */
-.cm-s-solarized.cm-s-dark .CodeMirror-activeline-background {
-  background: rgba(255, 255, 255, 0.06);
-}
-.cm-s-solarized.cm-s-light .CodeMirror-activeline-background {
-  background: rgba(0, 0, 0, 0.06);
-}
Index: admin/js/codemirror/theme/ssms.css
===================================================================
--- admin/js/codemirror/theme/ssms.css	(revision 3758)
+++ 	(revision )
@@ -1,16 +1,0 @@
-.cm-s-ssms span.cm-keyword { color: blue; }
-.cm-s-ssms span.cm-comment { color: darkgreen; }
-.cm-s-ssms span.cm-string { color: red; }
-.cm-s-ssms span.cm-def { color: black; }
-.cm-s-ssms span.cm-variable { color: black; }
-.cm-s-ssms span.cm-variable-2 { color: black; }
-.cm-s-ssms span.cm-atom { color: darkgray; }
-.cm-s-ssms .CodeMirror-linenumber { color: teal; }
-.cm-s-ssms .CodeMirror-activeline-background { background: #ffffff; }
-.cm-s-ssms span.cm-string-2 { color: #FF00FF; }
-.cm-s-ssms span.cm-operator, 
-.cm-s-ssms span.cm-bracket, 
-.cm-s-ssms span.cm-punctuation { color: darkgray; }
-.cm-s-ssms .CodeMirror-gutters { border-right: 3px solid #ffee62; background-color: #ffffff; }
-.cm-s-ssms div.CodeMirror-selected { background: #ADD6FF; }
-
Index: admin/js/codemirror/theme/the-matrix.css
===================================================================
--- admin/js/codemirror/theme/the-matrix.css	(revision 3617)
+++ 	(revision )
@@ -1,30 +1,0 @@
-.cm-s-the-matrix.CodeMirror { background: #000000; color: #00FF00; }
-.cm-s-the-matrix div.CodeMirror-selected { background: #2D2D2D; }
-.cm-s-the-matrix .CodeMirror-line::selection, .cm-s-the-matrix .CodeMirror-line > span::selection, .cm-s-the-matrix .CodeMirror-line > span > span::selection { background: rgba(45, 45, 45, 0.99); }
-.cm-s-the-matrix .CodeMirror-line::-moz-selection, .cm-s-the-matrix .CodeMirror-line > span::-moz-selection, .cm-s-the-matrix .CodeMirror-line > span > span::-moz-selection { background: rgba(45, 45, 45, 0.99); }
-.cm-s-the-matrix .CodeMirror-gutters { background: #060; border-right: 2px solid #00FF00; }
-.cm-s-the-matrix .CodeMirror-guttermarker { color: #0f0; }
-.cm-s-the-matrix .CodeMirror-guttermarker-subtle { color: white; }
-.cm-s-the-matrix .CodeMirror-linenumber { color: #FFFFFF; }
-.cm-s-the-matrix .CodeMirror-cursor { border-left: 1px solid #00FF00; }
-
-.cm-s-the-matrix span.cm-keyword { color: #008803; font-weight: bold; }
-.cm-s-the-matrix span.cm-atom { color: #3FF; }
-.cm-s-the-matrix span.cm-number { color: #FFB94F; }
-.cm-s-the-matrix span.cm-def { color: #99C; }
-.cm-s-the-matrix span.cm-variable { color: #F6C; }
-.cm-s-the-matrix span.cm-variable-2 { color: #C6F; }
-.cm-s-the-matrix span.cm-variable-3, .cm-s-the-matrix span.cm-type { color: #96F; }
-.cm-s-the-matrix span.cm-property { color: #62FFA0; }
-.cm-s-the-matrix span.cm-operator { color: #999; }
-.cm-s-the-matrix span.cm-comment { color: #CCCCCC; }
-.cm-s-the-matrix span.cm-string { color: #39C; }
-.cm-s-the-matrix span.cm-meta { color: #C9F; }
-.cm-s-the-matrix span.cm-qualifier { color: #FFF700; }
-.cm-s-the-matrix span.cm-builtin { color: #30a; }
-.cm-s-the-matrix span.cm-bracket { color: #cc7; }
-.cm-s-the-matrix span.cm-tag { color: #FFBD40; }
-.cm-s-the-matrix span.cm-attribute { color: #FFF700; }
-.cm-s-the-matrix span.cm-error { color: #FF0000; }
-
-.cm-s-the-matrix .CodeMirror-activeline-background { background: #040; }
Index: admin/js/codemirror/theme/tomorrow-night-bright.css
===================================================================
--- admin/js/codemirror/theme/tomorrow-night-bright.css	(revision 3251)
+++ 	(revision )
@@ -1,35 +1,0 @@
-/*
-
-    Name:       Tomorrow Night - Bright
-    Author:     Chris Kempson
-
-    Port done by Gerard Braad <me@gbraad.nl>
-
-*/
-
-.cm-s-tomorrow-night-bright.CodeMirror { background: #000000; color: #eaeaea; }
-.cm-s-tomorrow-night-bright div.CodeMirror-selected { background: #424242; }
-.cm-s-tomorrow-night-bright .CodeMirror-gutters { background: #000000; border-right: 0px; }
-.cm-s-tomorrow-night-bright .CodeMirror-guttermarker { color: #e78c45; }
-.cm-s-tomorrow-night-bright .CodeMirror-guttermarker-subtle { color: #777; }
-.cm-s-tomorrow-night-bright .CodeMirror-linenumber { color: #424242; }
-.cm-s-tomorrow-night-bright .CodeMirror-cursor { border-left: 1px solid #6A6A6A; }
-
-.cm-s-tomorrow-night-bright span.cm-comment { color: #d27b53; }
-.cm-s-tomorrow-night-bright span.cm-atom { color: #a16a94; }
-.cm-s-tomorrow-night-bright span.cm-number { color: #a16a94; }
-
-.cm-s-tomorrow-night-bright span.cm-property, .cm-s-tomorrow-night-bright span.cm-attribute { color: #99cc99; }
-.cm-s-tomorrow-night-bright span.cm-keyword { color: #d54e53; }
-.cm-s-tomorrow-night-bright span.cm-string { color: #e7c547; }
-
-.cm-s-tomorrow-night-bright span.cm-variable { color: #b9ca4a; }
-.cm-s-tomorrow-night-bright span.cm-variable-2 { color: #7aa6da; }
-.cm-s-tomorrow-night-bright span.cm-def { color: #e78c45; }
-.cm-s-tomorrow-night-bright span.cm-bracket { color: #eaeaea; }
-.cm-s-tomorrow-night-bright span.cm-tag { color: #d54e53; }
-.cm-s-tomorrow-night-bright span.cm-link { color: #a16a94; }
-.cm-s-tomorrow-night-bright span.cm-error { background: #d54e53; color: #6A6A6A; }
-
-.cm-s-tomorrow-night-bright .CodeMirror-activeline-background { background: #2a2a2a; }
-.cm-s-tomorrow-night-bright .CodeMirror-matchingbracket { text-decoration: underline; color: white !important; }
Index: admin/js/codemirror/theme/tomorrow-night-eighties.css
===================================================================
--- admin/js/codemirror/theme/tomorrow-night-eighties.css	(revision 3251)
+++ 	(revision )
@@ -1,38 +1,0 @@
-/*
-
-    Name:       Tomorrow Night - Eighties
-    Author:     Chris Kempson
-
-    CodeMirror template by Jan T. Sott (https://github.com/idleberg/base16-codemirror)
-    Original Base16 color scheme by Chris Kempson (https://github.com/chriskempson/base16)
-
-*/
-
-.cm-s-tomorrow-night-eighties.CodeMirror { background: #000000; color: #CCCCCC; }
-.cm-s-tomorrow-night-eighties div.CodeMirror-selected { background: #2D2D2D; }
-.cm-s-tomorrow-night-eighties .CodeMirror-line::selection, .cm-s-tomorrow-night-eighties .CodeMirror-line > span::selection, .cm-s-tomorrow-night-eighties .CodeMirror-line > span > span::selection { background: rgba(45, 45, 45, 0.99); }
-.cm-s-tomorrow-night-eighties .CodeMirror-line::-moz-selection, .cm-s-tomorrow-night-eighties .CodeMirror-line > span::-moz-selection, .cm-s-tomorrow-night-eighties .CodeMirror-line > span > span::-moz-selection { background: rgba(45, 45, 45, 0.99); }
-.cm-s-tomorrow-night-eighties .CodeMirror-gutters { background: #000000; border-right: 0px; }
-.cm-s-tomorrow-night-eighties .CodeMirror-guttermarker { color: #f2777a; }
-.cm-s-tomorrow-night-eighties .CodeMirror-guttermarker-subtle { color: #777; }
-.cm-s-tomorrow-night-eighties .CodeMirror-linenumber { color: #515151; }
-.cm-s-tomorrow-night-eighties .CodeMirror-cursor { border-left: 1px solid #6A6A6A; }
-
-.cm-s-tomorrow-night-eighties span.cm-comment { color: #d27b53; }
-.cm-s-tomorrow-night-eighties span.cm-atom { color: #a16a94; }
-.cm-s-tomorrow-night-eighties span.cm-number { color: #a16a94; }
-
-.cm-s-tomorrow-night-eighties span.cm-property, .cm-s-tomorrow-night-eighties span.cm-attribute { color: #99cc99; }
-.cm-s-tomorrow-night-eighties span.cm-keyword { color: #f2777a; }
-.cm-s-tomorrow-night-eighties span.cm-string { color: #ffcc66; }
-
-.cm-s-tomorrow-night-eighties span.cm-variable { color: #99cc99; }
-.cm-s-tomorrow-night-eighties span.cm-variable-2 { color: #6699cc; }
-.cm-s-tomorrow-night-eighties span.cm-def { color: #f99157; }
-.cm-s-tomorrow-night-eighties span.cm-bracket { color: #CCCCCC; }
-.cm-s-tomorrow-night-eighties span.cm-tag { color: #f2777a; }
-.cm-s-tomorrow-night-eighties span.cm-link { color: #a16a94; }
-.cm-s-tomorrow-night-eighties span.cm-error { background: #f2777a; color: #6A6A6A; }
-
-.cm-s-tomorrow-night-eighties .CodeMirror-activeline-background { background: #343600; }
-.cm-s-tomorrow-night-eighties .CodeMirror-matchingbracket { text-decoration: underline; color: white !important; }
Index: admin/js/codemirror/theme/ttcn.css
===================================================================
--- admin/js/codemirror/theme/ttcn.css	(revision 3617)
+++ 	(revision )
@@ -1,64 +1,0 @@
-.cm-s-ttcn .cm-quote { color: #090; }
-.cm-s-ttcn .cm-negative { color: #d44; }
-.cm-s-ttcn .cm-positive { color: #292; }
-.cm-s-ttcn .cm-header, .cm-strong { font-weight: bold; }
-.cm-s-ttcn .cm-em { font-style: italic; }
-.cm-s-ttcn .cm-link { text-decoration: underline; }
-.cm-s-ttcn .cm-strikethrough { text-decoration: line-through; }
-.cm-s-ttcn .cm-header { color: #00f; font-weight: bold; }
-
-.cm-s-ttcn .cm-atom { color: #219; }
-.cm-s-ttcn .cm-attribute { color: #00c; }
-.cm-s-ttcn .cm-bracket { color: #997; }
-.cm-s-ttcn .cm-comment { color: #333333; }
-.cm-s-ttcn .cm-def { color: #00f; }
-.cm-s-ttcn .cm-em { font-style: italic; }
-.cm-s-ttcn .cm-error { color: #f00; }
-.cm-s-ttcn .cm-hr { color: #999; }
-.cm-s-ttcn .cm-invalidchar { color: #f00; }
-.cm-s-ttcn .cm-keyword { font-weight:bold; }
-.cm-s-ttcn .cm-link { color: #00c; text-decoration: underline; }
-.cm-s-ttcn .cm-meta { color: #555; }
-.cm-s-ttcn .cm-negative { color: #d44; }
-.cm-s-ttcn .cm-positive { color: #292; }
-.cm-s-ttcn .cm-qualifier { color: #555; }
-.cm-s-ttcn .cm-strikethrough { text-decoration: line-through; }
-.cm-s-ttcn .cm-string { color: #006400; }
-.cm-s-ttcn .cm-string-2 { color: #f50; }
-.cm-s-ttcn .cm-strong { font-weight: bold; }
-.cm-s-ttcn .cm-tag { color: #170; }
-.cm-s-ttcn .cm-variable { color: #8B2252; }
-.cm-s-ttcn .cm-variable-2 { color: #05a; }
-.cm-s-ttcn .cm-variable-3, .cm-s-ttcn .cm-type { color: #085; }
-
-.cm-s-ttcn .cm-invalidchar { color: #f00; }
-
-/* ASN */
-.cm-s-ttcn .cm-accessTypes,
-.cm-s-ttcn .cm-compareTypes { color: #27408B; }
-.cm-s-ttcn .cm-cmipVerbs { color: #8B2252; }
-.cm-s-ttcn .cm-modifier { color:#D2691E; }
-.cm-s-ttcn .cm-status { color:#8B4545; }
-.cm-s-ttcn .cm-storage { color:#A020F0; }
-.cm-s-ttcn .cm-tags { color:#006400; }
-
-/* CFG */
-.cm-s-ttcn .cm-externalCommands { color: #8B4545; font-weight:bold; }
-.cm-s-ttcn .cm-fileNCtrlMaskOptions,
-.cm-s-ttcn .cm-sectionTitle { color: #2E8B57; font-weight:bold; }
-
-/* TTCN */
-.cm-s-ttcn .cm-booleanConsts,
-.cm-s-ttcn .cm-otherConsts,
-.cm-s-ttcn .cm-verdictConsts { color: #006400; }
-.cm-s-ttcn .cm-configOps,
-.cm-s-ttcn .cm-functionOps,
-.cm-s-ttcn .cm-portOps,
-.cm-s-ttcn .cm-sutOps,
-.cm-s-ttcn .cm-timerOps,
-.cm-s-ttcn .cm-verdictOps { color: #0000FF; }
-.cm-s-ttcn .cm-preprocessor,
-.cm-s-ttcn .cm-templateMatch,
-.cm-s-ttcn .cm-ttcn3Macros { color: #27408B; }
-.cm-s-ttcn .cm-types { color: #A52A2A; font-weight:bold; }
-.cm-s-ttcn .cm-visibilityModifiers { font-weight:bold; }
Index: admin/js/codemirror/theme/twilight.css
===================================================================
--- admin/js/codemirror/theme/twilight.css	(revision 3617)
+++ 	(revision )
@@ -1,32 +1,0 @@
-.cm-s-twilight.CodeMirror { background: #141414; color: #f7f7f7; } /**/
-.cm-s-twilight div.CodeMirror-selected { background: #323232; } /**/
-.cm-s-twilight .CodeMirror-line::selection, .cm-s-twilight .CodeMirror-line > span::selection, .cm-s-twilight .CodeMirror-line > span > span::selection { background: rgba(50, 50, 50, 0.99); }
-.cm-s-twilight .CodeMirror-line::-moz-selection, .cm-s-twilight .CodeMirror-line > span::-moz-selection, .cm-s-twilight .CodeMirror-line > span > span::-moz-selection { background: rgba(50, 50, 50, 0.99); }
-
-.cm-s-twilight .CodeMirror-gutters { background: #222; border-right: 1px solid #aaa; }
-.cm-s-twilight .CodeMirror-guttermarker { color: white; }
-.cm-s-twilight .CodeMirror-guttermarker-subtle { color: #aaa; }
-.cm-s-twilight .CodeMirror-linenumber { color: #aaa; }
-.cm-s-twilight .CodeMirror-cursor { border-left: 1px solid white; }
-
-.cm-s-twilight .cm-keyword { color: #f9ee98; } /**/
-.cm-s-twilight .cm-atom { color: #FC0; }
-.cm-s-twilight .cm-number { color:  #ca7841; } /**/
-.cm-s-twilight .cm-def { color: #8DA6CE; }
-.cm-s-twilight span.cm-variable-2, .cm-s-twilight span.cm-tag { color: #607392; } /**/
-.cm-s-twilight span.cm-variable-3, .cm-s-twilight span.cm-def, .cm-s-twilight span.cm-type { color: #607392; } /**/
-.cm-s-twilight .cm-operator { color: #cda869; } /**/
-.cm-s-twilight .cm-comment { color:#777; font-style:italic; font-weight:normal; } /**/
-.cm-s-twilight .cm-string { color:#8f9d6a; font-style:italic; } /**/
-.cm-s-twilight .cm-string-2 { color:#bd6b18; } /*?*/
-.cm-s-twilight .cm-meta { background-color:#141414; color:#f7f7f7; } /*?*/
-.cm-s-twilight .cm-builtin { color: #cda869; } /*?*/
-.cm-s-twilight .cm-tag { color: #997643; } /**/
-.cm-s-twilight .cm-attribute { color: #d6bb6d; } /*?*/
-.cm-s-twilight .cm-header { color: #FF6400; }
-.cm-s-twilight .cm-hr { color: #AEAEAE; }
-.cm-s-twilight .cm-link { color:#ad9361; font-style:italic; text-decoration:none; } /**/
-.cm-s-twilight .cm-error { border-bottom: 1px solid red; }
-
-.cm-s-twilight .CodeMirror-activeline-background { background: #27282E; }
-.cm-s-twilight .CodeMirror-matchingbracket { outline:1px solid grey; color:white !important; }
Index: admin/js/codemirror/theme/vibrant-ink.css
===================================================================
--- admin/js/codemirror/theme/vibrant-ink.css	(revision 3979)
+++ 	(revision )
@@ -1,34 +1,0 @@
-/* Taken from the popular Visual Studio Vibrant Ink Schema */
-
-.cm-s-vibrant-ink.CodeMirror { background: black; color: white; }
-.cm-s-vibrant-ink div.CodeMirror-selected { background: #35493c; }
-.cm-s-vibrant-ink .CodeMirror-line::selection, .cm-s-vibrant-ink .CodeMirror-line > span::selection, .cm-s-vibrant-ink .CodeMirror-line > span > span::selection { background: rgba(53, 73, 60, 0.99); }
-.cm-s-vibrant-ink .CodeMirror-line::-moz-selection, .cm-s-vibrant-ink .CodeMirror-line > span::-moz-selection, .cm-s-vibrant-ink .CodeMirror-line > span > span::-moz-selection { background: rgba(53, 73, 60, 0.99); }
-
-.cm-s-vibrant-ink .CodeMirror-gutters { background: #002240; border-right: 1px solid #aaa; }
-.cm-s-vibrant-ink .CodeMirror-guttermarker { color: white; }
-.cm-s-vibrant-ink .CodeMirror-guttermarker-subtle { color: #d0d0d0; }
-.cm-s-vibrant-ink .CodeMirror-linenumber { color: #d0d0d0; }
-.cm-s-vibrant-ink .CodeMirror-cursor { border-left: 1px solid white; }
-
-.cm-s-vibrant-ink .cm-keyword { color: #CC7832; }
-.cm-s-vibrant-ink .cm-atom { color: #FC0; }
-.cm-s-vibrant-ink .cm-number { color:  #FFEE98; }
-.cm-s-vibrant-ink .cm-def { color: #8DA6CE; }
-.cm-s-vibrant-ink span.cm-variable-2, .cm-s-vibrant span.cm-tag { color: #FFC66D; }
-.cm-s-vibrant-ink span.cm-variable-3, .cm-s-vibrant span.cm-def, .cm-s-vibrant span.cm-type { color: #FFC66D; }
-.cm-s-vibrant-ink .cm-operator { color: #888; }
-.cm-s-vibrant-ink .cm-comment { color: gray; font-weight: bold; }
-.cm-s-vibrant-ink .cm-string { color:  #A5C25C; }
-.cm-s-vibrant-ink .cm-string-2 { color: red; }
-.cm-s-vibrant-ink .cm-meta { color: #D8FA3C; }
-.cm-s-vibrant-ink .cm-builtin { color: #8DA6CE; }
-.cm-s-vibrant-ink .cm-tag { color: #8DA6CE; }
-.cm-s-vibrant-ink .cm-attribute { color: #8DA6CE; }
-.cm-s-vibrant-ink .cm-header { color: #FF6400; }
-.cm-s-vibrant-ink .cm-hr { color: #AEAEAE; }
-.cm-s-vibrant-ink .cm-link { color: #5656F3; }
-.cm-s-vibrant-ink .cm-error { border-bottom: 1px solid red; }
-
-.cm-s-vibrant-ink .CodeMirror-activeline-background { background: #27282E; }
-.cm-s-vibrant-ink .CodeMirror-matchingbracket { outline:1px solid grey; color:white !important; }
Index: admin/js/codemirror/theme/xq-dark.css
===================================================================
--- admin/js/codemirror/theme/xq-dark.css	(revision 3617)
+++ 	(revision )
@@ -1,53 +1,0 @@
-/*
-Copyright (C) 2011 by MarkLogic Corporation
-Author: Mike Brevoort <mike@brevoort.com>
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
-*/
-.cm-s-xq-dark.CodeMirror { background: #0a001f; color: #f8f8f8; }
-.cm-s-xq-dark div.CodeMirror-selected { background: #27007A; }
-.cm-s-xq-dark .CodeMirror-line::selection, .cm-s-xq-dark .CodeMirror-line > span::selection, .cm-s-xq-dark .CodeMirror-line > span > span::selection { background: rgba(39, 0, 122, 0.99); }
-.cm-s-xq-dark .CodeMirror-line::-moz-selection, .cm-s-xq-dark .CodeMirror-line > span::-moz-selection, .cm-s-xq-dark .CodeMirror-line > span > span::-moz-selection { background: rgba(39, 0, 122, 0.99); }
-.cm-s-xq-dark .CodeMirror-gutters { background: #0a001f; border-right: 1px solid #aaa; }
-.cm-s-xq-dark .CodeMirror-guttermarker { color: #FFBD40; }
-.cm-s-xq-dark .CodeMirror-guttermarker-subtle { color: #f8f8f8; }
-.cm-s-xq-dark .CodeMirror-linenumber { color: #f8f8f8; }
-.cm-s-xq-dark .CodeMirror-cursor { border-left: 1px solid white; }
-
-.cm-s-xq-dark span.cm-keyword { color: #FFBD40; }
-.cm-s-xq-dark span.cm-atom { color: #6C8CD5; }
-.cm-s-xq-dark span.cm-number { color: #164; }
-.cm-s-xq-dark span.cm-def { color: #FFF; text-decoration:underline; }
-.cm-s-xq-dark span.cm-variable { color: #FFF; }
-.cm-s-xq-dark span.cm-variable-2 { color: #EEE; }
-.cm-s-xq-dark span.cm-variable-3, .cm-s-xq-dark span.cm-type { color: #DDD; }
-.cm-s-xq-dark span.cm-property {}
-.cm-s-xq-dark span.cm-operator {}
-.cm-s-xq-dark span.cm-comment { color: gray; }
-.cm-s-xq-dark span.cm-string { color: #9FEE00; }
-.cm-s-xq-dark span.cm-meta { color: yellow; }
-.cm-s-xq-dark span.cm-qualifier { color: #FFF700; }
-.cm-s-xq-dark span.cm-builtin { color: #30a; }
-.cm-s-xq-dark span.cm-bracket { color: #cc7; }
-.cm-s-xq-dark span.cm-tag { color: #FFBD40; }
-.cm-s-xq-dark span.cm-attribute { color: #FFF700; }
-.cm-s-xq-dark span.cm-error { color: #f00; }
-
-.cm-s-xq-dark .CodeMirror-activeline-background { background: #27282E; }
-.cm-s-xq-dark .CodeMirror-matchingbracket { outline:1px solid grey; color:white !important; }
Index: admin/js/codemirror/theme/xq-light.css
===================================================================
--- admin/js/codemirror/theme/xq-light.css	(revision 3617)
+++ 	(revision )
@@ -1,43 +1,0 @@
-/*
-Copyright (C) 2011 by MarkLogic Corporation
-Author: Mike Brevoort <mike@brevoort.com>
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
-*/
-.cm-s-xq-light span.cm-keyword { line-height: 1em; font-weight: bold; color: #5A5CAD; }
-.cm-s-xq-light span.cm-atom { color: #6C8CD5; }
-.cm-s-xq-light span.cm-number { color: #164; }
-.cm-s-xq-light span.cm-def { text-decoration:underline; }
-.cm-s-xq-light span.cm-variable { color: black; }
-.cm-s-xq-light span.cm-variable-2 { color:black; }
-.cm-s-xq-light span.cm-variable-3, .cm-s-xq-light span.cm-type { color: black; }
-.cm-s-xq-light span.cm-property {}
-.cm-s-xq-light span.cm-operator {}
-.cm-s-xq-light span.cm-comment { color: #0080FF; font-style: italic; }
-.cm-s-xq-light span.cm-string { color: red; }
-.cm-s-xq-light span.cm-meta { color: yellow; }
-.cm-s-xq-light span.cm-qualifier { color: grey; }
-.cm-s-xq-light span.cm-builtin { color: #7EA656; }
-.cm-s-xq-light span.cm-bracket { color: #cc7; }
-.cm-s-xq-light span.cm-tag { color: #3F7F7F; }
-.cm-s-xq-light span.cm-attribute { color: #7F007F; }
-.cm-s-xq-light span.cm-error { color: #f00; }
-
-.cm-s-xq-light .CodeMirror-activeline-background { background: #e8f2ff; }
-.cm-s-xq-light .CodeMirror-matchingbracket { outline:1px solid grey;color:black !important;background:yellow; }
Index: admin/js/codemirror/theme/yeti.css
===================================================================
--- admin/js/codemirror/theme/yeti.css	(revision 3617)
+++ 	(revision )
@@ -1,44 +1,0 @@
-/*
-
-    Name:       yeti
-    Author:     Michael Kaminsky (http://github.com/mkaminsky11)
-
-    Original yeti color scheme by Jesse Weed (https://github.com/jesseweed/yeti-syntax)
-
-*/
-
-
-.cm-s-yeti.CodeMirror {
-  background-color: #ECEAE8 !important;
-  color: #d1c9c0 !important;
-  border: none;
-}
-
-.cm-s-yeti .CodeMirror-gutters {
-  color: #adaba6;
-  background-color: #E5E1DB;
-  border: none;
-}
-.cm-s-yeti .CodeMirror-cursor { border-left: solid thin #d1c9c0; }
-.cm-s-yeti .CodeMirror-linenumber { color: #adaba6; }
-.cm-s-yeti.CodeMirror-focused div.CodeMirror-selected { background: #DCD8D2; }
-.cm-s-yeti .CodeMirror-line::selection, .cm-s-yeti .CodeMirror-line > span::selection, .cm-s-yeti .CodeMirror-line > span > span::selection { background: #DCD8D2; }
-.cm-s-yeti .CodeMirror-line::-moz-selection, .cm-s-yeti .CodeMirror-line > span::-moz-selection, .cm-s-yeti .CodeMirror-line > span > span::-moz-selection { background: #DCD8D2; }
-.cm-s-yeti span.cm-comment { color: #d4c8be; }
-.cm-s-yeti span.cm-string, .cm-s-yeti span.cm-string-2 { color: #96c0d8; }
-.cm-s-yeti span.cm-number { color: #a074c4; }
-.cm-s-yeti span.cm-variable { color: #55b5db; }
-.cm-s-yeti span.cm-variable-2 { color: #a074c4; }
-.cm-s-yeti span.cm-def { color: #55b5db; }
-.cm-s-yeti span.cm-operator { color: #9fb96e; }
-.cm-s-yeti span.cm-keyword { color: #9fb96e; }
-.cm-s-yeti span.cm-atom { color: #a074c4; }
-.cm-s-yeti span.cm-meta { color: #96c0d8; }
-.cm-s-yeti span.cm-tag { color: #96c0d8; }
-.cm-s-yeti span.cm-attribute { color: #9fb96e; }
-.cm-s-yeti span.cm-qualifier { color: #96c0d8; }
-.cm-s-yeti span.cm-property { color: #a074c4; }
-.cm-s-yeti span.cm-builtin { color: #a074c4; }
-.cm-s-yeti span.cm-variable-3, .cm-s-yeti span.cm-type { color: #96c0d8; }
-.cm-s-yeti .CodeMirror-activeline-background { background: #E7E4E0; }
-.cm-s-yeti .CodeMirror-matchingbracket { text-decoration: underline; }
Index: admin/js/codemirror/theme/yonce.css
===================================================================
--- admin/js/codemirror/theme/yonce.css	(revision 3979)
+++ 	(revision )
@@ -1,59 +1,0 @@
-/*
-
-    Name:       yoncé
-    Author:     Thomas MacLean (http://github.com/thomasmaclean)
-
-    Original yoncé color scheme by Mina Markham (https://github.com/minamarkham)
-
-*/
-
-.cm-s-yonce.CodeMirror { background: #1C1C1C; color: #d4d4d4; } /**/
-.cm-s-yonce div.CodeMirror-selected { background: rgba(252, 69, 133, 0.478); } /**/
-.cm-s-yonce .CodeMirror-selectedtext,
-.cm-s-yonce .CodeMirror-selected,
-.cm-s-yonce .CodeMirror-line::selection,
-.cm-s-yonce .CodeMirror-line > span::selection,
-.cm-s-yonce .CodeMirror-line > span > span::selection,
-.cm-s-yonce .CodeMirror-line::-moz-selection,
-.cm-s-yonce .CodeMirror-line > span::-moz-selection,
-.cm-s-yonce .CodeMirror-line > span > span::-moz-selection { background: rgba(252, 67, 132, 0.47); }
-
-.cm-s-yonce.CodeMirror pre { padding-left: 0px; }
-.cm-s-yonce .CodeMirror-gutters {background: #1C1C1C; border-right: 0px;}
-.cm-s-yonce .CodeMirror-linenumber {color: #777777;  padding-right: 10px; }
-.cm-s-yonce .CodeMirror-activeline .CodeMirror-linenumber.CodeMirror-gutter-elt { background: #1C1C1C; color: #fc4384; }
-.cm-s-yonce .CodeMirror-linenumber { color: #777; }
-.cm-s-yonce .CodeMirror-cursor { border-left: 2px solid #FC4384; }
-.cm-s-yonce .cm-searching { background: rgb(243, 155, 53, .3) !important; outline: 1px solid #F39B35; }
-.cm-s-yonce .cm-searching.CodeMirror-selectedtext { background: rgb(243, 155, 53, .7) !important; color: white; }
-
-.cm-s-yonce .cm-keyword { color: #00A7AA; } /**/
-.cm-s-yonce .cm-atom { color: #F39B35; }
-.cm-s-yonce .cm-number, .cm-s-yonce span.cm-type { color:  #A06FCA; } /**/
-.cm-s-yonce .cm-def { color: #98E342; }
-.cm-s-yonce .cm-property,
-.cm-s-yonce span.cm-variable { color: #D4D4D4; font-style: italic; }
-.cm-s-yonce span.cm-variable-2 { color: #da7dae; font-style: italic; }
-.cm-s-yonce span.cm-variable-3 { color: #A06FCA; }
-.cm-s-yonce .cm-type.cm-def { color: #FC4384; font-style: normal; text-decoration: underline; }
-.cm-s-yonce .cm-property.cm-def { color: #FC4384; font-style: normal; }
-.cm-s-yonce .cm-callee { color: #FC4384; font-style: normal; }
-.cm-s-yonce .cm-operator { color: #FC4384; } /**/
-.cm-s-yonce .cm-qualifier,
-.cm-s-yonce .cm-tag { color: #FC4384; }
-.cm-s-yonce .cm-tag.cm-bracket { color: #D4D4D4; }
-.cm-s-yonce .cm-attribute { color: #A06FCA; }
-.cm-s-yonce .cm-comment { color:#696d70; font-style:italic; font-weight:normal; } /**/
-.cm-s-yonce .cm-comment.cm-tag { color: #FC4384 }
-.cm-s-yonce .cm-comment.cm-attribute { color: #D4D4D4; }
-.cm-s-yonce .cm-string { color:#E6DB74; } /**/
-.cm-s-yonce .cm-string-2 { color:#F39B35; } /*?*/
-.cm-s-yonce .cm-meta { color: #D4D4D4; background: inherit; }
-.cm-s-yonce .cm-builtin { color: #FC4384; } /*?*/
-.cm-s-yonce .cm-header { color: #da7dae; }
-.cm-s-yonce .cm-hr { color: #98E342; }
-.cm-s-yonce .cm-link { color:#696d70; font-style:italic; text-decoration:none; } /**/
-.cm-s-yonce .cm-error { border-bottom: 1px solid #C42412; }
-
-.cm-s-yonce .CodeMirror-activeline-background { background: #272727; }
-.cm-s-yonce .CodeMirror-matchingbracket { outline:1px solid grey; color:#D4D4D4 !important; }
Index: admin/js/codemirror/theme/zenburn.css
===================================================================
--- admin/js/codemirror/theme/zenburn.css	(revision 3251)
+++ 	(revision )
@@ -1,37 +1,0 @@
-/**
- * "
- *  Using Zenburn color palette from the Emacs Zenburn Theme
- *  https://github.com/bbatsov/zenburn-emacs/blob/master/zenburn-theme.el
- *
- *  Also using parts of https://github.com/xavi/coderay-lighttable-theme
- * "
- * From: https://github.com/wisenomad/zenburn-lighttable-theme/blob/master/zenburn.css
- */
-
-.cm-s-zenburn .CodeMirror-gutters { background: #3f3f3f !important; }
-.cm-s-zenburn .CodeMirror-foldgutter-open, .CodeMirror-foldgutter-folded { color: #999; }
-.cm-s-zenburn .CodeMirror-cursor { border-left: 1px solid white; }
-.cm-s-zenburn { background-color: #3f3f3f; color: #dcdccc; }
-.cm-s-zenburn span.cm-builtin { color: #dcdccc; font-weight: bold; }
-.cm-s-zenburn span.cm-comment { color: #7f9f7f; }
-.cm-s-zenburn span.cm-keyword { color: #f0dfaf; font-weight: bold; }
-.cm-s-zenburn span.cm-atom { color: #bfebbf; }
-.cm-s-zenburn span.cm-def { color: #dcdccc; }
-.cm-s-zenburn span.cm-variable { color: #dfaf8f; }
-.cm-s-zenburn span.cm-variable-2 { color: #dcdccc; }
-.cm-s-zenburn span.cm-string { color: #cc9393; }
-.cm-s-zenburn span.cm-string-2 { color: #cc9393; }
-.cm-s-zenburn span.cm-number { color: #dcdccc; }
-.cm-s-zenburn span.cm-tag { color: #93e0e3; }
-.cm-s-zenburn span.cm-property { color: #dfaf8f; }
-.cm-s-zenburn span.cm-attribute { color: #dfaf8f; }
-.cm-s-zenburn span.cm-qualifier { color: #7cb8bb; }
-.cm-s-zenburn span.cm-meta { color: #f0dfaf; }
-.cm-s-zenburn span.cm-header { color: #f0efd0; }
-.cm-s-zenburn span.cm-operator { color: #f0efd0; }
-.cm-s-zenburn span.CodeMirror-matchingbracket { box-sizing: border-box; background: transparent; border-bottom: 1px solid; }
-.cm-s-zenburn span.CodeMirror-nonmatchingbracket { border-bottom: 1px solid; background: none; }
-.cm-s-zenburn .CodeMirror-activeline { background: #000000; }
-.cm-s-zenburn .CodeMirror-activeline-background { background: #000000; }
-.cm-s-zenburn div.CodeMirror-selected { background: #545454; }
-.cm-s-zenburn .CodeMirror-focused div.CodeMirror-selected { background: #4f4f4f; }
Index: admin/js/color-picker.js
===================================================================
--- admin/js/color-picker.js	(revision 3880)
+++ admin/js/color-picker.js	(revision 0)
@@ -1,87 +1,79 @@
-/*global $, jQuery */
-'use strict';
-
 $(function() {
-  $('.colorpicker').colorPicker();
+	$('.colorpicker').colorPicker();
 });
 
 jQuery.fn.colorPicker = function() {
-  $(this).each(function() {
-    let colbox = $('#jquery-colorpicker')[0];
-    if (colbox == undefined) {
-      colbox = document.createElement('div');
-      colbox.id = 'jquery-colorpicker';
-      colbox.linkedto = null;
-
-      $(colbox).addClass('color-color-picker');
-      $(colbox).css({
-        display: 'none',
-        position: 'absolute'
-      });
-      $('body').append(colbox);
-    }
-    const f = $.farbtastic(colbox);
-    f.linkTo(this);
-
-    const handler = $(document.createElement('img'));
-    handler.attr('src', 'images/picker.png');
-    handler.attr('alt', '');
-
-    const span = $(document.createElement('span'));
-
-    if ($(this).css('position') == 'absolute') {
-      span.css('position', 'absolute');
-      span.css('top', $(this).css('top'));
-      span.css('left', $(this).css('left'));
-      $(this).css('position', 'static');
-    } else {
-      span.css('position', 'relative');
-    }
-    span.css('display', 'inline-block');
-    span.css('padding', '0 5px 0 0');
-    $(this).wrap(span);
-    $(this).after(handler);
-
-    handler.css({
-      position: 'absolute',
-      top: 3,
-    });
-
-    handler.css({
-      cursor: 'default'
-    });
-
-    const This = this;
-    handler.click(function() {
-      if ($(colbox).css('display') == 'none' || this != colbox.linkedto) {
-        f.linkTo(This);
-        This.focus();
-        const offset = $(This).offset();
-        $(colbox).css({
-          zIndex: 1000,
-          top: offset.top + $(this).height() + 5,
-          left: offset.left
-        });
-        if (document.all) {
-          $('select').hide();
-        }
-        $(colbox).show();
-        colbox.linkedto = this;
-
-      } else {
-        $(colbox).hide();
-        if (document.all) {
-          $('select').show();
-        }
-        colbox.linkedto = null;
-      }
-    });
-    $(this).blur(function() {
-      $(colbox).hide();
-      if (document.all) {
-        $('select').show();
-      }
-    });
-  });
-  return this;
+	$(this).each(function() {
+		var colbox, f;
+		var colbox = $('#jquery-colorpicker')[0];
+		
+		if (colbox == undefined) {
+			colbox = document.createElement('div');
+			colbox.id = 'jquery-colorpicker';
+			colbox.linkedto = null;
+			
+			$(colbox).css({border: '1px solid #000', width: '195px', background: '#fff', position: 'absolute'});
+			$(colbox).css({display: 'none'});
+			$('body').append(colbox);
+		}
+		f = $.farbtastic(colbox);
+		f.linkTo(this);
+		
+		var handler = $(document.createElement('img'));
+		handler.attr('src','images/picker.png');
+		handler.attr('alt','');
+		
+		var span = $(document.createElement('span'));
+		
+		if ($(this).css('position') == 'absolute') {
+			span.css('position','absolute');
+			span.css('top',$(this).css('top'));
+			span.css('left',$(this).css('left'));
+			$(this).css('position','static');
+		} else {
+			span.css('position','relative');
+		}
+		span.css('display','block');
+		
+		span.css('width',($(this).width()+12)+'px');
+		span.css('padding','0 5px 0 0');
+		$(this).wrap(span);
+		$(this).after(handler);
+		
+		var offset = $(this).offset();
+		handler.css({
+			position: 'absolute',
+			top: 3,
+			right: 0
+		});
+		
+		handler.css({cursor: 'default'});
+		
+		var This = this;
+		handler.click(function() {
+			if ($(colbox).css('display') == 'none' || this != colbox.linkedto) {
+				f.linkTo(This);
+				This.focus();
+				var offset = $(This).offset();
+				$(colbox).css({
+					zIndex: 1000,
+					top: offset.top + $(this).height() + 5,
+					left: offset.left
+				});
+				if (document.all) { $('select').hide(); }
+				$(colbox).show();
+				colbox.linkedto = this;
+				
+			} else {
+				$(colbox).hide();
+				if (document.all) { $('select').show(); }
+				colbox.linkedto = null;
+			}
+		});
+		$(this).blur(function() {
+			$(colbox).hide();
+			if (document.all) { $('select').show(); }
+		});
+	});
+	return this;
 };
Index: admin/js/common.js
===================================================================
--- admin/js/common.js	(revision 4042)
+++ admin/js/common.js	(revision 0)
@@ -1,581 +1,317 @@
-/*global $, jQuery, getData */
-/*exported chainHandler */
-'use strict';
-
-/* Get PreInit JSON data */
-const dotclear_init = getData('dotclear_init');
-
-/* Set some CSS variables here
--------------------------------------------------------- */
-// set base font-size of body (62.5% default, usually : 50% to 75%)
-if (typeof dotclear_init.htmlFontSize !== 'undefined') {
-  document.documentElement.style.setProperty('--html-font-size', dotclear_init.htmlFontSize);
-}
 /* ChainHandler, py Peter van der Beken
 -------------------------------------------------------- */
 function chainHandler(obj, handlerName, handler) {
-  obj[handlerName] = (function(existingFunction) {
-    return function() {
-      handler.apply(this, arguments);
-      if (existingFunction) existingFunction.apply(this, arguments);
-    };
-  })(handlerName in obj ? obj[handlerName] : null);
-}
+	obj[handlerName] = (function(existingFunction) {
+		return function() {
+			handler.apply(this, arguments);
+			if (existingFunction)
+				existingFunction.apply(this, arguments); 
+		};
+	})(handlerName in obj ? obj[handlerName] : null);
+};
+
 /* jQuery extensions
 -------------------------------------------------------- */
 jQuery.fn.check = function() {
-  return this.each(function() {
-    if (this.checked != undefined) {
-      this.checked = true;
-    }
-  });
+	return this.each(function() {
+		if (this.checked != undefined) { this.checked = true; }
+	});
 };
 jQuery.fn.unCheck = function() {
-  return this.each(function() {
-    if (this.checked != undefined) {
-      this.checked = false;
-    }
-  });
+	return this.each(function() {
+		if (this.checked != undefined) { this.checked = false; }
+	});
 };
 jQuery.fn.setChecked = function(status) {
-  return this.each(function() {
-    if (this.checked != undefined) {
-      this.checked = status;
-    }
-  });
+	return this.each(function() {
+		if (this.checked != undefined) { this.checked = status; }
+	});
 };
 jQuery.fn.toggleCheck = function() {
-  return this.each(function() {
-    if (this.checked != undefined) {
-      this.checked = !this.checked;
-    }
-  });
-};
+	return this.each(function() {
+		if (this.checked != undefined) { this.checked = !this.checked; }
+	});
+};
+
 jQuery.fn.enableShiftClick = function() {
-  this.click(function(event) {
-    if (event.shiftKey) {
-      if (dotclear.lastclicked != '') {
-        let range;
-        const trparent = $(this).parents('tr');
-        const id = `#${dotclear.lastclicked}`;
-        if (trparent.nextAll(id).length != 0) {
-          range = trparent.nextUntil(id);
-        } else {
-          range = trparent.prevUntil(id);
-        }
-        range.find('input[type=checkbox]').setChecked(dotclear.lastclickedstatus);
-        this.checked = dotclear.lastclickedstatus;
-      }
-    } else {
-      dotclear.lastclicked = $(this).parents('tr')[0].id;
-      dotclear.lastclickedstatus = this.checked;
-    }
-    return true;
-  });
-};
-jQuery.fn.toggleWithLegend = function(target, s) {
-  const defaults = {
-    img_on_txt: dotclear.img_plus_txt,
-    img_on_alt: dotclear.img_plus_alt,
-    img_off_txt: dotclear.img_minus_txt,
-    img_off_alt: dotclear.img_minus_alt,
-    unfolded_sections: dotclear.unfolded_sections,
-    hide: true,
-    legend_click: false,
-    fn: false, // A function called on first display,
-    user_pref: false,
-    reverse_user_pref: false // Reverse cookie behavior
-  };
-  const p = jQuery.extend(defaults, s);
-  if (!target) {
-    return this;
-  }
-  const set_cookie = p.hide ^ p.reverse_cookie;
-  if (p.cookie && jQuery.cookie(p.cookie)) {
-    p.hide = p.reverse_cookie;
-  }
-  let set_user_pref = p.hide ^ p.reverse_user_pref;
-  if (p.user_pref && p.unfolded_sections !== undefined && (p.user_pref in p.unfolded_sections)) {
-    p.hide = p.reverse_user_pref;
-  }
-  const toggle = function(i) {
-    const b = $(i).get(0);
-    if (p.hide) {
-      b.firstChild.data = p.img_on_txt;
-      b.setAttribute('value', p.img_on_txt);
-      b.setAttribute('aria-label', p.img_on_alt);
-      target.addClass('hide');
-    } else {
-      b.firstChild.data = p.img_off_txt;
-      b.setAttribute('value', p.img_off_txt);
-      b.setAttribute('aria-label', p.img_off_alt);
-      target.removeClass('hide');
-      if (p.fn) {
-        p.fn.apply(target);
-        p.fn = false;
-      }
-    }
-    if (p.cookie && set_cookie) {
-      if (p.hide ^ p.reverse_cookie) {
-        jQuery.cookie(p.cookie, '', {
-          expires: -1
-        });
-      } else {
-        jQuery.cookie(p.cookie, 1, {
-          expires: 30
-        });
-      }
-    }
-    p.hide = !p.hide;
-  };
-  return this.each(function() {
-    const b = document.createElement('button');
-    b.setAttribute('type', 'button');
-    b.className = 'details-cmd';
-    b.value = p.img_on_txt;
-    b.setAttribute('aria-label', p.img_on_alt);
-    const t = document.createTextNode(p.img_on_txt);
-    b.appendChild(t);
-
-    const ctarget = p.legend_click ? this : b;
-    $(ctarget).css('cursor', 'pointer');
-    if (p.legend_click) {
-      $(ctarget).find('label').css('cursor', 'pointer');
-    }
-    $(ctarget).click(function(e) {
-      if (p.user_pref && set_user_pref) {
-        jQuery.post('services.php', {
-          f: 'setSectionFold',
-          section: p.user_pref,
-          value: (p.hide ^ p.reverse_user_pref ? 1 : 0),
-          xd_check: dotclear.nonce
-        }, function() {});
-        jQuery.cookie(p.user_pref, '', {
-          expires: -1
-        });
-      }
-      toggle(b);
-      e.preventDefault();
-      return false;
-    });
-    toggle($(b).get(0));
-    $(this).prepend(b);
-  });
-};
-
-(function($) {
-  $.expandContent = function(opts) {
-    if (opts == undefined || opts.callback == undefined || !$.isFunction(opts.callback)) {
-      return;
-    }
-    if (opts.line != undefined) {
-      multipleExpander(opts.line, opts.lines, opts.callback);
-    }
-    opts.lines.each(function() {
-      singleExpander(this, opts.callback);
-    });
-  };
-  const singleExpander = function(line, callback) {
-    $(`<button type="button" class="details-cmd" aria-label="${dotclear.img_plus_alt}">${dotclear.img_plus_txt}</button>`).click(function(e) {
-      toggleArrow(this);
-      callback(line, '', e);
-      e.preventDefault();
-    }).prependTo($(line).children().get(0)); // first td
-  };
-  const multipleExpander = function(line, lines, callback) {
-    $(`<button type="button" class="details-cmd" aria-label="${dotclear.img_plus_alt}">${dotclear.img_plus_txt}</button>`).click(function(e) {
-      var action = toggleArrow(this);
-      lines.each(function() {
-        toggleArrow(this.firstChild.firstChild, action);
-        callback(this, action, e);
-      });
-      e.preventDefault();
-    }).prependTo($(line).children().get(0)); // first td
-  };
-  const toggleArrow = function(button, action) {
-    action = action || '';
-    if (action == '') {
-      if (button.getAttribute('aria-label') == dotclear.img_plus_alt) {
-        action = 'open';
-      } else {
-        action = 'close';
-      }
-    }
-    if (action == 'open') {
-      button.firstChild.data = dotclear.img_minus_txt;
-      button.setAttribute('value', dotclear.img_minus_txt);
-      button.setAttribute('aria-label', dotclear.img_minus_alt);
-    } else {
-      button.firstChild.data = dotclear.img_plus_txt;
-      button.setAttribute('value', dotclear.img_plus_txt);
-      button.setAttribute('aria-label', dotclear.img_plus_alt);
-    }
-    return action;
-  };
-})(jQuery);
+	this.click(
+	function (event) {
+		if (event.shiftKey) {
+			if (dotclear.lastclicked != '') {
+				var range;
+				var trparent = $(this).parents('tr');
+				if (trparent.nextAll('#'+dotclear.lastclicked).length != 0)
+					range = trparent.nextUntil('#'+dotclear.lastclicked);
+				else
+					range = trparent.prevUntil('#'+dotclear.lastclicked);
+				
+				range.find('input[type=checkbox]').setChecked(dotclear.lastclickedstatus);
+				this.checked = dotclear.lastclickedstatus;
+			}
+		} else {
+			dotclear.lastclicked = $(this).parents('tr')[0].id;
+			dotclear.lastclickedstatus = this.checked;
+		}
+		return true;
+	});
+}
+
+jQuery.fn.toggleWithLegend = function(target,s) {
+	var defaults = {
+		img_on_src: dotclear.img_plus_src,
+		img_on_alt: dotclear.img_plus_alt,
+		img_off_src: dotclear.img_minus_src,
+		img_off_alt: dotclear.img_minus_alt,
+		hide: true,
+		speed: 0,
+		legend_click: false,
+		fn: false, // A function called on first display,
+		cookie: false,
+		reverse_cookie: false // Reverse cookie behavior
+	};
+	var p = jQuery.extend(defaults,s);
+	
+	if (!target) { return this; }
+	
+	var set_cookie = p.hide ^ p.reverse_cookie;
+	if (p.cookie && jQuery.cookie(p.cookie)) {
+		p.hide = p.reverse_cookie;
+	}
+	
+	var toggle = function(i,speed) {
+		speed = speed || 0;
+		if (p.hide) {
+			$(i).get(0).src = p.img_on_src;
+			$(i).get(0).alt = p.img_on_alt;
+			target.hide(speed);
+		} else {
+			$(i).get(0).src = p.img_off_src;
+			$(i).get(0).alt = p.img_off_alt;
+			target.show(speed);
+			if (p.fn) {
+				p.fn.apply(target);
+				p.fn = false;
+			}
+		}
+		
+		if (p.cookie && set_cookie) {
+			if (p.hide ^ p.reverse_cookie) {
+				jQuery.cookie(p.cookie,'',{expires: -1});
+			} else {
+				jQuery.cookie(p.cookie,1,{expires: 30});
+			}
+		}
+		
+		p.hide = !p.hide;
+	};
+	
+	return this.each(function() {
+		var i = document.createElement('img');
+		i.src = p.img_off_src;
+		i.alt = p.img_off_alt;
+		var a = document.createElement('a');
+		a.href= '#';
+		$(a).append(i);
+		$(a).css({
+			border: 'none',
+			outline: 'none'
+		});
+		
+		var ctarget = p.legend_click ? this : a;
+		
+		$(ctarget).css('cursor','pointer');
+		$(ctarget).click(function() {
+			toggle(i,p.speed);
+			return false;
+		});
+		
+		
+		toggle($(i).get(0));
+		$(this).prepend(' ').prepend(a);
+	});
+};
+
 jQuery.fn.helpViewer = function() {
-  if (this.length < 1) {
-    return this;
-  }
-  let select = $();
-  const p = {
-    img_on_txt: dotclear.img_plus_txt,
-    img_on_alt: dotclear.img_plus_alt,
-    img_off_txt: dotclear.img_minus_txt,
-    img_off_alt: dotclear.img_minus_alt
-  };
-  const This = this;
-  const toggle = function() {
-    $('#content').toggleClass('with-help');
-    if (document.all) {
-      if ($('#content').hasClass('with-help')) {
-        select = $('#content select:visible').hide();
-      } else {
-        select.show();
-      }
-    }
-    $('p#help-button span a').text($('#content').hasClass('with-help') ? dotclear.msg.help_hide : dotclear.msg.help);
-    sizeBox();
-    return false;
-  };
-  const sizeBox = function() {
-    This.css('height', 'auto');
-    if ($('#wrapper').height() > This.height()) {
-      This.css('height', $('#wrapper').height() + 'px');
-    }
-  };
-  const textToggler = function(o) {
-    const b = $(`<button type="button" class="details-cmd" aria-label="${p.img_on_alt}">${p.img_on_txt}</button>`);
-    o.css('cursor', 'pointer');
-    let hide = true;
-    o.prepend(' ').prepend(b);
-    o.click(function() {
-      $(this).nextAll().each(function() {
-        if ($(this).is('h4')) {
-          return false;
-        }
-        $(this).toggle();
-        sizeBox();
-        return true;
-      });
-      hide = !hide;
-      const img = $(this).find('button.details-cmd');
-      if (!hide) {
-        img.html(p.img_off_txt);
-        img.attr('value', p.img_off_txt);
-        img.attr('aria-label', p.img_off_alt);
-      } else {
-        img.html(p.img_on_txt);
-        img.attr('value', p.img_on_txt);
-        img.attr('aria-label', p.img_on_alt);
-      }
-    });
-  };
-  this.addClass('help-box');
-  this.find('>hr').remove();
-  this.find('h4').each(function() {
-    textToggler($(this));
-  });
-  this.find('h4:first').nextAll('*:not(h4)').hide();
-  sizeBox();
-  const img = $(`<p id="help-button"><span><a href="">${dotclear.msg.help}</a></span></p>`);
-  img.click(function(e) {
-    e.preventDefault();
-    return toggle();
-  });
-  $('#content').append(img);
-  // listen for scroll
-  const peInPage = $('#help-button').offset().top;
-  $('#help-button').addClass('floatable');
-  const peInFloat = $('#help-button').offset().top - $(window).scrollTop();
-  $('#help-button').removeClass('floatable');
-  $(window).scroll(function() {
-    if ($(window).scrollTop() >= peInPage - peInFloat) {
-      $('#help-button').addClass('floatable');
-    } else {
-      $('#help-button').removeClass('floatable');
-    }
-  });
-  return this;
+	if (this.length < 1) {
+		return this;
+	}
+	
+	var p = {
+		img_on_src: dotclear.img_plus_src,
+		img_on_alt: dotclear.img_plus_alt,
+		img_off_src: dotclear.img_minus_src,
+		img_off_alt: dotclear.img_minus_alt
+	};
+	var This = this;
+	var toggle = function() {
+		$('#content').toggleClass('with-help');
+		if (document.all) {
+			if ($('#content').hasClass('with-help')) {
+				select = $('#content select:visible').hide();
+			} else {
+				select.show();
+			}
+		}
+		sizeBox();
+		return false;
+	};
+	
+	var sizeBox = function() {
+		This.css('height','auto');
+		if ($('body').height() > This.height()) {
+			This.css('height',$('body').height() + 'px');
+		}
+	};
+	
+	var textToggler = function(o) {
+		var i = $('<img src="'+p.img_on_src+'" alt="'+p.img_on_alt+'" />');
+		o.css('cursor','pointer');
+		var hide = true;
+		
+		o.prepend(' ').prepend(i);
+		o.click(function() {
+			$(this).nextAll().each(function() {
+				if ($(this).is('h3')) {
+					return false;
+				}
+				$(this).toggle();
+				sizeBox();
+				return true;
+			});
+			hide = !hide;
+			var img = $(this).find('img');
+			if (!hide) {
+				img.attr('src',p.img_off_src);
+			} else {
+				img.attr('src',p.img_on_src);
+			}
+		});
+	};
+	
+	this.addClass('help-box');
+	this.find('>hr').remove();
+	
+	this.find('h3').each(function() { textToggler($(this)); });
+	this.find('h3:first').nextAll('*:not(h3)').hide();
+	sizeBox();
+	
+	var img = $('<img src="images/help.png" alt="'+dotclear.msg.help+'" title="'+dotclear.msg.help+'" id="help-button" />');
+	var select = $();
+	img.click(function() { return toggle(); });
+	
+	$('#content').append(img);
+	
+	return this;
 };
 
 /* Dotclear common object
 -------------------------------------------------------- */
-const dotclear = {
-  msg: {},
-
-  enterKeyInForm: function(frm_id, ok_id, cancel_id) {
-    $(frm_id + ':not(' + cancel_id + ')').keyup(function(e) {
-      if ((e.key == 'Enter') && ($(ok_id).prop('disabled') !== true)) {
-        e.preventDefault();
-        e.stopPropagation();
-        $(ok_id).trigger('click');
-      }
-    });
-  },
-
-  condSubmit: function(chkboxes, target) {
-    const checkboxes = $(chkboxes),
-      submitButt = $(target);
-    if (checkboxes === undefined || submitButt === undefined) {
-      return;
-    }
-    // Set initial state
-    submitButt.attr('disabled', !checkboxes.is(':checked'));
-    if (!checkboxes.is(':checked')) {
-      submitButt.addClass('disabled');
-    } else {
-      submitButt.removeClass('disabled');
-    }
-    checkboxes.click(function() {
-      // Update target state
-      submitButt.attr('disabled', !checkboxes.is(':checked'));
-      if (!checkboxes.is(':checked')) {
-        submitButt.addClass('disabled');
-      } else {
-        submitButt.removeClass('disabled');
-      }
-    });
-  },
-
-  hideLockable: function() {
-    $('div.lockable').each(function() {
-      const current_lockable_div = this;
-      $(this).find('p.form-note').hide();
-      $(this).find('input').each(function() {
-        this.disabled = true;
-        $(this).width(`${$(this).width() - 14}px`);
-        const imgE = document.createElement('img');
-        imgE.src = 'images/locker.png';
-        imgE.style.position = 'absolute';
-        imgE.style.top = '1.8em';
-        imgE.style.left = `${$(this).width() + 14}px`;
-        imgE.alt = dotclear.msg.click_to_unlock;
-        $(imgE).css('cursor', 'pointer');
-        $(imgE).click(function() {
-          $(this).hide();
-          $(this).prev('input').each(function() {
-            this.disabled = false;
-            $(this).width(($(this).width() + 14) + 'px');
-          });
-          $(current_lockable_div).find('p.form-note').show();
-        });
-        $(this).parent().css('position', 'relative');
-        $(this).after(imgE);
-      });
-    });
-  },
-
-  checkboxesHelpers: function(e, target, c, s) {
-    $(e).append(document.createTextNode(dotclear.msg.to_select));
-    $(e).append(document.createTextNode(' '));
-    $(`<button type="button" class="checkbox-helper select-all">${dotclear.msg.select_all}</button>`).click(function() {
-      if (target !== undefined) {
-        target.check();
-      } else {
-        $(e).parents('form').find('input[type="checkbox"]').check();
-      }
-      if (c !== undefined && s !== undefined) {
-        dotclear.condSubmit(c, s);
-      }
-      return false;
-    }).appendTo($(e));
-    $(e).append(document.createTextNode(' '));
-    $(`<button type="button" class="checkbox-helper select-none">${dotclear.msg.no_selection}</button>`).click(function() {
-      if (target !== undefined) {
-        target.unCheck();
-      } else {
-        $(e).parents('form').find('input[type="checkbox"]').unCheck();
-      }
-      if (c !== undefined && s !== undefined) {
-        dotclear.condSubmit(c, s);
-      }
-      return false;
-    }).appendTo($(e));
-    $(e).append(document.createTextNode(' '));
-    $(`<button type="button" class="checkbox-helper select-reverse">${dotclear.msg.invert_sel}</button>`).click(function() {
-      if (target !== undefined) {
-        target.toggleCheck();
-      } else {
-        $(e).parents('form').find('input[type="checkbox"]').toggleCheck();
-      }
-      if (c !== undefined && s !== undefined) {
-        dotclear.condSubmit(c, s);
-      }
-      return false;
-    }).appendTo($(e));
-  },
-
-  postsActionsHelper: function() {
-    $('#form-entries').submit(function() {
-      const action = $(this).find('select[name="action"]').val();
-      if (action === undefined) {
-        return;
-      }
-      let checked = false;
-      $(this).find('input[name="entries[]"]').each(function() {
-        if (this.checked) {
-          checked = true;
-        }
-      });
-      if (!checked) {
-        return false;
-      }
-      if (action == 'delete') {
-        return window.confirm(dotclear.msg.confirm_delete_posts.replace('%s', $('input[name="entries[]"]:checked').size()));
-      }
-      return true;
-    });
-  },
-
-  commentsActionsHelper: function() {
-    $('#form-comments').submit(function() {
-      const action = $(this).find('select[name="action"]').val();
-      let checked = false;
-      $(this).find('input[name="comments[]"]').each(function() {
-        if (this.checked) {
-          checked = true;
-        }
-      });
-      if (!checked) {
-        return false;
-      }
-      if (action == 'delete') {
-        return window.confirm(dotclear.msg.confirm_delete_comments.replace('%s', $('input[name="comments[]"]:checked').size()));
-      }
-      return true;
-    });
-  },
-
-  outgoingLinks: function(target) {
-    $(target).filter(function() {
-      return ((this.hostname && this.hostname != location.hostname && !$(this).hasClass('modal') && !$(this).hasClass('modal-image')) || $(this).hasClass('outgoing'));
-    }).each(function() {
-      $(this).prop('title', `${$(this).prop('title')} (${dotclear.msg.new_window})`);
-      if (!$(this).hasClass('outgoing')) {
-        $(this).append('&nbsp;<img class="outgoing-js" src="images/outgoing-link.svg" alt=""/>');
-      }
-    }).click(function(e) {
-      e.preventDefault();
-      window.open($(this).attr('href'));
-    });
-  },
-
-  /**
-   * Add headers on each cells (responsive tables)
-   *
-   * @param      DOM elt   table         The table
-   * @param      string    selector      The selector
-   * @param      number    [offset=0]    The offset = number of firsts columns to ignore
-   * @param      boolean   [thead=false] True if titles are in thead rather than in the first tr of the body
-   */
-  responsiveCellHeaders: function(table, selector, offset = 0, thead = false) {
-    try {
-      let THarray = [];
-      const ths = table.getElementsByTagName("th");
-      for (let i = 0; i < ths.length; i++) {
-        for (let colspan = ths[i].colSpan; colspan > 0; colspan--) {
-          THarray.push(ths[i].innerText.replace('►', ''));
-        }
-      }
-      let styleElm = document.createElement("style");
-      let styleSheet;
-      document.head.appendChild(styleElm);
-      styleSheet = styleElm.sheet;
-      for (let i = offset; i < THarray.length; i++) {
-        styleSheet.insertRule(
-          selector + " td:nth-child(" + (i + 1) + ')::before {content:"' + THarray[i] + ' ";}',
-          styleSheet.cssRules.length
-        );
-      }
-      table.className += (table.className !== '' ? ' ' : '') + 'rch' + (thead ? ' rch-thead' : '');
-    } catch (e) {
-      console.log("responsiveCellHeaders(): " + e);
-    }
-  },
-
-  badge: function($elt, options = null) {
-    // Cope with selector given as string or DOM element rather than a jQuery object
-    if (typeof $elt === 'string' || $elt instanceof Element) {
-      $elt = $($elt);
-    }
-
-    // Return if elt does not exist
-    if (!$elt.length) return;
-
-    // Cope with options
-    const opt = $.extend({
-      /* sibling: define if the given element is a sibling of the badge or it's parent
-       *  true: use $elt.after() to add badge
-       *  false: use $elt.parent().append() to add badge (default)
-       */
-      sibling: false,
-      /* id: badge unique class
-       *  this class will be used to delete all corresponding badge (used for removing and updating)
-       */
-      id: 'default',
-      /* remove: will remove the badge if set to true */
-      remove: false,
-      /* value: badge value */
-      value: null,
-      /* inline: if set to true, the badge is an inline element (useful for menu item) rather than a block */
-      inline: false,
-      /* icon: if set to true, the badge is attached to a dashboard icon (needed for correct positionning) */
-      icon: false,
-      /* type: Override default background (which may vary)
-       *  by default badge background are soft grey for dashboard icons (see opt.icon) and bright red for all other elements
-       *  possible values:
-       *    'std':  bright red
-       *    'info': blue
-       *    'soft': soft grey
-       */
-      type: '',
-      /* left: display badge on the left rather than on the right (unused for inline badge) */
-      left: false,
-      /* noborder: do not display the badge border */
-      noborder: false,
-      /* small: use a smaller font-size */
-      small: false,
-      /* classes: additionnal badge classes */
-      classes: ''
-    }, options);
-
-    // Set some constants
-    const classid = `span.badge.badge-${opt.id}`; // Pseudo unique class
-
-    // Set badgeable class to elt parent's (if sibling) or elt itself, if it is necessary
-    const $parent = (opt.sibling ? $elt.parent() : $elt);
-    if (!opt.inline && !opt.remove && !$parent.hasClass('badgeable')) {
-      $parent.addClass('badgeable');
-    }
-
-    // Remove existing badge if exists
-    const $badge = (opt.sibling ? $parent.children(classid) : $elt.children(classid));
-    if ($badge.length) {
-      $badge.remove();
-    }
-
-    // Add the new badge if any
-    if (!opt.remove && opt.value !== null) {
-      // Compose badge classes
-      const cls = `badge badge-${opt.id} \
-${opt.inline ? ' badge-inline' : ' badge-block'}\
-${opt.icon ? ' badge-icon' : ''}\
-${opt.type !== '' ? ` badge-${opt.type}` : ''}\
-${opt.left ? ' badge-left' : ''}\
-${opt.noborder ? ' badge-noborder' : ''}\
-${opt.small ? ' badge-small' : ''}\
-${opt.classes !== '' ? ` ${opt.classes}` : ''}`;
-      // Compose badge
-      const xml = `<span class="${cls}" aria-hidden="true">${opt.value}</span>`;
-      if (opt.sibling) {
-        // Add badge after it's sibling
-        $elt.after(xml);
-      } else {
-        // Append badge to the elt
-        $elt.append(xml);
-      }
-    }
-  }
+var dotclear = {
+	msg: {},
+	
+	hideLockable: function() {
+		$('div.lockable').each(function() {
+			var current_lockable_div = this;
+			$(this).find('p.form-note').hide();
+			$(this).find('input').each(function() {
+				this.disabled = true;
+				$(this).width(($(this).width()-14) + 'px');
+				
+				var imgE = document.createElement('img');
+				imgE.src = 'images/locker.png';
+				imgE.style.position = 'absolute';
+				imgE.style.top = '1.7em';
+				imgE.style.left = ($(this).width()+4)+'px';
+				$(imgE).css('cursor','pointer');
+				
+				$(imgE).click(function() {
+					$(this).hide();
+					$(this).prev('input').each(function() {
+						this.disabled = false;
+						$(this).width(($(this).width()+14) + 'px');
+					});
+					$(current_lockable_div).find('p.form-note').show();
+				});
+				
+				$(this).parent().css('position','relative');
+				$(this).after(imgE);
+			});
+		});
+	},
+	
+	checkboxesHelpers: function(e) {
+		var a = document.createElement('a');
+		a.href='#';
+		$(a).append(document.createTextNode(dotclear.msg.select_all));
+		a.onclick = function() {
+			$(this).parents('form').find('input[type="checkbox"]').check();
+			return false;
+		};
+		$(e).append(a);
+		
+		$(e).append(document.createTextNode(' - '));
+		
+		a = document.createElement('a');
+		a.href='#';
+		$(a).append(document.createTextNode(dotclear.msg.no_selection));
+		a.onclick = function() {
+			$(this).parents('form').find('input[type="checkbox"]').unCheck();
+			return false;
+		};
+		$(e).append(a);
+		
+		$(e).append(document.createTextNode(' - '));
+		
+		a = document.createElement('a');
+		a.href='#';
+		$(a).append(document.createTextNode(dotclear.msg.invert_sel));
+		a.onclick = function() {
+			$(this).parents('form').find('input[type="checkbox"]').toggleCheck();
+			return false;
+		};
+		$(e).append(a);
+	},
+	
+	postsActionsHelper: function() {
+		$('#form-entries').submit(function() {
+			var action = $(this).find('select[name="action"]').val();
+			var checked = false;
+			
+			$(this).find('input[name="entries[]"]').each(function() {
+				if (this.checked) {
+					checked = true;
+				}
+			});
+			
+			if (!checked) { return false; }
+			
+			if (action == 'delete') {
+				return window.confirm(dotclear.msg.confirm_delete_posts.replace('%s',$('input[name="entries[]"]:checked').size()));
+			}
+			
+			return true;
+		});
+	},
+	
+	commentsActionsHelper: function() {
+		$('#form-comments').submit(function() {
+			var action = $(this).find('select[name="action"]').val();
+			var checked = false;
+			
+			$(this).find('input[name="comments[]"]').each(function() {
+				if (this.checked) {
+					checked = true;
+				}
+			});
+			
+			if (!checked) { return false; }
+			
+			if (action == 'delete') {
+				return window.confirm(dotclear.msg.confirm_delete_comments.replace('%s',$('input[name="comments[]"]:checked').size()));
+			}
+			
+			return true;
+		});
+	}
 };
 
@@ -583,151 +319,41 @@
 -------------------------------------------------------- */
 $(function() {
-  // Store preinit DATA in dotclear object
-  dotclear.data = dotclear_init;
-  // Get other DATA
-  Object.assign(dotclear, getData('dotclear'));
-  Object.assign(dotclear.msg, getData('dotclear_msg'));
-
-  // remove class no-js from html tag; cf style/default.css for examples
-  $('body').removeClass('no-js').addClass('with-js');
-  $('body').contents().each(function() {
-    if (this.nodeType == 8) {
-      let data = this.data;
-      data = data.replace(/ /g, '&nbsp;').replace(/\n/g, '<br/>');
-      $(`<span class="tooltip" aria-hidden="true">${$('#footer a').prop('title')}${data}</span>`).appendTo('#footer a');
-    }
-  });
-  // manage outgoing links
-  dotclear.outgoingLinks('a');
-  // Popups: dealing with Escape key fired
-  $('#dotclear-admin.popup').keyup(function(e) {
-    if (e.key == 'Escape') {
-      e.preventDefault();
-      window.close();
-      return false;
-    }
-  });
-  // Blog switcher
-  $('#switchblog').change(function() {
-    this.form.submit();
-  });
-  const menu_settings = {
-    img_on_src: dotclear.img_menu_off,
-    img_off_src: dotclear.img_menu_on,
-    legend_click: true,
-    speed: 100
-  };
-  $('#blog-menu h3:first').toggleWithLegend($('#blog-menu ul:first'), $.extend({
-    user_pref: 'dc_blog_menu'
-  }, menu_settings));
-  $('#system-menu h3:first').toggleWithLegend($('#system-menu ul:first'), $.extend({
-    user_pref: 'dc_system_menu'
-  }, menu_settings));
-  $('#plugins-menu h3:first').toggleWithLegend($('#plugins-menu ul:first'), $.extend({
-    user_pref: 'dc_plugins_menu'
-  }, menu_settings));
-  $('#favorites-menu h3:first').toggleWithLegend($('#favorites-menu ul:first'), $.extend({
-    user_pref: 'dc_favorites_menu',
-    hide: false,
-    reverse_user_pref: true
-  }, menu_settings));
-  $('#help').helpViewer();
-  // Notices
-  $('p.success,p.warning,p.error,div.error').each(function() {
-    $(this).addClass('close-notice-parent');
-    $(this).append(`<button class="close-notice" type="button"><img src="images/close.png" alt="${dotclear.msg.close_notice}" /></button>`);
-  });
-  $('button.close-notice').click(function(e) {
-    e.preventDefault();
-    $(this).parent().hide();
-  });
-  // Password
-  $('form:has(input[type=password][name=your_pwd])').submit(function() {
-    const e = this.elements.your_pwd;
-    if (e.value == '') {
-      $(e).addClass('missing').focusout(function() {
-        $(this).removeClass('missing');
-      });
-      e.focus();
-      return false;
-    }
-    return true;
-  });
-  // Cope with ellipsis'ed cells
-  $('table .maximal').each(function() {
-    if (this.offsetWidth < this.scrollWidth) {
-      if (this.title == '') {
-        this.title = this.innerText;
-        $(this).addClass('ellipsis');
-      }
-    }
-  });
-  $('table .maximal.ellipsis a').each(function() {
-    if (this.title == '') {
-      this.title = this.innerText;
-    }
-  });
-  // Advanced users
-  if (dotclear.data.hideMoreInfo) {
-    $('.more-info,.form-note:not(.warn,.warning,.info)').addClass('no-more-info');
-  }
-  // Ajax loader activity indicator
-  if (dotclear.data.showAjaxLoader) {
-    $(document).ajaxStart(function() {
-      $('body').addClass('ajax-loader');
-      $('div.ajax-loader').show();
-    });
-    $(document).ajaxStop(function() {
-      $('body').removeClass('ajax-loader');
-      $('div.ajax-loader').hide();
-    });
-  }
-  // Main menu collapser
-  const objMain = $('#wrapper');
-
-  function showSidebar() {
-    // Show sidebar
-    objMain.removeClass('hide-mm');
-    $.cookie('sidebar-pref', null, {
-      expires: 30
-    });
-  }
-
-  function hideSidebar() {
-    // Hide sidebar
-    objMain.addClass('hide-mm');
-    $.cookie('sidebar-pref', 'hide-mm', {
-      expires: 30
-    });
-  }
-  // Sidebar separator
-  $('#collapser').click(function(e) {
-    e.preventDefault();
-    if (objMain.hasClass('hide-mm')) {
-      showSidebar();
-      $('#main-menu input#qx').focus();
-    } else {
-      hideSidebar();
-      $('#content a.go_home').focus();
-    }
-  });
-  if ($.cookie('sidebar-pref') == 'hide-mm') {
-    objMain.addClass('hide-mm');
-  } else {
-    objMain.removeClass('hide-mm');
-  }
-  // totop scroll
-  $(window).scroll(function() {
-    if ($(this).scrollTop() != 0) {
-      $('#gototop').fadeIn();
-    } else {
-      $('#gototop').fadeOut();
-    }
-  });
-  $('#gototop').click(function(e) {
-    $('body,html').animate({
-      scrollTop: 0
-    }, 800);
-    e.preventDefault();
-  });
+	// Blog switcher
+	$('#switchblog').change(function() {
+		this.form.submit();
+	});
+	
+	var menu_settings = {
+		img_on_src: dotclear.img_menu_off,
+		img_off_src: dotclear.img_menu_on,
+		legend_click: true,
+		speed: 100
+	}
+	$('#blog-menu h3:first').toggleWithLegend($('#blog-menu ul:first'),
+		$.extend({cookie:'dc_blog_menu',hide:false,reverse_cookie:true},menu_settings)
+	);
+	$('#system-menu h3:first').toggleWithLegend($('#system-menu ul:first'),
+		$.extend({cookie:'dc_system_menu'},menu_settings)
+	);
+	$('#plugins-menu h3:first').toggleWithLegend($('#plugins-menu ul:first'),
+		$.extend({cookie:'dc_plugins_menu'},menu_settings)
+	);
+	
+	$('#help').helpViewer();
+	
+	$('.message').backgroundFade({sColor:'#cccccc',eColor:'#666666',steps:20});
+	$('.error').backgroundFade({sColor:'#f5e5e5',eColor:'#e5bfbf',steps:20});
+	
+	$('form:has(input[type=password][name=your_pwd])').submit(function() {
+		var e = this.elements['your_pwd'];
+		if (e.value == '') {
+			e.focus();
+			$(e).backgroundFade({sColor:'#ffffff',eColor:'#ff9999',steps:50},function() {
+				$(this).backgroundFade({sColor:'#ff9999',eColor:'#ffffff'});
+			});
+			return false;
+		}
+		return true;
+	});
 });
+
Index: admin/js/confirm-close.js
===================================================================
--- admin/js/confirm-close.js	(revision 3929)
+++ admin/js/confirm-close.js	(revision 0)
@@ -1,164 +1,122 @@
-/*global chainHandler, getData */
-'use strict';
-
 function confirmClose() {
-  if (arguments.length > 0) {
-    for (let i = 0; i < arguments.length; i++) {
-      this.forms_id.push(arguments[i]);
-    }
-  }
-}
+	
+	if (arguments.length > 0) {
+		for (var i=0; i<arguments.length; i++) {
+			this.forms_id.push(arguments[i]);
+		}
+	}
+};
 
 confirmClose.prototype = {
-  prompt: 'You have unsaved changes.',
-  forms_id: [],
-  forms: [],
-  formSubmit: false,
-
-  getCurrentForms: function() {
-    // Store current form's element's values
-
-    const formsInPage = this.getForms();
-    const This = this;
-    this.forms = [];
-    for (let i = 0; i < formsInPage.length; i++) {
-      const f = formsInPage[i];
-      let tmpForm = [];
-      for (let j = 0; j < f.elements.length; j++) {
-        const e = this.getFormElementValue(f[j]);
-        if (e != undefined) {
-          tmpForm.push(e);
-        }
-      }
-      this.forms.push(tmpForm);
-
-      chainHandler(f, 'onsubmit', function() {
-        This.formSubmit = true;
-      });
-    }
-  },
-
-  compareForms: function() {
-    // Compare current form's element's values to their original values
-    // Return false if any difference, else true
-
-    if (this.forms.length == 0) {
-      return true;
-    }
-
-    const formsInPage = this.getForms();
-    for (let i = 0; i < formsInPage.length; i++) {
-      const f = formsInPage[i];
-      var tmpForm = [];
-      for (let j = 0; j < f.elements.length; j++) {
-        const e = this.getFormElementValue(f[j]);
-        if (e != undefined) {
-          tmpForm.push(e);
-        }
-      }
-      for (let j = 0; j < this.forms[i].length; j++) {
-        if (this.forms[i][j] != tmpForm[j]) {
-          return false;
-        }
-      }
-    }
-
-    return true;
-  },
-
-  getForms: function() {
-    // Get current list of forms as HTMLCollection(s)
-
-    if (!document.getElementsByTagName || !document.getElementById) {
-      return [];
-    }
-
-    if (this.forms_id.length > 0) {
-      let res = [];
-      for (let i = 0; i < this.forms_id.length; i++) {
-        const f = document.getElementById(this.forms_id[i]);
-        if (f != undefined) {
-          res.push(f);
-        }
-      }
-      return res;
-    } else {
-      return document.getElementsByTagName('form');
-    }
-
-    return [];
-  },
-
-  getFormElementValue: function(e) {
-    // Return current value of an form element
-
-    if (e == undefined) {
-      // Unknown object
-      return undefined;
-    }
-    if (e.type != undefined && e.type == 'button') {
-      // Ignore button element
-      return undefined;
-    }
-    if (e.classList.contains('meta-helper') || e.classList.contains('checkbox-helper')) {
-      // Ignore some application helper element
-      return undefined;
-    }
-    if (e.type != undefined && e.type == 'radio') {
-      // Return actual radio button value if selected, else null
-      return this.getFormRadioValue(e);
-    } else if (e.type != undefined && e.type == 'checkbox') {
-      // Return actual checkbox button value if checked, else null
-      return this.getFormCheckValue(e);
-    } else if (e.type != undefined && e.type == 'password') {
-      // Ignore password element
-      return null;
-    } else if (e.value != undefined) {
-      // Return element value if not undefined
-      return e.value;
-    } else {
-      // Every other case, return null
-      return null;
-    }
-  },
-
-  getFormCheckValue: function(e) {
-    if (e.checked) {
-      return e.value;
-    }
-    return null;
-  },
-
-  getFormRadioValue: function(e) {
-    for (let i = 0; i < e.length; i++) {
-      if (e[i].checked) {
-        return e[i].value;
-      } else {
-        return null;
-      }
-    }
-    return null;
-  }
+	prompt: 'You have unsaved changes.',
+	forms_id: new Array(),
+	forms: new Array(),
+	formSubmit: false,
+	
+	getCurrentForms: function() {
+		var formsInPage = this.getForms();
+		var f;
+		var This = this;
+		for (var i=0; i<formsInPage.length; i++) {
+			f = formsInPage[i];
+			var tmpForm = new Array();
+			for (var j=0; j<f.elements.length; j++) {
+				tmpForm.push(this.getFormElementValue(f[j]));
+			}
+			this.forms.push(tmpForm);
+			
+			chainHandler(f,'onsubmit',function() {
+				This.formSubmit = true;
+			});
+		}
+	},
+	
+	compareForms: function() {
+		if (this.forms.length == 0) {
+			return true;
+		}
+		
+		var formsInPage = this.getForms();
+		var f;
+		for (var i=0; i<formsInPage.length; i++) {
+			f = formsInPage[i];
+			for (var j=0; j<f.elements.length; j++) {
+				if (this.forms[i][j] != this.getFormElementValue(f[j])) {
+					return false;
+				}
+			}
+		}
+		
+		return true;
+	},
+	
+	getForms: function() {
+		if (!document.getElementsByTagName || !document.getElementById) {
+			return new Array();
+		}
+		
+		if (this.forms_id.length > 0) {
+			var res = new Array();
+			var f;
+			for (var i=0; i<this.forms_id.length; i++) {
+				f = document.getElementById(this.forms_id[i]);
+				if (f != undefined) {
+					res.push(f);
+				}
+			}
+			return res;
+		} else {
+			return document.getElementsByTagName('form');
+		}
+		
+		return new Array();
+	},
+	
+	getFormElementValue: function(e) {
+		if (e.type != undefined && e.type == 'radio') {
+			return this.getFormRadioValue(e);
+		} else if (e.type != undefined && e.type == 'checkbox') {
+			return this.getFormCheckValue(e);
+		} else if (e.value != undefined) {
+			return e.value;
+		} else {
+			return null;
+		}
+	},
+	
+	getFormCheckValue: function(e) {
+		if (e.checked) {
+			return e.value;
+		}
+		return null;
+	},
+	
+	getFormRadioValue: function(e) {
+		for (var i=0; i <e.length; i++) {
+			if (e[i].checked) {
+				return e[i].value;
+			} else {
+				return null;
+			}
+		}
+		return null;
+	}
 };
 
-let confirmClosePage = new confirmClose();
+var confirmClosePage = new confirmClose();
 
-chainHandler(window, 'onload', function() {
-  confirmClosePage.getCurrentForms();
+chainHandler(window,'onload',function() {
+	confirmClosePage.getCurrentForms();
 });
 
-chainHandler(window, 'onbeforeunload', function(event_) {
-  if (event_ == undefined && window.event) {
-    event_ = window.event;
-  }
-
-  if (!confirmClosePage.formSubmit && !confirmClosePage.compareForms()) {
-    event_.returnValue = confirmClosePage.prompt;
-    return confirmClosePage.prompt;
-  }
-  return false;
+chainHandler(window,'onbeforeunload',function(event_) {
+	if (event_ == undefined && window.event) {
+		event_ = window.event;
+	}
+	
+	if (!confirmClosePage.formSubmit && !confirmClosePage.compareForms()) {
+		event_.returnValue = confirmClosePage.prompt;
+		return confirmClosePage.prompt;
+	}
+	return false;
 });
-
-const confirm_close = getData('confirm_close');
-confirmClose.prototype.prompt = confirm_close.prompt;
-confirmClosePage = new confirmClose(...confirm_close.forms);
Index: admin/js/date-picker.js
===================================================================
--- admin/js/date-picker.js	(revision 3930)
+++ admin/js/date-picker.js	(revision 0)
@@ -1,521 +1,452 @@
-/*global getData */
-/*exported datePicker */
-'use strict';
-
-function datePicker(target) {
-  if (!document.getElementById) {
-    return;
-  }
-
-  if (!target || target.nodeName.toLowerCase() != 'input') {
-    return;
-  }
-
-  this.target = target;
-  this.oTable = document.createElement('table');
-  this.oBody = document.createElement('tbody');
-  this.oDates = [];
-  this.oMonth = document.createElement('span');
-  this.oYear = document.createElement('span');
-  this.oHour = document.createElement('input');
-  this.oMinute = document.createElement('input');
-  this.oTable.id = 'dc_datepicker_' + target.id;
-  this.oTable.className = 'date-picker';
-
-  let cur = 1;
-  let oRow;
-  let oHeading;
-  let oSpan;
-
-  // Set title
-  oRow = document.createElement('tr');
-
-  // Month block
-  oHeading = document.createElement('th');
-  oHeading.colSpan = 4;
-  oHeading.className = 'date-picker-month';
-
-  let nav = document.createElement('span');
-  nav.appendChild(document.createTextNode(String.fromCharCode(171)));
-  nav.fn = this.changeMonth;
-  nav.obj = this;
-  nav.onclick = function() {
-    this.fn.call(this.obj, -1);
-  };
-  nav.className = 'date-picker-control';
-  oHeading.appendChild(nav);
-
-  oHeading.appendChild(document.createTextNode(String.fromCharCode(160)));
-
-  nav = document.createElement('span');
-  nav.appendChild(document.createTextNode(String.fromCharCode(187)));
-  nav.fn = this.changeMonth;
-  nav.obj = this;
-  nav.onclick = function() {
-    this.fn.call(this.obj, +1);
-  };
-  nav.className = 'date-picker-control';
-  oHeading.appendChild(nav);
-
-  oHeading.appendChild(document.createTextNode(String.fromCharCode(160)));
-
-  oHeading.appendChild(this.oMonth);
-
-  oRow.appendChild(oHeading);
-
-  // Year block
-  oHeading = document.createElement('th');
-  oHeading.colSpan = 3;
-  oHeading.className = 'date-picker-year';
-
-  oHeading.appendChild(this.oYear);
-
-  oHeading.appendChild(document.createTextNode(String.fromCharCode(160)));
-
-  nav = document.createElement('span');
-  nav.appendChild(document.createTextNode(String.fromCharCode(171)));
-  nav.fn = this.changeYear;
-  nav.obj = this;
-  nav.onclick = function() {
-    this.fn.call(this.obj, -1);
-  };
-  nav.className = 'date-picker-control';
-  oHeading.appendChild(nav);
-
-  oHeading.appendChild(document.createTextNode(String.fromCharCode(160)));
-
-  nav = document.createElement('span');
-  nav.appendChild(document.createTextNode(String.fromCharCode(187)));
-  nav.fn = this.changeYear;
-  nav.obj = this;
-  nav.onclick = function() {
-    this.fn.call(this.obj, +1);
-  };
-  nav.className = 'date-picker-control';
-  oHeading.appendChild(nav);
-
-  oRow.appendChild(oHeading);
-
-  this.oBody.appendChild(oRow);
-
-  // Create legend
-  oRow = document.createElement('tr');
-  for (let i = 0; i < this.days.length; i++) {
-    const cday = this.days[i].substring(0, 1).toUpperCase();
-    oHeading = document.createElement('th');
-    oHeading.appendChild(document.createTextNode(cday));
-    oHeading.setAttribute('title', this.days[i]);
-    oRow.appendChild(oHeading);
-  }
-  this.oBody.appendChild(oRow);
-
-  // Create 6 rows of 7 cols for days
-  for (let i = 0; i < 6; i++) {
-    oRow = document.createElement('tr');
-
-    for (let j = 0; j < 7; j++) {
-      this.oDates[cur] = document.createElement('td');
-      this.oDates[cur].appendChild(document.createTextNode(
-        String.fromCharCode(160)));
-      oRow.appendChild(this.oDates[cur]);
-      cur++;
-    }
-
-    this.oBody.appendChild(oRow);
-  }
-
-  // Time controls
-  oRow = document.createElement('tr');
-
-  oHeading = document.createElement('th');
-  oHeading.className = 'date-picker-control';
-  oHeading.appendChild(document.createTextNode('!'));
-  oHeading.setAttribute('title', this.now_msg);
-  oHeading.fn = this.sendNow;
-  oHeading.obj = this;
-  oHeading.onclick = function() {
-    this.fn.call(this.obj);
-  };
-
-  oRow.appendChild(oHeading);
-
-  oHeading = document.createElement('th');
-  oHeading.colSpan = 5;
-
-  oSpan = document.createElement('span');
-  oSpan.className = 'date-picker-control';
-  oSpan.appendChild(document.createTextNode('-'));
-  oSpan.fn = this.changeHour;
-  oSpan.obj = this;
-  oSpan.onclick = function() {
-    this.fn.call(this.obj, -1);
-  };
-  oHeading.appendChild(oSpan);
-  oHeading.appendChild(document.createTextNode(String.fromCharCode(160)));
-  oSpan = document.createElement('span');
-  oSpan.className = 'date-picker-control';
-  oSpan.appendChild(document.createTextNode('+'));
-  oSpan.fn = this.changeHour;
-  oSpan.obj = this;
-  oSpan.onclick = function() {
-    this.fn.call(this.obj, +1);
-  };
-  oHeading.appendChild(oSpan);
-  oHeading.appendChild(document.createTextNode(String.fromCharCode(160)));
-
-  this.oHour.size = 2;
-  oHeading.appendChild(this.oHour);
-
-  oHeading.appendChild(document.createTextNode(' : '));
-
-  this.oMinute.size = 2;
-  oHeading.appendChild(this.oMinute);
-
-  oHeading.appendChild(document.createTextNode(String.fromCharCode(160)));
-  oSpan = document.createElement('span');
-  oSpan.className = 'date-picker-control';
-  oSpan.appendChild(document.createTextNode('-'));
-  oSpan.fn = this.changeMinute;
-  oSpan.obj = this;
-  oSpan.onclick = function() {
-    this.fn.call(this.obj, -1);
-  };
-  oHeading.appendChild(oSpan);
-  oHeading.appendChild(document.createTextNode(String.fromCharCode(160)));
-  oSpan = document.createElement('span');
-  oSpan.className = 'date-picker-control';
-  oSpan.appendChild(document.createTextNode('+'));
-  oSpan.fn = this.changeMinute;
-  oSpan.obj = this;
-  oSpan.onclick = function() {
-    this.fn.call(this.obj, +1);
-  };
-
-  oHeading.appendChild(oSpan);
-
-  oRow.appendChild(oHeading);
-
-  // Close control
-  oHeading = document.createElement('th');
-  oHeading.className = 'date-picker-control';
-  oHeading.appendChild(document.createTextNode('x'));
-  oHeading.setAttribute('title', this.close_msg);
-  oHeading.fn = this.close;
-  oHeading.obj = this;
-  oHeading.onclick = function() {
-    this.fn.call(this.obj);
-  };
-
-  oRow.appendChild(oHeading);
-
-  this.oBody.appendChild(oRow);
-}
+function datePicker(target)
+{
+	if (!document.getElementById) { return; }
+	
+	if (!target || target.nodeName.toLowerCase() != 'input') {
+		return;
+	}
+	
+	this.target = target;
+	this.oTable = document.createElement('table');
+	this.oBody = document.createElement('tbody');
+	this.oDates = new Array();
+	this.oMonth = document.createElement('span');
+	this.oYear = document.createElement('span');
+	this.oHour = document.createElement('input');
+	this.oMinute = document.createElement('input');
+	this.oTable.id = 'dc_datepicker_'+target.id;
+	this.oTable.className = 'date-picker';
+	
+	var cur = 1;
+	var oRow, oHeading, oSpan;
+	
+	// Set title
+	oRow = document.createElement('tr');
+	
+	// Month block
+	oHeading = document.createElement('th');
+	oHeading.colSpan = 4;
+	oHeading.className = 'date-picker-month';
+	
+	var nav = document.createElement('span');
+	nav.appendChild(document.createTextNode(String.fromCharCode(171)));
+	nav.fn = this.changeMonth;
+	nav.obj = this;
+	nav.onclick = function() { this.fn.call(this.obj,-1); };
+	nav.className = 'date-picker-control';
+	oHeading.appendChild(nav);
+	
+	oHeading.appendChild(document.createTextNode(String.fromCharCode(160)));
+	
+	nav = document.createElement('span');
+	nav.appendChild(document.createTextNode(String.fromCharCode(187)));
+	nav.fn = this.changeMonth;
+	nav.obj = this;
+	nav.onclick = function() { this.fn.call(this.obj,+1); };
+	nav.className = 'date-picker-control';
+	oHeading.appendChild(nav);
+	
+	oHeading.appendChild(document.createTextNode(String.fromCharCode(160)));
+	
+	oHeading.appendChild(this.oMonth);
+	
+	oRow.appendChild(oHeading);
+	
+	// Year block
+	oHeading = document.createElement('th');
+	oHeading.colSpan = 3;
+	oHeading.className = 'date-picker-year';
+	
+	oHeading.appendChild(this.oYear);
+	
+	oHeading.appendChild(document.createTextNode(String.fromCharCode(160)));
+	
+	nav = document.createElement('span');
+	nav.appendChild(document.createTextNode(String.fromCharCode(171)));
+	nav.fn = this.changeYear;
+	nav.obj = this;
+	nav.onclick = function() { this.fn.call(this.obj,-1); };
+	nav.className = 'date-picker-control';
+	oHeading.appendChild(nav);
+	
+	oHeading.appendChild(document.createTextNode(String.fromCharCode(160)));
+	
+	nav = document.createElement('span');
+	nav.appendChild(document.createTextNode(String.fromCharCode(187)));
+	nav.fn = this.changeYear;
+	nav.obj = this;
+	nav.onclick = function() { this.fn.call(this.obj,+1); };
+	nav.className = 'date-picker-control';
+	oHeading.appendChild(nav);
+	
+	oRow.appendChild(oHeading);
+	
+	this.oBody.appendChild(oRow);
+	
+	// Create legend
+	oRow = document.createElement('tr');
+	var cday;
+	for (i=0; i<this.days.length; i++) {
+		cday = this.days[i].substring(0,1).toUpperCase();
+		oHeading = document.createElement('th');
+		oHeading.appendChild(document.createTextNode(cday));
+		oHeading.setAttribute('title',this.days[i]);
+		oRow.appendChild(oHeading);
+	}
+	this.oBody.appendChild(oRow);
+	
+	// Create 6 rows of 7 cols for days
+	for (var i=0; i<6; i++) {
+		oRow = document.createElement('tr');
+		
+		for (var j=0; j<7; j++) {
+			this.oDates[cur] = document.createElement('td');
+			this.oDates[cur].appendChild(document.createTextNode(
+				String.fromCharCode(160)));
+			oRow.appendChild(this.oDates[cur]);
+			cur++;
+		}
+		
+		this.oBody.appendChild(oRow);
+	}
+	
+	// Time controls
+	oRow = document.createElement('tr');
+	
+	oHeading = document.createElement('th');
+	oHeading.className = 'date-picker-control';
+	oHeading.appendChild(document.createTextNode('!'));
+	oHeading.setAttribute('title',this.now_msg);
+	oHeading.fn = this.sendNow;
+	oHeading.obj = this;
+	oHeading.onclick = function() { this.fn.call(this.obj); };
+	
+	oRow.appendChild(oHeading);
+	
+	oHeading = document.createElement('th');
+	oHeading.colSpan = 5;
+	
+	oSpan = document.createElement('span');
+	oSpan.className = 'date-picker-control';
+	oSpan.appendChild(document.createTextNode('-'));
+	oSpan.fn = this.changeHour;
+	oSpan.obj = this;
+	oSpan.onclick = function() { this.fn.call(this.obj,-1); };
+	oHeading.appendChild(oSpan);
+	oHeading.appendChild(document.createTextNode(String.fromCharCode(160)));
+	oSpan = document.createElement('span');
+	oSpan.className = 'date-picker-control';
+	oSpan.appendChild(document.createTextNode('+'));
+	oSpan.fn = this.changeHour;
+	oSpan.obj = this;
+	oSpan.onclick = function() { this.fn.call(this.obj,+1); };
+	oHeading.appendChild(oSpan);
+	oHeading.appendChild(document.createTextNode(String.fromCharCode(160)));
+	
+	this.oHour.size = 3;
+	oHeading.appendChild(this.oHour);
+	
+	oHeading.appendChild(document.createTextNode(' : '));
+	
+	this.oMinute.size = 3;
+	oHeading.appendChild(this.oMinute);
+	
+	oHeading.appendChild(document.createTextNode(String.fromCharCode(160)));
+	oSpan = document.createElement('span');
+	oSpan.className = 'date-picker-control';
+	oSpan.appendChild(document.createTextNode('-'));
+	oSpan.fn = this.changeMinute;
+	oSpan.obj = this;
+	oSpan.onclick = function() { this.fn.call(this.obj,-1); };
+	oHeading.appendChild(oSpan);
+	oHeading.appendChild(document.createTextNode(String.fromCharCode(160)));
+	oSpan = document.createElement('span');
+	oSpan.className = 'date-picker-control';
+	oSpan.appendChild(document.createTextNode('+'));
+	oSpan.fn = this.changeMinute;
+	oSpan.obj = this;
+	oSpan.onclick = function() { this.fn.call(this.obj,+1); };
+	
+	oHeading.appendChild(oSpan);
+	
+	oRow.appendChild(oHeading);
+	
+	// Close control
+	oHeading = document.createElement('th');
+	oHeading.className = 'date-picker-control';
+	oHeading.appendChild(document.createTextNode('x'));
+	oHeading.setAttribute('title',this.close_msg);
+	oHeading.fn = this.close;
+	oHeading.obj = this;
+	oHeading.onclick = function() { this.fn.call(this.obj); };
+	
+	oRow.appendChild(oHeading);
+	
+	this.oBody.appendChild(oRow);
+};
 
 datePicker.prototype = {
-  year: 0,
-  month: 0,
-  day: 0,
-  hour: 0,
-  minute: 0,
-
-  img_src: '',
-  img_top: '0.2em',
-  now_msg: 'now',
-  close_msg: 'close',
-
-  days: new Array('Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday',
-    'Saturday', 'Sunday'),
-
-  months: new Array('January', 'February', 'March', 'April', 'May', 'June',
-    'July', 'August', 'September', 'October', 'November', 'December'),
-
-  setDate: function() {
-    if (this.numberOfDays() < this.day) {
-      this.day = this.numberOfDays();
-    }
-
-    while (this.oYear.hasChildNodes()) {
-      this.oYear.removeChild(this.oYear.firstChild);
-    }
-    this.oYear.appendChild(document.createTextNode(this.year));
-
-    while (this.oMonth.hasChildNodes()) {
-      this.oMonth.removeChild(this.oMonth.firstChild);
-    }
-    this.oMonth.appendChild(document.createTextNode(
-      this.months[this.month - 1]));
-
-    const firstDay = this.firstDay();
-    const nbDays = this.numberOfDays();
-
-    // Empty days
-    for (let i = 1; i <= 42; i++) {
-      while (this.oDates[i].hasChildNodes()) {
-        this.oDates[i].removeChild(this.oDates[i].firstChild);
-      }
-      this.oDates[i].appendChild(document.createTextNode('-'));
-      this.oDates[i].className = '';
-      this.oDates[i].onclick = function() {
-        return;
-      };
-    }
-
-    // Insert days from the first day to the last
-    for (let i = 1; i <= nbDays; i++) {
-      const j = firstDay + i - 1;
-
-      while (this.oDates[j].hasChildNodes()) {
-        this.oDates[j].removeChild(this.oDates[j].firstChild);
-      }
-
-      this.oDates[j].appendChild(document.createTextNode(i));
-      this.oDates[j].index = i;
-      this.oDates[j].fn = this.sendDate;
-      this.oDates[j].obj = this;
-      this.oDates[j].onclick = function() {
-        this.fn.call(this.obj, this.index);
-      };
-      if (i == this.day) {
-        this.oDates[j].className = 'date-picker-today';
-      } else {
-        this.oDates[j].className = 'date-picker-day';
-      }
-    }
-
-    // Set time
-    this.setHour(this.hour);
-    this.setMinute(this.minute);
-  },
-
-  setHour: function(h) {
-    if (h < 0) {
-      h = 23;
-    }
-    if (h > 23) {
-      h = 0;
-    }
-    if (h < 10) {
-      h = '0' + h;
-    }
-
-    this.hour = h * 1;
-    this.oHour.value = h;
-  },
-
-  setMinute: function(m) {
-    if (m < 0) {
-      m = 59;
-    }
-    if (m > 59) {
-      m = 0;
-    }
-    if (m < 10) {
-      m = '0' + m;
-    }
-
-    this.minute = m * 1;
-    this.oMinute.value = m;
-  },
-
-  changeMonth: function(dir) {
-    const m = this.month + dir;
-
-    if (m > 12) {
-      this.month = 1;
-      this.year++;
-    } else if (m < 1) {
-      this.month = 12;
-      this.year--;
-    } else {
-      this.month = m;
-    }
-
-    this.setDate();
-  },
-
-  changeYear: function(dir) {
-    this.year = this.year + dir;
-    this.setDate();
-  },
-
-  changeHour: function(dir) {
-    this.setHour(this.hour * 1 + dir);
-  },
-
-  changeMinute: function(dir) {
-    this.setMinute(this.minute * 1 + dir);
-  },
-
-  sendDate: function(d) {
-    let m = this.month;
-    let hour = this.oHour.value * 1;
-    let minute = this.oMinute.value * 1;
-
-    if (hour < 0 || hour > 23 || isNaN(hour)) {
-      hour = 0;
-    }
-    if (minute < 0 || minute > 59 || isNaN(minute)) {
-      minute = 0;
-    }
-
-    if (m < 10) {
-      m = '0' + m;
-    }
-    if (d < 10) {
-      d = '0' + d;
-    }
-    if (hour < 10) {
-      hour = '0' + hour;
-    }
-    if (minute < 10) {
-      minute = '0' + minute;
-    }
-
-    this.target.value = `${this.year}-${m}-${d} ${hour}:${minute}`;
-    this.close();
-  },
-
-  sendNow: function() {
-    let dt = new Date();
-    const y = dt.getFullYear();
-    let m = dt.getMonth() + 1;
-    let d = dt.getDate();
-    let h = dt.getHours();
-    let i = dt.getMinutes();
-
-    if (m < 10) {
-      m = '0' + m;
-    }
-    if (d < 10) {
-      d = '0' + d;
-    }
-    if (h < 10) {
-      h = '0' + h;
-    }
-    if (i < 10) {
-      i = '0' + i;
-    }
-
-    this.target.value = `${y}-${m}-${d} ${h}:${i}`;
-    this.close();
-  },
-
-  close: function() {
-    document.body.removeChild(this.oTable);
-  },
-
-  numberOfDays: function() {
-    let res = 31;
-    if (this.month == 4 || this.month == 6 || this.month == 9 ||
-      this.month == 11) {
-      res = 30;
-    } else if (this.month == 2) {
-      res = 28;
-      if (this.year % 4 == 0 && (this.year % 100 != 0 ||
-          this.year % 400 == 0)) {
-        res = 29;
-      }
-    }
-
-    return res;
-  },
-
-  firstDay: function() {
-    let dt = new Date(this.year, this.month - 1, 1);
-    let res = dt.getDay();
-
-    if (res == 0) {
-      res = 7;
-    }
-
-    return res;
-  },
-
-  show: function() {
-    // Parsing target value
-    const re = /(\d{4})-(\d{2})-(\d{2}) (\d{2}):(\d{2})/;
-    const match = re.exec(this.target.value);
-    if (match) {
-      this.year = match[1] * 1;
-      this.month = match[2] * 1;
-      this.day = match[3] * 1;
-      this.hour = match[4] * 1;
-      this.minute = match[5] * 1;
-    } else {
-      let dt = new Date();
-      this.year = dt.getFullYear();
-      this.month = dt.getMonth() + 1;
-      this.day = dt.getDate();
-      this.hour = dt.getHours();
-      this.minute = dt.getMinutes();
-    }
-
-    this.oTable.appendChild(this.oBody);
-    this.setDate();
-    this.setPosition();
-    document.body.appendChild(this.oTable);
-    this.oHour.focus();
-  },
-
-  setPosition: function() {
-    const t_x = this.findPosX(this.target);
-    const t_y = this.findPosY(this.target);
-
-    this.oTable.style.position = 'absolute';
-    this.oTable.style.zIndex = '100';
-    this.oTable.style.top = t_y + 'px';
-    this.oTable.style.left = t_x + 'px';
-  },
-
-  findPosX: function(obj) {
-    let curleft = 0;
-    if (obj.offsetParent) {
-      while (1) {
-        curleft += obj.offsetLeft;
-        if (!obj.offsetParent) {
-          break;
-        }
-        obj = obj.offsetParent;
-      }
-    } else if (obj.x) {
-      curleft += obj.x;
-    }
-    return curleft;
-  },
-
-  findPosY: function(obj) {
-    let curtop = 0;
-    if (obj.offsetParent) {
-      while (1) {
-        curtop += obj.offsetTop;
-        if (!obj.offsetParent) {
-          break;
-        }
-        obj = obj.offsetParent;
-      }
-    } else if (obj.y) {
-      curtop += obj.y;
-    }
-    return curtop;
-  },
-
-  draw: function() {
-    const imgE = document.createElement('img');
-    imgE.src = this.img_src;
-    imgE.alt = this.img_alt;
-    imgE.style.position = 'absolute';
-    imgE.style.top = this.img_top;
-    imgE.style.left = (this.target.clientWidth + 4) + 'px';
-    imgE.obj = this;
-    imgE.fn = this.show;
-    imgE.onclick = function() {
-      this.fn.apply(this.obj);
-    };
-
-    this.target.parentNode.style.position = 'relative';
-    this.target.parentNode.insertBefore(imgE, this.target.nextSibling);
-  }
+	year: 0,
+	month: 0,
+	day: 0,
+	hour: 0,
+	minute: 0,
+	
+	img_src: '',
+	img_top: '0.2em',
+	now_msg: 'now',
+	close_msg: 'close',
+	
+	days: new Array('Monday','Tuesday','Wednesday','Thursday','Friday',
+	'Saturday','Sunday'),
+	
+	months: new Array('January','February','March','April','May','June',
+	'July','August','September','October','November','December'),
+	
+	
+	setDate: function() {
+		if (this.numberOfDays() < this.day) {
+			this.day = this.numberOfDays();
+		}
+		
+		while (this.oYear.hasChildNodes()) {
+			this.oYear.removeChild(this.oYear.firstChild)
+		}
+		this.oYear.appendChild(document.createTextNode(this.year));
+		
+		while (this.oMonth.hasChildNodes()) {
+			this.oMonth.removeChild(this.oMonth.firstChild)
+		}
+		this.oMonth.appendChild(document.createTextNode(
+			this.months[this.month-1]));
+		
+		var firstDay = this.firstDay();
+		var nbDays = this.numberOfDays();
+		
+		// Empty days
+		for (var i=1; i<=42; i++) {
+			while (this.oDates[i].hasChildNodes()) {
+				this.oDates[i].removeChild(this.oDates[i].firstChild)
+			}
+			this.oDates[i].appendChild(document.createTextNode('-'));
+			this.oDates[i].className = '';
+			this.oDates[i].onclick = function() { return; };
+		}
+		
+		// Insert days from the first day to the last
+		for (i=1; i<=nbDays; i++) {
+			var j=firstDay+i-1;
+			
+			while (this.oDates[j].hasChildNodes()) {
+				this.oDates[j].removeChild(this.oDates[j].firstChild)
+			}
+			
+			this.oDates[j].appendChild(document.createTextNode(i));
+			this.oDates[j].index = i;
+			this.oDates[j].fn = this.sendDate;
+			this.oDates[j].obj = this;
+			this.oDates[j].onclick = function() { this.fn.call(this.obj,this.index); };
+			if (i == this.day) {
+				this.oDates[j].className = 'date-picker-today';
+			} else {
+				this.oDates[j].className = 'date-picker-day';
+			}
+		}
+		
+		// Set time
+		this.setHour(this.hour);
+		this.setMinute(this.minute);
+	},
+	
+	setHour: function(h) {
+		if (h < 0) { h = 23; }
+		if (h > 23) { h = 0; }
+		if (h < 10) { h = '0'+h; }
+		
+		this.hour = h*1;
+		this.oHour.value = h;
+	},
+	
+	setMinute: function(m) {
+		if (m < 0) { m = 59; }
+		if (m > 59) { m = 0; }
+		if (m < 10) { m = '0'+m; }
+		
+		this.minute = m*1;
+		this.oMinute.value = m;
+	},
+	
+	changeMonth: function(dir) {
+		var y = this.year;
+		var m = this.month;
+		m = m+dir;
+		
+		if (m > 12) { this.month = 1; this.year++; }
+		else if ( m < 1) { this.month = 12; this.year--; }
+		else { this.month = m; }
+		
+		this.setDate();
+	},
+	
+	changeYear: function(dir) {
+		this.year = this.year + dir;
+		this.setDate();
+	},
+	
+	changeHour: function(dir) {
+		this.setHour(this.hour*1+dir);
+	},
+	
+	changeMinute: function(dir) {
+		this.setMinute(this.minute*1+dir);
+	},
+	
+	sendDate: function(d) {
+		var m = this.month;
+		var hour = this.oHour.value*1;
+		var minute = this.oMinute.value*1;
+		
+		if (hour < 0 || hour > 23 || isNaN(hour)) { hour = 0; }
+		if (minute < 0 || minute > 59 || isNaN(minute)) { minute = 0; }
+		
+		if (m < 10) { m = '0'+m; }
+		if (d < 10) { d = '0'+d; }
+		if (hour < 10) { hour = '0'+hour; }
+		if (minute < 10) { minute = '0'+minute; }
+		
+		this.target.value = this.year+'-'+m+'-'+d+' '+hour+':'+minute;
+		this.close();
+	},
+	
+	sendNow: function() {
+		var dt = new Date();
+		var y = dt.getFullYear();
+		var m = dt.getMonth() + 1;
+		var d = dt.getDate();
+		var h = dt.getHours();
+		var i = dt.getMinutes();
+		
+		if (m < 10) { m = '0'+m; }
+		if (d < 10) { d = '0'+d; }
+		if (h < 10) { h = '0'+h; }
+		if (i < 10) { i = '0'+i; }
+		
+		this.target.value = y+'-'+m+'-'+d+' '+h+':'+i;
+		this.close();
+	},
+	
+	close: function() {
+		document.body.removeChild(this.oTable);
+	},
+	
+	numberOfDays: function() {
+		var res = 31;
+		if (this.month == 4 || this.month == 6 || this.month == 9 ||
+		this.month == 11) {
+			res = 30;
+		} else if (this.month == 2) {
+			res = 28;
+			if (this.year%4 == 0 && (this.year%100 != 0 ||
+			this.year%400 == 0)) {
+				res = 29;
+			}
+		}
+		
+		return res;
+	},
+	
+	firstDay: function() {
+		var dt = new Date(this.year,this.month-1,1);
+		var res = dt.getDay();
+		
+		if (res == 0) {
+			res = 7;
+		}
+		
+		return res;
+	},
+	
+	show: function() {
+		// Parsing target value
+		var re = /(\d{4})-(\d{2})-(\d{2}) (\d{2}):(\d{2})/;
+		var match = re.exec(this.target.value);
+		if (match) {
+			this.year = match[1]*1;
+			this.month = match[2]*1;
+			this.day = match[3]*1;
+			this.hour = match[4]*1;
+			this.minute = match[5]*1;
+		} else {
+			var dt = new Date();
+			this.year = dt.getFullYear();
+			this.month = dt.getMonth() + 1;
+			this.day = dt.getDate();
+			this.hour = dt.getHours();
+			this.minute = dt.getMinutes();
+		}
+		
+		this.oTable.appendChild(this.oBody);
+		this.setDate();
+		this.setPosition();
+		document.body.appendChild(this.oTable);
+		this.oHour.focus();
+	},
+	
+	setPosition: function() {
+		var t_x = this.findPosX(this.target);
+		var t_y = this.findPosY(this.target);
+		var o_h = this.oTable.offsetHeight;
+		var o_w = this.oTable.offsetWidth;
+		
+		this.oTable.style.position = 'absolute';
+		this.oTable.style.zIndex = '100';
+		this.oTable.style.top = t_y+'px';
+		this.oTable.style.left = t_x+'px';
+	},
+	
+	findPosX: function(obj) {
+		var curleft = 0;
+		if(obj.offsetParent) {
+			while(1) {
+				curleft += obj.offsetLeft;
+				if(!obj.offsetParent) {
+					break;
+				}
+				obj = obj.offsetParent;
+			}
+		} else if(obj.x) {
+			curleft += obj.x;
+		}
+		return curleft;
+	},
+	
+	findPosY: function(obj) {
+		var curtop = 0;
+		if(obj.offsetParent) {
+			while(1) {
+				curtop += obj.offsetTop;
+				if(!obj.offsetParent) {
+					break;
+				}
+				obj = obj.offsetParent;
+			}
+		} else if(obj.y) {
+			curtop += obj.y;
+		}
+		return curtop;
+	},
+	
+	draw: function() {
+		var imgE = document.createElement('img');
+		imgE.src = this.img_src;
+		imgE.style.position = 'absolute';
+		imgE.style.top = this.img_top;
+		imgE.style.left = (this.target.clientWidth+4)+'px';
+		imgE.obj = this;
+		imgE.fn = this.show;
+		imgE.onclick = function() { this.fn.apply(this.obj); };
+		
+		this.target.parentNode.style.position = 'relative';
+		this.target.parentNode.insertBefore(imgE,this.target.nextSibling);
+	}
 };
-
-// Get some DATA
-Object.assign(datePicker.prototype, getData('date_picker'));
Index: admin/js/dragsort-tablerows.js
===================================================================
--- admin/js/dragsort-tablerows.js	(revision 0)
+++ admin/js/dragsort-tablerows.js	(revision 0)
@@ -0,0 +1,30 @@
+ToolMan._dragsortFactory.makeTableSortable = function(table) {
+	if (table == null) return;
+	
+	var helpers = ToolMan.helpers();
+	var coordinates = ToolMan.coordinates();
+	var items = table.getElementsByTagName("tr");
+	
+	helpers.map(items, function(item) {
+		var dragGroup = dragsort.makeSortable(item);
+		dragGroup.setThreshold(4);
+		var min, max;
+		dragGroup.addTransform(function(coordinate, dragEvent) {
+			return coordinate.constrainTo(min, max);
+		});
+		dragGroup.register('dragstart', function() {
+			var items = table.getElementsByTagName("tr");
+			min = max = coordinates.topLeftOffset(items[0]);
+			for (var i = 1, n = items.length; i < n; i++) {
+				var offset = coordinates.topLeftOffset(items[i]);
+				min = min.min(offset);
+				max = max.max(offset);
+			}
+		});
+	});
+	for (var i = 1, n = arguments.length; i < n; i++) {
+		helpers.map(items, arguments[i]);
+	}
+};
+
+ToolMan._dragsortFactory.registerOrder = function(dest) { };
Index: admin/js/file-upload.js
===================================================================
--- admin/js/file-upload.js	(revision 3927)
+++ 	(revision )
@@ -1,9 +1,0 @@
-/*global dotclear, getData */
-'use strict';
-
-// Get dotclear messages
-Object.assign(dotclear.msg, getData('file_upload_msg'));
-
-// Get jsUpload data
-dotclear.jsUpload = {};
-Object.assign(dotclear.jsUpload, getData('file_upload'));
Index: admin/js/filter-controls.js
===================================================================
--- admin/js/filter-controls.js	(revision 3926)
+++ admin/js/filter-controls.js	(revision 0)
@@ -1,40 +1,10 @@
-/*global $, dotclear, getData */
-'use strict';
-
 $(function() {
-  // Get some DATA
-  Object.assign(dotclear.msg, getData('filter_controls'));
-
-  let reset_url = '?';
-  if (dotclear.filter_reset_url != undefined) {
-    reset_url = dotclear.filter_reset_url;
-  }
-
-  const $filtersform = $('#filters-form');
-  $filtersform.before(`<p><a id="filter-control" class="form-control" href="${reset_url}" style="display:inline">${dotclear.msg.filter_posts_list}</a></p>`);
-
-  if (!dotclear.msg.show_filters) {
-    $filtersform.hide();
-  } else {
-    $('#filter-control')
-      .addClass('open')
-      .text(dotclear.msg.cancel_the_filter);
-  }
-
-  $('#filter-control').click(function() {
-    if ($(this).hasClass('open')) {
-      if (dotclear.msg.show_filters) {
-        return true;
-      } else {
-        $filtersform.hide();
-        $(this).removeClass('open')
-          .text(dotclear.msg.filter_posts_list);
-      }
-    } else {
-      $filtersform.show();
-      $(this).addClass('open')
-        .text(dotclear.msg.cancel_the_filter);
-    }
-    return false;
-  });
+	var c = $('#filter-control');
+	c.css('display','inline');
+	$('#filters-form').hide();
+	c.click(function() {
+		$('#filters-form').show();
+		$(this).hide();
+		return false;
+	});
 });
Index: admin/js/ie7/IE7.js
===================================================================
--- admin/js/ie7/IE7.js	(revision 0)
+++ admin/js/ie7/IE7.js	(revision 0)
@@ -0,0 +1,2 @@
+/* IE7/IE8.js - copyright 2004-2008, Dean Edwards */
+(function(){IE7={toString:function(){return"IE7 version 2.0 (beta2)"}};var k=IE7.appVersion=navigator.appVersion.match(/MSIE (\d\.\d)/)[1];if(/ie7_off/.test(top.location.search)||k<5)return;var Q=bG();var C=document.compatMode!="CSS1Compat";var bm=document.documentElement,v,s;var bA="!";var G=":link{ie7-link:link}:visited{ie7-link:visited}";var cj=/^[\w\.]+[^:]*$/;function W(a,b){if(cj.test(a))a=(b||"")+a;return a};function bn(a,b){a=W(a,b);return a.slice(0,a.lastIndexOf("/")+1)};var bB=document.scripts[document.scripts.length-1];var ck=bn(bB.src);try{var H=new ActiveXObject("Microsoft.XMLHTTP")}catch(e){}var X={};function cl(a,b){try{a=W(a,b);if(!X[a]){H.open("GET",a,false);H.send();if(H.status==0||H.status==200){X[a]=H.responseText}}}catch(e){}finally{return X[a]||""}};if(k<5.5){undefined=Q();bA="HTML:!";var cm=/(g|gi)$/;var cn=String.prototype.replace;String.prototype.replace=function(a,b){if(typeof b=="function"){if(a&&a.constructor==RegExp){var c=a;var d=c.global;if(d==null)d=cm.test(c);if(d)c=new RegExp(c.source)}else{c=new RegExp(bb(a))}var f,g=this,h="";while(g&&(f=c.exec(g))){h+=g.slice(0,f.index)+b.apply(this,f);g=g.slice(f.index+f[0].length);if(!d)break}return h+g}return cn.apply(this,arguments)};Array.prototype.pop=function(){if(this.length){var a=this[this.length-1];this.length--;return a}return undefined};Array.prototype.push=function(){for(var a=0;a<arguments.length;a++){this[this.length]=arguments[a]}return this.length};var co=this;Function.prototype.apply=function(a,b){if(a===undefined)a=co;else if(a==null)a=window;else if(typeof a=="string")a=new String(a);else if(typeof a=="number")a=new Number(a);else if(typeof a=="boolean")a=new Boolean(a);if(arguments.length==1)b=[];else if(b[0]&&b[0].writeln)b[0]=b[0].documentElement.document||b[0];var c="#ie7_apply",d;a[c]=this;switch(b.length){case 0:d=a[c]();break;case 1:d=a[c](b[0]);break;case 2:d=a[c](b[0],b[1]);break;case 3:d=a[c](b[0],b[1],b[2]);break;case 4:d=a[c](b[0],b[1],b[2],b[3]);break;case 5:d=a[c](b[0],b[1],b[2],b[3],b[4]);break;default:var f=[],g=b.length-1;do f[g]="a["+g+"]";while(g--);eval("r=o[$]("+f+")")}if(typeof a.valueOf=="function"){delete a[c]}else{a[c]=undefined;if(d&&d.writeln)d=d.documentElement.document||d}return d};Function.prototype.call=function(a){return this.apply(a,bC.apply(arguments,[1]))};G+="address,blockquote,body,dd,div,dt,fieldset,form,"+"frame,frameset,h1,h2,h3,h4,h5,h6,iframe,noframes,object,p,"+"hr,applet,center,dir,menu,pre,dl,li,ol,ul{display:block}"}var bC=Array.prototype.slice;var cJ=/%([1-9])/g;var cp=/^\s\s*/;var cq=/\s\s*$/;var cr=/([\/()[\]{}|*+-.,^$?\\])/g;var bD=/\bbase\b/;var bE=["constructor","toString"];var Y;function z(){};z.extend=function(a,b){Y=true;var c=new this;ba(c,a);Y=false;var d=c.constructor;function f(){if(!Y)d.apply(this,arguments)};c.constructor=f;f.extend=arguments.callee;ba(f,b);f.prototype=c;return f};z.prototype.extend=function(a){return ba(this,a)};var bo="#";var Z="~";var cs=/\\./g;var ct=/\(\?[:=!]|\[[^\]]+\]/g;var cu=/\(/g;var D=z.extend({constructor:function(a){this[Z]=[];this.merge(a)},exec:function(g){var h=this,p=this[Z];return String(g).replace(new RegExp(this,this.ignoreCase?"gi":"g"),function(){var a,b=1,c=0;while((a=h[bo+p[c++]])){var d=b+a.length+1;if(arguments[b]){var f=a.replacement;switch(typeof f){case"function":return f.apply(h,bC.call(arguments,b,d));case"number":return arguments[b+f];default:return f}}b=d}})},add:function(a,b){if(a instanceof RegExp){a=a.source}if(!this[bo+a])this[Z].push(String(a));this[bo+a]=new D.Item(a,b)},merge:function(a){for(var b in a)this.add(b,a[b])},toString:function(){return"("+this[Z].join(")|(")+")"}},{IGNORE:"$0",Item:z.extend({constructor:function(a,b){a=a instanceof RegExp?a.source:String(a);if(typeof b=="number")b=String(b);else if(b==null)b="";if(typeof b=="string"&&/\$(\d+)/.test(b)){if(/^\$\d+$/.test(b)){b=parseInt(b.slice(1))}else{var c=/'/.test(b.replace(/\\./g,""))?'"':"'";b=b.replace(/\n/g,"\\n").replace(/\r/g,"\\r").replace(/\$(\d+)/g,c+"+(arguments[$1]||"+c+c+")+"+c);b=new Function("return "+c+b.replace(/(['"])\1\+(.*)\+\1\1$/,"$1")+c)}}this.length=D.count(a);this.replacement=b;this.toString=bG(a)}}),count:function(a){a=String(a).replace(cs,"").replace(ct,"");return I(a,cu).length}});function ba(a,b){if(a&&b){var c=(typeof b=="function"?Function:Object).prototype;var d=bE.length,f;if(Y)while(f=bE[--d]){var g=b[f];if(g!=c[f]){if(bD.test(g)){bF(a,f,g)}else{a[f]=g}}}for(f in b)if(c[f]===undefined){var g=b[f];if(a[f]&&typeof g=="function"&&bD.test(g)){bF(a,f,g)}else{a[f]=g}}}return a};function bF(c,d,f){var g=c[d];c[d]=function(){var a=this.base;this.base=g;var b=f.apply(this,arguments);this.base=a;return b}};function cv(a,b){if(!b)b=a;var c={};for(var d in a)c[d]=b[d];return c};function i(c){var d=arguments;var f=new RegExp("%([1-"+arguments.length+"])","g");return String(c).replace(f,function(a,b){return b<d.length?d[b]:a})};function I(a,b){return String(a).match(b)||[]};function bb(a){return String(a).replace(cr,"\\$1")};function cK(a){return String(a).replace(cp,"").replace(cq,"")};function bG(a){return function(){return a}};var bH=D.extend({ignoreCase:true});var cw=/\x01(\d+)/g,cx=/'/g,cy=/^\x01/,cz=/\\([\da-fA-F]{1,4})/g;var bp=[];var cA=new bH({"<!\\-\\-|\\-\\->":"","\\/\\*[^*]*\\*+([^\\/][^*]*\\*+)*\\/":"","@(namespace|import)[^;\\n]+[;\\n]":"","'(\\\\.|[^'\\\\])*'":bJ,'"(\\\\.|[^"\\\\])*"':bJ,"\\s+":" "});function cB(a){return cA.exec(a)};function bI(c){return c.replace(cw,function(a,b){return bp[b-1]})};function bJ(c){return"\x01"+bp.push(c.replace(cz,function(a,b){return eval("'\\u"+"0000".slice(b.length)+b+"'")}).slice(1,-1).replace(cx,"\\'"))};function cC(a){return cy.test(a)?bp[a.slice(1)-1]:a};var cD=new D({Width:"Height",width:"height",Left:"Top",left:"top",Right:"Bottom",right:"bottom",onX:"onY"});function A(a){return cD.exec(a)};var bK=[];function bq(a){cF(a);w(window,"onresize",a)};function w(a,b,c){a.attachEvent(b,c);bK.push(arguments)};function cE(a,b,c){try{a.detachEvent(b,c)}catch(ignore){}};w(window,"onunload",function(){var a;while(a=bK.pop()){cE(a[0],a[1],a[2])}});function R(a,b,c){if(!a.elements)a.elements={};if(c)a.elements[b.uniqueID]=b;else delete a.elements[b.uniqueID];return c};w(window,"onbeforeprint",function(){if(!IE7.CSS.print)new bw("print");IE7.CSS.print.recalc()});var bL=/^\d+(px)?$/i;var J=/^\d+%$/;var E=function(a,b){if(bL.test(b))return parseInt(b);var c=a.style.left;var d=a.runtimeStyle.left;a.runtimeStyle.left=a.currentStyle.left;a.style.left=b||0;b=a.style.pixelLeft;a.style.left=c;a.runtimeStyle.left=d;return b};var br="ie7-";var bM=z.extend({constructor:function(){this.fixes=[];this.recalcs=[]},init:Q});var bs=[];function cF(a){bs.push(a)};IE7.recalc=function(){IE7.HTML.recalc();IE7.CSS.recalc();for(var a=0;a<bs.length;a++)bs[a]()};function bc(a){return a.currentStyle["ie7-position"]=="fixed"};function bt(a,b){return a.currentStyle[br+b]||a.currentStyle[b]};function K(a,b,c){if(a.currentStyle[br+b]==null){a.runtimeStyle[br+b]=a.currentStyle[b]}a.runtimeStyle[b]=c};function bN(a){var b=document.createElement(a||"object");b.style.cssText="position:absolute;padding:0;display:block;border:none;clip:rect(0 0 0 0);left:-9999";b.ie7_anon=true;return b};function B(a,b,c){if(!be[a]){F=[];var d="";var f=T.escape(a).split(",");for(var g=0;g<f.length;g++){o=m=x=0;S=f.length>1?2:0;var h=T.exec(f[g])||"if(0){";if(o){h+=i("if(e%1.nodeName!='!'){",m)}var p=S>1?bV:"";h+=i(p+bW,m);h+=Array(I(h,/\{/g).length+1).join("}");d+=h}eval(i(bX,F)+T.unescape(d)+"return s?null:r}");be[a]=_h}return be[a](b||document,c)};var bd=k<6;var bO=/^(href|src)$/;var bu={"class":"className","for":"htmlFor"};IE7._5=1;IE7._e=function(a,b){var c=a.all[b]||null;if(!c||c.id==b)return c;for(var d=0;d<c.length;d++){if(c[d].id==b)return c[d]}return null};IE7._f=function(a,b){if(b=="src"&&a.pngSrc)return a.pngSrc;var c=bd?(a.attributes[b]||a.attributes[bu[b.toLowerCase()]]):a.getAttributeNode(b);if(c&&(c.specified||b=="value")){if(bO.test(b)){return a.getAttribute(b,2)}else if(b=="class"){return a.className.replace(/\sie7_\w+/g,"")}else if(b=="style"){return a.style.cssText}else{return c.nodeValue}}return null};var bP="colSpan,rowSpan,vAlign,dateTime,accessKey,tabIndex,encType,maxLength,readOnly,longDesc";ba(bu,cv(bP.toLowerCase().split(","),bP.split(",")));IE7._a=function(a){while(a&&(a=a.nextSibling)&&(a.nodeType!=1||a.nodeName=="!"))continue;return a};IE7._b=function(a){while(a&&(a=a.previousSibling)&&(a.nodeType!=1||a.nodeName=="!"))continue;return a};var cG=/([\s>+~,]|[^(]\+|^)([#.:\[])/g,cH=/(^|,)([^\s>+~])/g,cI=/\s*([\s>+~(),]|^|$)\s*/g,bQ=/\s\*\s/g;var bR=D.extend({constructor:function(a){this.base(a);this.sorter=new D;this.sorter.add(/:not\([^)]*\)/,D.IGNORE);this.sorter.add(/([ >](\*|[\w-]+))([^: >+~]*)(:\w+-child(\([^)]+\))?)([^: >+~]*)/,"$1$3$6$4")},ignoreCase:true,escape:function(a){return this.optimise(this.format(a))},format:function(a){return a.replace(cI,"$1").replace(cH,"$1 $2").replace(cG,"$1*$2")},optimise:function(a){return this.sorter.exec(a.replace(bQ,">* "))},unescape:function(a){return bI(a)}});var bS={"":"%1!=null","=":"%1=='%2'","~=":/(^| )%1( |$)/,"|=":/^%1(-|$)/,"^=":/^%1/,"$=":/%1$/,"*=":/%1/};var bT={"first-child":"!IE7._b(e%1)","link":"e%1.currentStyle['ie7-link']=='link'","visited":"e%1.currentStyle['ie7-link']=='visited'"};var bv="var p%2=0,i%2,e%2,n%2=e%1.";var bU="e%1.sourceIndex";var bV="var g="+bU+";if(!p[g]){p[g]=1;";var bW="r[r.length]=e%1;if(s)return e%1;";var bX="var _h=function(e0,s){IE7._5++;var r=[],p={},reg=[%1],d=document;";var F;var m;var o;var x;var S;var be={};var T=new bR({" (\\*|[\\w-]+)#([\\w-]+)":function(a,b,c){o=false;var d="var e%2=IE7._e(d,'%4');if(e%2&&";if(b!="*")d+="e%2.nodeName=='%3'&&";d+="(e%1==d||e%1.contains(e%2))){";if(x)d+=i("i%1=n%1.length;",x);return i(d,m++,m,b.toUpperCase(),c)}," (\\*|[\\w-]+)":function(a,b){S++;o=b=="*";var c=bv;c+=(o&&bd)?"all":"getElementsByTagName('%3')";c+=";for(i%2=0;(e%2=n%2[i%2]);i%2++){";return i(c,m++,x=m,b.toUpperCase())},">(\\*|[\\w-]+)":function(a,b){var c=x;o=b=="*";var d=bv;d+=c?"children":"childNodes";if(!o&&c)d+=".tags('%3')";d+=";for(i%2=0;(e%2=n%2[i%2]);i%2++){";if(o){d+="if(e%2.nodeType==1){";o=bd}else{if(!c)d+="if(e%2.nodeName=='%3'){"}return i(d,m++,x=m,b.toUpperCase())},"\\+(\\*|[\\w-]+)":function(a,b){var c="";if(o)c+="if(e%1.nodeName!='!'){";o=false;c+="e%1=IE7._a(e%1);if(e%1";if(b!="*")c+="&&e%1.nodeName=='%2'";c+="){";return i(c,m,b.toUpperCase())},"~(\\*|[\\w-]+)":function(a,b){var c="";if(o)c+="if(e%1.nodeName!='!'){";o=false;S=2;c+="while(e%1=e%1.nextSibling){if(e%1.ie7_adjacent==IE7._5)break;if(";if(b=="*"){c+="e%1.nodeType==1";if(bd)c+="&&e%1.nodeName!='!'"}else c+="e%1.nodeName=='%2'";c+="){e%1.ie7_adjacent=IE7._5;";return i(c,m,b.toUpperCase())},"#([\\w-]+)":function(a,b){o=false;var c="if(e%1.id=='%2'){";if(x)c+=i("i%1=n%1.length;",x);return i(c,m,b)},"\\.([\\w-]+)":function(a,b){o=false;F.push(new RegExp("(^|\\s)"+bb(b)+"(\\s|$)"));return i("if(e%1.className&&reg[%2].test(e%1.className)){",m,F.length-1)},"\\[([\\w-]+)\\s*([^=]?=)?\\s*([^\\]]*)\\]":function(a,b,c,d){var f=bu[b]||b;if(c){var g="e%1.getAttribute('%2',2)";if(!bO.test(b)){g="e%1.%3||"+g}b=i("("+g+")",m,b,f)}else{b=i("IE7._f(e%1,'%2')",m,b)}var h=bS[c||""]||"0";if(h&&h.source){F.push(new RegExp(i(h.source,bb(T.unescape(d)))));h="reg[%2].test(%1)";d=F.length-1}return"if("+i(h,b,d)+"){"},":+([\\w-]+)(\\(([^)]+)\\))?":function(a,b,c,d){b=bT[b];return"if("+(b?i(b,m,d||""):"0")+"){"}});var bY=/a(#[\w-]+)?(\.[\w-]+)?:(hover|active)/i;var bZ=/\s*\{\s*/,ca=/\s*\}\s*/,cb=/\s*\,\s*/;var cc=/(.*)(:first-(line|letter))/;var y=document.styleSheets;IE7.CSS=new(bM.extend({parser:new bH,screen:"",print:"",styles:[],rules:[],pseudoClasses:k<7?"first\\-child":"",dynamicPseudoClasses:{toString:function(){var a=[];for(var b in this)a.push(b);return a.join("|")}},init:function(){var a="^\x01$";var b="\\[class=?[^\\]]*\\]";var c=[];if(this.pseudoClasses)c.push(this.pseudoClasses);var d=this.dynamicPseudoClasses.toString();if(d)c.push(d);c=c.join("|");var f=k<7?["[>+~[(]|([:.])\\w+\\1"]:[b];if(c)f.push(":("+c+")");this.UNKNOWN=new RegExp(f.join("|")||a,"i");var g=k<7?["\\[[^\\]]+\\]|[^\\s(\\[]+\\s*[+~]"]:[b];var h=g.concat();if(c)h.push(":("+c+")");n.COMPLEX=new RegExp(h.join("|")||a,"ig");if(this.pseudoClasses)g.push(":("+this.pseudoClasses+")");L.COMPLEX=new RegExp(g.join("|")||a,"i");L.MATCH=new RegExp(d?"(.*):("+d+")(.*)":a,"i");this.createStyleSheet();this.refresh()},addEventHandler:function(){w.apply(null,arguments)},addFix:function(a,b){this.parser.add(a,b)},addRecalc:function(c,d,f,g){d=new RegExp("([{;\\s])"+c+"\\s*:\\s*"+d+"[^;}]*");var h=this.recalcs.length;if(g)g=c+":"+g;this.addFix(d,function(a,b){return(g?b+g:a)+";ie7-"+a.slice(1)+";ie7_recalc"+h+":1"});this.recalcs.push(arguments);return h},apply:function(){this.getInlineStyles();new bw("screen");this.trash()},createStyleSheet:function(){this.styleSheet=document.createStyleSheet();this.styleSheet.ie7=true;this.styleSheet.owningElement.ie7=true;this.styleSheet.cssText=G},getInlineStyles:function(){var a=document.getElementsByTagName("style"),b;for(var c=a.length-1;(b=a[c]);c--){if(!b.disabled&&!b.ie7){this.styles.push(b.innerHTML)}}},getText:function(a,b){try{var c=a.cssText}catch(e){c=""}if(H)c=cl(a.href,b)||c;return c},recalc:function(){this.screen.recalc();var a=/ie7_recalc\d+/g;var b=G.match(/[{,]/g).length;var c=b+(this.screen.cssText.match(/\{/g)||"").length;var d=this.styleSheet.rules,f;var g,h,p,t,q,j,u,l;for(q=b;q<c;q++){f=d[q];var r=f.style.cssText;if(f&&(g=r.match(a))){p=B(f.selectorText);if(p.length)for(j=0;j<g.length;j++){l=g[j];h=IE7.CSS.recalcs[l.slice(10)][2];for(u=0;(t=p[u]);u++){if(t.currentStyle[l])h(t,r)}}}}},refresh:function(){this.styleSheet.cssText=G+this.screen+this.print},trash:function(){for(var a=0;a<y.length;a++){if(!y[a].ie7){try{var b=y[a].cssText}catch(e){b=""}if(b)y[a].cssText=""}}}}));var bw=z.extend({constructor:function(a){this.media=a;this.load();IE7.CSS[a]=this;IE7.CSS.refresh()},createRule:function(a,b){if(IE7.CSS.UNKNOWN.test(a)){var c;if(bf&&(c=a.match(bf.MATCH))){return new bf(c[1],c[2],b)}else if(c=a.match(L.MATCH)){if(!bY.test(c[0])||L.COMPLEX.test(c[0])){return new L(a,c[1],c[2],c[3],b)}}else return new n(a,b)}return a+" {"+b+"}"},getText:function(){var h=[].concat(IE7.CSS.styles);var p=/@media\s+([^{]*)\{([^@]+\})\s*\}/gi;var t=/\ball\b|^$/i,q=/\bscreen\b/i,j=/\bprint\b/i;function u(a,b){l.value=b;return a.replace(p,l)};function l(a,b,c){b=r(b);switch(b){case"screen":case"print":if(b!=l.value)return"";case"all":return c}return""};function r(a){if(t.test(a))return"all";else if(q.test(a))return(j.test(a))?"all":"screen";else if(j.test(a))return"print"};var N=this;function O(a,b,c,d){var f="";if(!d){c=r(a.media);d=0}if(c=="all"||c==N.media){if(d<3){for(var g=0;g<a.imports.length;g++){f+=O(a.imports[g],bn(a.href,b),c,d+1)}}f+=cB(a.href?cg(a,b):h.pop()||"");f=u(f,N.media)}return f};var bl={};function cg(a,b){var c=W(a.href,b);if(bl[c])return"";bl[c]=(a.disabled)?"":ci(IE7.CSS.getText(a,b),bn(a.href,b));return bl[c]};var ch=/(url\s*\(\s*['"]?)([\w\.]+[^:\)]*['"]?\))/gi;function ci(a,b){return a.replace(ch,"$1"+b.slice(0,b.lastIndexOf("/")+1)+"$2")};for(var P=0;P<y.length;P++){if(!y[P].disabled&&!y[P].ie7){this.cssText+=O(y[P])}}},load:function(){this.cssText="";this.getText();this.parse();this.cssText=bI(this.cssText);X={}},parse:function(){this.cssText=IE7.CSS.parser.exec(this.cssText);var a=IE7.CSS.rules.length;var b=this.cssText.split(ca),c;var d,f,g,h;for(g=0;g<b.length;g++){c=b[g].split(bZ);d=c[0].split(cb);f=c[1];for(h=0;h<d.length;h++){d[h]=f?this.createRule(d[h],f):""}b[g]=d.join("\n")}this.cssText=b.join("\n");this.rules=IE7.CSS.rules.slice(a)},recalc:function(){var a,b;for(b=0;(a=this.rules[b]);b++)a.recalc()},toString:function(){return"@media "+this.media+"{"+this.cssText+"}"}});var bf;var n=IE7.Rule=z.extend({constructor:function(a,b){this.id=IE7.CSS.rules.length;this.className=n.PREFIX+this.id;a=a.match(cc)||a||"*";this.selector=a[1]||a;this.selectorText=this.parse(this.selector)+(a[2]||"");this.cssText=b;this.MATCH=new RegExp("\\s"+this.className+"(\\s|$)","g");IE7.CSS.rules.push(this);this.init()},init:Q,add:function(a){a.className+=" "+this.className},recalc:function(){var a=B(this.selector);for(var b=0;b<a.length;b++)this.add(a[b])},parse:function(a){var b=a.replace(n.CHILD," ").replace(n.COMPLEX,"");if(k<7)b=b.replace(n.MULTI,"");var c=I(b,n.TAGS).length-I(a,n.TAGS).length;var d=I(b,n.CLASSES).length-I(a,n.CLASSES).length+1;while(d>0&&n.CLASS.test(b)){b=b.replace(n.CLASS,"");d--}while(c>0&&n.TAG.test(b)){b=b.replace(n.TAG,"$1*");c--}b+="."+this.className;d=Math.min(d,2);c=Math.min(c,2);var f=-10*d-c;if(f>0){b=b+","+n.MAP[f]+" "+b}return b},remove:function(a){a.className=a.className.replace(this.MATCH,"$1")},toString:function(){return i("%1 {%2}",this.selectorText,this.cssText)}},{CHILD:/>/g,CLASS:/\.[\w-]+/,CLASSES:/[.:\[]/g,MULTI:/(\.[\w-]+)+/g,PREFIX:"ie7_class",TAG:/^\w+|([\s>+~])\w+/,TAGS:/^\w|[\s>+~]\w/g,MAP:{1:"html",2:"html body",10:".ie7_html",11:"html.ie7_html",12:"html.ie7_html body",20:".ie7_html .ie7_body",21:"html.ie7_html .ie7_body",22:"html.ie7_html body.ie7_body"}});var L=n.extend({constructor:function(a,b,c,d,f){this.attach=b||"*";this.dynamicPseudoClass=IE7.CSS.dynamicPseudoClasses[c];this.target=d;this.base(a,f)},recalc:function(){var a=B(this.attach),b;for(var c=0;b=a[c];c++){var d=this.target?B(this.target,b):[b];if(d.length)this.dynamicPseudoClass.apply(b,d,this)}}});var cd=z.extend({constructor:function(a,b){this.name=a;this.apply=b;this.instances={};IE7.CSS.dynamicPseudoClasses[a]=this},register:function(a){var b=a[2];a.id=b.id+a[0].uniqueID;if(!this.instances[a.id]){var c=a[1],d;for(d=0;d<c.length;d++)b.add(c[d]);this.instances[a.id]=a}},unregister:function(a){if(this.instances[a.id]){var b=a[2];var c=a[1],d;for(d=0;d<c.length;d++)b.remove(c[d]);delete this.instances[a.id]}}});if(k<7){var U=new cd("hover",function(a){var b=arguments;IE7.CSS.addEventHandler(a,k<5.5?"onmouseover":"onmouseenter",function(){U.register(b)});IE7.CSS.addEventHandler(a,k<5.5?"onmouseout":"onmouseleave",function(){U.unregister(b)})});w(document,"onmouseup",function(){var a=U.instances;for(var b in a)if(!a[b][0].contains(event.srcElement))U.unregister(a[b])})}IE7.CSS.addRecalc("[\\w-]+","inherit",function(c,d){var f=d.match(/[\w-]+\s*:\s*inherit/g);for(var g=0;g<f.length;g++){var h=f[g].replace(/ie7\-|\s*:\s*inherit/g,"").replace(/\-([a-z])/g,function(a,b){return b.toUpperCase()});c.runtimeStyle[h]=c.parentElement.currentStyle[h]}});IE7.HTML=new(bM.extend({fixed:{},init:Q,addFix:function(){this.fixes.push(arguments)},apply:function(){for(var a=0;a<this.fixes.length;a++){var b=B(this.fixes[a][0]);var c=this.fixes[a][1];for(var d=0;d<b.length;d++)c(b[d])}},addRecalc:function(){this.recalcs.push(arguments)},recalc:function(){for(var a=0;a<this.recalcs.length;a++){var b=B(this.recalcs[a][0]);var c=this.recalcs[a][1],d;var f=Math.pow(2,a);for(var g=0;(d=b[g]);g++){var h=d.uniqueID;if((this.fixed[h]&f)==0){d=c(d)||d;this.fixed[h]|=f}}}}}));if(k<7){document.createElement("abbr");IE7.HTML.addRecalc("label",function(a){if(!a.htmlFor){var b=B("input,textarea",a,true);if(b){w(a,"onclick",function(){b.click()})}}})}var V="[.\\d]";new function(_){var layout=IE7.Layout=this;G+="*{boxSizing:content-box}";IE7.hasLayout=k<5.5?function(a){return a.clientWidth}:function(a){return a.currentStyle.hasLayout};layout.boxSizing=function(a){if(!IE7.hasLayout(a)){a.style.height="0cm";if(a.currentStyle.verticalAlign=="auto")a.runtimeStyle.verticalAlign="top";collapseMargins(a)}};function collapseMargins(a){if(a!=s&&a.currentStyle.position!="absolute"){collapseMargin(a,"marginTop");collapseMargin(a,"marginBottom")}};function collapseMargin(a,b){if(!a.runtimeStyle[b]){var c=a.parentElement;if(c&&IE7.hasLayout(c)&&!IE7[b=="marginTop"?"_b":"_a"](a))return;var d=B(">*:"+(b=="marginTop"?"first":"last")+"-child",a,true);if(d&&d.currentStyle.styleFloat=="none"&&IE7.hasLayout(d)){collapseMargin(d,b);margin=_9(a,a.currentStyle[b]);childMargin=_9(d,d.currentStyle[b]);if(margin<0||childMargin<0){a.runtimeStyle[b]=margin+childMargin}else{a.runtimeStyle[b]=Math.max(childMargin,margin)}d.runtimeStyle[b]="0px"}}};function _9(a,b){return b=="auto"?0:E(a,b)};var UNIT=/^[.\d][\w%]*$/,AUTO=/^(auto|0cm)$/;var applyWidth,applyHeight;IE7.Layout.borderBox=function(a){applyWidth(a);applyHeight(a)};var fixWidth=function(g){applyWidth=function(a){if(!J.test(a.currentStyle.width))h(a);collapseMargins(a)};function h(a,b){if(!a.runtimeStyle.fixedWidth){if(!b)b=a.currentStyle.width;a.runtimeStyle.fixedWidth=(UNIT.test(b))?Math.max(0,q(a,b)):b;K(a,"width",a.runtimeStyle.fixedWidth)}};function p(a){if(!bc(a)){var b=a.offsetParent;while(b&&!IE7.hasLayout(b))b=b.offsetParent}return(b||s).clientWidth};function t(a,b){if(J.test(b))return parseInt(parseFloat(b)/100*p(a));return E(a,b)};var q=function(a,b){var c=a.currentStyle["box-sizing"]=="border-box";var d=0;if(C&&!c)d+=j(a)+u(a,"padding");else if(!C&&c)d-=j(a)+u(a,"padding");return t(a,b)+d};function j(a){return a.offsetWidth-a.clientWidth};function u(a,b){return t(a,a.currentStyle[b+"Left"])+t(a,a.currentStyle[b+"Right"])};G+="*{minWidth:none;maxWidth:none;min-width:none;max-width:none}";layout.minWidth=function(a){if(a.currentStyle["min-width"]!=null){a.style.minWidth=a.currentStyle["min-width"]}if(R(arguments.callee,a,a.currentStyle.minWidth!="none")){layout.boxSizing(a);h(a);l(a)}};eval("IE7.Layout.maxWidth="+String(layout.minWidth).replace(/min/g,"max"));function l(a){var b=a.getBoundingClientRect();var c=b.right-b.left;if(a.currentStyle.minWidth!="none"&&c<=q(a,a.currentStyle.minWidth)){a.runtimeStyle.width=a.currentStyle.minWidth}else if(a.currentStyle.maxWidth!="none"&&c>=q(a,a.currentStyle.maxWidth)){a.runtimeStyle.width=a.currentStyle.maxWidth}else{a.runtimeStyle.width=a.runtimeStyle.fixedWidth}};function r(a){if(R(r,a,/^(fixed|absolute)$/.test(a.currentStyle.position)&&bt(a,"left")!="auto"&&bt(a,"right")!="auto"&&AUTO.test(bt(a,"width")))){N(a);IE7.Layout.boxSizing(a)}};IE7.Layout.fixRight=r;function N(a){var b=t(a,a.runtimeStyle._c||a.currentStyle.left);var c=p(a)-t(a,a.currentStyle.right)-b-u(a,"margin");if(parseInt(a.runtimeStyle.width)==c)return;a.runtimeStyle.width="";if(bc(a)||g||a.offsetWidth<c){if(!C)c-=j(a)+u(a,"padding");if(c<0)c=0;a.runtimeStyle.fixedWidth=c;K(a,"width",c)}};var O=0;bq(function(){if(!s)return;var a,b=(O<s.clientWidth);O=s.clientWidth;var c=layout.minWidth.elements;for(a in c){var d=c[a];var f=(parseInt(d.runtimeStyle.width)==q(d,d.currentStyle.minWidth));if(b&&f)d.runtimeStyle.width="";if(b==f)l(d)}var c=layout.maxWidth.elements;for(a in c){var d=c[a];var f=(parseInt(d.runtimeStyle.width)==q(d,d.currentStyle.maxWidth));if(!b&&f)d.runtimeStyle.width="";if(b!=f)l(d)}for(a in r.elements)N(r.elements[a])});if(C){IE7.CSS.addRecalc("width",V,applyWidth)}if(k<7){IE7.CSS.addRecalc("min-width",V,layout.minWidth);IE7.CSS.addRecalc("max-width",V,layout.maxWidth);IE7.CSS.addRecalc("right",V,r)}};eval("var fixHeight="+A(fixWidth));fixWidth();fixHeight(true)};var bg=W("blank.gif",ck);var bh="DXImageTransform.Microsoft.AlphaImageLoader";var bx="progid:"+bh+"(src='%1',sizingMethod='%2')";var bi;var M=[];function by(a){if(bi.test(a.src)){var b=new Image(a.width,a.height);b.onload=function(){a.width=b.width;a.height=b.height;b=null};b.src=a.src;a.pngSrc=a.src;bz(a)}};if(k>=5.5&&k<7){IE7.CSS.addFix(/background(-image)?\s*:\s*([^};]*)?url\(([^\)]+)\)([^;}]*)?/,function(a,b,c,d,f){d=cC(d);return bi.test(d)?"filter:"+i(bx,d,"crop")+";zoom:1;background"+(b||"")+":"+(c||"")+"none"+(f||""):a});IE7.HTML.addRecalc("img,input",function(a){if(a.tagName=="INPUT"&&a.type!="image")return;by(a);w(a,"onpropertychange",function(){if(!bj&&event.propertyName=="src"&&a.src.indexOf(bg)==-1)by(a)})});var bj=false;w(window,"onbeforeprint",function(){bj=true;for(var a=0;a<M.length;a++)ce(M[a])});w(window,"onafterprint",function(){for(var a=0;a<M.length;a++)bz(M[a]);bj=false})}function bz(a,b){var c=a.filters[bh];if(c){c.src=a.src;c.enabled=true}else{a.runtimeStyle.filter=i(bx,a.src,b||"scale");M.push(a)}a.src=bg};function ce(a){a.src=a.pngSrc;a.filters[bh].enabled=false};new function(_){if(k>=7)return;IE7.CSS.addRecalc("position","fixed",_6,"absolute");IE7.CSS.addRecalc("background(-attachment)?","[^};]*fixed",_2);var $viewport=C?"body":"documentElement";function _3(){if(v.currentStyle.backgroundAttachment!="fixed"){if(v.currentStyle.backgroundImage=="none"){v.runtimeStyle.backgroundRepeat="no-repeat";v.runtimeStyle.backgroundImage="url("+bg+")"}v.runtimeStyle.backgroundAttachment="fixed"}_3=Q};var _0=bN("img");function _1(a){return a?bc(a)||_1(a.parentElement):false};function _d(a,b,c){setTimeout("document.all."+a.uniqueID+".runtimeStyle.setExpression('"+b+"','"+c+"')",0)};function _2(a){if(R(_2,a,a.currentStyle.backgroundAttachment=="fixed"&&!a.contains(v))){_3();bgLeft(a);bgTop(a);_8(a)}};function _8(a){_0.src=a.currentStyle.backgroundImage.slice(5,-2);var b=a.canHaveChildren?a:a.parentElement;b.appendChild(_0);setOffsetLeft(a);setOffsetTop(a);b.removeChild(_0)};function bgLeft(a){a.style.backgroundPositionX=a.currentStyle.backgroundPositionX;if(!_1(a)){_d(a,"backgroundPositionX","(parseInt(runtimeStyle.offsetLeft)+document."+$viewport+".scrollLeft)||0")}};eval(A(bgLeft));function setOffsetLeft(a){var b=_1(a)?"backgroundPositionX":"offsetLeft";a.runtimeStyle[b]=getOffsetLeft(a,a.style.backgroundPositionX)-a.getBoundingClientRect().left-a.clientLeft+2};eval(A(setOffsetLeft));function getOffsetLeft(a,b){switch(b){case"left":case"top":return 0;case"right":case"bottom":return s.clientWidth-_0.offsetWidth;case"center":return(s.clientWidth-_0.offsetWidth)/2;default:if(J.test(b)){return parseInt((s.clientWidth-_0.offsetWidth)*parseFloat(b)/100)}_0.style.left=b;return _0.offsetLeft}};eval(A(getOffsetLeft));function _6(a){if(R(_6,a,bc(a))){K(a,"position","absolute");K(a,"left",a.currentStyle.left);K(a,"top",a.currentStyle.top);_3();IE7.Layout.fixRight(a);_4(a)}};function _4(a,b){positionTop(a,b);positionLeft(a,b,true);if(!a.runtimeStyle.autoLeft&&a.currentStyle.marginLeft=="auto"&&a.currentStyle.right!="auto"){var c=s.clientWidth-getPixelWidth(a,a.currentStyle.right)-getPixelWidth(a,a.runtimeStyle._c)-a.clientWidth;if(a.currentStyle.marginRight=="auto")c=parseInt(c/2);if(_1(a.offsetParent))a.runtimeStyle.pixelLeft+=c;else a.runtimeStyle.shiftLeft=c}clipWidth(a);clipHeight(a)};function clipWidth(a){var b=a.runtimeStyle.fixWidth;a.runtimeStyle.borderRightWidth="";a.runtimeStyle.width=b?getPixelWidth(a,b):"";if(a.currentStyle.width!="auto"){var c=a.getBoundingClientRect();var d=a.offsetWidth-s.clientWidth+c.left-2;if(d>=0){a.runtimeStyle.borderRightWidth="0px";d=Math.max(E(a,a.currentStyle.width)-d,0);K(a,"width",d);return d}}};eval(A(clipWidth));function positionLeft(a,b){if(!b&&J.test(a.currentStyle.width)){a.runtimeStyle.fixWidth=a.currentStyle.width}if(a.runtimeStyle.fixWidth){a.runtimeStyle.width=getPixelWidth(a,a.runtimeStyle.fixWidth)}a.runtimeStyle.shiftLeft=0;a.runtimeStyle._c=a.currentStyle.left;a.runtimeStyle.autoLeft=a.currentStyle.right!="auto"&&a.currentStyle.left=="auto";a.runtimeStyle.left="";a.runtimeStyle.screenLeft=getScreenLeft(a);a.runtimeStyle.pixelLeft=a.runtimeStyle.screenLeft;if(!b&&!_1(a.offsetParent)){_d(a,"pixelLeft","runtimeStyle.screenLeft+runtimeStyle.shiftLeft+document."+$viewport+".scrollLeft")}};eval(A(positionLeft));function getScreenLeft(a){var b=a.offsetLeft,c=1;if(a.runtimeStyle.autoLeft){b=s.clientWidth-a.offsetWidth-getPixelWidth(a,a.currentStyle.right)}if(a.currentStyle.marginLeft!="auto"){b-=getPixelWidth(a,a.currentStyle.marginLeft)}while(a=a.offsetParent){if(a.currentStyle.position!="static")c=-1;b+=a.offsetLeft*c}return b};eval(A(getScreenLeft));function getPixelWidth(a,b){return J.test(b)?parseInt(parseFloat(b)/100*s.clientWidth):E(a,b)};eval(A(getPixelWidth));function _g(){var a=_2.elements;for(var b in a)_8(a[b]);a=_6.elements;for(b in a){_4(a[b],true);_4(a[b],true)}_7=0};var _7;bq(function(){if(!_7)_7=setTimeout(_g,0)})};var bk={backgroundColor:"transparent",backgroundImage:"none",backgroundPositionX:null,backgroundPositionY:null,backgroundRepeat:null,borderTopWidth:0,borderRightWidth:0,borderBottomWidth:0,borderLeftStyle:"none",borderTopStyle:"none",borderRightStyle:"none",borderBottomStyle:"none",borderLeftWidth:0,height:null,marginTop:0,marginBottom:0,marginRight:0,marginLeft:0,width:"100%"};IE7.CSS.addRecalc("overflow","visible",function(a){if(a.parentNode.ie7_wrapped)return;if(IE7.Layout&&a.currentStyle["max-height"]!="auto"){IE7.Layout.maxHeight(a)}if(a.currentStyle.marginLeft=="auto")a.style.marginLeft=0;if(a.currentStyle.marginRight=="auto")a.style.marginRight=0;var b=document.createElement(bA);b.ie7_wrapped=a;for(var c in bk){b.style[c]=a.currentStyle[c];if(bk[c]!=null){a.runtimeStyle[c]=bk[c]}}b.style.display="block";b.style.position="relative";a.runtimeStyle.position="absolute";a.parentNode.insertBefore(b,a);b.appendChild(a)});function cf(){var f="xx-small,x-small,small,medium,large,x-large,xx-large".split(",");for(var g=0;g<f.length;g++){f[f[g]]=f[g-1]||"0.67em"}IE7.CSS.addFix(/(font(-size)?\s*:\s*)([\w.-]+)/,function(a,b,c,d){return b+(f[d]||d)});if(k<6){var h=/^\-/,p=/(em|ex)$/i;var t=/em$/i,q=/ex$/i;E=function(a,b){if(bL.test(b))return parseInt(b)||0;var c=h.test(b)?-1:1;if(p.test(b))c*=u(a);j.style.width=(c<0)?b.slice(1):b;v.appendChild(j);b=c*j.offsetWidth;j.removeNode();return parseInt(b)};var j=bN();function u(a){var b=1;j.style.fontFamily=a.currentStyle.fontFamily;j.style.lineHeight=a.currentStyle.lineHeight;while(a!=v){var c=a.currentStyle["ie7-font-size"];if(c){if(t.test(c))b*=parseFloat(c);else if(J.test(c))b*=(parseFloat(c)/100);else if(q.test(c))b*=(parseFloat(c)/2);else{j.style.fontSize=c;return 1}}a=a.parentElement}return b};IE7.CSS.addFix(/cursor\s*:\s*pointer/,"cursor:hand");IE7.CSS.addFix(/display\s*:\s*list-item/,"display:block")}function l(a){if(k<5.5)IE7.Layout.boxSizing(a.parentElement);var b=a.parentElement;var c=b.offsetWidth-a.offsetWidth-r(b);var d=(a.currentStyle["ie7-margin"]&&a.currentStyle.marginRight=="auto")||a.currentStyle["ie7-margin-right"]=="auto";switch(b.currentStyle.textAlign){case"right":c=d?parseInt(c/2):0;a.runtimeStyle.marginRight=c+"px";break;case"center":if(d)c=0;default:if(d)c/=2;a.runtimeStyle.marginLeft=parseInt(c)+"px"}};function r(a){return E(a,a.currentStyle.paddingLeft)+E(a,a.currentStyle.paddingRight)};IE7.CSS.addRecalc("margin(-left|-right)?","[^};]*auto",function(a){if(R(l,a,a.parentElement&&a.currentStyle.display=="block"&&a.currentStyle.marginLeft=="auto"&&a.currentStyle.position!="absolute")){l(a)}});bq(function(){for(var a in l.elements){var b=l.elements[a];b.runtimeStyle.marginLeft=b.runtimeStyle.marginRight="";l(b)}})};IE7.loaded=true;(function(){try{bm.doScroll("left")}catch(e){setTimeout(arguments.callee,1);return}try{eval(bB.innerHTML)}catch(e){}bi=new RegExp(bb(typeof IE7_PNG_SUFFIX=="string"?IE7_PNG_SUFFIX:"-trans.png")+"$","i");v=document.body;s=C?v:bm;v.className+=" ie7_body";bm.className+=" ie7_html";if(C)cf();IE7.CSS.init();IE7.HTML.init();IE7.HTML.apply();IE7.CSS.apply();IE7.recalc()})()})();
Index: admin/js/ie7/IE8.js
===================================================================
--- admin/js/ie7/IE8.js	(revision 0)
+++ admin/js/ie7/IE8.js	(revision 0)
@@ -0,0 +1,2 @@
+/* IE7/IE8.js - copyright 2004-2008, Dean Edwards */
+(function(){IE7={toString:function(){return"IE7 version 2.0 (beta2)"}};var m=IE7.appVersion=navigator.appVersion.match(/MSIE (\d\.\d)/)[1];if(/ie7_off/.test(top.location.search)||m<5)return;var U=bT();var G=document.compatMode!="CSS1Compat";var bx=document.documentElement,w,t;var bN="!";var J=":link{ie7-link:link}:visited{ie7-link:visited}";var cB=/^[\w\.]+[^:]*$/;function bc(a,b){if(cB.test(a))a=(b||"")+a;return a};function by(a,b){a=bc(a,b);return a.slice(0,a.lastIndexOf("/")+1)};var bO=document.scripts[document.scripts.length-1];var cC=by(bO.src);try{var K=new ActiveXObject("Microsoft.XMLHTTP")}catch(e){}var bd={};function cD(a,b){try{a=bc(a,b);if(!bd[a]){K.open("GET",a,false);K.send();if(K.status==0||K.status==200){bd[a]=K.responseText}}}catch(e){}finally{return bd[a]||""}};if(m<5.5){undefined=U();bN="HTML:!";var cE=/(g|gi)$/;var cF=String.prototype.replace;String.prototype.replace=function(a,b){if(typeof b=="function"){if(a&&a.constructor==RegExp){var c=a;var d=c.global;if(d==null)d=cE.test(c);if(d)c=new RegExp(c.source)}else{c=new RegExp(W(a))}var f,g=this,h="";while(g&&(f=c.exec(g))){h+=g.slice(0,f.index)+b.apply(this,f);g=g.slice(f.index+f[0].length);if(!d)break}return h+g}return cF.apply(this,arguments)};Array.prototype.pop=function(){if(this.length){var a=this[this.length-1];this.length--;return a}return undefined};Array.prototype.push=function(){for(var a=0;a<arguments.length;a++){this[this.length]=arguments[a]}return this.length};var cG=this;Function.prototype.apply=function(a,b){if(a===undefined)a=cG;else if(a==null)a=window;else if(typeof a=="string")a=new String(a);else if(typeof a=="number")a=new Number(a);else if(typeof a=="boolean")a=new Boolean(a);if(arguments.length==1)b=[];else if(b[0]&&b[0].writeln)b[0]=b[0].documentElement.document||b[0];var c="#ie7_apply",d;a[c]=this;switch(b.length){case 0:d=a[c]();break;case 1:d=a[c](b[0]);break;case 2:d=a[c](b[0],b[1]);break;case 3:d=a[c](b[0],b[1],b[2]);break;case 4:d=a[c](b[0],b[1],b[2],b[3]);break;case 5:d=a[c](b[0],b[1],b[2],b[3],b[4]);break;default:var f=[],g=b.length-1;do f[g]="a["+g+"]";while(g--);eval("r=o[$]("+f+")")}if(typeof a.valueOf=="function"){delete a[c]}else{a[c]=undefined;if(d&&d.writeln)d=d.documentElement.document||d}return d};Function.prototype.call=function(a){return this.apply(a,bP.apply(arguments,[1]))};J+="address,blockquote,body,dd,div,dt,fieldset,form,"+"frame,frameset,h1,h2,h3,h4,h5,h6,iframe,noframes,object,p,"+"hr,applet,center,dir,menu,pre,dl,li,ol,ul{display:block}"}var bP=Array.prototype.slice;var cZ=/%([1-9])/g;var cH=/^\s\s*/;var cI=/\s\s*$/;var cJ=/([\/()[\]{}|*+-.,^$?\\])/g;var bQ=/\bbase\b/;var bR=["constructor","toString"];var be;function B(){};B.extend=function(a,b){be=true;var c=new this;bf(c,a);be=false;var d=c.constructor;function f(){if(!be)d.apply(this,arguments)};c.constructor=f;f.extend=arguments.callee;bf(f,b);f.prototype=c;return f};B.prototype.extend=function(a){return bf(this,a)};var bz="#";var V="~";var cK=/\\./g;var cL=/\(\?[:=!]|\[[^\]]+\]/g;var cM=/\(/g;var H=B.extend({constructor:function(a){this[V]=[];this.merge(a)},exec:function(g){var h=this,j=this[V];return String(g).replace(new RegExp(this,this.ignoreCase?"gi":"g"),function(){var a,b=1,c=0;while((a=h[bz+j[c++]])){var d=b+a.length+1;if(arguments[b]){var f=a.replacement;switch(typeof f){case"function":return f.apply(h,bP.call(arguments,b,d));case"number":return arguments[b+f];default:return f}}b=d}})},add:function(a,b){if(a instanceof RegExp){a=a.source}if(!this[bz+a])this[V].push(String(a));this[bz+a]=new H.Item(a,b)},merge:function(a){for(var b in a)this.add(b,a[b])},toString:function(){return"("+this[V].join(")|(")+")"}},{IGNORE:"$0",Item:B.extend({constructor:function(a,b){a=a instanceof RegExp?a.source:String(a);if(typeof b=="number")b=String(b);else if(b==null)b="";if(typeof b=="string"&&/\$(\d+)/.test(b)){if(/^\$\d+$/.test(b)){b=parseInt(b.slice(1))}else{var c=/'/.test(b.replace(/\\./g,""))?'"':"'";b=b.replace(/\n/g,"\\n").replace(/\r/g,"\\r").replace(/\$(\d+)/g,c+"+(arguments[$1]||"+c+c+")+"+c);b=new Function("return "+c+b.replace(/(['"])\1\+(.*)\+\1\1$/,"$1")+c)}}this.length=H.count(a);this.replacement=b;this.toString=bT(a)}}),count:function(a){a=String(a).replace(cK,"").replace(cL,"");return L(a,cM).length}});function bf(a,b){if(a&&b){var c=(typeof b=="function"?Function:Object).prototype;var d=bR.length,f;if(be)while(f=bR[--d]){var g=b[f];if(g!=c[f]){if(bQ.test(g)){bS(a,f,g)}else{a[f]=g}}}for(f in b)if(c[f]===undefined){var g=b[f];if(a[f]&&typeof g=="function"&&bQ.test(g)){bS(a,f,g)}else{a[f]=g}}}return a};function bS(c,d,f){var g=c[d];c[d]=function(){var a=this.base;this.base=g;var b=f.apply(this,arguments);this.base=a;return b}};function cN(a,b){if(!b)b=a;var c={};for(var d in a)c[d]=b[d];return c};function i(c){var d=arguments;var f=new RegExp("%([1-"+arguments.length+"])","g");return String(c).replace(f,function(a,b){return b<d.length?d[b]:a})};function L(a,b){return String(a).match(b)||[]};function W(a){return String(a).replace(cJ,"\\$1")};function da(a){return String(a).replace(cH,"").replace(cI,"")};function bT(a){return function(){return a}};var bU=H.extend({ignoreCase:true});var cO=/\x01(\d+)/g,cP=/'/g,cQ=/^\x01/,cR=/\\([\da-fA-F]{1,4})/g;var bA=[];var bV=new bU({"<!\\-\\-|\\-\\->":"","\\/\\*[^*]*\\*+([^\\/][^*]*\\*+)*\\/":"","@(namespace|import)[^;\\n]+[;\\n]":"","'(\\\\.|[^'\\\\])*'":bW,'"(\\\\.|[^"\\\\])*"':bW,"\\s+":" "});function cS(a){return bV.exec(a)};function bg(c){return c.replace(cO,function(a,b){return bA[b-1]})};function bW(c){return"\x01"+bA.push(c.replace(cR,function(a,b){return eval("'\\u"+"0000".slice(b.length)+b+"'")}).slice(1,-1).replace(cP,"\\'"))};function bB(a){return cQ.test(a)?bA[a.slice(1)-1]:a};var cT=new H({Width:"Height",width:"height",Left:"Top",left:"top",Right:"Bottom",right:"bottom",onX:"onY"});function C(a){return cT.exec(a)};var bX=[];function bC(a){cV(a);v(window,"onresize",a)};function v(a,b,c){a.attachEvent(b,c);bX.push(arguments)};function cU(a,b,c){try{a.detachEvent(b,c)}catch(ignore){}};v(window,"onunload",function(){var a;while(a=bX.pop()){cU(a[0],a[1],a[2])}});function X(a,b,c){if(!a.elements)a.elements={};if(c)a.elements[b.uniqueID]=b;else delete a.elements[b.uniqueID];return c};v(window,"onbeforeprint",function(){if(!IE7.CSS.print)new bJ("print");IE7.CSS.print.recalc()});var bY=/^\d+(px)?$/i;var M=/^\d+%$/;var D=function(a,b){if(bY.test(b))return parseInt(b);var c=a.style.left;var d=a.runtimeStyle.left;a.runtimeStyle.left=a.currentStyle.left;a.style.left=b||0;b=a.style.pixelLeft;a.style.left=c;a.runtimeStyle.left=d;return b};var bD="ie7-";var bZ=B.extend({constructor:function(){this.fixes=[];this.recalcs=[]},init:U});var bE=[];function cV(a){bE.push(a)};IE7.recalc=function(){IE7.HTML.recalc();IE7.CSS.recalc();for(var a=0;a<bE.length;a++)bE[a]()};function bh(a){return a.currentStyle["ie7-position"]=="fixed"};function bF(a,b){return a.currentStyle[bD+b]||a.currentStyle[b]};function N(a,b,c){if(a.currentStyle[bD+b]==null){a.runtimeStyle[bD+b]=a.currentStyle[b]}a.runtimeStyle[b]=c};function ca(a){var b=document.createElement(a||"object");b.style.cssText="position:absolute;padding:0;display:block;border:none;clip:rect(0 0 0 0);left:-9999";b.ie7_anon=true;return b};function x(a,b,c){if(!bj[a]){I=[];var d="";var f=E.escape(a).split(",");for(var g=0;g<f.length;g++){p=l=y=0;Y=f.length>1?2:0;var h=E.exec(f[g])||"if(0){";if(p){h+=i("if(e%1.nodeName!='!'){",l)}var j=Y>1?ch:"";h+=i(j+ci,l);h+=Array(L(h,/\{/g).length+1).join("}");d+=h}eval(i(cj,I)+E.unescape(d)+"return s?null:r}");bj[a]=_k}return bj[a](b||document,c)};var bi=m<6;var cb=/^(href|src)$/;var bG={"class":"className","for":"htmlFor"};IE7._1=1;IE7._e=function(a,b){var c=a.all[b]||null;if(!c||c.id==b)return c;for(var d=0;d<c.length;d++){if(c[d].id==b)return c[d]}return null};IE7._f=function(a,b){if(b=="src"&&a.pngSrc)return a.pngSrc;var c=bi?(a.attributes[b]||a.attributes[bG[b.toLowerCase()]]):a.getAttributeNode(b);if(c&&(c.specified||b=="value")){if(cb.test(b)){return a.getAttribute(b,2)}else if(b=="class"){return a.className.replace(/\sie7_\w+/g,"")}else if(b=="style"){return a.style.cssText}else{return c.nodeValue}}return null};var cc="colSpan,rowSpan,vAlign,dateTime,accessKey,tabIndex,encType,maxLength,readOnly,longDesc";bf(bG,cN(cc.toLowerCase().split(","),cc.split(",")));IE7._3=function(a){while(a&&(a=a.nextSibling)&&(a.nodeType!=1||a.nodeName=="!"))continue;return a};IE7._4=function(a){while(a&&(a=a.previousSibling)&&(a.nodeType!=1||a.nodeName=="!"))continue;return a};var cW=/([\s>+~,]|[^(]\+|^)([#.:\[])/g,cX=/(^|,)([^\s>+~])/g,cY=/\s*([\s>+~(),]|^|$)\s*/g,cd=/\s\*\s/g;var ce=H.extend({constructor:function(a){this.base(a);this.sorter=new H;this.sorter.add(/:not\([^)]*\)/,H.IGNORE);this.sorter.add(/([ >](\*|[\w-]+))([^: >+~]*)(:\w+-child(\([^)]+\))?)([^: >+~]*)/,"$1$3$6$4")},ignoreCase:true,escape:function(a){return this.optimise(this.format(a))},format:function(a){return a.replace(cY,"$1").replace(cX,"$1 $2").replace(cW,"$1*$2")},optimise:function(a){return this.sorter.exec(a.replace(cd,">* "))},unescape:function(a){return bg(a)}});var cf={"":"%1!=null","=":"%1=='%2'","~=":/(^| )%1( |$)/,"|=":/^%1(-|$)/,"^=":/^%1/,"$=":/%1$/,"*=":/%1/};var bH={"first-child":"!IE7._4(e%1)","link":"e%1.currentStyle['ie7-link']=='link'","visited":"e%1.currentStyle['ie7-link']=='visited'"};var bI="var p%2=0,i%2,e%2,n%2=e%1.";var cg="e%1.sourceIndex";var ch="var g="+cg+";if(!p[g]){p[g]=1;";var ci="r[r.length]=e%1;if(s)return e%1;";var cj="var _k=function(e0,s){IE7._1++;var r=[],p={},reg=[%1],d=document;";var I;var l;var p;var y;var Y;var bj={};var E=new ce({" (\\*|[\\w-]+)#([\\w-]+)":function(a,b,c){p=false;var d="var e%2=IE7._e(d,'%4');if(e%2&&";if(b!="*")d+="e%2.nodeName=='%3'&&";d+="(e%1==d||e%1.contains(e%2))){";if(y)d+=i("i%1=n%1.length;",y);return i(d,l++,l,b.toUpperCase(),c)}," (\\*|[\\w-]+)":function(a,b){Y++;p=b=="*";var c=bI;c+=(p&&bi)?"all":"getElementsByTagName('%3')";c+=";for(i%2=0;(e%2=n%2[i%2]);i%2++){";return i(c,l++,y=l,b.toUpperCase())},">(\\*|[\\w-]+)":function(a,b){var c=y;p=b=="*";var d=bI;d+=c?"children":"childNodes";if(!p&&c)d+=".tags('%3')";d+=";for(i%2=0;(e%2=n%2[i%2]);i%2++){";if(p){d+="if(e%2.nodeType==1){";p=bi}else{if(!c)d+="if(e%2.nodeName=='%3'){"}return i(d,l++,y=l,b.toUpperCase())},"\\+(\\*|[\\w-]+)":function(a,b){var c="";if(p)c+="if(e%1.nodeName!='!'){";p=false;c+="e%1=IE7._3(e%1);if(e%1";if(b!="*")c+="&&e%1.nodeName=='%2'";c+="){";return i(c,l,b.toUpperCase())},"~(\\*|[\\w-]+)":function(a,b){var c="";if(p)c+="if(e%1.nodeName!='!'){";p=false;Y=2;c+="while(e%1=e%1.nextSibling){if(e%1.ie7_adjacent==IE7._1)break;if(";if(b=="*"){c+="e%1.nodeType==1";if(bi)c+="&&e%1.nodeName!='!'"}else c+="e%1.nodeName=='%2'";c+="){e%1.ie7_adjacent=IE7._1;";return i(c,l,b.toUpperCase())},"#([\\w-]+)":function(a,b){p=false;var c="if(e%1.id=='%2'){";if(y)c+=i("i%1=n%1.length;",y);return i(c,l,b)},"\\.([\\w-]+)":function(a,b){p=false;I.push(new RegExp("(^|\\s)"+W(b)+"(\\s|$)"));return i("if(e%1.className&&reg[%2].test(e%1.className)){",l,I.length-1)},"\\[([\\w-]+)\\s*([^=]?=)?\\s*([^\\]]*)\\]":function(a,b,c,d){var f=bG[b]||b;if(c){var g="e%1.getAttribute('%2',2)";if(!cb.test(b)){g="e%1.%3||"+g}b=i("("+g+")",l,b,f)}else{b=i("IE7._f(e%1,'%2')",l,b)}var h=cf[c||""]||"0";if(h&&h.source){I.push(new RegExp(i(h.source,W(E.unescape(d)))));h="reg[%2].test(%1)";d=I.length-1}return"if("+i(h,b,d)+"){"},":+([\\w-]+)(\\(([^)]+)\\))?":function(a,b,c,d){b=bH[b];return"if("+(b?i(b,l,d||""):"0")+"){"}});var ck=/a(#[\w-]+)?(\.[\w-]+)?:(hover|active)/i;var cl=/\s*\{\s*/,cm=/\s*\}\s*/,cn=/\s*\,\s*/;var co=/(.*)(:first-(line|letter))/;var z=document.styleSheets;IE7.CSS=new(bZ.extend({parser:new bU,screen:"",print:"",styles:[],rules:[],pseudoClasses:m<7?"first\\-child":"",dynamicPseudoClasses:{toString:function(){var a=[];for(var b in this)a.push(b);return a.join("|")}},init:function(){var a="^\x01$";var b="\\[class=?[^\\]]*\\]";var c=[];if(this.pseudoClasses)c.push(this.pseudoClasses);var d=this.dynamicPseudoClasses.toString();if(d)c.push(d);c=c.join("|");var f=m<7?["[>+~[(]|([:.])\\w+\\1"]:[b];if(c)f.push(":("+c+")");this.UNKNOWN=new RegExp(f.join("|")||a,"i");var g=m<7?["\\[[^\\]]+\\]|[^\\s(\\[]+\\s*[+~]"]:[b];var h=g.concat();if(c)h.push(":("+c+")");o.COMPLEX=new RegExp(h.join("|")||a,"ig");if(this.pseudoClasses)g.push(":("+this.pseudoClasses+")");O.COMPLEX=new RegExp(g.join("|")||a,"i");O.MATCH=new RegExp(d?"(.*):("+d+")(.*)":a,"i");this.createStyleSheet();this.refresh()},addEventHandler:function(){v.apply(null,arguments)},addFix:function(a,b){this.parser.add(a,b)},addRecalc:function(c,d,f,g){d=new RegExp("([{;\\s])"+c+"\\s*:\\s*"+d+"[^;}]*");var h=this.recalcs.length;if(g)g=c+":"+g;this.addFix(d,function(a,b){return(g?b+g:a)+";ie7-"+a.slice(1)+";ie7_recalc"+h+":1"});this.recalcs.push(arguments);return h},apply:function(){this.getInlineStyles();new bJ("screen");this.trash()},createStyleSheet:function(){this.styleSheet=document.createStyleSheet();this.styleSheet.ie7=true;this.styleSheet.owningElement.ie7=true;this.styleSheet.cssText=J},getInlineStyles:function(){var a=document.getElementsByTagName("style"),b;for(var c=a.length-1;(b=a[c]);c--){if(!b.disabled&&!b.ie7){this.styles.push(b.innerHTML)}}},getText:function(a,b){try{var c=a.cssText}catch(e){c=""}if(K)c=cD(a.href,b)||c;return c},recalc:function(){this.screen.recalc();var a=/ie7_recalc\d+/g;var b=J.match(/[{,]/g).length;var c=b+(this.screen.cssText.match(/\{/g)||"").length;var d=this.styleSheet.rules,f;var g,h,j,q,r,k,u,n;for(r=b;r<c;r++){f=d[r];var s=f.style.cssText;if(f&&(g=s.match(a))){j=x(f.selectorText);if(j.length)for(k=0;k<g.length;k++){n=g[k];h=IE7.CSS.recalcs[n.slice(10)][2];for(u=0;(q=j[u]);u++){if(q.currentStyle[n])h(q,s)}}}}},refresh:function(){this.styleSheet.cssText=J+this.screen+this.print},trash:function(){for(var a=0;a<z.length;a++){if(!z[a].ie7){try{var b=z[a].cssText}catch(e){b=""}if(b)z[a].cssText=""}}}}));var bJ=B.extend({constructor:function(a){this.media=a;this.load();IE7.CSS[a]=this;IE7.CSS.refresh()},createRule:function(a,b){if(IE7.CSS.UNKNOWN.test(a)){var c;if(F&&(c=a.match(F.MATCH))){return new F(c[1],c[2],b)}else if(c=a.match(O.MATCH)){if(!ck.test(c[0])||O.COMPLEX.test(c[0])){return new O(a,c[1],c[2],c[3],b)}}else return new o(a,b)}return a+" {"+b+"}"},getText:function(){var h=[].concat(IE7.CSS.styles);var j=/@media\s+([^{]*)\{([^@]+\})\s*\}/gi;var q=/\ball\b|^$/i,r=/\bscreen\b/i,k=/\bprint\b/i;function u(a,b){n.value=b;return a.replace(j,n)};function n(a,b,c){b=s(b);switch(b){case"screen":case"print":if(b!=n.value)return"";case"all":return c}return""};function s(a){if(q.test(a))return"all";else if(r.test(a))return(k.test(a))?"all":"screen";else if(k.test(a))return"print"};var R=this;function S(a,b,c,d){var f="";if(!d){c=s(a.media);d=0}if(c=="all"||c==R.media){if(d<3){for(var g=0;g<a.imports.length;g++){f+=S(a.imports[g],by(a.href,b),c,d+1)}}f+=cS(a.href?cy(a,b):h.pop()||"");f=u(f,R.media)}return f};var bw={};function cy(a,b){var c=bc(a.href,b);if(bw[c])return"";bw[c]=(a.disabled)?"":cA(IE7.CSS.getText(a,b),by(a.href,b));return bw[c]};var cz=/(url\s*\(\s*['"]?)([\w\.]+[^:\)]*['"]?\))/gi;function cA(a,b){return a.replace(cz,"$1"+b.slice(0,b.lastIndexOf("/")+1)+"$2")};for(var T=0;T<z.length;T++){if(!z[T].disabled&&!z[T].ie7){this.cssText+=S(z[T])}}},load:function(){this.cssText="";this.getText();this.parse();this.cssText=bg(this.cssText);bd={}},parse:function(){this.cssText=IE7.CSS.parser.exec(this.cssText);var a=IE7.CSS.rules.length;var b=this.cssText.split(cm),c;var d,f,g,h;for(g=0;g<b.length;g++){c=b[g].split(cl);d=c[0].split(cn);f=c[1];for(h=0;h<d.length;h++){d[h]=f?this.createRule(d[h],f):""}b[g]=d.join("\n")}this.cssText=b.join("\n");this.rules=IE7.CSS.rules.slice(a)},recalc:function(){var a,b;for(b=0;(a=this.rules[b]);b++)a.recalc()},toString:function(){return"@media "+this.media+"{"+this.cssText+"}"}});var F;var o=IE7.Rule=B.extend({constructor:function(a,b){this.id=IE7.CSS.rules.length;this.className=o.PREFIX+this.id;a=a.match(co)||a||"*";this.selector=a[1]||a;this.selectorText=this.parse(this.selector)+(a[2]||"");this.cssText=b;this.MATCH=new RegExp("\\s"+this.className+"(\\s|$)","g");IE7.CSS.rules.push(this);this.init()},init:U,add:function(a){a.className+=" "+this.className},recalc:function(){var a=x(this.selector);for(var b=0;b<a.length;b++)this.add(a[b])},parse:function(a){var b=a.replace(o.CHILD," ").replace(o.COMPLEX,"");if(m<7)b=b.replace(o.MULTI,"");var c=L(b,o.TAGS).length-L(a,o.TAGS).length;var d=L(b,o.CLASSES).length-L(a,o.CLASSES).length+1;while(d>0&&o.CLASS.test(b)){b=b.replace(o.CLASS,"");d--}while(c>0&&o.TAG.test(b)){b=b.replace(o.TAG,"$1*");c--}b+="."+this.className;d=Math.min(d,2);c=Math.min(c,2);var f=-10*d-c;if(f>0){b=b+","+o.MAP[f]+" "+b}return b},remove:function(a){a.className=a.className.replace(this.MATCH,"$1")},toString:function(){return i("%1 {%2}",this.selectorText,this.cssText)}},{CHILD:/>/g,CLASS:/\.[\w-]+/,CLASSES:/[.:\[]/g,MULTI:/(\.[\w-]+)+/g,PREFIX:"ie7_class",TAG:/^\w+|([\s>+~])\w+/,TAGS:/^\w|[\s>+~]\w/g,MAP:{1:"html",2:"html body",10:".ie7_html",11:"html.ie7_html",12:"html.ie7_html body",20:".ie7_html .ie7_body",21:"html.ie7_html .ie7_body",22:"html.ie7_html body.ie7_body"}});var O=o.extend({constructor:function(a,b,c,d,f){this.attach=b||"*";this.dynamicPseudoClass=IE7.CSS.dynamicPseudoClasses[c];this.target=d;this.base(a,f)},recalc:function(){var a=x(this.attach),b;for(var c=0;b=a[c];c++){var d=this.target?x(this.target,b):[b];if(d.length)this.dynamicPseudoClass.apply(b,d,this)}}});var A=B.extend({constructor:function(a,b){this.name=a;this.apply=b;this.instances={};IE7.CSS.dynamicPseudoClasses[a]=this},register:function(a){var b=a[2];a.id=b.id+a[0].uniqueID;if(!this.instances[a.id]){var c=a[1],d;for(d=0;d<c.length;d++)b.add(c[d]);this.instances[a.id]=a}},unregister:function(a){if(this.instances[a.id]){var b=a[2];var c=a[1],d;for(d=0;d<c.length;d++)b.remove(c[d]);delete this.instances[a.id]}}});if(m<7){var Z=new A("hover",function(a){var b=arguments;IE7.CSS.addEventHandler(a,m<5.5?"onmouseover":"onmouseenter",function(){Z.register(b)});IE7.CSS.addEventHandler(a,m<5.5?"onmouseout":"onmouseleave",function(){Z.unregister(b)})});v(document,"onmouseup",function(){var a=Z.instances;for(var b in a)if(!a[b][0].contains(event.srcElement))Z.unregister(a[b])})}IE7.CSS.addRecalc("[\\w-]+","inherit",function(c,d){var f=d.match(/[\w-]+\s*:\s*inherit/g);for(var g=0;g<f.length;g++){var h=f[g].replace(/ie7\-|\s*:\s*inherit/g,"").replace(/\-([a-z])/g,function(a,b){return b.toUpperCase()});c.runtimeStyle[h]=c.parentElement.currentStyle[h]}});IE7.HTML=new(bZ.extend({fixed:{},init:U,addFix:function(){this.fixes.push(arguments)},apply:function(){for(var a=0;a<this.fixes.length;a++){var b=x(this.fixes[a][0]);var c=this.fixes[a][1];for(var d=0;d<b.length;d++)c(b[d])}},addRecalc:function(){this.recalcs.push(arguments)},recalc:function(){for(var a=0;a<this.recalcs.length;a++){var b=x(this.recalcs[a][0]);var c=this.recalcs[a][1],d;var f=Math.pow(2,a);for(var g=0;(d=b[g]);g++){var h=d.uniqueID;if((this.fixed[h]&f)==0){d=c(d)||d;this.fixed[h]|=f}}}}}));if(m<7){document.createElement("abbr");IE7.HTML.addRecalc("label",function(a){if(!a.htmlFor){var b=x("input,textarea",a,true);if(b){v(a,"onclick",function(){b.click()})}}})}var P="[.\\d]";new function(_){var layout=IE7.Layout=this;J+="*{boxSizing:content-box}";IE7.hasLayout=m<5.5?function(a){return a.clientWidth}:function(a){return a.currentStyle.hasLayout};layout.boxSizing=function(a){if(!IE7.hasLayout(a)){a.style.height="0cm";if(a.currentStyle.verticalAlign=="auto")a.runtimeStyle.verticalAlign="top";collapseMargins(a)}};function collapseMargins(a){if(a!=t&&a.currentStyle.position!="absolute"){collapseMargin(a,"marginTop");collapseMargin(a,"marginBottom")}};function collapseMargin(a,b){if(!a.runtimeStyle[b]){var c=a.parentElement;if(c&&IE7.hasLayout(c)&&!IE7[b=="marginTop"?"_4":"_3"](a))return;var d=x(">*:"+(b=="marginTop"?"first":"last")+"-child",a,true);if(d&&d.currentStyle.styleFloat=="none"&&IE7.hasLayout(d)){collapseMargin(d,b);margin=_b(a,a.currentStyle[b]);childMargin=_b(d,d.currentStyle[b]);if(margin<0||childMargin<0){a.runtimeStyle[b]=margin+childMargin}else{a.runtimeStyle[b]=Math.max(childMargin,margin)}d.runtimeStyle[b]="0px"}}};function _b(a,b){return b=="auto"?0:D(a,b)};var UNIT=/^[.\d][\w%]*$/,AUTO=/^(auto|0cm)$/;var applyWidth,applyHeight;IE7.Layout.borderBox=function(a){applyWidth(a);applyHeight(a)};var fixWidth=function(g){applyWidth=function(a){if(!M.test(a.currentStyle.width))h(a);collapseMargins(a)};function h(a,b){if(!a.runtimeStyle.fixedWidth){if(!b)b=a.currentStyle.width;a.runtimeStyle.fixedWidth=(UNIT.test(b))?Math.max(0,r(a,b)):b;N(a,"width",a.runtimeStyle.fixedWidth)}};function j(a){if(!bh(a)){var b=a.offsetParent;while(b&&!IE7.hasLayout(b))b=b.offsetParent}return(b||t).clientWidth};function q(a,b){if(M.test(b))return parseInt(parseFloat(b)/100*j(a));return D(a,b)};var r=function(a,b){var c=a.currentStyle["box-sizing"]=="border-box";var d=0;if(G&&!c)d+=k(a)+u(a,"padding");else if(!G&&c)d-=k(a)+u(a,"padding");return q(a,b)+d};function k(a){return a.offsetWidth-a.clientWidth};function u(a,b){return q(a,a.currentStyle[b+"Left"])+q(a,a.currentStyle[b+"Right"])};J+="*{minWidth:none;maxWidth:none;min-width:none;max-width:none}";layout.minWidth=function(a){if(a.currentStyle["min-width"]!=null){a.style.minWidth=a.currentStyle["min-width"]}if(X(arguments.callee,a,a.currentStyle.minWidth!="none")){layout.boxSizing(a);h(a);n(a)}};eval("IE7.Layout.maxWidth="+String(layout.minWidth).replace(/min/g,"max"));function n(a){var b=a.getBoundingClientRect();var c=b.right-b.left;if(a.currentStyle.minWidth!="none"&&c<=r(a,a.currentStyle.minWidth)){a.runtimeStyle.width=a.currentStyle.minWidth}else if(a.currentStyle.maxWidth!="none"&&c>=r(a,a.currentStyle.maxWidth)){a.runtimeStyle.width=a.currentStyle.maxWidth}else{a.runtimeStyle.width=a.runtimeStyle.fixedWidth}};function s(a){if(X(s,a,/^(fixed|absolute)$/.test(a.currentStyle.position)&&bF(a,"left")!="auto"&&bF(a,"right")!="auto"&&AUTO.test(bF(a,"width")))){R(a);IE7.Layout.boxSizing(a)}};IE7.Layout.fixRight=s;function R(a){var b=q(a,a.runtimeStyle._c||a.currentStyle.left);var c=j(a)-q(a,a.currentStyle.right)-b-u(a,"margin");if(parseInt(a.runtimeStyle.width)==c)return;a.runtimeStyle.width="";if(bh(a)||g||a.offsetWidth<c){if(!G)c-=k(a)+u(a,"padding");if(c<0)c=0;a.runtimeStyle.fixedWidth=c;N(a,"width",c)}};var S=0;bC(function(){if(!t)return;var a,b=(S<t.clientWidth);S=t.clientWidth;var c=layout.minWidth.elements;for(a in c){var d=c[a];var f=(parseInt(d.runtimeStyle.width)==r(d,d.currentStyle.minWidth));if(b&&f)d.runtimeStyle.width="";if(b==f)n(d)}var c=layout.maxWidth.elements;for(a in c){var d=c[a];var f=(parseInt(d.runtimeStyle.width)==r(d,d.currentStyle.maxWidth));if(!b&&f)d.runtimeStyle.width="";if(b!=f)n(d)}for(a in s.elements)R(s.elements[a])});if(G){IE7.CSS.addRecalc("width",P,applyWidth)}if(m<7){IE7.CSS.addRecalc("min-width",P,layout.minWidth);IE7.CSS.addRecalc("max-width",P,layout.maxWidth);IE7.CSS.addRecalc("right",P,s)}};eval("var fixHeight="+C(fixWidth));fixWidth();fixHeight(true)};var bk=bc("blank.gif",cC);var bl="DXImageTransform.Microsoft.AlphaImageLoader";var bK="progid:"+bl+"(src='%1',sizingMethod='%2')";var bm;var Q=[];function bL(a){if(bm.test(a.src)){var b=new Image(a.width,a.height);b.onload=function(){a.width=b.width;a.height=b.height;b=null};b.src=a.src;a.pngSrc=a.src;bo(a)}};if(m>=5.5&&m<7){IE7.CSS.addFix(/background(-image)?\s*:\s*([^};]*)?url\(([^\)]+)\)([^;}]*)?/,function(a,b,c,d,f){d=bB(d);return bm.test(d)?"filter:"+i(bK,d,"crop")+";zoom:1;background"+(b||"")+":"+(c||"")+"none"+(f||""):a});IE7.HTML.addRecalc("img,input",function(a){if(a.tagName=="INPUT"&&a.type!="image")return;bL(a);v(a,"onpropertychange",function(){if(!bn&&event.propertyName=="src"&&a.src.indexOf(bk)==-1)bL(a)})});var bn=false;v(window,"onbeforeprint",function(){bn=true;for(var a=0;a<Q.length;a++)cp(Q[a])});v(window,"onafterprint",function(){for(var a=0;a<Q.length;a++)bo(Q[a]);bn=false})}function bo(a,b){var c=a.filters[bl];if(c){c.src=a.src;c.enabled=true}else{a.runtimeStyle.filter=i(bK,a.src,b||"scale");Q.push(a)}a.src=bk};function cp(a){a.src=a.pngSrc;a.filters[bl].enabled=false};new function(_){if(m>=7)return;IE7.CSS.addRecalc("position","fixed",_8,"absolute");IE7.CSS.addRecalc("background(-attachment)?","[^};]*fixed",_5);var $viewport=G?"body":"documentElement";function _6(){if(w.currentStyle.backgroundAttachment!="fixed"){if(w.currentStyle.backgroundImage=="none"){w.runtimeStyle.backgroundRepeat="no-repeat";w.runtimeStyle.backgroundImage="url("+bk+")"}w.runtimeStyle.backgroundAttachment="fixed"}_6=U};var _0=ca("img");function _2(a){return a?bh(a)||_2(a.parentElement):false};function _d(a,b,c){setTimeout("document.all."+a.uniqueID+".runtimeStyle.setExpression('"+b+"','"+c+"')",0)};function _5(a){if(X(_5,a,a.currentStyle.backgroundAttachment=="fixed"&&!a.contains(w))){_6();bgLeft(a);bgTop(a);_a(a)}};function _a(a){_0.src=a.currentStyle.backgroundImage.slice(5,-2);var b=a.canHaveChildren?a:a.parentElement;b.appendChild(_0);setOffsetLeft(a);setOffsetTop(a);b.removeChild(_0)};function bgLeft(a){a.style.backgroundPositionX=a.currentStyle.backgroundPositionX;if(!_2(a)){_d(a,"backgroundPositionX","(parseInt(runtimeStyle.offsetLeft)+document."+$viewport+".scrollLeft)||0")}};eval(C(bgLeft));function setOffsetLeft(a){var b=_2(a)?"backgroundPositionX":"offsetLeft";a.runtimeStyle[b]=getOffsetLeft(a,a.style.backgroundPositionX)-a.getBoundingClientRect().left-a.clientLeft+2};eval(C(setOffsetLeft));function getOffsetLeft(a,b){switch(b){case"left":case"top":return 0;case"right":case"bottom":return t.clientWidth-_0.offsetWidth;case"center":return(t.clientWidth-_0.offsetWidth)/2;default:if(M.test(b)){return parseInt((t.clientWidth-_0.offsetWidth)*parseFloat(b)/100)}_0.style.left=b;return _0.offsetLeft}};eval(C(getOffsetLeft));function _8(a){if(X(_8,a,bh(a))){N(a,"position","absolute");N(a,"left",a.currentStyle.left);N(a,"top",a.currentStyle.top);_6();IE7.Layout.fixRight(a);_7(a)}};function _7(a,b){positionTop(a,b);positionLeft(a,b,true);if(!a.runtimeStyle.autoLeft&&a.currentStyle.marginLeft=="auto"&&a.currentStyle.right!="auto"){var c=t.clientWidth-getPixelWidth(a,a.currentStyle.right)-getPixelWidth(a,a.runtimeStyle._c)-a.clientWidth;if(a.currentStyle.marginRight=="auto")c=parseInt(c/2);if(_2(a.offsetParent))a.runtimeStyle.pixelLeft+=c;else a.runtimeStyle.shiftLeft=c}clipWidth(a);clipHeight(a)};function clipWidth(a){var b=a.runtimeStyle.fixWidth;a.runtimeStyle.borderRightWidth="";a.runtimeStyle.width=b?getPixelWidth(a,b):"";if(a.currentStyle.width!="auto"){var c=a.getBoundingClientRect();var d=a.offsetWidth-t.clientWidth+c.left-2;if(d>=0){a.runtimeStyle.borderRightWidth="0px";d=Math.max(D(a,a.currentStyle.width)-d,0);N(a,"width",d);return d}}};eval(C(clipWidth));function positionLeft(a,b){if(!b&&M.test(a.currentStyle.width)){a.runtimeStyle.fixWidth=a.currentStyle.width}if(a.runtimeStyle.fixWidth){a.runtimeStyle.width=getPixelWidth(a,a.runtimeStyle.fixWidth)}a.runtimeStyle.shiftLeft=0;a.runtimeStyle._c=a.currentStyle.left;a.runtimeStyle.autoLeft=a.currentStyle.right!="auto"&&a.currentStyle.left=="auto";a.runtimeStyle.left="";a.runtimeStyle.screenLeft=getScreenLeft(a);a.runtimeStyle.pixelLeft=a.runtimeStyle.screenLeft;if(!b&&!_2(a.offsetParent)){_d(a,"pixelLeft","runtimeStyle.screenLeft+runtimeStyle.shiftLeft+document."+$viewport+".scrollLeft")}};eval(C(positionLeft));function getScreenLeft(a){var b=a.offsetLeft,c=1;if(a.runtimeStyle.autoLeft){b=t.clientWidth-a.offsetWidth-getPixelWidth(a,a.currentStyle.right)}if(a.currentStyle.marginLeft!="auto"){b-=getPixelWidth(a,a.currentStyle.marginLeft)}while(a=a.offsetParent){if(a.currentStyle.position!="static")c=-1;b+=a.offsetLeft*c}return b};eval(C(getScreenLeft));function getPixelWidth(a,b){return M.test(b)?parseInt(parseFloat(b)/100*t.clientWidth):D(a,b)};eval(C(getPixelWidth));function _j(){var a=_5.elements;for(var b in a)_a(a[b]);a=_8.elements;for(b in a){_7(a[b],true);_7(a[b],true)}_9=0};var _9;bC(function(){if(!_9)_9=setTimeout(_j,0)})};var bp={backgroundColor:"transparent",backgroundImage:"none",backgroundPositionX:null,backgroundPositionY:null,backgroundRepeat:null,borderTopWidth:0,borderRightWidth:0,borderBottomWidth:0,borderLeftStyle:"none",borderTopStyle:"none",borderRightStyle:"none",borderBottomStyle:"none",borderLeftWidth:0,height:null,marginTop:0,marginBottom:0,marginRight:0,marginLeft:0,width:"100%"};IE7.CSS.addRecalc("overflow","visible",function(a){if(a.parentNode.ie7_wrapped)return;if(IE7.Layout&&a.currentStyle["max-height"]!="auto"){IE7.Layout.maxHeight(a)}if(a.currentStyle.marginLeft=="auto")a.style.marginLeft=0;if(a.currentStyle.marginRight=="auto")a.style.marginRight=0;var b=document.createElement(bN);b.ie7_wrapped=a;for(var c in bp){b.style[c]=a.currentStyle[c];if(bp[c]!=null){a.runtimeStyle[c]=bp[c]}}b.style.display="block";b.style.position="relative";a.runtimeStyle.position="absolute";a.parentNode.insertBefore(b,a);b.appendChild(a)});function cq(){var f="xx-small,x-small,small,medium,large,x-large,xx-large".split(",");for(var g=0;g<f.length;g++){f[f[g]]=f[g-1]||"0.67em"}IE7.CSS.addFix(/(font(-size)?\s*:\s*)([\w.-]+)/,function(a,b,c,d){return b+(f[d]||d)});if(m<6){var h=/^\-/,j=/(em|ex)$/i;var q=/em$/i,r=/ex$/i;D=function(a,b){if(bY.test(b))return parseInt(b)||0;var c=h.test(b)?-1:1;if(j.test(b))c*=u(a);k.style.width=(c<0)?b.slice(1):b;w.appendChild(k);b=c*k.offsetWidth;k.removeNode();return parseInt(b)};var k=ca();function u(a){var b=1;k.style.fontFamily=a.currentStyle.fontFamily;k.style.lineHeight=a.currentStyle.lineHeight;while(a!=w){var c=a.currentStyle["ie7-font-size"];if(c){if(q.test(c))b*=parseFloat(c);else if(M.test(c))b*=(parseFloat(c)/100);else if(r.test(c))b*=(parseFloat(c)/2);else{k.style.fontSize=c;return 1}}a=a.parentElement}return b};IE7.CSS.addFix(/cursor\s*:\s*pointer/,"cursor:hand");IE7.CSS.addFix(/display\s*:\s*list-item/,"display:block")}function n(a){if(m<5.5)IE7.Layout.boxSizing(a.parentElement);var b=a.parentElement;var c=b.offsetWidth-a.offsetWidth-s(b);var d=(a.currentStyle["ie7-margin"]&&a.currentStyle.marginRight=="auto")||a.currentStyle["ie7-margin-right"]=="auto";switch(b.currentStyle.textAlign){case"right":c=d?parseInt(c/2):0;a.runtimeStyle.marginRight=c+"px";break;case"center":if(d)c=0;default:if(d)c/=2;a.runtimeStyle.marginLeft=parseInt(c)+"px"}};function s(a){return D(a,a.currentStyle.paddingLeft)+D(a,a.currentStyle.paddingRight)};IE7.CSS.addRecalc("margin(-left|-right)?","[^};]*auto",function(a){if(X(n,a,a.parentElement&&a.currentStyle.display=="block"&&a.currentStyle.marginLeft=="auto"&&a.currentStyle.position!="absolute")){n(a)}});bC(function(){for(var a in n.elements){var b=n.elements[a];b.runtimeStyle.marginLeft=b.runtimeStyle.marginRight="";n(b)}})};IE7._g=function(a){a=a.firstChild;while(a){if(a.nodeType==3||(a.nodeType==1&&a.nodeName!="!"))return false;a=a.nextSibling}return true};IE7._h=function(a,b){while(a&&!a.getAttribute("lang"))a=a.parentNode;return a&&new RegExp("^"+W(b),"i").test(a.getAttribute("lang"))};function cr(a,b,c,d){d=/last/i.test(a)?d+"+1-":"";if(!isNaN(b))b="0n+"+b;else if(b=="even")b="2n";else if(b=="odd")b="2n+1";b=b.split("n");var f=b[0]?(b[0]=="-")?-1:parseInt(b[0]):1;var g=parseInt(b[1])||0;var h=f<0;if(h){f=-f;if(f==1)g++}var j=i(f==0?"%3%7"+(d+g):"(%4%3-%2)%6%1%70%5%4%3>=%2",f,g,c,d,"&&","%","==");if(h)j="!("+j+")";return j};bH={"link":"e%1.currentStyle['ie7-link']=='link'","visited":"e%1.currentStyle['ie7-link']=='visited'","checked":"e%1.checked","contains":"e%1.innerText.indexOf('%2')!=-1","disabled":"e%1.isDisabled","empty":"IE7._g(e%1)","enabled":"e%1.disabled===false","first-child":"!IE7._4(e%1)","lang":"IE7._h(e%1,'%2')","last-child":"!IE7._3(e%1)","only-child":"!IE7._4(e%1)&&!IE7._3(e%1)","target":"e%1.id==location.hash.slice(1)","indeterminate":"e%1.indeterminate"};IE7._i=function(a){if(a.rows){a.ie7_length=a.rows.length;a.ie7_lookup="rowIndex"}else if(a.cells){a.ie7_length=a.cells.length;a.ie7_lookup="cellIndex"}else if(a.ie7_indexed!=IE7._1){var b=0;var c=a.firstChild;while(c){if(c.nodeType==1&&c.nodeName!="!"){c.ie7_index=++b}c=c.nextSibling}a.ie7_length=b;a.ie7_lookup="ie7_index"}a.ie7_indexed=IE7._1;return a};var ba=E[V];var cs=ba[ba.length-1];ba.length--;E.merge({":not\\((\\*|[\\w-]+)?([^)]*)\\)":function(a,b,c){var d=(b&&b!="*")?i("if(e%1.nodeName=='%2'){",l,b.toUpperCase()):"";d+=E.exec(c);return"if(!"+d.slice(2,-1).replace(/\)\{if\(/g,"&&")+"){"},":nth(-last)?-child\\(([^)]+)\\)":function(a,b,c){p=false;b=i("e%1.parentNode.ie7_length",l);var d="if(p%1!==e%1.parentNode)p%1=IE7._i(e%1.parentNode);";d+="var i=e%1[p%1.ie7_lookup];if(p%1.ie7_lookup!='ie7_index')i++;if(";return i(d,l)+cr(a,c,"i",b)+"){"}});ba.push(cs);var bM="\\([^)]*\\)";if(IE7.CSS.pseudoClasses)IE7.CSS.pseudoClasses+="|";IE7.CSS.pseudoClasses+="before|after|last\\-child|only\\-child|empty|root|"+"not|nth\\-child|nth\\-last\\-child|contains|lang".split("|").join(bM+"|")+bM;bV.add(/::/,":");var bb=new A("focus",function(a){var b=arguments;IE7.CSS.addEventHandler(a,"onfocus",function(){bb.unregister(b);bb.register(b)});IE7.CSS.addEventHandler(a,"onblur",function(){bb.unregister(b)});if(a==document.activeElement){bb.register(b)}});var bq=new A("active",function(a){var b=arguments;IE7.CSS.addEventHandler(a,"onmousedown",function(){bq.register(b)})});v(document,"onmouseup",function(){var a=bq.instances;for(var b in a)bq.unregister(a[b])});var br=new A("checked",function(a){if(typeof a.checked!="boolean")return;var b=arguments;IE7.CSS.addEventHandler(a,"onpropertychange",function(){if(event.propertyName=="checked"){if(a.checked)br.register(b);else br.unregister(b)}});if(a.checked)br.register(b)});var bs=new A("enabled",function(a){if(typeof a.disabled!="boolean")return;var b=arguments;IE7.CSS.addEventHandler(a,"onpropertychange",function(){if(event.propertyName=="disabled"){if(!a.isDisabled)bs.register(b);else bs.unregister(b)}});if(!a.isDisabled)bs.register(b)});var bt=new A("disabled",function(a){if(typeof a.disabled!="boolean")return;var b=arguments;IE7.CSS.addEventHandler(a,"onpropertychange",function(){if(event.propertyName=="disabled"){if(a.isDisabled)bt.register(b);else bt.unregister(b)}});if(a.isDisabled)bt.register(b)});var bu=new A("indeterminate",function(a){if(typeof a.indeterminate!="boolean")return;var b=arguments;IE7.CSS.addEventHandler(a,"onpropertychange",function(){if(event.propertyName=="indeterminate"){if(a.indeterminate)bu.register(b);else bu.unregister(b)}});IE7.CSS.addEventHandler(a,"onclick",function(){bu.unregister(b)})});var bv=new A("target",function(a){var b=arguments;if(!a.tabIndex)a.tabIndex=0;IE7.CSS.addEventHandler(document,"onpropertychange",function(){if(event.propertyName=="activeElement"){if(a.id&&a.id==location.hash.slice(1))bv.register(b);else bv.unregister(b)}});if(a.id&&a.id==location.hash.slice(1))bv.register(b)});var ct=/^attr/;var cu=/^url\s*\(\s*([^)]*)\)$/;var cv={before0:"beforeBegin",before1:"afterBegin",after0:"afterEnd",after1:"beforeEnd"};var F=IE7.PseudoElement=o.extend({constructor:function(a,b,c){this.position=b;var d=c.match(F.CONTENT),f,g;if(d){d=d[1];f=d.split(/\s+/);for(var h=0;(g=f[h]);h++){f[h]=ct.test(g)?{attr:g.slice(5,-1)}:(g.charAt(0)=="'")?bB(g):bg(g)}d=f}this.content=d;this.base(a,bg(c))},init:function(){this.match=x(this.selector);for(var a=0;a<this.match.length;a++){var b=this.match[a].runtimeStyle;if(!b[this.position])b[this.position]={cssText:""};b[this.position].cssText+=";"+this.cssText;if(this.content!=null)b[this.position].content=this.content}},create:function(a){var b=a.runtimeStyle[this.position];if(b){var c=[].concat(b.content||"");for(var d=0;d<c.length;d++){if(typeof c[d]=="object"){c[d]=a.getAttribute(c[d].attr)}}c=c.join("");var f=c.match(cu);var g="overflow:hidden;"+b.cssText.replace(/'/g,'"');if(a.currentStyle.styleFloat!="none"){}var h=cv[this.position+Number(a.canHaveChildren)];var j='ie7_pseudo'+F.count++;a.insertAdjacentHTML(h,i(F.ANON,this.className,j,g,f?"":c));if(f){var q=document.getElementById(j);q.src=bB(f[1]);bo(q,"crop")}a.runtimeStyle[this.position]=null}},recalc:function(){if(this.content==null)return;for(var a=0;a<this.match.length;a++){this.create(this.match[a])}},toString:function(){return"."+this.className+"{display:inline}"}},{CONTENT:/content\s*:\s*([^;]*)(;|$)/,ANON:"<ie7:! class='ie7_anon %1' id=%2 style='%3'>%4</ie7:!>",MATCH:/(.*):(before|after).*/,count:0});var cw=/^(submit|reset|button)$/;IE7.HTML.addRecalc("button,input",function(a){if(a.tagName=="BUTTON"){var b=a.outerHTML.match(/ value="([^"]*)"/i);a.runtimeStyle.value=(b)?b[1]:""}if(a.type=="submit"){v(a,"onclick",function(){a.runtimeStyle.clicked=true;setTimeout("document.all."+a.uniqueID+".runtimeStyle.clicked=false",1)})}});IE7.HTML.addRecalc("form",function(c){v(c,"onsubmit",function(){for(var a,b=0;a=c[b];b++){if(cw.test(a.type)&&!a.disabled&&!a.runtimeStyle.clicked){a.disabled=true;setTimeout("document.all."+a.uniqueID+".disabled=false",1)}else if(a.tagName=="BUTTON"&&a.type=="submit"){setTimeout("document.all."+a.uniqueID+".value='"+a.value+"'",1);a.value=a.runtimeStyle.value}}})});IE7.HTML.addRecalc("img",function(a){if(a.alt&&!a.title)a.title=""});IE7.CSS.addRecalc("border-spacing",P,function(a){if(a.currentStyle.borderCollapse!="collapse"){a.cellSpacing=D(a,a.currentStyle["border-spacing"])}});IE7.CSS.addRecalc("box-sizing","content-box",IE7.Layout.boxSizing);IE7.CSS.addRecalc("box-sizing","border-box",IE7.Layout.borderBox);IE7.CSS.addFix(/opacity\s*:\s*([\d.]+)/,function(a,b){return"zoom:1;filter:Alpha(opacity="+((b*100)||1)+")"});var cx=/^image/i;IE7.HTML.addRecalc("object",function(a){if(cx.test(a.type)){a.body.style.cssText="margin:0;padding:0;border:none;overflow:hidden";return a}});IE7.loaded=true;(function(){try{bx.doScroll("left")}catch(e){setTimeout(arguments.callee,1);return}try{eval(bO.innerHTML)}catch(e){}bm=new RegExp(W(typeof IE7_PNG_SUFFIX=="string"?IE7_PNG_SUFFIX:"-trans.png")+"$","i");w=document.body;t=G?w:bx;w.className+=" ie7_body";bx.className+=" ie7_html";if(G)cq();IE7.CSS.init();IE7.HTML.init();IE7.HTML.apply();IE7.CSS.apply();IE7.recalc()})()})();
Index: admin/js/ie7/ie7-recalc.js
===================================================================
--- admin/js/ie7/ie7-recalc.js	(revision 0)
+++ admin/js/ie7/ie7-recalc.js	(revision 0)
@@ -0,0 +1,2 @@
+/* IE7/IE8.js - copyright 2004-2008, Dean Edwards */
+(function(){if(!IE7.loaded)return;CLASSES=/\sie7_class\d+/g;IE7.CSS.extend({elements:{},handlers:[],reset:function(){this.removeEventHandlers();var a=this.elements;for(var b in a)a[b].runtimeStyle.cssText="";this.elements={};var a=IE7.Rule.elements;for(var b in a){with(a[b])className=className.replace(CLASSES,"")}IE7.Rule.elements={}},reload:function(){this.rules=[];this.getInlineStyles();this.screen.load();if(this.print)this.print.load();this.refresh();this.trash()},addRecalc:function(b,c,d,e){this.base(b,c,function(a){d(a);IE7.CSS.elements[a.uniqueID]=a},e)},recalc:function(){this.reset();this.base()},addEventHandler:function(a,b,c){a.attachEvent(b,c);this.handlers.push(arguments)},removeEventHandlers:function(){var a;while(a=this.handlers.pop()){a[0].detachEvent(a[1],a[2])}},getInlineStyles:function(){var a=document.getElementsByTagName("style"),b;for(var c=a.length-1;(b=a[c]);c--){if(!b.disabled&&!b.ie7){var d=b.cssText||b.innerHTML;this.styles.push(d);b.cssText=d}}},trash:function(){var a=document.styleSheets,b,c;for(c=0;c<a.length;c++){b=a[c];if(!b.ie7&&!b.cssText){b.cssText=b.cssText}}this.base()},getText:function(a){return a.cssText||this.base(a)}});IE7.CSS.addEventHandler(window,"onunload",function(){IE7.CSS.removeEventHandlers()});IE7.Rule.elements={};IE7.Rule.prototype.extend({add:function(a){this.base(a);IE7.Rule.elements[a.uniqueID]=a}});if(IE7.PseudoElement){IE7.PseudoElement.hash={};IE7.PseudoElement.prototype.extend({create:function(a){var b=this.selector+":"+a.uniqueID;if(!IE7.PseudoElement.hash[b]){IE7.PseudoElement.hash[b]=true;this.base(a)}}})}IE7.HTML.extend({elements:{},addRecalc:function(b,c){this.base(b,function(a){if(!this.elements[a.uniqueID]){c(a);this.elements[a.uniqueID]=a}})}});document.recalc=function(a){if(IE7.CSS.screen){if(a)IE7.CSS.reload();IE7.recalc()}}})();
Index: admin/js/ie7/ie7-squish.js
===================================================================
--- admin/js/ie7/ie7-squish.js	(revision 0)
+++ admin/js/ie7/ie7-squish.js	(revision 0)
@@ -0,0 +1,36 @@
+
+/* ---------------------------------------------------------------------
+
+  Squish some IE bugs!
+
+  Some of these bug fixes may have adverse effects so they are
+  not included in the standard library. Add your own if you want.
+
+--------------------------------------------------------------------- */
+
+// @NOTE: ie7Layout.boxSizing is the same as the "Holly Hack"
+
+if (IE7.loaded && IE7.appVersion < 7) {
+
+  // "doubled margin" bug
+  // http://www.positioniseverything.net/explorer/doubled-margin.html
+  IE7.CSS.addFix(/(float\s*:\s*(left|right))/, "display:inline;$1");
+
+  // "peekaboo" bug
+  // http://www.positioniseverything.net/explorer/peekaboo.html
+  if (IE7.appVersion >= 6) IE7.CSS.addRecalc("float", "(left|right)", function(element) {
+  	IE7.Layout.boxSizing(element.parentElement); // assing "hasLayout" to parent element
+  	// "doubled margin" bug
+  	element.style.display = "inline";
+  });
+
+  // "unscrollable content" bug
+  // http://www.positioniseverything.net/explorer/unscrollable.html
+  IE7.CSS.addRecalc("position", "absolute|fixed", function(element) {
+  	if (element.offsetParent && element.offsetParent.currentStyle.position == "relative")
+  		IE7.Layout.boxSizing(element.offsetParent); // assing "hasLayout"
+  });
+}
+
+//# // get rid of Microsoft's pesky image toolbar
+//# document.write('<meta http-equiv="imagetoolbar" content="no">');
Index: admin/js/jquery-mute.js
===================================================================
--- admin/js/jquery-mute.js	(revision 3930)
+++ 	(revision )
@@ -1,4 +1,0 @@
-/*global jQuery, getData */
-'use strict';
-
-jQuery.migrateMute = getData('dotclear_jquery').mute;
Index: admin/js/jquery/jquery-migrate.js
===================================================================
--- admin/js/jquery/jquery-migrate.js	(revision 3684)
+++ 	(revision )
@@ -1,752 +1,0 @@
-/*!
- * jQuery Migrate - v1.4.1 - 2016-05-19
- * Copyright jQuery Foundation and other contributors
- */
-(function( jQuery, window, undefined ) {
-// See http://bugs.jquery.com/ticket/13335
-// "use strict";
-
-
-jQuery.migrateVersion = "1.4.1";
-
-
-var warnedAbout = {};
-
-// List of warnings already given; public read only
-jQuery.migrateWarnings = [];
-
-// Set to true to prevent console output; migrateWarnings still maintained
-// jQuery.migrateMute = false;
-
-// Show a message on the console so devs know we're active
-if ( window.console && window.console.log ) {
-	window.console.log( "JQMIGRATE: Migrate is installed" +
-		( jQuery.migrateMute ? "" : " with logging active" ) +
-		", version " + jQuery.migrateVersion );
-}
-
-// Set to false to disable traces that appear with warnings
-if ( jQuery.migrateTrace === undefined ) {
-	jQuery.migrateTrace = true;
-}
-
-// Forget any warnings we've already given; public
-jQuery.migrateReset = function() {
-	warnedAbout = {};
-	jQuery.migrateWarnings.length = 0;
-};
-
-function migrateWarn( msg) {
-	var console = window.console;
-	if ( !warnedAbout[ msg ] ) {
-		warnedAbout[ msg ] = true;
-		jQuery.migrateWarnings.push( msg );
-		if ( console && console.warn && !jQuery.migrateMute ) {
-			console.warn( "JQMIGRATE: " + msg );
-			if ( jQuery.migrateTrace && console.trace ) {
-				console.trace();
-			}
-		}
-	}
-}
-
-function migrateWarnProp( obj, prop, value, msg ) {
-	if ( Object.defineProperty ) {
-		// On ES5 browsers (non-oldIE), warn if the code tries to get prop;
-		// allow property to be overwritten in case some other plugin wants it
-		try {
-			Object.defineProperty( obj, prop, {
-				configurable: true,
-				enumerable: true,
-				get: function() {
-					migrateWarn( msg );
-					return value;
-				},
-				set: function( newValue ) {
-					migrateWarn( msg );
-					value = newValue;
-				}
-			});
-			return;
-		} catch( err ) {
-			// IE8 is a dope about Object.defineProperty, can't warn there
-		}
-	}
-
-	// Non-ES5 (or broken) browser; just set the property
-	jQuery._definePropertyBroken = true;
-	obj[ prop ] = value;
-}
-
-if ( document.compatMode === "BackCompat" ) {
-	// jQuery has never supported or tested Quirks Mode
-	migrateWarn( "jQuery is not compatible with Quirks Mode" );
-}
-
-
-var attrFn = jQuery( "<input/>", { size: 1 } ).attr("size") && jQuery.attrFn,
-	oldAttr = jQuery.attr,
-	valueAttrGet = jQuery.attrHooks.value && jQuery.attrHooks.value.get ||
-		function() { return null; },
-	valueAttrSet = jQuery.attrHooks.value && jQuery.attrHooks.value.set ||
-		function() { return undefined; },
-	rnoType = /^(?:input|button)$/i,
-	rnoAttrNodeType = /^[238]$/,
-	rboolean = /^(?:autofocus|autoplay|async|checked|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped|selected)$/i,
-	ruseDefault = /^(?:checked|selected)$/i;
-
-// jQuery.attrFn
-migrateWarnProp( jQuery, "attrFn", attrFn || {}, "jQuery.attrFn is deprecated" );
-
-jQuery.attr = function( elem, name, value, pass ) {
-	var lowerName = name.toLowerCase(),
-		nType = elem && elem.nodeType;
-
-	if ( pass ) {
-		// Since pass is used internally, we only warn for new jQuery
-		// versions where there isn't a pass arg in the formal params
-		if ( oldAttr.length < 4 ) {
-			migrateWarn("jQuery.fn.attr( props, pass ) is deprecated");
-		}
-		if ( elem && !rnoAttrNodeType.test( nType ) &&
-			(attrFn ? name in attrFn : jQuery.isFunction(jQuery.fn[name])) ) {
-			return jQuery( elem )[ name ]( value );
-		}
-	}
-
-	// Warn if user tries to set `type`, since it breaks on IE 6/7/8; by checking
-	// for disconnected elements we don't warn on $( "<button>", { type: "button" } ).
-	if ( name === "type" && value !== undefined && rnoType.test( elem.nodeName ) && elem.parentNode ) {
-		migrateWarn("Can't change the 'type' of an input or button in IE 6/7/8");
-	}
-
-	// Restore boolHook for boolean property/attribute synchronization
-	if ( !jQuery.attrHooks[ lowerName ] && rboolean.test( lowerName ) ) {
-		jQuery.attrHooks[ lowerName ] = {
-			get: function( elem, name ) {
-				// Align boolean attributes with corresponding properties
-				// Fall back to attribute presence where some booleans are not supported
-				var attrNode,
-					property = jQuery.prop( elem, name );
-				return property === true || typeof property !== "boolean" &&
-					( attrNode = elem.getAttributeNode(name) ) && attrNode.nodeValue !== false ?
-
-					name.toLowerCase() :
-					undefined;
-			},
-			set: function( elem, value, name ) {
-				var propName;
-				if ( value === false ) {
-					// Remove boolean attributes when set to false
-					jQuery.removeAttr( elem, name );
-				} else {
-					// value is true since we know at this point it's type boolean and not false
-					// Set boolean attributes to the same name and set the DOM property
-					propName = jQuery.propFix[ name ] || name;
-					if ( propName in elem ) {
-						// Only set the IDL specifically if it already exists on the element
-						elem[ propName ] = true;
-					}
-
-					elem.setAttribute( name, name.toLowerCase() );
-				}
-				return name;
-			}
-		};
-
-		// Warn only for attributes that can remain distinct from their properties post-1.9
-		if ( ruseDefault.test( lowerName ) ) {
-			migrateWarn( "jQuery.fn.attr('" + lowerName + "') might use property instead of attribute" );
-		}
-	}
-
-	return oldAttr.call( jQuery, elem, name, value );
-};
-
-// attrHooks: value
-jQuery.attrHooks.value = {
-	get: function( elem, name ) {
-		var nodeName = ( elem.nodeName || "" ).toLowerCase();
-		if ( nodeName === "button" ) {
-			return valueAttrGet.apply( this, arguments );
-		}
-		if ( nodeName !== "input" && nodeName !== "option" ) {
-			migrateWarn("jQuery.fn.attr('value') no longer gets properties");
-		}
-		return name in elem ?
-			elem.value :
-			null;
-	},
-	set: function( elem, value ) {
-		var nodeName = ( elem.nodeName || "" ).toLowerCase();
-		if ( nodeName === "button" ) {
-			return valueAttrSet.apply( this, arguments );
-		}
-		if ( nodeName !== "input" && nodeName !== "option" ) {
-			migrateWarn("jQuery.fn.attr('value', val) no longer sets properties");
-		}
-		// Does not return so that setAttribute is also used
-		elem.value = value;
-	}
-};
-
-
-var matched, browser,
-	oldInit = jQuery.fn.init,
-	oldFind = jQuery.find,
-	oldParseJSON = jQuery.parseJSON,
-	rspaceAngle = /^\s*</,
-	rattrHashTest = /\[(\s*[-\w]+\s*)([~|^$*]?=)\s*([-\w#]*?#[-\w#]*)\s*\]/,
-	rattrHashGlob = /\[(\s*[-\w]+\s*)([~|^$*]?=)\s*([-\w#]*?#[-\w#]*)\s*\]/g,
-	// Note: XSS check is done below after string is trimmed
-	rquickExpr = /^([^<]*)(<[\w\W]+>)([^>]*)$/;
-
-// $(html) "looks like html" rule change
-jQuery.fn.init = function( selector, context, rootjQuery ) {
-	var match, ret;
-
-	if ( selector && typeof selector === "string" ) {
-		if ( !jQuery.isPlainObject( context ) &&
-				(match = rquickExpr.exec( jQuery.trim( selector ) )) && match[ 0 ] ) {
-
-			// This is an HTML string according to the "old" rules; is it still?
-			if ( !rspaceAngle.test( selector ) ) {
-				migrateWarn("$(html) HTML strings must start with '<' character");
-			}
-			if ( match[ 3 ] ) {
-				migrateWarn("$(html) HTML text after last tag is ignored");
-			}
-
-			// Consistently reject any HTML-like string starting with a hash (gh-9521)
-			// Note that this may break jQuery 1.6.x code that otherwise would work.
-			if ( match[ 0 ].charAt( 0 ) === "#" ) {
-				migrateWarn("HTML string cannot start with a '#' character");
-				jQuery.error("JQMIGRATE: Invalid selector string (XSS)");
-			}
-
-			// Now process using loose rules; let pre-1.8 play too
-			// Is this a jQuery context? parseHTML expects a DOM element (#178)
-			if ( context && context.context && context.context.nodeType ) {
-				context = context.context;
-			}
-
-			if ( jQuery.parseHTML ) {
-				return oldInit.call( this,
-						jQuery.parseHTML( match[ 2 ], context && context.ownerDocument ||
-							context || document, true ), context, rootjQuery );
-			}
-		}
-	}
-
-	ret = oldInit.apply( this, arguments );
-
-	// Fill in selector and context properties so .live() works
-	if ( selector && selector.selector !== undefined ) {
-		// A jQuery object, copy its properties
-		ret.selector = selector.selector;
-		ret.context = selector.context;
-
-	} else {
-		ret.selector = typeof selector === "string" ? selector : "";
-		if ( selector ) {
-			ret.context = selector.nodeType? selector : context || document;
-		}
-	}
-
-	return ret;
-};
-jQuery.fn.init.prototype = jQuery.fn;
-
-jQuery.find = function( selector ) {
-	var args = Array.prototype.slice.call( arguments );
-
-	// Support: PhantomJS 1.x
-	// String#match fails to match when used with a //g RegExp, only on some strings
-	if ( typeof selector === "string" && rattrHashTest.test( selector ) ) {
-
-		// The nonstandard and undocumented unquoted-hash was removed in jQuery 1.12.0
-		// First see if qS thinks it's a valid selector, if so avoid a false positive
-		try {
-			document.querySelector( selector );
-		} catch ( err1 ) {
-
-			// Didn't *look* valid to qSA, warn and try quoting what we think is the value
-			selector = selector.replace( rattrHashGlob, function( _, attr, op, value ) {
-				return "[" + attr + op + "\"" + value + "\"]";
-			} );
-
-			// If the regexp *may* have created an invalid selector, don't update it
-			// Note that there may be false alarms if selector uses jQuery extensions
-			try {
-				document.querySelector( selector );
-				migrateWarn( "Attribute selector with '#' must be quoted: " + args[ 0 ] );
-				args[ 0 ] = selector;
-			} catch ( err2 ) {
-				migrateWarn( "Attribute selector with '#' was not fixed: " + args[ 0 ] );
-			}
-		}
-	}
-
-	return oldFind.apply( this, args );
-};
-
-// Copy properties attached to original jQuery.find method (e.g. .attr, .isXML)
-var findProp;
-for ( findProp in oldFind ) {
-	if ( Object.prototype.hasOwnProperty.call( oldFind, findProp ) ) {
-		jQuery.find[ findProp ] = oldFind[ findProp ];
-	}
-}
-
-// Let $.parseJSON(falsy_value) return null
-jQuery.parseJSON = function( json ) {
-	if ( !json ) {
-		migrateWarn("jQuery.parseJSON requires a valid JSON string");
-		return null;
-	}
-	return oldParseJSON.apply( this, arguments );
-};
-
-jQuery.uaMatch = function( ua ) {
-	ua = ua.toLowerCase();
-
-	var match = /(chrome)[ \/]([\w.]+)/.exec( ua ) ||
-		/(webkit)[ \/]([\w.]+)/.exec( ua ) ||
-		/(opera)(?:.*version|)[ \/]([\w.]+)/.exec( ua ) ||
-		/(msie) ([\w.]+)/.exec( ua ) ||
-		ua.indexOf("compatible") < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec( ua ) ||
-		[];
-
-	return {
-		browser: match[ 1 ] || "",
-		version: match[ 2 ] || "0"
-	};
-};
-
-// Don't clobber any existing jQuery.browser in case it's different
-if ( !jQuery.browser ) {
-	matched = jQuery.uaMatch( navigator.userAgent );
-	browser = {};
-
-	if ( matched.browser ) {
-		browser[ matched.browser ] = true;
-		browser.version = matched.version;
-	}
-
-	// Chrome is Webkit, but Webkit is also Safari.
-	if ( browser.chrome ) {
-		browser.webkit = true;
-	} else if ( browser.webkit ) {
-		browser.safari = true;
-	}
-
-	jQuery.browser = browser;
-}
-
-// Warn if the code tries to get jQuery.browser
-migrateWarnProp( jQuery, "browser", jQuery.browser, "jQuery.browser is deprecated" );
-
-// jQuery.boxModel deprecated in 1.3, jQuery.support.boxModel deprecated in 1.7
-jQuery.boxModel = jQuery.support.boxModel = (document.compatMode === "CSS1Compat");
-migrateWarnProp( jQuery, "boxModel", jQuery.boxModel, "jQuery.boxModel is deprecated" );
-migrateWarnProp( jQuery.support, "boxModel", jQuery.support.boxModel, "jQuery.support.boxModel is deprecated" );
-
-jQuery.sub = function() {
-	function jQuerySub( selector, context ) {
-		return new jQuerySub.fn.init( selector, context );
-	}
-	jQuery.extend( true, jQuerySub, this );
-	jQuerySub.superclass = this;
-	jQuerySub.fn = jQuerySub.prototype = this();
-	jQuerySub.fn.constructor = jQuerySub;
-	jQuerySub.sub = this.sub;
-	jQuerySub.fn.init = function init( selector, context ) {
-		var instance = jQuery.fn.init.call( this, selector, context, rootjQuerySub );
-		return instance instanceof jQuerySub ?
-			instance :
-			jQuerySub( instance );
-	};
-	jQuerySub.fn.init.prototype = jQuerySub.fn;
-	var rootjQuerySub = jQuerySub(document);
-	migrateWarn( "jQuery.sub() is deprecated" );
-	return jQuerySub;
-};
-
-// The number of elements contained in the matched element set
-jQuery.fn.size = function() {
-	migrateWarn( "jQuery.fn.size() is deprecated; use the .length property" );
-	return this.length;
-};
-
-
-var internalSwapCall = false;
-
-// If this version of jQuery has .swap(), don't false-alarm on internal uses
-if ( jQuery.swap ) {
-	jQuery.each( [ "height", "width", "reliableMarginRight" ], function( _, name ) {
-		var oldHook = jQuery.cssHooks[ name ] && jQuery.cssHooks[ name ].get;
-
-		if ( oldHook ) {
-			jQuery.cssHooks[ name ].get = function() {
-				var ret;
-
-				internalSwapCall = true;
-				ret = oldHook.apply( this, arguments );
-				internalSwapCall = false;
-				return ret;
-			};
-		}
-	});
-}
-
-jQuery.swap = function( elem, options, callback, args ) {
-	var ret, name,
-		old = {};
-
-	if ( !internalSwapCall ) {
-		migrateWarn( "jQuery.swap() is undocumented and deprecated" );
-	}
-
-	// Remember the old values, and insert the new ones
-	for ( name in options ) {
-		old[ name ] = elem.style[ name ];
-		elem.style[ name ] = options[ name ];
-	}
-
-	ret = callback.apply( elem, args || [] );
-
-	// Revert the old values
-	for ( name in options ) {
-		elem.style[ name ] = old[ name ];
-	}
-
-	return ret;
-};
-
-
-// Ensure that $.ajax gets the new parseJSON defined in core.js
-jQuery.ajaxSetup({
-	converters: {
-		"text json": jQuery.parseJSON
-	}
-});
-
-
-var oldFnData = jQuery.fn.data;
-
-jQuery.fn.data = function( name ) {
-	var ret, evt,
-		elem = this[0];
-
-	// Handles 1.7 which has this behavior and 1.8 which doesn't
-	if ( elem && name === "events" && arguments.length === 1 ) {
-		ret = jQuery.data( elem, name );
-		evt = jQuery._data( elem, name );
-		if ( ( ret === undefined || ret === evt ) && evt !== undefined ) {
-			migrateWarn("Use of jQuery.fn.data('events') is deprecated");
-			return evt;
-		}
-	}
-	return oldFnData.apply( this, arguments );
-};
-
-
-var rscriptType = /\/(java|ecma)script/i;
-
-// Since jQuery.clean is used internally on older versions, we only shim if it's missing
-if ( !jQuery.clean ) {
-	jQuery.clean = function( elems, context, fragment, scripts ) {
-		// Set context per 1.8 logic
-		context = context || document;
-		context = !context.nodeType && context[0] || context;
-		context = context.ownerDocument || context;
-
-		migrateWarn("jQuery.clean() is deprecated");
-
-		var i, elem, handleScript, jsTags,
-			ret = [];
-
-		jQuery.merge( ret, jQuery.buildFragment( elems, context ).childNodes );
-
-		// Complex logic lifted directly from jQuery 1.8
-		if ( fragment ) {
-			// Special handling of each script element
-			handleScript = function( elem ) {
-				// Check if we consider it executable
-				if ( !elem.type || rscriptType.test( elem.type ) ) {
-					// Detach the script and store it in the scripts array (if provided) or the fragment
-					// Return truthy to indicate that it has been handled
-					return scripts ?
-						scripts.push( elem.parentNode ? elem.parentNode.removeChild( elem ) : elem ) :
-						fragment.appendChild( elem );
-				}
-			};
-
-			for ( i = 0; (elem = ret[i]) != null; i++ ) {
-				// Check if we're done after handling an executable script
-				if ( !( jQuery.nodeName( elem, "script" ) && handleScript( elem ) ) ) {
-					// Append to fragment and handle embedded scripts
-					fragment.appendChild( elem );
-					if ( typeof elem.getElementsByTagName !== "undefined" ) {
-						// handleScript alters the DOM, so use jQuery.merge to ensure snapshot iteration
-						jsTags = jQuery.grep( jQuery.merge( [], elem.getElementsByTagName("script") ), handleScript );
-
-						// Splice the scripts into ret after their former ancestor and advance our index beyond them
-						ret.splice.apply( ret, [i + 1, 0].concat( jsTags ) );
-						i += jsTags.length;
-					}
-				}
-			}
-		}
-
-		return ret;
-	};
-}
-
-var eventAdd = jQuery.event.add,
-	eventRemove = jQuery.event.remove,
-	eventTrigger = jQuery.event.trigger,
-	oldToggle = jQuery.fn.toggle,
-	oldLive = jQuery.fn.live,
-	oldDie = jQuery.fn.die,
-	oldLoad = jQuery.fn.load,
-	ajaxEvents = "ajaxStart|ajaxStop|ajaxSend|ajaxComplete|ajaxError|ajaxSuccess",
-	rajaxEvent = new RegExp( "\\b(?:" + ajaxEvents + ")\\b" ),
-	rhoverHack = /(?:^|\s)hover(\.\S+|)\b/,
-	hoverHack = function( events ) {
-		if ( typeof( events ) !== "string" || jQuery.event.special.hover ) {
-			return events;
-		}
-		if ( rhoverHack.test( events ) ) {
-			migrateWarn("'hover' pseudo-event is deprecated, use 'mouseenter mouseleave'");
-		}
-		return events && events.replace( rhoverHack, "mouseenter$1 mouseleave$1" );
-	};
-
-// Event props removed in 1.9, put them back if needed; no practical way to warn them
-if ( jQuery.event.props && jQuery.event.props[ 0 ] !== "attrChange" ) {
-	jQuery.event.props.unshift( "attrChange", "attrName", "relatedNode", "srcElement" );
-}
-
-// Undocumented jQuery.event.handle was "deprecated" in jQuery 1.7
-if ( jQuery.event.dispatch ) {
-	migrateWarnProp( jQuery.event, "handle", jQuery.event.dispatch, "jQuery.event.handle is undocumented and deprecated" );
-}
-
-// Support for 'hover' pseudo-event and ajax event warnings
-jQuery.event.add = function( elem, types, handler, data, selector ){
-	if ( elem !== document && rajaxEvent.test( types ) ) {
-		migrateWarn( "AJAX events should be attached to document: " + types );
-	}
-	eventAdd.call( this, elem, hoverHack( types || "" ), handler, data, selector );
-};
-jQuery.event.remove = function( elem, types, handler, selector, mappedTypes ){
-	eventRemove.call( this, elem, hoverHack( types ) || "", handler, selector, mappedTypes );
-};
-
-jQuery.each( [ "load", "unload", "error" ], function( _, name ) {
-
-	jQuery.fn[ name ] = function() {
-		var args = Array.prototype.slice.call( arguments, 0 );
-
-		// If this is an ajax load() the first arg should be the string URL;
-		// technically this could also be the "Anything" arg of the event .load()
-		// which just goes to show why this dumb signature has been deprecated!
-		// jQuery custom builds that exclude the Ajax module justifiably die here.
-		if ( name === "load" && typeof args[ 0 ] === "string" ) {
-			return oldLoad.apply( this, args );
-		}
-
-		migrateWarn( "jQuery.fn." + name + "() is deprecated" );
-
-		args.splice( 0, 0, name );
-		if ( arguments.length ) {
-			return this.bind.apply( this, args );
-		}
-
-		// Use .triggerHandler here because:
-		// - load and unload events don't need to bubble, only applied to window or image
-		// - error event should not bubble to window, although it does pre-1.7
-		// See http://bugs.jquery.com/ticket/11820
-		this.triggerHandler.apply( this, args );
-		return this;
-	};
-
-});
-
-jQuery.fn.toggle = function( fn, fn2 ) {
-
-	// Don't mess with animation or css toggles
-	if ( !jQuery.isFunction( fn ) || !jQuery.isFunction( fn2 ) ) {
-		return oldToggle.apply( this, arguments );
-	}
-	migrateWarn("jQuery.fn.toggle(handler, handler...) is deprecated");
-
-	// Save reference to arguments for access in closure
-	var args = arguments,
-		guid = fn.guid || jQuery.guid++,
-		i = 0,
-		toggler = function( event ) {
-			// Figure out which function to execute
-			var lastToggle = ( jQuery._data( this, "lastToggle" + fn.guid ) || 0 ) % i;
-			jQuery._data( this, "lastToggle" + fn.guid, lastToggle + 1 );
-
-			// Make sure that clicks stop
-			event.preventDefault();
-
-			// and execute the function
-			return args[ lastToggle ].apply( this, arguments ) || false;
-		};
-
-	// link all the functions, so any of them can unbind this click handler
-	toggler.guid = guid;
-	while ( i < args.length ) {
-		args[ i++ ].guid = guid;
-	}
-
-	return this.click( toggler );
-};
-
-jQuery.fn.live = function( types, data, fn ) {
-	migrateWarn("jQuery.fn.live() is deprecated");
-	if ( oldLive ) {
-		return oldLive.apply( this, arguments );
-	}
-	jQuery( this.context ).on( types, this.selector, data, fn );
-	return this;
-};
-
-jQuery.fn.die = function( types, fn ) {
-	migrateWarn("jQuery.fn.die() is deprecated");
-	if ( oldDie ) {
-		return oldDie.apply( this, arguments );
-	}
-	jQuery( this.context ).off( types, this.selector || "**", fn );
-	return this;
-};
-
-// Turn global events into document-triggered events
-jQuery.event.trigger = function( event, data, elem, onlyHandlers  ){
-	if ( !elem && !rajaxEvent.test( event ) ) {
-		migrateWarn( "Global events are undocumented and deprecated" );
-	}
-	return eventTrigger.call( this,  event, data, elem || document, onlyHandlers  );
-};
-jQuery.each( ajaxEvents.split("|"),
-	function( _, name ) {
-		jQuery.event.special[ name ] = {
-			setup: function() {
-				var elem = this;
-
-				// The document needs no shimming; must be !== for oldIE
-				if ( elem !== document ) {
-					jQuery.event.add( document, name + "." + jQuery.guid, function() {
-						jQuery.event.trigger( name, Array.prototype.slice.call( arguments, 1 ), elem, true );
-					});
-					jQuery._data( this, name, jQuery.guid++ );
-				}
-				return false;
-			},
-			teardown: function() {
-				if ( this !== document ) {
-					jQuery.event.remove( document, name + "." + jQuery._data( this, name ) );
-				}
-				return false;
-			}
-		};
-	}
-);
-
-jQuery.event.special.ready = {
-	setup: function() {
-		if ( this === document ) {
-			migrateWarn( "'ready' event is deprecated" );
-		}
-	}
-};
-
-var oldSelf = jQuery.fn.andSelf || jQuery.fn.addBack,
-	oldFnFind = jQuery.fn.find;
-
-jQuery.fn.andSelf = function() {
-	migrateWarn("jQuery.fn.andSelf() replaced by jQuery.fn.addBack()");
-	return oldSelf.apply( this, arguments );
-};
-
-jQuery.fn.find = function( selector ) {
-	var ret = oldFnFind.apply( this, arguments );
-	ret.context = this.context;
-	ret.selector = this.selector ? this.selector + " " + selector : selector;
-	return ret;
-};
-
-
-// jQuery 1.6 did not support Callbacks, do not warn there
-if ( jQuery.Callbacks ) {
-
-	var oldDeferred = jQuery.Deferred,
-		tuples = [
-			// action, add listener, callbacks, .then handlers, final state
-			[ "resolve", "done", jQuery.Callbacks("once memory"),
-				jQuery.Callbacks("once memory"), "resolved" ],
-			[ "reject", "fail", jQuery.Callbacks("once memory"),
-				jQuery.Callbacks("once memory"), "rejected" ],
-			[ "notify", "progress", jQuery.Callbacks("memory"),
-				jQuery.Callbacks("memory") ]
-		];
-
-	jQuery.Deferred = function( func ) {
-		var deferred = oldDeferred(),
-			promise = deferred.promise();
-
-		deferred.pipe = promise.pipe = function( /* fnDone, fnFail, fnProgress */ ) {
-			var fns = arguments;
-
-			migrateWarn( "deferred.pipe() is deprecated" );
-
-			return jQuery.Deferred(function( newDefer ) {
-				jQuery.each( tuples, function( i, tuple ) {
-					var fn = jQuery.isFunction( fns[ i ] ) && fns[ i ];
-					// deferred.done(function() { bind to newDefer or newDefer.resolve })
-					// deferred.fail(function() { bind to newDefer or newDefer.reject })
-					// deferred.progress(function() { bind to newDefer or newDefer.notify })
-					deferred[ tuple[1] ](function() {
-						var returned = fn && fn.apply( this, arguments );
-						if ( returned && jQuery.isFunction( returned.promise ) ) {
-							returned.promise()
-								.done( newDefer.resolve )
-								.fail( newDefer.reject )
-								.progress( newDefer.notify );
-						} else {
-							newDefer[ tuple[ 0 ] + "With" ](
-								this === promise ? newDefer.promise() : this,
-								fn ? [ returned ] : arguments
-							);
-						}
-					});
-				});
-				fns = null;
-			}).promise();
-
-		};
-
-		deferred.isResolved = function() {
-			migrateWarn( "deferred.isResolved is deprecated" );
-			return deferred.state() === "resolved";
-		};
-
-		deferred.isRejected = function() {
-			migrateWarn( "deferred.isRejected is deprecated" );
-			return deferred.state() === "rejected";
-		};
-
-		if ( func ) {
-			func.call( deferred, deferred );
-		}
-
-		return deferred;
-	};
-
-}
-
-})( jQuery, window );
Index: admin/js/jquery/jquery-ui.custom.js
===================================================================
--- admin/js/jquery/jquery-ui.custom.js	(revision 3684)
+++ 	(revision )
@@ -1,4540 +1,0 @@
-/*! jQuery UI - v1.12.1 - 2018-01-27
-* http://jqueryui.com
-* Includes: widget.js, data.js, keycode.js, scroll-parent.js, unique-id.js, widgets/draggable.js, widgets/sortable.js, widgets/accordion.js, widgets/mouse.js
-* Copyright jQuery Foundation and other contributors; Licensed MIT */
-
-(function( factory ) {
-	if ( typeof define === "function" && define.amd ) {
-
-		// AMD. Register as an anonymous module.
-		define([ "jquery" ], factory );
-	} else {
-
-		// Browser globals
-		factory( jQuery );
-	}
-}(function( $ ) {
-
-$.ui = $.ui || {};
-
-var version = $.ui.version = "1.12.1";
-
-
-/*!
- * jQuery UI Widget 1.12.1
- * http://jqueryui.com
- *
- * Copyright jQuery Foundation and other contributors
- * Released under the MIT license.
- * http://jquery.org/license
- */
-
-//>>label: Widget
-//>>group: Core
-//>>description: Provides a factory for creating stateful widgets with a common API.
-//>>docs: http://api.jqueryui.com/jQuery.widget/
-//>>demos: http://jqueryui.com/widget/
-
-
-
-var widgetUuid = 0;
-var widgetSlice = Array.prototype.slice;
-
-$.cleanData = ( function( orig ) {
-	return function( elems ) {
-		var events, elem, i;
-		for ( i = 0; ( elem = elems[ i ] ) != null; i++ ) {
-			try {
-
-				// Only trigger remove when necessary to save time
-				events = $._data( elem, "events" );
-				if ( events && events.remove ) {
-					$( elem ).triggerHandler( "remove" );
-				}
-
-			// Http://bugs.jquery.com/ticket/8235
-			} catch ( e ) {}
-		}
-		orig( elems );
-	};
-} )( $.cleanData );
-
-$.widget = function( name, base, prototype ) {
-	var existingConstructor, constructor, basePrototype;
-
-	// ProxiedPrototype allows the provided prototype to remain unmodified
-	// so that it can be used as a mixin for multiple widgets (#8876)
-	var proxiedPrototype = {};
-
-	var namespace = name.split( "." )[ 0 ];
-	name = name.split( "." )[ 1 ];
-	var fullName = namespace + "-" + name;
-
-	if ( !prototype ) {
-		prototype = base;
-		base = $.Widget;
-	}
-
-	if ( $.isArray( prototype ) ) {
-		prototype = $.extend.apply( null, [ {} ].concat( prototype ) );
-	}
-
-	// Create selector for plugin
-	$.expr[ ":" ][ fullName.toLowerCase() ] = function( elem ) {
-		return !!$.data( elem, fullName );
-	};
-
-	$[ namespace ] = $[ namespace ] || {};
-	existingConstructor = $[ namespace ][ name ];
-	constructor = $[ namespace ][ name ] = function( options, element ) {
-
-		// Allow instantiation without "new" keyword
-		if ( !this._createWidget ) {
-			return new constructor( options, element );
-		}
-
-		// Allow instantiation without initializing for simple inheritance
-		// must use "new" keyword (the code above always passes args)
-		if ( arguments.length ) {
-			this._createWidget( options, element );
-		}
-	};
-
-	// Extend with the existing constructor to carry over any static properties
-	$.extend( constructor, existingConstructor, {
-		version: prototype.version,
-
-		// Copy the object used to create the prototype in case we need to
-		// redefine the widget later
-		_proto: $.extend( {}, prototype ),
-
-		// Track widgets that inherit from this widget in case this widget is
-		// redefined after a widget inherits from it
-		_childConstructors: []
-	} );
-
-	basePrototype = new base();
-
-	// We need to make the options hash a property directly on the new instance
-	// otherwise we'll modify the options hash on the prototype that we're
-	// inheriting from
-	basePrototype.options = $.widget.extend( {}, basePrototype.options );
-	$.each( prototype, function( prop, value ) {
-		if ( !$.isFunction( value ) ) {
-			proxiedPrototype[ prop ] = value;
-			return;
-		}
-		proxiedPrototype[ prop ] = ( function() {
-			function _super() {
-				return base.prototype[ prop ].apply( this, arguments );
-			}
-
-			function _superApply( args ) {
-				return base.prototype[ prop ].apply( this, args );
-			}
-
-			return function() {
-				var __super = this._super;
-				var __superApply = this._superApply;
-				var returnValue;
-
-				this._super = _super;
-				this._superApply = _superApply;
-
-				returnValue = value.apply( this, arguments );
-
-				this._super = __super;
-				this._superApply = __superApply;
-
-				return returnValue;
-			};
-		} )();
-	} );
-	constructor.prototype = $.widget.extend( basePrototype, {
-
-		// TODO: remove support for widgetEventPrefix
-		// always use the name + a colon as the prefix, e.g., draggable:start
-		// don't prefix for widgets that aren't DOM-based
-		widgetEventPrefix: existingConstructor ? ( basePrototype.widgetEventPrefix || name ) : name
-	}, proxiedPrototype, {
-		constructor: constructor,
-		namespace: namespace,
-		widgetName: name,
-		widgetFullName: fullName
-	} );
-
-	// If this widget is being redefined then we need to find all widgets that
-	// are inheriting from it and redefine all of them so that they inherit from
-	// the new version of this widget. We're essentially trying to replace one
-	// level in the prototype chain.
-	if ( existingConstructor ) {
-		$.each( existingConstructor._childConstructors, function( i, child ) {
-			var childPrototype = child.prototype;
-
-			// Redefine the child widget using the same prototype that was
-			// originally used, but inherit from the new version of the base
-			$.widget( childPrototype.namespace + "." + childPrototype.widgetName, constructor,
-				child._proto );
-		} );
-
-		// Remove the list of existing child constructors from the old constructor
-		// so the old child constructors can be garbage collected
-		delete existingConstructor._childConstructors;
-	} else {
-		base._childConstructors.push( constructor );
-	}
-
-	$.widget.bridge( name, constructor );
-
-	return constructor;
-};
-
-$.widget.extend = function( target ) {
-	var input = widgetSlice.call( arguments, 1 );
-	var inputIndex = 0;
-	var inputLength = input.length;
-	var key;
-	var value;
-
-	for ( ; inputIndex < inputLength; inputIndex++ ) {
-		for ( key in input[ inputIndex ] ) {
-			value = input[ inputIndex ][ key ];
-			if ( input[ inputIndex ].hasOwnProperty( key ) && value !== undefined ) {
-
-				// Clone objects
-				if ( $.isPlainObject( value ) ) {
-					target[ key ] = $.isPlainObject( target[ key ] ) ?
-						$.widget.extend( {}, target[ key ], value ) :
-
-						// Don't extend strings, arrays, etc. with objects
-						$.widget.extend( {}, value );
-
-				// Copy everything else by reference
-				} else {
-					target[ key ] = value;
-				}
-			}
-		}
-	}
-	return target;
-};
-
-$.widget.bridge = function( name, object ) {
-	var fullName = object.prototype.widgetFullName || name;
-	$.fn[ name ] = function( options ) {
-		var isMethodCall = typeof options === "string";
-		var args = widgetSlice.call( arguments, 1 );
-		var returnValue = this;
-
-		if ( isMethodCall ) {
-
-			// If this is an empty collection, we need to have the instance method
-			// return undefined instead of the jQuery instance
-			if ( !this.length && options === "instance" ) {
-				returnValue = undefined;
-			} else {
-				this.each( function() {
-					var methodValue;
-					var instance = $.data( this, fullName );
-
-					if ( options === "instance" ) {
-						returnValue = instance;
-						return false;
-					}
-
-					if ( !instance ) {
-						return $.error( "cannot call methods on " + name +
-							" prior to initialization; " +
-							"attempted to call method '" + options + "'" );
-					}
-
-					if ( !$.isFunction( instance[ options ] ) || options.charAt( 0 ) === "_" ) {
-						return $.error( "no such method '" + options + "' for " + name +
-							" widget instance" );
-					}
-
-					methodValue = instance[ options ].apply( instance, args );
-
-					if ( methodValue !== instance && methodValue !== undefined ) {
-						returnValue = methodValue && methodValue.jquery ?
-							returnValue.pushStack( methodValue.get() ) :
-							methodValue;
-						return false;
-					}
-				} );
-			}
-		} else {
-
-			// Allow multiple hashes to be passed on init
-			if ( args.length ) {
-				options = $.widget.extend.apply( null, [ options ].concat( args ) );
-			}
-
-			this.each( function() {
-				var instance = $.data( this, fullName );
-				if ( instance ) {
-					instance.option( options || {} );
-					if ( instance._init ) {
-						instance._init();
-					}
-				} else {
-					$.data( this, fullName, new object( options, this ) );
-				}
-			} );
-		}
-
-		return returnValue;
-	};
-};
-
-$.Widget = function( /* options, element */ ) {};
-$.Widget._childConstructors = [];
-
-$.Widget.prototype = {
-	widgetName: "widget",
-	widgetEventPrefix: "",
-	defaultElement: "<div>",
-
-	options: {
-		classes: {},
-		disabled: false,
-
-		// Callbacks
-		create: null
-	},
-
-	_createWidget: function( options, element ) {
-		element = $( element || this.defaultElement || this )[ 0 ];
-		this.element = $( element );
-		this.uuid = widgetUuid++;
-		this.eventNamespace = "." + this.widgetName + this.uuid;
-
-		this.bindings = $();
-		this.hoverable = $();
-		this.focusable = $();
-		this.classesElementLookup = {};
-
-		if ( element !== this ) {
-			$.data( element, this.widgetFullName, this );
-			this._on( true, this.element, {
-				remove: function( event ) {
-					if ( event.target === element ) {
-						this.destroy();
-					}
-				}
-			} );
-			this.document = $( element.style ?
-
-				// Element within the document
-				element.ownerDocument :
-
-				// Element is window or document
-				element.document || element );
-			this.window = $( this.document[ 0 ].defaultView || this.document[ 0 ].parentWindow );
-		}
-
-		this.options = $.widget.extend( {},
-			this.options,
-			this._getCreateOptions(),
-			options );
-
-		this._create();
-
-		if ( this.options.disabled ) {
-			this._setOptionDisabled( this.options.disabled );
-		}
-
-		this._trigger( "create", null, this._getCreateEventData() );
-		this._init();
-	},
-
-	_getCreateOptions: function() {
-		return {};
-	},
-
-	_getCreateEventData: $.noop,
-
-	_create: $.noop,
-
-	_init: $.noop,
-
-	destroy: function() {
-		var that = this;
-
-		this._destroy();
-		$.each( this.classesElementLookup, function( key, value ) {
-			that._removeClass( value, key );
-		} );
-
-		// We can probably remove the unbind calls in 2.0
-		// all event bindings should go through this._on()
-		this.element
-			.off( this.eventNamespace )
-			.removeData( this.widgetFullName );
-		this.widget()
-			.off( this.eventNamespace )
-			.removeAttr( "aria-disabled" );
-
-		// Clean up events and states
-		this.bindings.off( this.eventNamespace );
-	},
-
-	_destroy: $.noop,
-
-	widget: function() {
-		return this.element;
-	},
-
-	option: function( key, value ) {
-		var options = key;
-		var parts;
-		var curOption;
-		var i;
-
-		if ( arguments.length === 0 ) {
-
-			// Don't return a reference to the internal hash
-			return $.widget.extend( {}, this.options );
-		}
-
-		if ( typeof key === "string" ) {
-
-			// Handle nested keys, e.g., "foo.bar" => { foo: { bar: ___ } }
-			options = {};
-			parts = key.split( "." );
-			key = parts.shift();
-			if ( parts.length ) {
-				curOption = options[ key ] = $.widget.extend( {}, this.options[ key ] );
-				for ( i = 0; i < parts.length - 1; i++ ) {
-					curOption[ parts[ i ] ] = curOption[ parts[ i ] ] || {};
-					curOption = curOption[ parts[ i ] ];
-				}
-				key = parts.pop();
-				if ( arguments.length === 1 ) {
-					return curOption[ key ] === undefined ? null : curOption[ key ];
-				}
-				curOption[ key ] = value;
-			} else {
-				if ( arguments.length === 1 ) {
-					return this.options[ key ] === undefined ? null : this.options[ key ];
-				}
-				options[ key ] = value;
-			}
-		}
-
-		this._setOptions( options );
-
-		return this;
-	},
-
-	_setOptions: function( options ) {
-		var key;
-
-		for ( key in options ) {
-			this._setOption( key, options[ key ] );
-		}
-
-		return this;
-	},
-
-	_setOption: function( key, value ) {
-		if ( key === "classes" ) {
-			this._setOptionClasses( value );
-		}
-
-		this.options[ key ] = value;
-
-		if ( key === "disabled" ) {
-			this._setOptionDisabled( value );
-		}
-
-		return this;
-	},
-
-	_setOptionClasses: function( value ) {
-		var classKey, elements, currentElements;
-
-		for ( classKey in value ) {
-			currentElements = this.classesElementLookup[ classKey ];
-			if ( value[ classKey ] === this.options.classes[ classKey ] ||
-					!currentElements ||
-					!currentElements.length ) {
-				continue;
-			}
-
-			// We are doing this to create a new jQuery object because the _removeClass() call
-			// on the next line is going to destroy the reference to the current elements being
-			// tracked. We need to save a copy of this collection so that we can add the new classes
-			// below.
-			elements = $( currentElements.get() );
-			this._removeClass( currentElements, classKey );
-
-			// We don't use _addClass() here, because that uses this.options.classes
-			// for generating the string of classes. We want to use the value passed in from
-			// _setOption(), this is the new value of the classes option which was passed to
-			// _setOption(). We pass this value directly to _classes().
-			elements.addClass( this._classes( {
-				element: elements,
-				keys: classKey,
-				classes: value,
-				add: true
-			} ) );
-		}
-	},
-
-	_setOptionDisabled: function( value ) {
-		this._toggleClass( this.widget(), this.widgetFullName + "-disabled", null, !!value );
-
-		// If the widget is becoming disabled, then nothing is interactive
-		if ( value ) {
-			this._removeClass( this.hoverable, null, "ui-state-hover" );
-			this._removeClass( this.focusable, null, "ui-state-focus" );
-		}
-	},
-
-	enable: function() {
-		return this._setOptions( { disabled: false } );
-	},
-
-	disable: function() {
-		return this._setOptions( { disabled: true } );
-	},
-
-	_classes: function( options ) {
-		var full = [];
-		var that = this;
-
-		options = $.extend( {
-			element: this.element,
-			classes: this.options.classes || {}
-		}, options );
-
-		function processClassString( classes, checkOption ) {
-			var current, i;
-			for ( i = 0; i < classes.length; i++ ) {
-				current = that.classesElementLookup[ classes[ i ] ] || $();
-				if ( options.add ) {
-					current = $( $.unique( current.get().concat( options.element.get() ) ) );
-				} else {
-					current = $( current.not( options.element ).get() );
-				}
-				that.classesElementLookup[ classes[ i ] ] = current;
-				full.push( classes[ i ] );
-				if ( checkOption && options.classes[ classes[ i ] ] ) {
-					full.push( options.classes[ classes[ i ] ] );
-				}
-			}
-		}
-
-		this._on( options.element, {
-			"remove": "_untrackClassesElement"
-		} );
-
-		if ( options.keys ) {
-			processClassString( options.keys.match( /\S+/g ) || [], true );
-		}
-		if ( options.extra ) {
-			processClassString( options.extra.match( /\S+/g ) || [] );
-		}
-
-		return full.join( " " );
-	},
-
-	_untrackClassesElement: function( event ) {
-		var that = this;
-		$.each( that.classesElementLookup, function( key, value ) {
-			if ( $.inArray( event.target, value ) !== -1 ) {
-				that.classesElementLookup[ key ] = $( value.not( event.target ).get() );
-			}
-		} );
-	},
-
-	_removeClass: function( element, keys, extra ) {
-		return this._toggleClass( element, keys, extra, false );
-	},
-
-	_addClass: function( element, keys, extra ) {
-		return this._toggleClass( element, keys, extra, true );
-	},
-
-	_toggleClass: function( element, keys, extra, add ) {
-		add = ( typeof add === "boolean" ) ? add : extra;
-		var shift = ( typeof element === "string" || element === null ),
-			options = {
-				extra: shift ? keys : extra,
-				keys: shift ? element : keys,
-				element: shift ? this.element : element,
-				add: add
-			};
-		options.element.toggleClass( this._classes( options ), add );
-		return this;
-	},
-
-	_on: function( suppressDisabledCheck, element, handlers ) {
-		var delegateElement;
-		var instance = this;
-
-		// No suppressDisabledCheck flag, shuffle arguments
-		if ( typeof suppressDisabledCheck !== "boolean" ) {
-			handlers = element;
-			element = suppressDisabledCheck;
-			suppressDisabledCheck = false;
-		}
-
-		// No element argument, shuffle and use this.element
-		if ( !handlers ) {
-			handlers = element;
-			element = this.element;
-			delegateElement = this.widget();
-		} else {
-			element = delegateElement = $( element );
-			this.bindings = this.bindings.add( element );
-		}
-
-		$.each( handlers, function( event, handler ) {
-			function handlerProxy() {
-
-				// Allow widgets to customize the disabled handling
-				// - disabled as an array instead of boolean
-				// - disabled class as method for disabling individual parts
-				if ( !suppressDisabledCheck &&
-						( instance.options.disabled === true ||
-						$( this ).hasClass( "ui-state-disabled" ) ) ) {
-					return;
-				}
-				return ( typeof handler === "string" ? instance[ handler ] : handler )
-					.apply( instance, arguments );
-			}
-
-			// Copy the guid so direct unbinding works
-			if ( typeof handler !== "string" ) {
-				handlerProxy.guid = handler.guid =
-					handler.guid || handlerProxy.guid || $.guid++;
-			}
-
-			var match = event.match( /^([\w:-]*)\s*(.*)$/ );
-			var eventName = match[ 1 ] + instance.eventNamespace;
-			var selector = match[ 2 ];
-
-			if ( selector ) {
-				delegateElement.on( eventName, selector, handlerProxy );
-			} else {
-				element.on( eventName, handlerProxy );
-			}
-		} );
-	},
-
-	_off: function( element, eventName ) {
-		eventName = ( eventName || "" ).split( " " ).join( this.eventNamespace + " " ) +
-			this.eventNamespace;
-		element.off( eventName ).off( eventName );
-
-		// Clear the stack to avoid memory leaks (#10056)
-		this.bindings = $( this.bindings.not( element ).get() );
-		this.focusable = $( this.focusable.not( element ).get() );
-		this.hoverable = $( this.hoverable.not( element ).get() );
-	},
-
-	_delay: function( handler, delay ) {
-		function handlerProxy() {
-			return ( typeof handler === "string" ? instance[ handler ] : handler )
-				.apply( instance, arguments );
-		}
-		var instance = this;
-		return setTimeout( handlerProxy, delay || 0 );
-	},
-
-	_hoverable: function( element ) {
-		this.hoverable = this.hoverable.add( element );
-		this._on( element, {
-			mouseenter: function( event ) {
-				this._addClass( $( event.currentTarget ), null, "ui-state-hover" );
-			},
-			mouseleave: function( event ) {
-				this._removeClass( $( event.currentTarget ), null, "ui-state-hover" );
-			}
-		} );
-	},
-
-	_focusable: function( element ) {
-		this.focusable = this.focusable.add( element );
-		this._on( element, {
-			focusin: function( event ) {
-				this._addClass( $( event.currentTarget ), null, "ui-state-focus" );
-			},
-			focusout: function( event ) {
-				this._removeClass( $( event.currentTarget ), null, "ui-state-focus" );
-			}
-		} );
-	},
-
-	_trigger: function( type, event, data ) {
-		var prop, orig;
-		var callback = this.options[ type ];
-
-		data = data || {};
-		event = $.Event( event );
-		event.type = ( type === this.widgetEventPrefix ?
-			type :
-			this.widgetEventPrefix + type ).toLowerCase();
-
-		// The original event may come from any element
-		// so we need to reset the target on the new event
-		event.target = this.element[ 0 ];
-
-		// Copy original event properties over to the new event
-		orig = event.originalEvent;
-		if ( orig ) {
-			for ( prop in orig ) {
-				if ( !( prop in event ) ) {
-					event[ prop ] = orig[ prop ];
-				}
-			}
-		}
-
-		this.element.trigger( event, data );
-		return !( $.isFunction( callback ) &&
-			callback.apply( this.element[ 0 ], [ event ].concat( data ) ) === false ||
-			event.isDefaultPrevented() );
-	}
-};
-
-$.each( { show: "fadeIn", hide: "fadeOut" }, function( method, defaultEffect ) {
-	$.Widget.prototype[ "_" + method ] = function( element, options, callback ) {
-		if ( typeof options === "string" ) {
-			options = { effect: options };
-		}
-
-		var hasOptions;
-		var effectName = !options ?
-			method :
-			options === true || typeof options === "number" ?
-				defaultEffect :
-				options.effect || defaultEffect;
-
-		options = options || {};
-		if ( typeof options === "number" ) {
-			options = { duration: options };
-		}
-
-		hasOptions = !$.isEmptyObject( options );
-		options.complete = callback;
-
-		if ( options.delay ) {
-			element.delay( options.delay );
-		}
-
-		if ( hasOptions && $.effects && $.effects.effect[ effectName ] ) {
-			element[ method ]( options );
-		} else if ( effectName !== method && element[ effectName ] ) {
-			element[ effectName ]( options.duration, options.easing, callback );
-		} else {
-			element.queue( function( next ) {
-				$( this )[ method ]();
-				if ( callback ) {
-					callback.call( element[ 0 ] );
-				}
-				next();
-			} );
-		}
-	};
-} );
-
-var widget = $.widget;
-
-
-/*!
- * jQuery UI :data 1.12.1
- * http://jqueryui.com
- *
- * Copyright jQuery Foundation and other contributors
- * Released under the MIT license.
- * http://jquery.org/license
- */
-
-//>>label: :data Selector
-//>>group: Core
-//>>description: Selects elements which have data stored under the specified key.
-//>>docs: http://api.jqueryui.com/data-selector/
-
-
-var data = $.extend( $.expr[ ":" ], {
-	data: $.expr.createPseudo ?
-		$.expr.createPseudo( function( dataName ) {
-			return function( elem ) {
-				return !!$.data( elem, dataName );
-			};
-		} ) :
-
-		// Support: jQuery <1.8
-		function( elem, i, match ) {
-			return !!$.data( elem, match[ 3 ] );
-		}
-} );
-
-/*!
- * jQuery UI Keycode 1.12.1
- * http://jqueryui.com
- *
- * Copyright jQuery Foundation and other contributors
- * Released under the MIT license.
- * http://jquery.org/license
- */
-
-//>>label: Keycode
-//>>group: Core
-//>>description: Provide keycodes as keynames
-//>>docs: http://api.jqueryui.com/jQuery.ui.keyCode/
-
-
-var keycode = $.ui.keyCode = {
-	BACKSPACE: 8,
-	COMMA: 188,
-	DELETE: 46,
-	DOWN: 40,
-	END: 35,
-	ENTER: 13,
-	ESCAPE: 27,
-	HOME: 36,
-	LEFT: 37,
-	PAGE_DOWN: 34,
-	PAGE_UP: 33,
-	PERIOD: 190,
-	RIGHT: 39,
-	SPACE: 32,
-	TAB: 9,
-	UP: 38
-};
-
-
-/*!
- * jQuery UI Scroll Parent 1.12.1
- * http://jqueryui.com
- *
- * Copyright jQuery Foundation and other contributors
- * Released under the MIT license.
- * http://jquery.org/license
- */
-
-//>>label: scrollParent
-//>>group: Core
-//>>description: Get the closest ancestor element that is scrollable.
-//>>docs: http://api.jqueryui.com/scrollParent/
-
-
-
-var scrollParent = $.fn.scrollParent = function( includeHidden ) {
-	var position = this.css( "position" ),
-		excludeStaticParent = position === "absolute",
-		overflowRegex = includeHidden ? /(auto|scroll|hidden)/ : /(auto|scroll)/,
-		scrollParent = this.parents().filter( function() {
-			var parent = $( this );
-			if ( excludeStaticParent && parent.css( "position" ) === "static" ) {
-				return false;
-			}
-			return overflowRegex.test( parent.css( "overflow" ) + parent.css( "overflow-y" ) +
-				parent.css( "overflow-x" ) );
-		} ).eq( 0 );
-
-	return position === "fixed" || !scrollParent.length ?
-		$( this[ 0 ].ownerDocument || document ) :
-		scrollParent;
-};
-
-
-/*!
- * jQuery UI Unique ID 1.12.1
- * http://jqueryui.com
- *
- * Copyright jQuery Foundation and other contributors
- * Released under the MIT license.
- * http://jquery.org/license
- */
-
-//>>label: uniqueId
-//>>group: Core
-//>>description: Functions to generate and remove uniqueId's
-//>>docs: http://api.jqueryui.com/uniqueId/
-
-
-
-var uniqueId = $.fn.extend( {
-	uniqueId: ( function() {
-		var uuid = 0;
-
-		return function() {
-			return this.each( function() {
-				if ( !this.id ) {
-					this.id = "ui-id-" + ( ++uuid );
-				}
-			} );
-		};
-	} )(),
-
-	removeUniqueId: function() {
-		return this.each( function() {
-			if ( /^ui-id-\d+$/.test( this.id ) ) {
-				$( this ).removeAttr( "id" );
-			}
-		} );
-	}
-} );
-
-
-
-
-// This file is deprecated
-var ie = $.ui.ie = !!/msie [\w.]+/.exec( navigator.userAgent.toLowerCase() );
-
-/*!
- * jQuery UI Mouse 1.12.1
- * http://jqueryui.com
- *
- * Copyright jQuery Foundation and other contributors
- * Released under the MIT license.
- * http://jquery.org/license
- */
-
-//>>label: Mouse
-//>>group: Widgets
-//>>description: Abstracts mouse-based interactions to assist in creating certain widgets.
-//>>docs: http://api.jqueryui.com/mouse/
-
-
-
-var mouseHandled = false;
-$( document ).on( "mouseup", function() {
-	mouseHandled = false;
-} );
-
-var widgetsMouse = $.widget( "ui.mouse", {
-	version: "1.12.1",
-	options: {
-		cancel: "input, textarea, button, select, option",
-		distance: 1,
-		delay: 0
-	},
-	_mouseInit: function() {
-		var that = this;
-
-		this.element
-			.on( "mousedown." + this.widgetName, function( event ) {
-				return that._mouseDown( event );
-			} )
-			.on( "click." + this.widgetName, function( event ) {
-				if ( true === $.data( event.target, that.widgetName + ".preventClickEvent" ) ) {
-					$.removeData( event.target, that.widgetName + ".preventClickEvent" );
-					event.stopImmediatePropagation();
-					return false;
-				}
-			} );
-
-		this.started = false;
-	},
-
-	// TODO: make sure destroying one instance of mouse doesn't mess with
-	// other instances of mouse
-	_mouseDestroy: function() {
-		this.element.off( "." + this.widgetName );
-		if ( this._mouseMoveDelegate ) {
-			this.document
-				.off( "mousemove." + this.widgetName, this._mouseMoveDelegate )
-				.off( "mouseup." + this.widgetName, this._mouseUpDelegate );
-		}
-	},
-
-	_mouseDown: function( event ) {
-
-		// don't let more than one widget handle mouseStart
-		if ( mouseHandled ) {
-			return;
-		}
-
-		this._mouseMoved = false;
-
-		// We may have missed mouseup (out of window)
-		( this._mouseStarted && this._mouseUp( event ) );
-
-		this._mouseDownEvent = event;
-
-		var that = this,
-			btnIsLeft = ( event.which === 1 ),
-
-			// event.target.nodeName works around a bug in IE 8 with
-			// disabled inputs (#7620)
-			elIsCancel = ( typeof this.options.cancel === "string" && event.target.nodeName ?
-				$( event.target ).closest( this.options.cancel ).length : false );
-		if ( !btnIsLeft || elIsCancel || !this._mouseCapture( event ) ) {
-			return true;
-		}
-
-		this.mouseDelayMet = !this.options.delay;
-		if ( !this.mouseDelayMet ) {
-			this._mouseDelayTimer = setTimeout( function() {
-				that.mouseDelayMet = true;
-			}, this.options.delay );
-		}
-
-		if ( this._mouseDistanceMet( event ) && this._mouseDelayMet( event ) ) {
-			this._mouseStarted = ( this._mouseStart( event ) !== false );
-			if ( !this._mouseStarted ) {
-				event.preventDefault();
-				return true;
-			}
-		}
-
-		// Click event may never have fired (Gecko & Opera)
-		if ( true === $.data( event.target, this.widgetName + ".preventClickEvent" ) ) {
-			$.removeData( event.target, this.widgetName + ".preventClickEvent" );
-		}
-
-		// These delegates are required to keep context
-		this._mouseMoveDelegate = function( event ) {
-			return that._mouseMove( event );
-		};
-		this._mouseUpDelegate = function( event ) {
-			return that._mouseUp( event );
-		};
-
-		this.document
-			.on( "mousemove." + this.widgetName, this._mouseMoveDelegate )
-			.on( "mouseup." + this.widgetName, this._mouseUpDelegate );
-
-		event.preventDefault();
-
-		mouseHandled = true;
-		return true;
-	},
-
-	_mouseMove: function( event ) {
-
-		// Only check for mouseups outside the document if you've moved inside the document
-		// at least once. This prevents the firing of mouseup in the case of IE<9, which will
-		// fire a mousemove event if content is placed under the cursor. See #7778
-		// Support: IE <9
-		if ( this._mouseMoved ) {
-
-			// IE mouseup check - mouseup happened when mouse was out of window
-			if ( $.ui.ie && ( !document.documentMode || document.documentMode < 9 ) &&
-					!event.button ) {
-				return this._mouseUp( event );
-
-			// Iframe mouseup check - mouseup occurred in another document
-			} else if ( !event.which ) {
-
-				// Support: Safari <=8 - 9
-				// Safari sets which to 0 if you press any of the following keys
-				// during a drag (#14461)
-				if ( event.originalEvent.altKey || event.originalEvent.ctrlKey ||
-						event.originalEvent.metaKey || event.originalEvent.shiftKey ) {
-					this.ignoreMissingWhich = true;
-				} else if ( !this.ignoreMissingWhich ) {
-					return this._mouseUp( event );
-				}
-			}
-		}
-
-		if ( event.which || event.button ) {
-			this._mouseMoved = true;
-		}
-
-		if ( this._mouseStarted ) {
-			this._mouseDrag( event );
-			return event.preventDefault();
-		}
-
-		if ( this._mouseDistanceMet( event ) && this._mouseDelayMet( event ) ) {
-			this._mouseStarted =
-				( this._mouseStart( this._mouseDownEvent, event ) !== false );
-			( this._mouseStarted ? this._mouseDrag( event ) : this._mouseUp( event ) );
-		}
-
-		return !this._mouseStarted;
-	},
-
-	_mouseUp: function( event ) {
-		this.document
-			.off( "mousemove." + this.widgetName, this._mouseMoveDelegate )
-			.off( "mouseup." + this.widgetName, this._mouseUpDelegate );
-
-		if ( this._mouseStarted ) {
-			this._mouseStarted = false;
-
-			if ( event.target === this._mouseDownEvent.target ) {
-				$.data( event.target, this.widgetName + ".preventClickEvent", true );
-			}
-
-			this._mouseStop( event );
-		}
-
-		if ( this._mouseDelayTimer ) {
-			clearTimeout( this._mouseDelayTimer );
-			delete this._mouseDelayTimer;
-		}
-
-		this.ignoreMissingWhich = false;
-		mouseHandled = false;
-		event.preventDefault();
-	},
-
-	_mouseDistanceMet: function( event ) {
-		return ( Math.max(
-				Math.abs( this._mouseDownEvent.pageX - event.pageX ),
-				Math.abs( this._mouseDownEvent.pageY - event.pageY )
-			) >= this.options.distance
-		);
-	},
-
-	_mouseDelayMet: function( /* event */ ) {
-		return this.mouseDelayMet;
-	},
-
-	// These are placeholder methods, to be overriden by extending plugin
-	_mouseStart: function( /* event */ ) {},
-	_mouseDrag: function( /* event */ ) {},
-	_mouseStop: function( /* event */ ) {},
-	_mouseCapture: function( /* event */ ) { return true; }
-} );
-
-
-
-
-// $.ui.plugin is deprecated. Use $.widget() extensions instead.
-var plugin = $.ui.plugin = {
-	add: function( module, option, set ) {
-		var i,
-			proto = $.ui[ module ].prototype;
-		for ( i in set ) {
-			proto.plugins[ i ] = proto.plugins[ i ] || [];
-			proto.plugins[ i ].push( [ option, set[ i ] ] );
-		}
-	},
-	call: function( instance, name, args, allowDisconnected ) {
-		var i,
-			set = instance.plugins[ name ];
-
-		if ( !set ) {
-			return;
-		}
-
-		if ( !allowDisconnected && ( !instance.element[ 0 ].parentNode ||
-				instance.element[ 0 ].parentNode.nodeType === 11 ) ) {
-			return;
-		}
-
-		for ( i = 0; i < set.length; i++ ) {
-			if ( instance.options[ set[ i ][ 0 ] ] ) {
-				set[ i ][ 1 ].apply( instance.element, args );
-			}
-		}
-	}
-};
-
-
-
-var safeActiveElement = $.ui.safeActiveElement = function( document ) {
-	var activeElement;
-
-	// Support: IE 9 only
-	// IE9 throws an "Unspecified error" accessing document.activeElement from an <iframe>
-	try {
-		activeElement = document.activeElement;
-	} catch ( error ) {
-		activeElement = document.body;
-	}
-
-	// Support: IE 9 - 11 only
-	// IE may return null instead of an element
-	// Interestingly, this only seems to occur when NOT in an iframe
-	if ( !activeElement ) {
-		activeElement = document.body;
-	}
-
-	// Support: IE 11 only
-	// IE11 returns a seemingly empty object in some cases when accessing
-	// document.activeElement from an <iframe>
-	if ( !activeElement.nodeName ) {
-		activeElement = document.body;
-	}
-
-	return activeElement;
-};
-
-
-
-var safeBlur = $.ui.safeBlur = function( element ) {
-
-	// Support: IE9 - 10 only
-	// If the <body> is blurred, IE will switch windows, see #9420
-	if ( element && element.nodeName.toLowerCase() !== "body" ) {
-		$( element ).trigger( "blur" );
-	}
-};
-
-
-/*!
- * jQuery UI Draggable 1.12.1
- * http://jqueryui.com
- *
- * Copyright jQuery Foundation and other contributors
- * Released under the MIT license.
- * http://jquery.org/license
- */
-
-//>>label: Draggable
-//>>group: Interactions
-//>>description: Enables dragging functionality for any element.
-//>>docs: http://api.jqueryui.com/draggable/
-//>>demos: http://jqueryui.com/draggable/
-//>>css.structure: ../../themes/base/draggable.css
-
-
-
-$.widget( "ui.draggable", $.ui.mouse, {
-	version: "1.12.1",
-	widgetEventPrefix: "drag",
-	options: {
-		addClasses: true,
-		appendTo: "parent",
-		axis: false,
-		connectToSortable: false,
-		containment: false,
-		cursor: "auto",
-		cursorAt: false,
-		grid: false,
-		handle: false,
-		helper: "original",
-		iframeFix: false,
-		opacity: false,
-		refreshPositions: false,
-		revert: false,
-		revertDuration: 500,
-		scope: "default",
-		scroll: true,
-		scrollSensitivity: 20,
-		scrollSpeed: 20,
-		snap: false,
-		snapMode: "both",
-		snapTolerance: 20,
-		stack: false,
-		zIndex: false,
-
-		// Callbacks
-		drag: null,
-		start: null,
-		stop: null
-	},
-	_create: function() {
-
-		if ( this.options.helper === "original" ) {
-			this._setPositionRelative();
-		}
-		if ( this.options.addClasses ) {
-			this._addClass( "ui-draggable" );
-		}
-		this._setHandleClassName();
-
-		this._mouseInit();
-	},
-
-	_setOption: function( key, value ) {
-		this._super( key, value );
-		if ( key === "handle" ) {
-			this._removeHandleClassName();
-			this._setHandleClassName();
-		}
-	},
-
-	_destroy: function() {
-		if ( ( this.helper || this.element ).is( ".ui-draggable-dragging" ) ) {
-			this.destroyOnClear = true;
-			return;
-		}
-		this._removeHandleClassName();
-		this._mouseDestroy();
-	},
-
-	_mouseCapture: function( event ) {
-		var o = this.options;
-
-		// Among others, prevent a drag on a resizable-handle
-		if ( this.helper || o.disabled ||
-				$( event.target ).closest( ".ui-resizable-handle" ).length > 0 ) {
-			return false;
-		}
-
-		//Quit if we're not on a valid handle
-		this.handle = this._getHandle( event );
-		if ( !this.handle ) {
-			return false;
-		}
-
-		this._blurActiveElement( event );
-
-		this._blockFrames( o.iframeFix === true ? "iframe" : o.iframeFix );
-
-		return true;
-
-	},
-
-	_blockFrames: function( selector ) {
-		this.iframeBlocks = this.document.find( selector ).map( function() {
-			var iframe = $( this );
-
-			return $( "<div>" )
-				.css( "position", "absolute" )
-				.appendTo( iframe.parent() )
-				.outerWidth( iframe.outerWidth() )
-				.outerHeight( iframe.outerHeight() )
-				.offset( iframe.offset() )[ 0 ];
-		} );
-	},
-
-	_unblockFrames: function() {
-		if ( this.iframeBlocks ) {
-			this.iframeBlocks.remove();
-			delete this.iframeBlocks;
-		}
-	},
-
-	_blurActiveElement: function( event ) {
-		var activeElement = $.ui.safeActiveElement( this.document[ 0 ] ),
-			target = $( event.target );
-
-		// Don't blur if the event occurred on an element that is within
-		// the currently focused element
-		// See #10527, #12472
-		if ( target.closest( activeElement ).length ) {
-			return;
-		}
-
-		// Blur any element that currently has focus, see #4261
-		$.ui.safeBlur( activeElement );
-	},
-
-	_mouseStart: function( event ) {
-
-		var o = this.options;
-
-		//Create and append the visible helper
-		this.helper = this._createHelper( event );
-
-		this._addClass( this.helper, "ui-draggable-dragging" );
-
-		//Cache the helper size
-		this._cacheHelperProportions();
-
-		//If ddmanager is used for droppables, set the global draggable
-		if ( $.ui.ddmanager ) {
-			$.ui.ddmanager.current = this;
-		}
-
-		/*
-		 * - Position generation -
-		 * This block generates everything position related - it's the core of draggables.
-		 */
-
-		//Cache the margins of the original element
-		this._cacheMargins();
-
-		//Store the helper's css position
-		this.cssPosition = this.helper.css( "position" );
-		this.scrollParent = this.helper.scrollParent( true );
-		this.offsetParent = this.helper.offsetParent();
-		this.hasFixedAncestor = this.helper.parents().filter( function() {
-				return $( this ).css( "position" ) === "fixed";
-			} ).length > 0;
-
-		//The element's absolute position on the page minus margins
-		this.positionAbs = this.element.offset();
-		this._refreshOffsets( event );
-
-		//Generate the original position
-		this.originalPosition = this.position = this._generatePosition( event, false );
-		this.originalPageX = event.pageX;
-		this.originalPageY = event.pageY;
-
-		//Adjust the mouse offset relative to the helper if "cursorAt" is supplied
-		( o.cursorAt && this._adjustOffsetFromHelper( o.cursorAt ) );
-
-		//Set a containment if given in the options
-		this._setContainment();
-
-		//Trigger event + callbacks
-		if ( this._trigger( "start", event ) === false ) {
-			this._clear();
-			return false;
-		}
-
-		//Recache the helper size
-		this._cacheHelperProportions();
-
-		//Prepare the droppable offsets
-		if ( $.ui.ddmanager && !o.dropBehaviour ) {
-			$.ui.ddmanager.prepareOffsets( this, event );
-		}
-
-		// Execute the drag once - this causes the helper not to be visible before getting its
-		// correct position
-		this._mouseDrag( event, true );
-
-		// If the ddmanager is used for droppables, inform the manager that dragging has started
-		// (see #5003)
-		if ( $.ui.ddmanager ) {
-			$.ui.ddmanager.dragStart( this, event );
-		}
-
-		return true;
-	},
-
-	_refreshOffsets: function( event ) {
-		this.offset = {
-			top: this.positionAbs.top - this.margins.top,
-			left: this.positionAbs.left - this.margins.left,
-			scroll: false,
-			parent: this._getParentOffset(),
-			relative: this._getRelativeOffset()
-		};
-
-		this.offset.click = {
-			left: event.pageX - this.offset.left,
-			top: event.pageY - this.offset.top
-		};
-	},
-
-	_mouseDrag: function( event, noPropagation ) {
-
-		// reset any necessary cached properties (see #5009)
-		if ( this.hasFixedAncestor ) {
-			this.offset.parent = this._getParentOffset();
-		}
-
-		//Compute the helpers position
-		this.position = this._generatePosition( event, true );
-		this.positionAbs = this._convertPositionTo( "absolute" );
-
-		//Call plugins and callbacks and use the resulting position if something is returned
-		if ( !noPropagation ) {
-			var ui = this._uiHash();
-			if ( this._trigger( "drag", event, ui ) === false ) {
-				this._mouseUp( new $.Event( "mouseup", event ) );
-				return false;
-			}
-			this.position = ui.position;
-		}
-
-		this.helper[ 0 ].style.left = this.position.left + "px";
-		this.helper[ 0 ].style.top = this.position.top + "px";
-
-		if ( $.ui.ddmanager ) {
-			$.ui.ddmanager.drag( this, event );
-		}
-
-		return false;
-	},
-
-	_mouseStop: function( event ) {
-
-		//If we are using droppables, inform the manager about the drop
-		var that = this,
-			dropped = false;
-		if ( $.ui.ddmanager && !this.options.dropBehaviour ) {
-			dropped = $.ui.ddmanager.drop( this, event );
-		}
-
-		//if a drop comes from outside (a sortable)
-		if ( this.dropped ) {
-			dropped = this.dropped;
-			this.dropped = false;
-		}
-
-		if ( ( this.options.revert === "invalid" && !dropped ) ||
-				( this.options.revert === "valid" && dropped ) ||
-				this.options.revert === true || ( $.isFunction( this.options.revert ) &&
-				this.options.revert.call( this.element, dropped ) )
-		) {
-			$( this.helper ).animate(
-				this.originalPosition,
-				parseInt( this.options.revertDuration, 10 ),
-				function() {
-					if ( that._trigger( "stop", event ) !== false ) {
-						that._clear();
-					}
-				}
-			);
-		} else {
-			if ( this._trigger( "stop", event ) !== false ) {
-				this._clear();
-			}
-		}
-
-		return false;
-	},
-
-	_mouseUp: function( event ) {
-		this._unblockFrames();
-
-		// If the ddmanager is used for droppables, inform the manager that dragging has stopped
-		// (see #5003)
-		if ( $.ui.ddmanager ) {
-			$.ui.ddmanager.dragStop( this, event );
-		}
-
-		// Only need to focus if the event occurred on the draggable itself, see #10527
-		if ( this.handleElement.is( event.target ) ) {
-
-			// The interaction is over; whether or not the click resulted in a drag,
-			// focus the element
-			this.element.trigger( "focus" );
-		}
-
-		return $.ui.mouse.prototype._mouseUp.call( this, event );
-	},
-
-	cancel: function() {
-
-		if ( this.helper.is( ".ui-draggable-dragging" ) ) {
-			this._mouseUp( new $.Event( "mouseup", { target: this.element[ 0 ] } ) );
-		} else {
-			this._clear();
-		}
-
-		return this;
-
-	},
-
-	_getHandle: function( event ) {
-		return this.options.handle ?
-			!!$( event.target ).closest( this.element.find( this.options.handle ) ).length :
-			true;
-	},
-
-	_setHandleClassName: function() {
-		this.handleElement = this.options.handle ?
-			this.element.find( this.options.handle ) : this.element;
-		this._addClass( this.handleElement, "ui-draggable-handle" );
-	},
-
-	_removeHandleClassName: function() {
-		this._removeClass( this.handleElement, "ui-draggable-handle" );
-	},
-
-	_createHelper: function( event ) {
-
-		var o = this.options,
-			helperIsFunction = $.isFunction( o.helper ),
-			helper = helperIsFunction ?
-				$( o.helper.apply( this.element[ 0 ], [ event ] ) ) :
-				( o.helper === "clone" ?
-					this.element.clone().removeAttr( "id" ) :
-					this.element );
-
-		if ( !helper.parents( "body" ).length ) {
-			helper.appendTo( ( o.appendTo === "parent" ?
-				this.element[ 0 ].parentNode :
-				o.appendTo ) );
-		}
-
-		// Http://bugs.jqueryui.com/ticket/9446
-		// a helper function can return the original element
-		// which wouldn't have been set to relative in _create
-		if ( helperIsFunction && helper[ 0 ] === this.element[ 0 ] ) {
-			this._setPositionRelative();
-		}
-
-		if ( helper[ 0 ] !== this.element[ 0 ] &&
-				!( /(fixed|absolute)/ ).test( helper.css( "position" ) ) ) {
-			helper.css( "position", "absolute" );
-		}
-
-		return helper;
-
-	},
-
-	_setPositionRelative: function() {
-		if ( !( /^(?:r|a|f)/ ).test( this.element.css( "position" ) ) ) {
-			this.element[ 0 ].style.position = "relative";
-		}
-	},
-
-	_adjustOffsetFromHelper: function( obj ) {
-		if ( typeof obj === "string" ) {
-			obj = obj.split( " " );
-		}
-		if ( $.isArray( obj ) ) {
-			obj = { left: +obj[ 0 ], top: +obj[ 1 ] || 0 };
-		}
-		if ( "left" in obj ) {
-			this.offset.click.left = obj.left + this.margins.left;
-		}
-		if ( "right" in obj ) {
-			this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
-		}
-		if ( "top" in obj ) {
-			this.offset.click.top = obj.top + this.margins.top;
-		}
-		if ( "bottom" in obj ) {
-			this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
-		}
-	},
-
-	_isRootNode: function( element ) {
-		return ( /(html|body)/i ).test( element.tagName ) || element === this.document[ 0 ];
-	},
-
-	_getParentOffset: function() {
-
-		//Get the offsetParent and cache its position
-		var po = this.offsetParent.offset(),
-			document = this.document[ 0 ];
-
-		// This is a special case where we need to modify a offset calculated on start, since the
-		// following happened:
-		// 1. The position of the helper is absolute, so it's position is calculated based on the
-		// next positioned parent
-		// 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't
-		// the document, which means that the scroll is included in the initial calculation of the
-		// offset of the parent, and never recalculated upon drag
-		if ( this.cssPosition === "absolute" && this.scrollParent[ 0 ] !== document &&
-				$.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) {
-			po.left += this.scrollParent.scrollLeft();
-			po.top += this.scrollParent.scrollTop();
-		}
-
-		if ( this._isRootNode( this.offsetParent[ 0 ] ) ) {
-			po = { top: 0, left: 0 };
-		}
-
-		return {
-			top: po.top + ( parseInt( this.offsetParent.css( "borderTopWidth" ), 10 ) || 0 ),
-			left: po.left + ( parseInt( this.offsetParent.css( "borderLeftWidth" ), 10 ) || 0 )
-		};
-
-	},
-
-	_getRelativeOffset: function() {
-		if ( this.cssPosition !== "relative" ) {
-			return { top: 0, left: 0 };
-		}
-
-		var p = this.element.position(),
-			scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] );
-
-		return {
-			top: p.top - ( parseInt( this.helper.css( "top" ), 10 ) || 0 ) +
-				( !scrollIsRootNode ? this.scrollParent.scrollTop() : 0 ),
-			left: p.left - ( parseInt( this.helper.css( "left" ), 10 ) || 0 ) +
-				( !scrollIsRootNode ? this.scrollParent.scrollLeft() : 0 )
-		};
-
-	},
-
-	_cacheMargins: function() {
-		this.margins = {
-			left: ( parseInt( this.element.css( "marginLeft" ), 10 ) || 0 ),
-			top: ( parseInt( this.element.css( "marginTop" ), 10 ) || 0 ),
-			right: ( parseInt( this.element.css( "marginRight" ), 10 ) || 0 ),
-			bottom: ( parseInt( this.element.css( "marginBottom" ), 10 ) || 0 )
-		};
-	},
-
-	_cacheHelperProportions: function() {
-		this.helperProportions = {
-			width: this.helper.outerWidth(),
-			height: this.helper.outerHeight()
-		};
-	},
-
-	_setContainment: function() {
-
-		var isUserScrollable, c, ce,
-			o = this.options,
-			document = this.document[ 0 ];
-
-		this.relativeContainer = null;
-
-		if ( !o.containment ) {
-			this.containment = null;
-			return;
-		}
-
-		if ( o.containment === "window" ) {
-			this.containment = [
-				$( window ).scrollLeft() - this.offset.relative.left - this.offset.parent.left,
-				$( window ).scrollTop() - this.offset.relative.top - this.offset.parent.top,
-				$( window ).scrollLeft() + $( window ).width() -
-					this.helperProportions.width - this.margins.left,
-				$( window ).scrollTop() +
-					( $( window ).height() || document.body.parentNode.scrollHeight ) -
-					this.helperProportions.height - this.margins.top
-			];
-			return;
-		}
-
-		if ( o.containment === "document" ) {
-			this.containment = [
-				0,
-				0,
-				$( document ).width() - this.helperProportions.width - this.margins.left,
-				( $( document ).height() || document.body.parentNode.scrollHeight ) -
-					this.helperProportions.height - this.margins.top
-			];
-			return;
-		}
-
-		if ( o.containment.constructor === Array ) {
-			this.containment = o.containment;
-			return;
-		}
-
-		if ( o.containment === "parent" ) {
-			o.containment = this.helper[ 0 ].parentNode;
-		}
-
-		c = $( o.containment );
-		ce = c[ 0 ];
-
-		if ( !ce ) {
-			return;
-		}
-
-		isUserScrollable = /(scroll|auto)/.test( c.css( "overflow" ) );
-
-		this.containment = [
-			( parseInt( c.css( "borderLeftWidth" ), 10 ) || 0 ) +
-				( parseInt( c.css( "paddingLeft" ), 10 ) || 0 ),
-			( parseInt( c.css( "borderTopWidth" ), 10 ) || 0 ) +
-				( parseInt( c.css( "paddingTop" ), 10 ) || 0 ),
-			( isUserScrollable ? Math.max( ce.scrollWidth, ce.offsetWidth ) : ce.offsetWidth ) -
-				( parseInt( c.css( "borderRightWidth" ), 10 ) || 0 ) -
-				( parseInt( c.css( "paddingRight" ), 10 ) || 0 ) -
-				this.helperProportions.width -
-				this.margins.left -
-				this.margins.right,
-			( isUserScrollable ? Math.max( ce.scrollHeight, ce.offsetHeight ) : ce.offsetHeight ) -
-				( parseInt( c.css( "borderBottomWidth" ), 10 ) || 0 ) -
-				( parseInt( c.css( "paddingBottom" ), 10 ) || 0 ) -
-				this.helperProportions.height -
-				this.margins.top -
-				this.margins.bottom
-		];
-		this.relativeContainer = c;
-	},
-
-	_convertPositionTo: function( d, pos ) {
-
-		if ( !pos ) {
-			pos = this.position;
-		}
-
-		var mod = d === "absolute" ? 1 : -1,
-			scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] );
-
-		return {
-			top: (
-
-				// The absolute mouse position
-				pos.top	+
-
-				// Only for relative positioned nodes: Relative offset from element to offset parent
-				this.offset.relative.top * mod +
-
-				// The offsetParent's offset without borders (offset + border)
-				this.offset.parent.top * mod -
-				( ( this.cssPosition === "fixed" ?
-					-this.offset.scroll.top :
-					( scrollIsRootNode ? 0 : this.offset.scroll.top ) ) * mod )
-			),
-			left: (
-
-				// The absolute mouse position
-				pos.left +
-
-				// Only for relative positioned nodes: Relative offset from element to offset parent
-				this.offset.relative.left * mod +
-
-				// The offsetParent's offset without borders (offset + border)
-				this.offset.parent.left * mod	-
-				( ( this.cssPosition === "fixed" ?
-					-this.offset.scroll.left :
-					( scrollIsRootNode ? 0 : this.offset.scroll.left ) ) * mod )
-			)
-		};
-
-	},
-
-	_generatePosition: function( event, constrainPosition ) {
-
-		var containment, co, top, left,
-			o = this.options,
-			scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] ),
-			pageX = event.pageX,
-			pageY = event.pageY;
-
-		// Cache the scroll
-		if ( !scrollIsRootNode || !this.offset.scroll ) {
-			this.offset.scroll = {
-				top: this.scrollParent.scrollTop(),
-				left: this.scrollParent.scrollLeft()
-			};
-		}
-
-		/*
-		 * - Position constraining -
-		 * Constrain the position to a mix of grid, containment.
-		 */
-
-		// If we are not dragging yet, we won't check for options
-		if ( constrainPosition ) {
-			if ( this.containment ) {
-				if ( this.relativeContainer ) {
-					co = this.relativeContainer.offset();
-					containment = [
-						this.containment[ 0 ] + co.left,
-						this.containment[ 1 ] + co.top,
-						this.containment[ 2 ] + co.left,
-						this.containment[ 3 ] + co.top
-					];
-				} else {
-					containment = this.containment;
-				}
-
-				if ( event.pageX - this.offset.click.left < containment[ 0 ] ) {
-					pageX = containment[ 0 ] + this.offset.click.left;
-				}
-				if ( event.pageY - this.offset.click.top < containment[ 1 ] ) {
-					pageY = containment[ 1 ] + this.offset.click.top;
-				}
-				if ( event.pageX - this.offset.click.left > containment[ 2 ] ) {
-					pageX = containment[ 2 ] + this.offset.click.left;
-				}
-				if ( event.pageY - this.offset.click.top > containment[ 3 ] ) {
-					pageY = containment[ 3 ] + this.offset.click.top;
-				}
-			}
-
-			if ( o.grid ) {
-
-				//Check for grid elements set to 0 to prevent divide by 0 error causing invalid
-				// argument errors in IE (see ticket #6950)
-				top = o.grid[ 1 ] ? this.originalPageY + Math.round( ( pageY -
-					this.originalPageY ) / o.grid[ 1 ] ) * o.grid[ 1 ] : this.originalPageY;
-				pageY = containment ? ( ( top - this.offset.click.top >= containment[ 1 ] ||
-					top - this.offset.click.top > containment[ 3 ] ) ?
-						top :
-						( ( top - this.offset.click.top >= containment[ 1 ] ) ?
-							top - o.grid[ 1 ] : top + o.grid[ 1 ] ) ) : top;
-
-				left = o.grid[ 0 ] ? this.originalPageX +
-					Math.round( ( pageX - this.originalPageX ) / o.grid[ 0 ] ) * o.grid[ 0 ] :
-					this.originalPageX;
-				pageX = containment ? ( ( left - this.offset.click.left >= containment[ 0 ] ||
-					left - this.offset.click.left > containment[ 2 ] ) ?
-						left :
-						( ( left - this.offset.click.left >= containment[ 0 ] ) ?
-							left - o.grid[ 0 ] : left + o.grid[ 0 ] ) ) : left;
-			}
-
-			if ( o.axis === "y" ) {
-				pageX = this.originalPageX;
-			}
-
-			if ( o.axis === "x" ) {
-				pageY = this.originalPageY;
-			}
-		}
-
-		return {
-			top: (
-
-				// The absolute mouse position
-				pageY -
-
-				// Click offset (relative to the element)
-				this.offset.click.top -
-
-				// Only for relative positioned nodes: Relative offset from element to offset parent
-				this.offset.relative.top -
-
-				// The offsetParent's offset without borders (offset + border)
-				this.offset.parent.top +
-				( this.cssPosition === "fixed" ?
-					-this.offset.scroll.top :
-					( scrollIsRootNode ? 0 : this.offset.scroll.top ) )
-			),
-			left: (
-
-				// The absolute mouse position
-				pageX -
-
-				// Click offset (relative to the element)
-				this.offset.click.left -
-
-				// Only for relative positioned nodes: Relative offset from element to offset parent
-				this.offset.relative.left -
-
-				// The offsetParent's offset without borders (offset + border)
-				this.offset.parent.left +
-				( this.cssPosition === "fixed" ?
-					-this.offset.scroll.left :
-					( scrollIsRootNode ? 0 : this.offset.scroll.left ) )
-			)
-		};
-
-	},
-
-	_clear: function() {
-		this._removeClass( this.helper, "ui-draggable-dragging" );
-		if ( this.helper[ 0 ] !== this.element[ 0 ] && !this.cancelHelperRemoval ) {
-			this.helper.remove();
-		}
-		this.helper = null;
-		this.cancelHelperRemoval = false;
-		if ( this.destroyOnClear ) {
-			this.destroy();
-		}
-	},
-
-	// From now on bulk stuff - mainly helpers
-
-	_trigger: function( type, event, ui ) {
-		ui = ui || this._uiHash();
-		$.ui.plugin.call( this, type, [ event, ui, this ], true );
-
-		// Absolute position and offset (see #6884 ) have to be recalculated after plugins
-		if ( /^(drag|start|stop)/.test( type ) ) {
-			this.positionAbs = this._convertPositionTo( "absolute" );
-			ui.offset = this.positionAbs;
-		}
-		return $.Widget.prototype._trigger.call( this, type, event, ui );
-	},
-
-	plugins: {},
-
-	_uiHash: function() {
-		return {
-			helper: this.helper,
-			position: this.position,
-			originalPosition: this.originalPosition,
-			offset: this.positionAbs
-		};
-	}
-
-} );
-
-$.ui.plugin.add( "draggable", "connectToSortable", {
-	start: function( event, ui, draggable ) {
-		var uiSortable = $.extend( {}, ui, {
-			item: draggable.element
-		} );
-
-		draggable.sortables = [];
-		$( draggable.options.connectToSortable ).each( function() {
-			var sortable = $( this ).sortable( "instance" );
-
-			if ( sortable && !sortable.options.disabled ) {
-				draggable.sortables.push( sortable );
-
-				// RefreshPositions is called at drag start to refresh the containerCache
-				// which is used in drag. This ensures it's initialized and synchronized
-				// with any changes that might have happened on the page since initialization.
-				sortable.refreshPositions();
-				sortable._trigger( "activate", event, uiSortable );
-			}
-		} );
-	},
-	stop: function( event, ui, draggable ) {
-		var uiSortable = $.extend( {}, ui, {
-			item: draggable.element
-		} );
-
-		draggable.cancelHelperRemoval = false;
-
-		$.each( draggable.sortables, function() {
-			var sortable = this;
-
-			if ( sortable.isOver ) {
-				sortable.isOver = 0;
-
-				// Allow this sortable to handle removing the helper
-				draggable.cancelHelperRemoval = true;
-				sortable.cancelHelperRemoval = false;
-
-				// Use _storedCSS To restore properties in the sortable,
-				// as this also handles revert (#9675) since the draggable
-				// may have modified them in unexpected ways (#8809)
-				sortable._storedCSS = {
-					position: sortable.placeholder.css( "position" ),
-					top: sortable.placeholder.css( "top" ),
-					left: sortable.placeholder.css( "left" )
-				};
-
-				sortable._mouseStop( event );
-
-				// Once drag has ended, the sortable should return to using
-				// its original helper, not the shared helper from draggable
-				sortable.options.helper = sortable.options._helper;
-			} else {
-
-				// Prevent this Sortable from removing the helper.
-				// However, don't set the draggable to remove the helper
-				// either as another connected Sortable may yet handle the removal.
-				sortable.cancelHelperRemoval = true;
-
-				sortable._trigger( "deactivate", event, uiSortable );
-			}
-		} );
-	},
-	drag: function( event, ui, draggable ) {
-		$.each( draggable.sortables, function() {
-			var innermostIntersecting = false,
-				sortable = this;
-
-			// Copy over variables that sortable's _intersectsWith uses
-			sortable.positionAbs = draggable.positionAbs;
-			sortable.helperProportions = draggable.helperProportions;
-			sortable.offset.click = draggable.offset.click;
-
-			if ( sortable._intersectsWith( sortable.containerCache ) ) {
-				innermostIntersecting = true;
-
-				$.each( draggable.sortables, function() {
-
-					// Copy over variables that sortable's _intersectsWith uses
-					this.positionAbs = draggable.positionAbs;
-					this.helperProportions = draggable.helperProportions;
-					this.offset.click = draggable.offset.click;
-
-					if ( this !== sortable &&
-							this._intersectsWith( this.containerCache ) &&
-							$.contains( sortable.element[ 0 ], this.element[ 0 ] ) ) {
-						innermostIntersecting = false;
-					}
-
-					return innermostIntersecting;
-				} );
-			}
-
-			if ( innermostIntersecting ) {
-
-				// If it intersects, we use a little isOver variable and set it once,
-				// so that the move-in stuff gets fired only once.
-				if ( !sortable.isOver ) {
-					sortable.isOver = 1;
-
-					// Store draggable's parent in case we need to reappend to it later.
-					draggable._parent = ui.helper.parent();
-
-					sortable.currentItem = ui.helper
-						.appendTo( sortable.element )
-						.data( "ui-sortable-item", true );
-
-					// Store helper option to later restore it
-					sortable.options._helper = sortable.options.helper;
-
-					sortable.options.helper = function() {
-						return ui.helper[ 0 ];
-					};
-
-					// Fire the start events of the sortable with our passed browser event,
-					// and our own helper (so it doesn't create a new one)
-					event.target = sortable.currentItem[ 0 ];
-					sortable._mouseCapture( event, true );
-					sortable._mouseStart( event, true, true );
-
-					// Because the browser event is way off the new appended portlet,
-					// modify necessary variables to reflect the changes
-					sortable.offset.click.top = draggable.offset.click.top;
-					sortable.offset.click.left = draggable.offset.click.left;
-					sortable.offset.parent.left -= draggable.offset.parent.left -
-						sortable.offset.parent.left;
-					sortable.offset.parent.top -= draggable.offset.parent.top -
-						sortable.offset.parent.top;
-
-					draggable._trigger( "toSortable", event );
-
-					// Inform draggable that the helper is in a valid drop zone,
-					// used solely in the revert option to handle "valid/invalid".
-					draggable.dropped = sortable.element;
-
-					// Need to refreshPositions of all sortables in the case that
-					// adding to one sortable changes the location of the other sortables (#9675)
-					$.each( draggable.sortables, function() {
-						this.refreshPositions();
-					} );
-
-					// Hack so receive/update callbacks work (mostly)
-					draggable.currentItem = draggable.element;
-					sortable.fromOutside = draggable;
-				}
-
-				if ( sortable.currentItem ) {
-					sortable._mouseDrag( event );
-
-					// Copy the sortable's position because the draggable's can potentially reflect
-					// a relative position, while sortable is always absolute, which the dragged
-					// element has now become. (#8809)
-					ui.position = sortable.position;
-				}
-			} else {
-
-				// If it doesn't intersect with the sortable, and it intersected before,
-				// we fake the drag stop of the sortable, but make sure it doesn't remove
-				// the helper by using cancelHelperRemoval.
-				if ( sortable.isOver ) {
-
-					sortable.isOver = 0;
-					sortable.cancelHelperRemoval = true;
-
-					// Calling sortable's mouseStop would trigger a revert,
-					// so revert must be temporarily false until after mouseStop is called.
-					sortable.options._revert = sortable.options.revert;
-					sortable.options.revert = false;
-
-					sortable._trigger( "out", event, sortable._uiHash( sortable ) );
-					sortable._mouseStop( event, true );
-
-					// Restore sortable behaviors that were modfied
-					// when the draggable entered the sortable area (#9481)
-					sortable.options.revert = sortable.options._revert;
-					sortable.options.helper = sortable.options._helper;
-
-					if ( sortable.placeholder ) {
-						sortable.placeholder.remove();
-					}
-
-					// Restore and recalculate the draggable's offset considering the sortable
-					// may have modified them in unexpected ways. (#8809, #10669)
-					ui.helper.appendTo( draggable._parent );
-					draggable._refreshOffsets( event );
-					ui.position = draggable._generatePosition( event, true );
-
-					draggable._trigger( "fromSortable", event );
-
-					// Inform draggable that the helper is no longer in a valid drop zone
-					draggable.dropped = false;
-
-					// Need to refreshPositions of all sortables just in case removing
-					// from one sortable changes the location of other sortables (#9675)
-					$.each( draggable.sortables, function() {
-						this.refreshPositions();
-					} );
-				}
-			}
-		} );
-	}
-} );
-
-$.ui.plugin.add( "draggable", "cursor", {
-	start: function( event, ui, instance ) {
-		var t = $( "body" ),
-			o = instance.options;
-
-		if ( t.css( "cursor" ) ) {
-			o._cursor = t.css( "cursor" );
-		}
-		t.css( "cursor", o.cursor );
-	},
-	stop: function( event, ui, instance ) {
-		var o = instance.options;
-		if ( o._cursor ) {
-			$( "body" ).css( "cursor", o._cursor );
-		}
-	}
-} );
-
-$.ui.plugin.add( "draggable", "opacity", {
-	start: function( event, ui, instance ) {
-		var t = $( ui.helper ),
-			o = instance.options;
-		if ( t.css( "opacity" ) ) {
-			o._opacity = t.css( "opacity" );
-		}
-		t.css( "opacity", o.opacity );
-	},
-	stop: function( event, ui, instance ) {
-		var o = instance.options;
-		if ( o._opacity ) {
-			$( ui.helper ).css( "opacity", o._opacity );
-		}
-	}
-} );
-
-$.ui.plugin.add( "draggable", "scroll", {
-	start: function( event, ui, i ) {
-		if ( !i.scrollParentNotHidden ) {
-			i.scrollParentNotHidden = i.helper.scrollParent( false );
-		}
-
-		if ( i.scrollParentNotHidden[ 0 ] !== i.document[ 0 ] &&
-				i.scrollParentNotHidden[ 0 ].tagName !== "HTML" ) {
-			i.overflowOffset = i.scrollParentNotHidden.offset();
-		}
-	},
-	drag: function( event, ui, i  ) {
-
-		var o = i.options,
-			scrolled = false,
-			scrollParent = i.scrollParentNotHidden[ 0 ],
-			document = i.document[ 0 ];
-
-		if ( scrollParent !== document && scrollParent.tagName !== "HTML" ) {
-			if ( !o.axis || o.axis !== "x" ) {
-				if ( ( i.overflowOffset.top + scrollParent.offsetHeight ) - event.pageY <
-						o.scrollSensitivity ) {
-					scrollParent.scrollTop = scrolled = scrollParent.scrollTop + o.scrollSpeed;
-				} else if ( event.pageY - i.overflowOffset.top < o.scrollSensitivity ) {
-					scrollParent.scrollTop = scrolled = scrollParent.scrollTop - o.scrollSpeed;
-				}
-			}
-
-			if ( !o.axis || o.axis !== "y" ) {
-				if ( ( i.overflowOffset.left + scrollParent.offsetWidth ) - event.pageX <
-						o.scrollSensitivity ) {
-					scrollParent.scrollLeft = scrolled = scrollParent.scrollLeft + o.scrollSpeed;
-				} else if ( event.pageX - i.overflowOffset.left < o.scrollSensitivity ) {
-					scrollParent.scrollLeft = scrolled = scrollParent.scrollLeft - o.scrollSpeed;
-				}
-			}
-
-		} else {
-
-			if ( !o.axis || o.axis !== "x" ) {
-				if ( event.pageY - $( document ).scrollTop() < o.scrollSensitivity ) {
-					scrolled = $( document ).scrollTop( $( document ).scrollTop() - o.scrollSpeed );
-				} else if ( $( window ).height() - ( event.pageY - $( document ).scrollTop() ) <
-						o.scrollSensitivity ) {
-					scrolled = $( document ).scrollTop( $( document ).scrollTop() + o.scrollSpeed );
-				}
-			}
-
-			if ( !o.axis || o.axis !== "y" ) {
-				if ( event.pageX - $( document ).scrollLeft() < o.scrollSensitivity ) {
-					scrolled = $( document ).scrollLeft(
-						$( document ).scrollLeft() - o.scrollSpeed
-					);
-				} else if ( $( window ).width() - ( event.pageX - $( document ).scrollLeft() ) <
-						o.scrollSensitivity ) {
-					scrolled = $( document ).scrollLeft(
-						$( document ).scrollLeft() + o.scrollSpeed
-					);
-				}
-			}
-
-		}
-
-		if ( scrolled !== false && $.ui.ddmanager && !o.dropBehaviour ) {
-			$.ui.ddmanager.prepareOffsets( i, event );
-		}
-
-	}
-} );
-
-$.ui.plugin.add( "draggable", "snap", {
-	start: function( event, ui, i ) {
-
-		var o = i.options;
-
-		i.snapElements = [];
-
-		$( o.snap.constructor !== String ? ( o.snap.items || ":data(ui-draggable)" ) : o.snap )
-			.each( function() {
-				var $t = $( this ),
-					$o = $t.offset();
-				if ( this !== i.element[ 0 ] ) {
-					i.snapElements.push( {
-						item: this,
-						width: $t.outerWidth(), height: $t.outerHeight(),
-						top: $o.top, left: $o.left
-					} );
-				}
-			} );
-
-	},
-	drag: function( event, ui, inst ) {
-
-		var ts, bs, ls, rs, l, r, t, b, i, first,
-			o = inst.options,
-			d = o.snapTolerance,
-			x1 = ui.offset.left, x2 = x1 + inst.helperProportions.width,
-			y1 = ui.offset.top, y2 = y1 + inst.helperProportions.height;
-
-		for ( i = inst.snapElements.length - 1; i >= 0; i-- ) {
-
-			l = inst.snapElements[ i ].left - inst.margins.left;
-			r = l + inst.snapElements[ i ].width;
-			t = inst.snapElements[ i ].top - inst.margins.top;
-			b = t + inst.snapElements[ i ].height;
-
-			if ( x2 < l - d || x1 > r + d || y2 < t - d || y1 > b + d ||
-					!$.contains( inst.snapElements[ i ].item.ownerDocument,
-					inst.snapElements[ i ].item ) ) {
-				if ( inst.snapElements[ i ].snapping ) {
-					( inst.options.snap.release &&
-						inst.options.snap.release.call(
-							inst.element,
-							event,
-							$.extend( inst._uiHash(), { snapItem: inst.snapElements[ i ].item } )
-						) );
-				}
-				inst.snapElements[ i ].snapping = false;
-				continue;
-			}
-
-			if ( o.snapMode !== "inner" ) {
-				ts = Math.abs( t - y2 ) <= d;
-				bs = Math.abs( b - y1 ) <= d;
-				ls = Math.abs( l - x2 ) <= d;
-				rs = Math.abs( r - x1 ) <= d;
-				if ( ts ) {
-					ui.position.top = inst._convertPositionTo( "relative", {
-						top: t - inst.helperProportions.height,
-						left: 0
-					} ).top;
-				}
-				if ( bs ) {
-					ui.position.top = inst._convertPositionTo( "relative", {
-						top: b,
-						left: 0
-					} ).top;
-				}
-				if ( ls ) {
-					ui.position.left = inst._convertPositionTo( "relative", {
-						top: 0,
-						left: l - inst.helperProportions.width
-					} ).left;
-				}
-				if ( rs ) {
-					ui.position.left = inst._convertPositionTo( "relative", {
-						top: 0,
-						left: r
-					} ).left;
-				}
-			}
-
-			first = ( ts || bs || ls || rs );
-
-			if ( o.snapMode !== "outer" ) {
-				ts = Math.abs( t - y1 ) <= d;
-				bs = Math.abs( b - y2 ) <= d;
-				ls = Math.abs( l - x1 ) <= d;
-				rs = Math.abs( r - x2 ) <= d;
-				if ( ts ) {
-					ui.position.top = inst._convertPositionTo( "relative", {
-						top: t,
-						left: 0
-					} ).top;
-				}
-				if ( bs ) {
-					ui.position.top = inst._convertPositionTo( "relative", {
-						top: b - inst.helperProportions.height,
-						left: 0
-					} ).top;
-				}
-				if ( ls ) {
-					ui.position.left = inst._convertPositionTo( "relative", {
-						top: 0,
-						left: l
-					} ).left;
-				}
-				if ( rs ) {
-					ui.position.left = inst._convertPositionTo( "relative", {
-						top: 0,
-						left: r - inst.helperProportions.width
-					} ).left;
-				}
-			}
-
-			if ( !inst.snapElements[ i ].snapping && ( ts || bs || ls || rs || first ) ) {
-				( inst.options.snap.snap &&
-					inst.options.snap.snap.call(
-						inst.element,
-						event,
-						$.extend( inst._uiHash(), {
-							snapItem: inst.snapElements[ i ].item
-						} ) ) );
-			}
-			inst.snapElements[ i ].snapping = ( ts || bs || ls || rs || first );
-
-		}
-
-	}
-} );
-
-$.ui.plugin.add( "draggable", "stack", {
-	start: function( event, ui, instance ) {
-		var min,
-			o = instance.options,
-			group = $.makeArray( $( o.stack ) ).sort( function( a, b ) {
-				return ( parseInt( $( a ).css( "zIndex" ), 10 ) || 0 ) -
-					( parseInt( $( b ).css( "zIndex" ), 10 ) || 0 );
-			} );
-
-		if ( !group.length ) { return; }
-
-		min = parseInt( $( group[ 0 ] ).css( "zIndex" ), 10 ) || 0;
-		$( group ).each( function( i ) {
-			$( this ).css( "zIndex", min + i );
-		} );
-		this.css( "zIndex", ( min + group.length ) );
-	}
-} );
-
-$.ui.plugin.add( "draggable", "zIndex", {
-	start: function( event, ui, instance ) {
-		var t = $( ui.helper ),
-			o = instance.options;
-
-		if ( t.css( "zIndex" ) ) {
-			o._zIndex = t.css( "zIndex" );
-		}
-		t.css( "zIndex", o.zIndex );
-	},
-	stop: function( event, ui, instance ) {
-		var o = instance.options;
-
-		if ( o._zIndex ) {
-			$( ui.helper ).css( "zIndex", o._zIndex );
-		}
-	}
-} );
-
-var widgetsDraggable = $.ui.draggable;
-
-
-/*!
- * jQuery UI Sortable 1.12.1
- * http://jqueryui.com
- *
- * Copyright jQuery Foundation and other contributors
- * Released under the MIT license.
- * http://jquery.org/license
- */
-
-//>>label: Sortable
-//>>group: Interactions
-//>>description: Enables items in a list to be sorted using the mouse.
-//>>docs: http://api.jqueryui.com/sortable/
-//>>demos: http://jqueryui.com/sortable/
-//>>css.structure: ../../themes/base/sortable.css
-
-
-
-var widgetsSortable = $.widget( "ui.sortable", $.ui.mouse, {
-	version: "1.12.1",
-	widgetEventPrefix: "sort",
-	ready: false,
-	options: {
-		appendTo: "parent",
-		axis: false,
-		connectWith: false,
-		containment: false,
-		cursor: "auto",
-		cursorAt: false,
-		dropOnEmpty: true,
-		forcePlaceholderSize: false,
-		forceHelperSize: false,
-		grid: false,
-		handle: false,
-		helper: "original",
-		items: "> *",
-		opacity: false,
-		placeholder: false,
-		revert: false,
-		scroll: true,
-		scrollSensitivity: 20,
-		scrollSpeed: 20,
-		scope: "default",
-		tolerance: "intersect",
-		zIndex: 1000,
-
-		// Callbacks
-		activate: null,
-		beforeStop: null,
-		change: null,
-		deactivate: null,
-		out: null,
-		over: null,
-		receive: null,
-		remove: null,
-		sort: null,
-		start: null,
-		stop: null,
-		update: null
-	},
-
-	_isOverAxis: function( x, reference, size ) {
-		return ( x >= reference ) && ( x < ( reference + size ) );
-	},
-
-	_isFloating: function( item ) {
-		return ( /left|right/ ).test( item.css( "float" ) ) ||
-			( /inline|table-cell/ ).test( item.css( "display" ) );
-	},
-
-	_create: function() {
-		this.containerCache = {};
-		this._addClass( "ui-sortable" );
-
-		//Get the items
-		this.refresh();
-
-		//Let's determine the parent's offset
-		this.offset = this.element.offset();
-
-		//Initialize mouse events for interaction
-		this._mouseInit();
-
-		this._setHandleClassName();
-
-		//We're ready to go
-		this.ready = true;
-
-	},
-
-	_setOption: function( key, value ) {
-		this._super( key, value );
-
-		if ( key === "handle" ) {
-			this._setHandleClassName();
-		}
-	},
-
-	_setHandleClassName: function() {
-		var that = this;
-		this._removeClass( this.element.find( ".ui-sortable-handle" ), "ui-sortable-handle" );
-		$.each( this.items, function() {
-			that._addClass(
-				this.instance.options.handle ?
-					this.item.find( this.instance.options.handle ) :
-					this.item,
-				"ui-sortable-handle"
-			);
-		} );
-	},
-
-	_destroy: function() {
-		this._mouseDestroy();
-
-		for ( var i = this.items.length - 1; i >= 0; i-- ) {
-			this.items[ i ].item.removeData( this.widgetName + "-item" );
-		}
-
-		return this;
-	},
-
-	_mouseCapture: function( event, overrideHandle ) {
-		var currentItem = null,
-			validHandle = false,
-			that = this;
-
-		if ( this.reverting ) {
-			return false;
-		}
-
-		if ( this.options.disabled || this.options.type === "static" ) {
-			return false;
-		}
-
-		//We have to refresh the items data once first
-		this._refreshItems( event );
-
-		//Find out if the clicked node (or one of its parents) is a actual item in this.items
-		$( event.target ).parents().each( function() {
-			if ( $.data( this, that.widgetName + "-item" ) === that ) {
-				currentItem = $( this );
-				return false;
-			}
-		} );
-		if ( $.data( event.target, that.widgetName + "-item" ) === that ) {
-			currentItem = $( event.target );
-		}
-
-		if ( !currentItem ) {
-			return false;
-		}
-		if ( this.options.handle && !overrideHandle ) {
-			$( this.options.handle, currentItem ).find( "*" ).addBack().each( function() {
-				if ( this === event.target ) {
-					validHandle = true;
-				}
-			} );
-			if ( !validHandle ) {
-				return false;
-			}
-		}
-
-		this.currentItem = currentItem;
-		this._removeCurrentsFromItems();
-		return true;
-
-	},
-
-	_mouseStart: function( event, overrideHandle, noActivation ) {
-
-		var i, body,
-			o = this.options;
-
-		this.currentContainer = this;
-
-		//We only need to call refreshPositions, because the refreshItems call has been moved to
-		// mouseCapture
-		this.refreshPositions();
-
-		//Create and append the visible helper
-		this.helper = this._createHelper( event );
-
-		//Cache the helper size
-		this._cacheHelperProportions();
-
-		/*
-		 * - Position generation -
-		 * This block generates everything position related - it's the core of draggables.
-		 */
-
-		//Cache the margins of the original element
-		this._cacheMargins();
-
-		//Get the next scrolling parent
-		this.scrollParent = this.helper.scrollParent();
-
-		//The element's absolute position on the page minus margins
-		this.offset = this.currentItem.offset();
-		this.offset = {
-			top: this.offset.top - this.margins.top,
-			left: this.offset.left - this.margins.left
-		};
-
-		$.extend( this.offset, {
-			click: { //Where the click happened, relative to the element
-				left: event.pageX - this.offset.left,
-				top: event.pageY - this.offset.top
-			},
-			parent: this._getParentOffset(),
-
-			// This is a relative to absolute position minus the actual position calculation -
-			// only used for relative positioned helper
-			relative: this._getRelativeOffset()
-		} );
-
-		// Only after we got the offset, we can change the helper's position to absolute
-		// TODO: Still need to figure out a way to make relative sorting possible
-		this.helper.css( "position", "absolute" );
-		this.cssPosition = this.helper.css( "position" );
-
-		//Generate the original position
-		this.originalPosition = this._generatePosition( event );
-		this.originalPageX = event.pageX;
-		this.originalPageY = event.pageY;
-
-		//Adjust the mouse offset relative to the helper if "cursorAt" is supplied
-		( o.cursorAt && this._adjustOffsetFromHelper( o.cursorAt ) );
-
-		//Cache the former DOM position
-		this.domPosition = {
-			prev: this.currentItem.prev()[ 0 ],
-			parent: this.currentItem.parent()[ 0 ]
-		};
-
-		// If the helper is not the original, hide the original so it's not playing any role during
-		// the drag, won't cause anything bad this way
-		if ( this.helper[ 0 ] !== this.currentItem[ 0 ] ) {
-			this.currentItem.hide();
-		}
-
-		//Create the placeholder
-		this._createPlaceholder();
-
-		//Set a containment if given in the options
-		if ( o.containment ) {
-			this._setContainment();
-		}
-
-		if ( o.cursor && o.cursor !== "auto" ) { // cursor option
-			body = this.document.find( "body" );
-
-			// Support: IE
-			this.storedCursor = body.css( "cursor" );
-			body.css( "cursor", o.cursor );
-
-			this.storedStylesheet =
-				$( "<style>*{ cursor: " + o.cursor + " !important; }</style>" ).appendTo( body );
-		}
-
-		if ( o.opacity ) { // opacity option
-			if ( this.helper.css( "opacity" ) ) {
-				this._storedOpacity = this.helper.css( "opacity" );
-			}
-			this.helper.css( "opacity", o.opacity );
-		}
-
-		if ( o.zIndex ) { // zIndex option
-			if ( this.helper.css( "zIndex" ) ) {
-				this._storedZIndex = this.helper.css( "zIndex" );
-			}
-			this.helper.css( "zIndex", o.zIndex );
-		}
-
-		//Prepare scrolling
-		if ( this.scrollParent[ 0 ] !== this.document[ 0 ] &&
-				this.scrollParent[ 0 ].tagName !== "HTML" ) {
-			this.overflowOffset = this.scrollParent.offset();
-		}
-
-		//Call callbacks
-		this._trigger( "start", event, this._uiHash() );
-
-		//Recache the helper size
-		if ( !this._preserveHelperProportions ) {
-			this._cacheHelperProportions();
-		}
-
-		//Post "activate" events to possible containers
-		if ( !noActivation ) {
-			for ( i = this.containers.length - 1; i >= 0; i-- ) {
-				this.containers[ i ]._trigger( "activate", event, this._uiHash( this ) );
-			}
-		}
-
-		//Prepare possible droppables
-		if ( $.ui.ddmanager ) {
-			$.ui.ddmanager.current = this;
-		}
-
-		if ( $.ui.ddmanager && !o.dropBehaviour ) {
-			$.ui.ddmanager.prepareOffsets( this, event );
-		}
-
-		this.dragging = true;
-
-		this._addClass( this.helper, "ui-sortable-helper" );
-
-		// Execute the drag once - this causes the helper not to be visiblebefore getting its
-		// correct position
-		this._mouseDrag( event );
-		return true;
-
-	},
-
-	_mouseDrag: function( event ) {
-		var i, item, itemElement, intersection,
-			o = this.options,
-			scrolled = false;
-
-		//Compute the helpers position
-		this.position = this._generatePosition( event );
-		this.positionAbs = this._convertPositionTo( "absolute" );
-
-		if ( !this.lastPositionAbs ) {
-			this.lastPositionAbs = this.positionAbs;
-		}
-
-		//Do scrolling
-		if ( this.options.scroll ) {
-			if ( this.scrollParent[ 0 ] !== this.document[ 0 ] &&
-					this.scrollParent[ 0 ].tagName !== "HTML" ) {
-
-				if ( ( this.overflowOffset.top + this.scrollParent[ 0 ].offsetHeight ) -
-						event.pageY < o.scrollSensitivity ) {
-					this.scrollParent[ 0 ].scrollTop =
-						scrolled = this.scrollParent[ 0 ].scrollTop + o.scrollSpeed;
-				} else if ( event.pageY - this.overflowOffset.top < o.scrollSensitivity ) {
-					this.scrollParent[ 0 ].scrollTop =
-						scrolled = this.scrollParent[ 0 ].scrollTop - o.scrollSpeed;
-				}
-
-				if ( ( this.overflowOffset.left + this.scrollParent[ 0 ].offsetWidth ) -
-						event.pageX < o.scrollSensitivity ) {
-					this.scrollParent[ 0 ].scrollLeft = scrolled =
-						this.scrollParent[ 0 ].scrollLeft + o.scrollSpeed;
-				} else if ( event.pageX - this.overflowOffset.left < o.scrollSensitivity ) {
-					this.scrollParent[ 0 ].scrollLeft = scrolled =
-						this.scrollParent[ 0 ].scrollLeft - o.scrollSpeed;
-				}
-
-			} else {
-
-				if ( event.pageY - this.document.scrollTop() < o.scrollSensitivity ) {
-					scrolled = this.document.scrollTop( this.document.scrollTop() - o.scrollSpeed );
-				} else if ( this.window.height() - ( event.pageY - this.document.scrollTop() ) <
-						o.scrollSensitivity ) {
-					scrolled = this.document.scrollTop( this.document.scrollTop() + o.scrollSpeed );
-				}
-
-				if ( event.pageX - this.document.scrollLeft() < o.scrollSensitivity ) {
-					scrolled = this.document.scrollLeft(
-						this.document.scrollLeft() - o.scrollSpeed
-					);
-				} else if ( this.window.width() - ( event.pageX - this.document.scrollLeft() ) <
-						o.scrollSensitivity ) {
-					scrolled = this.document.scrollLeft(
-						this.document.scrollLeft() + o.scrollSpeed
-					);
-				}
-
-			}
-
-			if ( scrolled !== false && $.ui.ddmanager && !o.dropBehaviour ) {
-				$.ui.ddmanager.prepareOffsets( this, event );
-			}
-		}
-
-		//Regenerate the absolute position used for position checks
-		this.positionAbs = this._convertPositionTo( "absolute" );
-
-		//Set the helper position
-		if ( !this.options.axis || this.options.axis !== "y" ) {
-			this.helper[ 0 ].style.left = this.position.left + "px";
-		}
-		if ( !this.options.axis || this.options.axis !== "x" ) {
-			this.helper[ 0 ].style.top = this.position.top + "px";
-		}
-
-		//Rearrange
-		for ( i = this.items.length - 1; i >= 0; i-- ) {
-
-			//Cache variables and intersection, continue if no intersection
-			item = this.items[ i ];
-			itemElement = item.item[ 0 ];
-			intersection = this._intersectsWithPointer( item );
-			if ( !intersection ) {
-				continue;
-			}
-
-			// Only put the placeholder inside the current Container, skip all
-			// items from other containers. This works because when moving
-			// an item from one container to another the
-			// currentContainer is switched before the placeholder is moved.
-			//
-			// Without this, moving items in "sub-sortables" can cause
-			// the placeholder to jitter between the outer and inner container.
-			if ( item.instance !== this.currentContainer ) {
-				continue;
-			}
-
-			// Cannot intersect with itself
-			// no useless actions that have been done before
-			// no action if the item moved is the parent of the item checked
-			if ( itemElement !== this.currentItem[ 0 ] &&
-				this.placeholder[ intersection === 1 ? "next" : "prev" ]()[ 0 ] !== itemElement &&
-				!$.contains( this.placeholder[ 0 ], itemElement ) &&
-				( this.options.type === "semi-dynamic" ?
-					!$.contains( this.element[ 0 ], itemElement ) :
-					true
-				)
-			) {
-
-				this.direction = intersection === 1 ? "down" : "up";
-
-				if ( this.options.tolerance === "pointer" || this._intersectsWithSides( item ) ) {
-					this._rearrange( event, item );
-				} else {
-					break;
-				}
-
-				this._trigger( "change", event, this._uiHash() );
-				break;
-			}
-		}
-
-		//Post events to containers
-		this._contactContainers( event );
-
-		//Interconnect with droppables
-		if ( $.ui.ddmanager ) {
-			$.ui.ddmanager.drag( this, event );
-		}
-
-		//Call callbacks
-		this._trigger( "sort", event, this._uiHash() );
-
-		this.lastPositionAbs = this.positionAbs;
-		return false;
-
-	},
-
-	_mouseStop: function( event, noPropagation ) {
-
-		if ( !event ) {
-			return;
-		}
-
-		//If we are using droppables, inform the manager about the drop
-		if ( $.ui.ddmanager && !this.options.dropBehaviour ) {
-			$.ui.ddmanager.drop( this, event );
-		}
-
-		if ( this.options.revert ) {
-			var that = this,
-				cur = this.placeholder.offset(),
-				axis = this.options.axis,
-				animation = {};
-
-			if ( !axis || axis === "x" ) {
-				animation.left = cur.left - this.offset.parent.left - this.margins.left +
-					( this.offsetParent[ 0 ] === this.document[ 0 ].body ?
-						0 :
-						this.offsetParent[ 0 ].scrollLeft
-					);
-			}
-			if ( !axis || axis === "y" ) {
-				animation.top = cur.top - this.offset.parent.top - this.margins.top +
-					( this.offsetParent[ 0 ] === this.document[ 0 ].body ?
-						0 :
-						this.offsetParent[ 0 ].scrollTop
-					);
-			}
-			this.reverting = true;
-			$( this.helper ).animate(
-				animation,
-				parseInt( this.options.revert, 10 ) || 500,
-				function() {
-					that._clear( event );
-				}
-			);
-		} else {
-			this._clear( event, noPropagation );
-		}
-
-		return false;
-
-	},
-
-	cancel: function() {
-
-		if ( this.dragging ) {
-
-			this._mouseUp( new $.Event( "mouseup", { target: null } ) );
-
-			if ( this.options.helper === "original" ) {
-				this.currentItem.css( this._storedCSS );
-				this._removeClass( this.currentItem, "ui-sortable-helper" );
-			} else {
-				this.currentItem.show();
-			}
-
-			//Post deactivating events to containers
-			for ( var i = this.containers.length - 1; i >= 0; i-- ) {
-				this.containers[ i ]._trigger( "deactivate", null, this._uiHash( this ) );
-				if ( this.containers[ i ].containerCache.over ) {
-					this.containers[ i ]._trigger( "out", null, this._uiHash( this ) );
-					this.containers[ i ].containerCache.over = 0;
-				}
-			}
-
-		}
-
-		if ( this.placeholder ) {
-
-			//$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately,
-			// it unbinds ALL events from the original node!
-			if ( this.placeholder[ 0 ].parentNode ) {
-				this.placeholder[ 0 ].parentNode.removeChild( this.placeholder[ 0 ] );
-			}
-			if ( this.options.helper !== "original" && this.helper &&
-					this.helper[ 0 ].parentNode ) {
-				this.helper.remove();
-			}
-
-			$.extend( this, {
-				helper: null,
-				dragging: false,
-				reverting: false,
-				_noFinalSort: null
-			} );
-
-			if ( this.domPosition.prev ) {
-				$( this.domPosition.prev ).after( this.currentItem );
-			} else {
-				$( this.domPosition.parent ).prepend( this.currentItem );
-			}
-		}
-
-		return this;
-
-	},
-
-	serialize: function( o ) {
-
-		var items = this._getItemsAsjQuery( o && o.connected ),
-			str = [];
-		o = o || {};
-
-		$( items ).each( function() {
-			var res = ( $( o.item || this ).attr( o.attribute || "id" ) || "" )
-				.match( o.expression || ( /(.+)[\-=_](.+)/ ) );
-			if ( res ) {
-				str.push(
-					( o.key || res[ 1 ] + "[]" ) +
-					"=" + ( o.key && o.expression ? res[ 1 ] : res[ 2 ] ) );
-			}
-		} );
-
-		if ( !str.length && o.key ) {
-			str.push( o.key + "=" );
-		}
-
-		return str.join( "&" );
-
-	},
-
-	toArray: function( o ) {
-
-		var items = this._getItemsAsjQuery( o && o.connected ),
-			ret = [];
-
-		o = o || {};
-
-		items.each( function() {
-			ret.push( $( o.item || this ).attr( o.attribute || "id" ) || "" );
-		} );
-		return ret;
-
-	},
-
-	/* Be careful with the following core functions */
-	_intersectsWith: function( item ) {
-
-		var x1 = this.positionAbs.left,
-			x2 = x1 + this.helperProportions.width,
-			y1 = this.positionAbs.top,
-			y2 = y1 + this.helperProportions.height,
-			l = item.left,
-			r = l + item.width,
-			t = item.top,
-			b = t + item.height,
-			dyClick = this.offset.click.top,
-			dxClick = this.offset.click.left,
-			isOverElementHeight = ( this.options.axis === "x" ) || ( ( y1 + dyClick ) > t &&
-				( y1 + dyClick ) < b ),
-			isOverElementWidth = ( this.options.axis === "y" ) || ( ( x1 + dxClick ) > l &&
-				( x1 + dxClick ) < r ),
-			isOverElement = isOverElementHeight && isOverElementWidth;
-
-		if ( this.options.tolerance === "pointer" ||
-			this.options.forcePointerForContainers ||
-			( this.options.tolerance !== "pointer" &&
-				this.helperProportions[ this.floating ? "width" : "height" ] >
-				item[ this.floating ? "width" : "height" ] )
-		) {
-			return isOverElement;
-		} else {
-
-			return ( l < x1 + ( this.helperProportions.width / 2 ) && // Right Half
-				x2 - ( this.helperProportions.width / 2 ) < r && // Left Half
-				t < y1 + ( this.helperProportions.height / 2 ) && // Bottom Half
-				y2 - ( this.helperProportions.height / 2 ) < b ); // Top Half
-
-		}
-	},
-
-	_intersectsWithPointer: function( item ) {
-		var verticalDirection, horizontalDirection,
-			isOverElementHeight = ( this.options.axis === "x" ) ||
-				this._isOverAxis(
-					this.positionAbs.top + this.offset.click.top, item.top, item.height ),
-			isOverElementWidth = ( this.options.axis === "y" ) ||
-				this._isOverAxis(
-					this.positionAbs.left + this.offset.click.left, item.left, item.width ),
-			isOverElement = isOverElementHeight && isOverElementWidth;
-
-		if ( !isOverElement ) {
-			return false;
-		}
-
-		verticalDirection = this._getDragVerticalDirection();
-		horizontalDirection = this._getDragHorizontalDirection();
-
-		return this.floating ?
-			( ( horizontalDirection === "right" || verticalDirection === "down" ) ? 2 : 1 )
-			: ( verticalDirection && ( verticalDirection === "down" ? 2 : 1 ) );
-
-	},
-
-	_intersectsWithSides: function( item ) {
-
-		var isOverBottomHalf = this._isOverAxis( this.positionAbs.top +
-				this.offset.click.top, item.top + ( item.height / 2 ), item.height ),
-			isOverRightHalf = this._isOverAxis( this.positionAbs.left +
-				this.offset.click.left, item.left + ( item.width / 2 ), item.width ),
-			verticalDirection = this._getDragVerticalDirection(),
-			horizontalDirection = this._getDragHorizontalDirection();
-
-		if ( this.floating && horizontalDirection ) {
-			return ( ( horizontalDirection === "right" && isOverRightHalf ) ||
-				( horizontalDirection === "left" && !isOverRightHalf ) );
-		} else {
-			return verticalDirection && ( ( verticalDirection === "down" && isOverBottomHalf ) ||
-				( verticalDirection === "up" && !isOverBottomHalf ) );
-		}
-
-	},
-
-	_getDragVerticalDirection: function() {
-		var delta = this.positionAbs.top - this.lastPositionAbs.top;
-		return delta !== 0 && ( delta > 0 ? "down" : "up" );
-	},
-
-	_getDragHorizontalDirection: function() {
-		var delta = this.positionAbs.left - this.lastPositionAbs.left;
-		return delta !== 0 && ( delta > 0 ? "right" : "left" );
-	},
-
-	refresh: function( event ) {
-		this._refreshItems( event );
-		this._setHandleClassName();
-		this.refreshPositions();
-		return this;
-	},
-
-	_connectWith: function() {
-		var options = this.options;
-		return options.connectWith.constructor === String ?
-			[ options.connectWith ] :
-			options.connectWith;
-	},
-
-	_getItemsAsjQuery: function( connected ) {
-
-		var i, j, cur, inst,
-			items = [],
-			queries = [],
-			connectWith = this._connectWith();
-
-		if ( connectWith && connected ) {
-			for ( i = connectWith.length - 1; i >= 0; i-- ) {
-				cur = $( connectWith[ i ], this.document[ 0 ] );
-				for ( j = cur.length - 1; j >= 0; j-- ) {
-					inst = $.data( cur[ j ], this.widgetFullName );
-					if ( inst && inst !== this && !inst.options.disabled ) {
-						queries.push( [ $.isFunction( inst.options.items ) ?
-							inst.options.items.call( inst.element ) :
-							$( inst.options.items, inst.element )
-								.not( ".ui-sortable-helper" )
-								.not( ".ui-sortable-placeholder" ), inst ] );
-					}
-				}
-			}
-		}
-
-		queries.push( [ $.isFunction( this.options.items ) ?
-			this.options.items
-				.call( this.element, null, { options: this.options, item: this.currentItem } ) :
-			$( this.options.items, this.element )
-				.not( ".ui-sortable-helper" )
-				.not( ".ui-sortable-placeholder" ), this ] );
-
-		function addItems() {
-			items.push( this );
-		}
-		for ( i = queries.length - 1; i >= 0; i-- ) {
-			queries[ i ][ 0 ].each( addItems );
-		}
-
-		return $( items );
-
-	},
-
-	_removeCurrentsFromItems: function() {
-
-		var list = this.currentItem.find( ":data(" + this.widgetName + "-item)" );
-
-		this.items = $.grep( this.items, function( item ) {
-			for ( var j = 0; j < list.length; j++ ) {
-				if ( list[ j ] === item.item[ 0 ] ) {
-					return false;
-				}
-			}
-			return true;
-		} );
-
-	},
-
-	_refreshItems: function( event ) {
-
-		this.items = [];
-		this.containers = [ this ];
-
-		var i, j, cur, inst, targetData, _queries, item, queriesLength,
-			items = this.items,
-			queries = [ [ $.isFunction( this.options.items ) ?
-				this.options.items.call( this.element[ 0 ], event, { item: this.currentItem } ) :
-				$( this.options.items, this.element ), this ] ],
-			connectWith = this._connectWith();
-
-		//Shouldn't be run the first time through due to massive slow-down
-		if ( connectWith && this.ready ) {
-			for ( i = connectWith.length - 1; i >= 0; i-- ) {
-				cur = $( connectWith[ i ], this.document[ 0 ] );
-				for ( j = cur.length - 1; j >= 0; j-- ) {
-					inst = $.data( cur[ j ], this.widgetFullName );
-					if ( inst && inst !== this && !inst.options.disabled ) {
-						queries.push( [ $.isFunction( inst.options.items ) ?
-							inst.options.items
-								.call( inst.element[ 0 ], event, { item: this.currentItem } ) :
-							$( inst.options.items, inst.element ), inst ] );
-						this.containers.push( inst );
-					}
-				}
-			}
-		}
-
-		for ( i = queries.length - 1; i >= 0; i-- ) {
-			targetData = queries[ i ][ 1 ];
-			_queries = queries[ i ][ 0 ];
-
-			for ( j = 0, queriesLength = _queries.length; j < queriesLength; j++ ) {
-				item = $( _queries[ j ] );
-
-				// Data for target checking (mouse manager)
-				item.data( this.widgetName + "-item", targetData );
-
-				items.push( {
-					item: item,
-					instance: targetData,
-					width: 0, height: 0,
-					left: 0, top: 0
-				} );
-			}
-		}
-
-	},
-
-	refreshPositions: function( fast ) {
-
-		// Determine whether items are being displayed horizontally
-		this.floating = this.items.length ?
-			this.options.axis === "x" || this._isFloating( this.items[ 0 ].item ) :
-			false;
-
-		//This has to be redone because due to the item being moved out/into the offsetParent,
-		// the offsetParent's position will change
-		if ( this.offsetParent && this.helper ) {
-			this.offset.parent = this._getParentOffset();
-		}
-
-		var i, item, t, p;
-
-		for ( i = this.items.length - 1; i >= 0; i-- ) {
-			item = this.items[ i ];
-
-			//We ignore calculating positions of all connected containers when we're not over them
-			if ( item.instance !== this.currentContainer && this.currentContainer &&
-					item.item[ 0 ] !== this.currentItem[ 0 ] ) {
-				continue;
-			}
-
-			t = this.options.toleranceElement ?
-				$( this.options.toleranceElement, item.item ) :
-				item.item;
-
-			if ( !fast ) {
-				item.width = t.outerWidth();
-				item.height = t.outerHeight();
-			}
-
-			p = t.offset();
-			item.left = p.left;
-			item.top = p.top;
-		}
-
-		if ( this.options.custom && this.options.custom.refreshContainers ) {
-			this.options.custom.refreshContainers.call( this );
-		} else {
-			for ( i = this.containers.length - 1; i >= 0; i-- ) {
-				p = this.containers[ i ].element.offset();
-				this.containers[ i ].containerCache.left = p.left;
-				this.containers[ i ].containerCache.top = p.top;
-				this.containers[ i ].containerCache.width =
-					this.containers[ i ].element.outerWidth();
-				this.containers[ i ].containerCache.height =
-					this.containers[ i ].element.outerHeight();
-			}
-		}
-
-		return this;
-	},
-
-	_createPlaceholder: function( that ) {
-		that = that || this;
-		var className,
-			o = that.options;
-
-		if ( !o.placeholder || o.placeholder.constructor === String ) {
-			className = o.placeholder;
-			o.placeholder = {
-				element: function() {
-
-					var nodeName = that.currentItem[ 0 ].nodeName.toLowerCase(),
-						element = $( "<" + nodeName + ">", that.document[ 0 ] );
-
-						that._addClass( element, "ui-sortable-placeholder",
-								className || that.currentItem[ 0 ].className )
-							._removeClass( element, "ui-sortable-helper" );
-
-					if ( nodeName === "tbody" ) {
-						that._createTrPlaceholder(
-							that.currentItem.find( "tr" ).eq( 0 ),
-							$( "<tr>", that.document[ 0 ] ).appendTo( element )
-						);
-					} else if ( nodeName === "tr" ) {
-						that._createTrPlaceholder( that.currentItem, element );
-					} else if ( nodeName === "img" ) {
-						element.attr( "src", that.currentItem.attr( "src" ) );
-					}
-
-					if ( !className ) {
-						element.css( "visibility", "hidden" );
-					}
-
-					return element;
-				},
-				update: function( container, p ) {
-
-					// 1. If a className is set as 'placeholder option, we don't force sizes -
-					// the class is responsible for that
-					// 2. The option 'forcePlaceholderSize can be enabled to force it even if a
-					// class name is specified
-					if ( className && !o.forcePlaceholderSize ) {
-						return;
-					}
-
-					//If the element doesn't have a actual height by itself (without styles coming
-					// from a stylesheet), it receives the inline height from the dragged item
-					if ( !p.height() ) {
-						p.height(
-							that.currentItem.innerHeight() -
-							parseInt( that.currentItem.css( "paddingTop" ) || 0, 10 ) -
-							parseInt( that.currentItem.css( "paddingBottom" ) || 0, 10 ) );
-					}
-					if ( !p.width() ) {
-						p.width(
-							that.currentItem.innerWidth() -
-							parseInt( that.currentItem.css( "paddingLeft" ) || 0, 10 ) -
-							parseInt( that.currentItem.css( "paddingRight" ) || 0, 10 ) );
-					}
-				}
-			};
-		}
-
-		//Create the placeholder
-		that.placeholder = $( o.placeholder.element.call( that.element, that.currentItem ) );
-
-		//Append it after the actual current item
-		that.currentItem.after( that.placeholder );
-
-		//Update the size of the placeholder (TODO: Logic to fuzzy, see line 316/317)
-		o.placeholder.update( that, that.placeholder );
-
-	},
-
-	_createTrPlaceholder: function( sourceTr, targetTr ) {
-		var that = this;
-
-		sourceTr.children().each( function() {
-			$( "<td>&#160;</td>", that.document[ 0 ] )
-				.attr( "colspan", $( this ).attr( "colspan" ) || 1 )
-				.appendTo( targetTr );
-		} );
-	},
-
-	_contactContainers: function( event ) {
-		var i, j, dist, itemWithLeastDistance, posProperty, sizeProperty, cur, nearBottom,
-			floating, axis,
-			innermostContainer = null,
-			innermostIndex = null;
-
-		// Get innermost container that intersects with item
-		for ( i = this.containers.length - 1; i >= 0; i-- ) {
-
-			// Never consider a container that's located within the item itself
-			if ( $.contains( this.currentItem[ 0 ], this.containers[ i ].element[ 0 ] ) ) {
-				continue;
-			}
-
-			if ( this._intersectsWith( this.containers[ i ].containerCache ) ) {
-
-				// If we've already found a container and it's more "inner" than this, then continue
-				if ( innermostContainer &&
-						$.contains(
-							this.containers[ i ].element[ 0 ],
-							innermostContainer.element[ 0 ] ) ) {
-					continue;
-				}
-
-				innermostContainer = this.containers[ i ];
-				innermostIndex = i;
-
-			} else {
-
-				// container doesn't intersect. trigger "out" event if necessary
-				if ( this.containers[ i ].containerCache.over ) {
-					this.containers[ i ]._trigger( "out", event, this._uiHash( this ) );
-					this.containers[ i ].containerCache.over = 0;
-				}
-			}
-
-		}
-
-		// If no intersecting containers found, return
-		if ( !innermostContainer ) {
-			return;
-		}
-
-		// Move the item into the container if it's not there already
-		if ( this.containers.length === 1 ) {
-			if ( !this.containers[ innermostIndex ].containerCache.over ) {
-				this.containers[ innermostIndex ]._trigger( "over", event, this._uiHash( this ) );
-				this.containers[ innermostIndex ].containerCache.over = 1;
-			}
-		} else {
-
-			// When entering a new container, we will find the item with the least distance and
-			// append our item near it
-			dist = 10000;
-			itemWithLeastDistance = null;
-			floating = innermostContainer.floating || this._isFloating( this.currentItem );
-			posProperty = floating ? "left" : "top";
-			sizeProperty = floating ? "width" : "height";
-			axis = floating ? "pageX" : "pageY";
-
-			for ( j = this.items.length - 1; j >= 0; j-- ) {
-				if ( !$.contains(
-						this.containers[ innermostIndex ].element[ 0 ], this.items[ j ].item[ 0 ] )
-				) {
-					continue;
-				}
-				if ( this.items[ j ].item[ 0 ] === this.currentItem[ 0 ] ) {
-					continue;
-				}
-
-				cur = this.items[ j ].item.offset()[ posProperty ];
-				nearBottom = false;
-				if ( event[ axis ] - cur > this.items[ j ][ sizeProperty ] / 2 ) {
-					nearBottom = true;
-				}
-
-				if ( Math.abs( event[ axis ] - cur ) < dist ) {
-					dist = Math.abs( event[ axis ] - cur );
-					itemWithLeastDistance = this.items[ j ];
-					this.direction = nearBottom ? "up" : "down";
-				}
-			}
-
-			//Check if dropOnEmpty is enabled
-			if ( !itemWithLeastDistance && !this.options.dropOnEmpty ) {
-				return;
-			}
-
-			if ( this.currentContainer === this.containers[ innermostIndex ] ) {
-				if ( !this.currentContainer.containerCache.over ) {
-					this.containers[ innermostIndex ]._trigger( "over", event, this._uiHash() );
-					this.currentContainer.containerCache.over = 1;
-				}
-				return;
-			}
-
-			itemWithLeastDistance ?
-				this._rearrange( event, itemWithLeastDistance, null, true ) :
-				this._rearrange( event, null, this.containers[ innermostIndex ].element, true );
-			this._trigger( "change", event, this._uiHash() );
-			this.containers[ innermostIndex ]._trigger( "change", event, this._uiHash( this ) );
-			this.currentContainer = this.containers[ innermostIndex ];
-
-			//Update the placeholder
-			this.options.placeholder.update( this.currentContainer, this.placeholder );
-
-			this.containers[ innermostIndex ]._trigger( "over", event, this._uiHash( this ) );
-			this.containers[ innermostIndex ].containerCache.over = 1;
-		}
-
-	},
-
-	_createHelper: function( event ) {
-
-		var o = this.options,
-			helper = $.isFunction( o.helper ) ?
-				$( o.helper.apply( this.element[ 0 ], [ event, this.currentItem ] ) ) :
-				( o.helper === "clone" ? this.currentItem.clone() : this.currentItem );
-
-		//Add the helper to the DOM if that didn't happen already
-		if ( !helper.parents( "body" ).length ) {
-			$( o.appendTo !== "parent" ?
-				o.appendTo :
-				this.currentItem[ 0 ].parentNode )[ 0 ].appendChild( helper[ 0 ] );
-		}
-
-		if ( helper[ 0 ] === this.currentItem[ 0 ] ) {
-			this._storedCSS = {
-				width: this.currentItem[ 0 ].style.width,
-				height: this.currentItem[ 0 ].style.height,
-				position: this.currentItem.css( "position" ),
-				top: this.currentItem.css( "top" ),
-				left: this.currentItem.css( "left" )
-			};
-		}
-
-		if ( !helper[ 0 ].style.width || o.forceHelperSize ) {
-			helper.width( this.currentItem.width() );
-		}
-		if ( !helper[ 0 ].style.height || o.forceHelperSize ) {
-			helper.height( this.currentItem.height() );
-		}
-
-		return helper;
-
-	},
-
-	_adjustOffsetFromHelper: function( obj ) {
-		if ( typeof obj === "string" ) {
-			obj = obj.split( " " );
-		}
-		if ( $.isArray( obj ) ) {
-			obj = { left: +obj[ 0 ], top: +obj[ 1 ] || 0 };
-		}
-		if ( "left" in obj ) {
-			this.offset.click.left = obj.left + this.margins.left;
-		}
-		if ( "right" in obj ) {
-			this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
-		}
-		if ( "top" in obj ) {
-			this.offset.click.top = obj.top + this.margins.top;
-		}
-		if ( "bottom" in obj ) {
-			this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
-		}
-	},
-
-	_getParentOffset: function() {
-
-		//Get the offsetParent and cache its position
-		this.offsetParent = this.helper.offsetParent();
-		var po = this.offsetParent.offset();
-
-		// This is a special case where we need to modify a offset calculated on start, since the
-		// following happened:
-		// 1. The position of the helper is absolute, so it's position is calculated based on the
-		// next positioned parent
-		// 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't
-		// the document, which means that the scroll is included in the initial calculation of the
-		// offset of the parent, and never recalculated upon drag
-		if ( this.cssPosition === "absolute" && this.scrollParent[ 0 ] !== this.document[ 0 ] &&
-				$.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) {
-			po.left += this.scrollParent.scrollLeft();
-			po.top += this.scrollParent.scrollTop();
-		}
-
-		// This needs to be actually done for all browsers, since pageX/pageY includes this
-		// information with an ugly IE fix
-		if ( this.offsetParent[ 0 ] === this.document[ 0 ].body ||
-				( this.offsetParent[ 0 ].tagName &&
-				this.offsetParent[ 0 ].tagName.toLowerCase() === "html" && $.ui.ie ) ) {
-			po = { top: 0, left: 0 };
-		}
-
-		return {
-			top: po.top + ( parseInt( this.offsetParent.css( "borderTopWidth" ), 10 ) || 0 ),
-			left: po.left + ( parseInt( this.offsetParent.css( "borderLeftWidth" ), 10 ) || 0 )
-		};
-
-	},
-
-	_getRelativeOffset: function() {
-
-		if ( this.cssPosition === "relative" ) {
-			var p = this.currentItem.position();
-			return {
-				top: p.top - ( parseInt( this.helper.css( "top" ), 10 ) || 0 ) +
-					this.scrollParent.scrollTop(),
-				left: p.left - ( parseInt( this.helper.css( "left" ), 10 ) || 0 ) +
-					this.scrollParent.scrollLeft()
-			};
-		} else {
-			return { top: 0, left: 0 };
-		}
-
-	},
-
-	_cacheMargins: function() {
-		this.margins = {
-			left: ( parseInt( this.currentItem.css( "marginLeft" ), 10 ) || 0 ),
-			top: ( parseInt( this.currentItem.css( "marginTop" ), 10 ) || 0 )
-		};
-	},
-
-	_cacheHelperProportions: function() {
-		this.helperProportions = {
-			width: this.helper.outerWidth(),
-			height: this.helper.outerHeight()
-		};
-	},
-
-	_setContainment: function() {
-
-		var ce, co, over,
-			o = this.options;
-		if ( o.containment === "parent" ) {
-			o.containment = this.helper[ 0 ].parentNode;
-		}
-		if ( o.containment === "document" || o.containment === "window" ) {
-			this.containment = [
-				0 - this.offset.relative.left - this.offset.parent.left,
-				0 - this.offset.relative.top - this.offset.parent.top,
-				o.containment === "document" ?
-					this.document.width() :
-					this.window.width() - this.helperProportions.width - this.margins.left,
-				( o.containment === "document" ?
-					( this.document.height() || document.body.parentNode.scrollHeight ) :
-					this.window.height() || this.document[ 0 ].body.parentNode.scrollHeight
-				) - this.helperProportions.height - this.margins.top
-			];
-		}
-
-		if ( !( /^(document|window|parent)$/ ).test( o.containment ) ) {
-			ce = $( o.containment )[ 0 ];
-			co = $( o.containment ).offset();
-			over = ( $( ce ).css( "overflow" ) !== "hidden" );
-
-			this.containment = [
-				co.left + ( parseInt( $( ce ).css( "borderLeftWidth" ), 10 ) || 0 ) +
-					( parseInt( $( ce ).css( "paddingLeft" ), 10 ) || 0 ) - this.margins.left,
-				co.top + ( parseInt( $( ce ).css( "borderTopWidth" ), 10 ) || 0 ) +
-					( parseInt( $( ce ).css( "paddingTop" ), 10 ) || 0 ) - this.margins.top,
-				co.left + ( over ? Math.max( ce.scrollWidth, ce.offsetWidth ) : ce.offsetWidth ) -
-					( parseInt( $( ce ).css( "borderLeftWidth" ), 10 ) || 0 ) -
-					( parseInt( $( ce ).css( "paddingRight" ), 10 ) || 0 ) -
-					this.helperProportions.width - this.margins.left,
-				co.top + ( over ? Math.max( ce.scrollHeight, ce.offsetHeight ) : ce.offsetHeight ) -
-					( parseInt( $( ce ).css( "borderTopWidth" ), 10 ) || 0 ) -
-					( parseInt( $( ce ).css( "paddingBottom" ), 10 ) || 0 ) -
-					this.helperProportions.height - this.margins.top
-			];
-		}
-
-	},
-
-	_convertPositionTo: function( d, pos ) {
-
-		if ( !pos ) {
-			pos = this.position;
-		}
-		var mod = d === "absolute" ? 1 : -1,
-			scroll = this.cssPosition === "absolute" &&
-				!( this.scrollParent[ 0 ] !== this.document[ 0 ] &&
-				$.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) ?
-					this.offsetParent :
-					this.scrollParent,
-			scrollIsRootNode = ( /(html|body)/i ).test( scroll[ 0 ].tagName );
-
-		return {
-			top: (
-
-				// The absolute mouse position
-				pos.top	+
-
-				// Only for relative positioned nodes: Relative offset from element to offset parent
-				this.offset.relative.top * mod +
-
-				// The offsetParent's offset without borders (offset + border)
-				this.offset.parent.top * mod -
-				( ( this.cssPosition === "fixed" ?
-					-this.scrollParent.scrollTop() :
-					( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod )
-			),
-			left: (
-
-				// The absolute mouse position
-				pos.left +
-
-				// Only for relative positioned nodes: Relative offset from element to offset parent
-				this.offset.relative.left * mod +
-
-				// The offsetParent's offset without borders (offset + border)
-				this.offset.parent.left * mod	-
-				( ( this.cssPosition === "fixed" ?
-					-this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 :
-					scroll.scrollLeft() ) * mod )
-			)
-		};
-
-	},
-
-	_generatePosition: function( event ) {
-
-		var top, left,
-			o = this.options,
-			pageX = event.pageX,
-			pageY = event.pageY,
-			scroll = this.cssPosition === "absolute" &&
-				!( this.scrollParent[ 0 ] !== this.document[ 0 ] &&
-				$.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) ?
-					this.offsetParent :
-					this.scrollParent,
-				scrollIsRootNode = ( /(html|body)/i ).test( scroll[ 0 ].tagName );
-
-		// This is another very weird special case that only happens for relative elements:
-		// 1. If the css position is relative
-		// 2. and the scroll parent is the document or similar to the offset parent
-		// we have to refresh the relative offset during the scroll so there are no jumps
-		if ( this.cssPosition === "relative" && !( this.scrollParent[ 0 ] !== this.document[ 0 ] &&
-				this.scrollParent[ 0 ] !== this.offsetParent[ 0 ] ) ) {
-			this.offset.relative = this._getRelativeOffset();
-		}
-
-		/*
-		 * - Position constraining -
-		 * Constrain the position to a mix of grid, containment.
-		 */
-
-		if ( this.originalPosition ) { //If we are not dragging yet, we won't check for options
-
-			if ( this.containment ) {
-				if ( event.pageX - this.offset.click.left < this.containment[ 0 ] ) {
-					pageX = this.containment[ 0 ] + this.offset.click.left;
-				}
-				if ( event.pageY - this.offset.click.top < this.containment[ 1 ] ) {
-					pageY = this.containment[ 1 ] + this.offset.click.top;
-				}
-				if ( event.pageX - this.offset.click.left > this.containment[ 2 ] ) {
-					pageX = this.containment[ 2 ] + this.offset.click.left;
-				}
-				if ( event.pageY - this.offset.click.top > this.containment[ 3 ] ) {
-					pageY = this.containment[ 3 ] + this.offset.click.top;
-				}
-			}
-
-			if ( o.grid ) {
-				top = this.originalPageY + Math.round( ( pageY - this.originalPageY ) /
-					o.grid[ 1 ] ) * o.grid[ 1 ];
-				pageY = this.containment ?
-					( ( top - this.offset.click.top >= this.containment[ 1 ] &&
-						top - this.offset.click.top <= this.containment[ 3 ] ) ?
-							top :
-							( ( top - this.offset.click.top >= this.containment[ 1 ] ) ?
-								top - o.grid[ 1 ] : top + o.grid[ 1 ] ) ) :
-								top;
-
-				left = this.originalPageX + Math.round( ( pageX - this.originalPageX ) /
-					o.grid[ 0 ] ) * o.grid[ 0 ];
-				pageX = this.containment ?
-					( ( left - this.offset.click.left >= this.containment[ 0 ] &&
-						left - this.offset.click.left <= this.containment[ 2 ] ) ?
-							left :
-							( ( left - this.offset.click.left >= this.containment[ 0 ] ) ?
-								left - o.grid[ 0 ] : left + o.grid[ 0 ] ) ) :
-								left;
-			}
-
-		}
-
-		return {
-			top: (
-
-				// The absolute mouse position
-				pageY -
-
-				// Click offset (relative to the element)
-				this.offset.click.top -
-
-				// Only for relative positioned nodes: Relative offset from element to offset parent
-				this.offset.relative.top -
-
-				// The offsetParent's offset without borders (offset + border)
-				this.offset.parent.top +
-				( ( this.cssPosition === "fixed" ?
-					-this.scrollParent.scrollTop() :
-					( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) )
-			),
-			left: (
-
-				// The absolute mouse position
-				pageX -
-
-				// Click offset (relative to the element)
-				this.offset.click.left -
-
-				// Only for relative positioned nodes: Relative offset from element to offset parent
-				this.offset.relative.left -
-
-				// The offsetParent's offset without borders (offset + border)
-				this.offset.parent.left +
-				( ( this.cssPosition === "fixed" ?
-					-this.scrollParent.scrollLeft() :
-					scrollIsRootNode ? 0 : scroll.scrollLeft() ) )
-			)
-		};
-
-	},
-
-	_rearrange: function( event, i, a, hardRefresh ) {
-
-		a ? a[ 0 ].appendChild( this.placeholder[ 0 ] ) :
-			i.item[ 0 ].parentNode.insertBefore( this.placeholder[ 0 ],
-				( this.direction === "down" ? i.item[ 0 ] : i.item[ 0 ].nextSibling ) );
-
-		//Various things done here to improve the performance:
-		// 1. we create a setTimeout, that calls refreshPositions
-		// 2. on the instance, we have a counter variable, that get's higher after every append
-		// 3. on the local scope, we copy the counter variable, and check in the timeout,
-		// if it's still the same
-		// 4. this lets only the last addition to the timeout stack through
-		this.counter = this.counter ? ++this.counter : 1;
-		var counter = this.counter;
-
-		this._delay( function() {
-			if ( counter === this.counter ) {
-
-				//Precompute after each DOM insertion, NOT on mousemove
-				this.refreshPositions( !hardRefresh );
-			}
-		} );
-
-	},
-
-	_clear: function( event, noPropagation ) {
-
-		this.reverting = false;
-
-		// We delay all events that have to be triggered to after the point where the placeholder
-		// has been removed and everything else normalized again
-		var i,
-			delayedTriggers = [];
-
-		// We first have to update the dom position of the actual currentItem
-		// Note: don't do it if the current item is already removed (by a user), or it gets
-		// reappended (see #4088)
-		if ( !this._noFinalSort && this.currentItem.parent().length ) {
-			this.placeholder.before( this.currentItem );
-		}
-		this._noFinalSort = null;
-
-		if ( this.helper[ 0 ] === this.currentItem[ 0 ] ) {
-			for ( i in this._storedCSS ) {
-				if ( this._storedCSS[ i ] === "auto" || this._storedCSS[ i ] === "static" ) {
-					this._storedCSS[ i ] = "";
-				}
-			}
-			this.currentItem.css( this._storedCSS );
-			this._removeClass( this.currentItem, "ui-sortable-helper" );
-		} else {
-			this.currentItem.show();
-		}
-
-		if ( this.fromOutside && !noPropagation ) {
-			delayedTriggers.push( function( event ) {
-				this._trigger( "receive", event, this._uiHash( this.fromOutside ) );
-			} );
-		}
-		if ( ( this.fromOutside ||
-				this.domPosition.prev !==
-				this.currentItem.prev().not( ".ui-sortable-helper" )[ 0 ] ||
-				this.domPosition.parent !== this.currentItem.parent()[ 0 ] ) && !noPropagation ) {
-
-			// Trigger update callback if the DOM position has changed
-			delayedTriggers.push( function( event ) {
-				this._trigger( "update", event, this._uiHash() );
-			} );
-		}
-
-		// Check if the items Container has Changed and trigger appropriate
-		// events.
-		if ( this !== this.currentContainer ) {
-			if ( !noPropagation ) {
-				delayedTriggers.push( function( event ) {
-					this._trigger( "remove", event, this._uiHash() );
-				} );
-				delayedTriggers.push( ( function( c ) {
-					return function( event ) {
-						c._trigger( "receive", event, this._uiHash( this ) );
-					};
-				} ).call( this, this.currentContainer ) );
-				delayedTriggers.push( ( function( c ) {
-					return function( event ) {
-						c._trigger( "update", event, this._uiHash( this ) );
-					};
-				} ).call( this, this.currentContainer ) );
-			}
-		}
-
-		//Post events to containers
-		function delayEvent( type, instance, container ) {
-			return function( event ) {
-				container._trigger( type, event, instance._uiHash( instance ) );
-			};
-		}
-		for ( i = this.containers.length - 1; i >= 0; i-- ) {
-			if ( !noPropagation ) {
-				delayedTriggers.push( delayEvent( "deactivate", this, this.containers[ i ] ) );
-			}
-			if ( this.containers[ i ].containerCache.over ) {
-				delayedTriggers.push( delayEvent( "out", this, this.containers[ i ] ) );
-				this.containers[ i ].containerCache.over = 0;
-			}
-		}
-
-		//Do what was originally in plugins
-		if ( this.storedCursor ) {
-			this.document.find( "body" ).css( "cursor", this.storedCursor );
-			this.storedStylesheet.remove();
-		}
-		if ( this._storedOpacity ) {
-			this.helper.css( "opacity", this._storedOpacity );
-		}
-		if ( this._storedZIndex ) {
-			this.helper.css( "zIndex", this._storedZIndex === "auto" ? "" : this._storedZIndex );
-		}
-
-		this.dragging = false;
-
-		if ( !noPropagation ) {
-			this._trigger( "beforeStop", event, this._uiHash() );
-		}
-
-		//$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately,
-		// it unbinds ALL events from the original node!
-		this.placeholder[ 0 ].parentNode.removeChild( this.placeholder[ 0 ] );
-
-		if ( !this.cancelHelperRemoval ) {
-			if ( this.helper[ 0 ] !== this.currentItem[ 0 ] ) {
-				this.helper.remove();
-			}
-			this.helper = null;
-		}
-
-		if ( !noPropagation ) {
-			for ( i = 0; i < delayedTriggers.length; i++ ) {
-
-				// Trigger all delayed events
-				delayedTriggers[ i ].call( this, event );
-			}
-			this._trigger( "stop", event, this._uiHash() );
-		}
-
-		this.fromOutside = false;
-		return !this.cancelHelperRemoval;
-
-	},
-
-	_trigger: function() {
-		if ( $.Widget.prototype._trigger.apply( this, arguments ) === false ) {
-			this.cancel();
-		}
-	},
-
-	_uiHash: function( _inst ) {
-		var inst = _inst || this;
-		return {
-			helper: inst.helper,
-			placeholder: inst.placeholder || $( [] ),
-			position: inst.position,
-			originalPosition: inst.originalPosition,
-			offset: inst.positionAbs,
-			item: inst.currentItem,
-			sender: _inst ? _inst.element : null
-		};
-	}
-
-} );
-
-
-/*!
- * jQuery UI Accordion 1.12.1
- * http://jqueryui.com
- *
- * Copyright jQuery Foundation and other contributors
- * Released under the MIT license.
- * http://jquery.org/license
- */
-
-//>>label: Accordion
-//>>group: Widgets
-// jscs:disable maximumLineLength
-//>>description: Displays collapsible content panels for presenting information in a limited amount of space.
-// jscs:enable maximumLineLength
-//>>docs: http://api.jqueryui.com/accordion/
-//>>demos: http://jqueryui.com/accordion/
-//>>css.structure: ../../themes/base/core.css
-//>>css.structure: ../../themes/base/accordion.css
-//>>css.theme: ../../themes/base/theme.css
-
-
-
-var widgetsAccordion = $.widget( "ui.accordion", {
-	version: "1.12.1",
-	options: {
-		active: 0,
-		animate: {},
-		classes: {
-			"ui-accordion-header": "ui-corner-top",
-			"ui-accordion-header-collapsed": "ui-corner-all",
-			"ui-accordion-content": "ui-corner-bottom"
-		},
-		collapsible: false,
-		event: "click",
-		header: "> li > :first-child, > :not(li):even",
-		heightStyle: "auto",
-		icons: {
-			activeHeader: "ui-icon-triangle-1-s",
-			header: "ui-icon-triangle-1-e"
-		},
-
-		// Callbacks
-		activate: null,
-		beforeActivate: null
-	},
-
-	hideProps: {
-		borderTopWidth: "hide",
-		borderBottomWidth: "hide",
-		paddingTop: "hide",
-		paddingBottom: "hide",
-		height: "hide"
-	},
-
-	showProps: {
-		borderTopWidth: "show",
-		borderBottomWidth: "show",
-		paddingTop: "show",
-		paddingBottom: "show",
-		height: "show"
-	},
-
-	_create: function() {
-		var options = this.options;
-
-		this.prevShow = this.prevHide = $();
-		this._addClass( "ui-accordion", "ui-widget ui-helper-reset" );
-		this.element.attr( "role", "tablist" );
-
-		// Don't allow collapsible: false and active: false / null
-		if ( !options.collapsible && ( options.active === false || options.active == null ) ) {
-			options.active = 0;
-		}
-
-		this._processPanels();
-
-		// handle negative values
-		if ( options.active < 0 ) {
-			options.active += this.headers.length;
-		}
-		this._refresh();
-	},
-
-	_getCreateEventData: function() {
-		return {
-			header: this.active,
-			panel: !this.active.length ? $() : this.active.next()
-		};
-	},
-
-	_createIcons: function() {
-		var icon, children,
-			icons = this.options.icons;
-
-		if ( icons ) {
-			icon = $( "<span>" );
-			this._addClass( icon, "ui-accordion-header-icon", "ui-icon " + icons.header );
-			icon.prependTo( this.headers );
-			children = this.active.children( ".ui-accordion-header-icon" );
-			this._removeClass( children, icons.header )
-				._addClass( children, null, icons.activeHeader )
-				._addClass( this.headers, "ui-accordion-icons" );
-		}
-	},
-
-	_destroyIcons: function() {
-		this._removeClass( this.headers, "ui-accordion-icons" );
-		this.headers.children( ".ui-accordion-header-icon" ).remove();
-	},
-
-	_destroy: function() {
-		var contents;
-
-		// Clean up main element
-		this.element.removeAttr( "role" );
-
-		// Clean up headers
-		this.headers
-			.removeAttr( "role aria-expanded aria-selected aria-controls tabIndex" )
-			.removeUniqueId();
-
-		this._destroyIcons();
-
-		// Clean up content panels
-		contents = this.headers.next()
-			.css( "display", "" )
-			.removeAttr( "role aria-hidden aria-labelledby" )
-			.removeUniqueId();
-
-		if ( this.options.heightStyle !== "content" ) {
-			contents.css( "height", "" );
-		}
-	},
-
-	_setOption: function( key, value ) {
-		if ( key === "active" ) {
-
-			// _activate() will handle invalid values and update this.options
-			this._activate( value );
-			return;
-		}
-
-		if ( key === "event" ) {
-			if ( this.options.event ) {
-				this._off( this.headers, this.options.event );
-			}
-			this._setupEvents( value );
-		}
-
-		this._super( key, value );
-
-		// Setting collapsible: false while collapsed; open first panel
-		if ( key === "collapsible" && !value && this.options.active === false ) {
-			this._activate( 0 );
-		}
-
-		if ( key === "icons" ) {
-			this._destroyIcons();
-			if ( value ) {
-				this._createIcons();
-			}
-		}
-	},
-
-	_setOptionDisabled: function( value ) {
-		this._super( value );
-
-		this.element.attr( "aria-disabled", value );
-
-		// Support: IE8 Only
-		// #5332 / #6059 - opacity doesn't cascade to positioned elements in IE
-		// so we need to add the disabled class to the headers and panels
-		this._toggleClass( null, "ui-state-disabled", !!value );
-		this._toggleClass( this.headers.add( this.headers.next() ), null, "ui-state-disabled",
-			!!value );
-	},
-
-	_keydown: function( event ) {
-		if ( event.altKey || event.ctrlKey ) {
-			return;
-		}
-
-		var keyCode = $.ui.keyCode,
-			length = this.headers.length,
-			currentIndex = this.headers.index( event.target ),
-			toFocus = false;
-
-		switch ( event.keyCode ) {
-		case keyCode.RIGHT:
-		case keyCode.DOWN:
-			toFocus = this.headers[ ( currentIndex + 1 ) % length ];
-			break;
-		case keyCode.LEFT:
-		case keyCode.UP:
-			toFocus = this.headers[ ( currentIndex - 1 + length ) % length ];
-			break;
-		case keyCode.SPACE:
-		case keyCode.ENTER:
-			this._eventHandler( event );
-			break;
-		case keyCode.HOME:
-			toFocus = this.headers[ 0 ];
-			break;
-		case keyCode.END:
-			toFocus = this.headers[ length - 1 ];
-			break;
-		}
-
-		if ( toFocus ) {
-			$( event.target ).attr( "tabIndex", -1 );
-			$( toFocus ).attr( "tabIndex", 0 );
-			$( toFocus ).trigger( "focus" );
-			event.preventDefault();
-		}
-	},
-
-	_panelKeyDown: function( event ) {
-		if ( event.keyCode === $.ui.keyCode.UP && event.ctrlKey ) {
-			$( event.currentTarget ).prev().trigger( "focus" );
-		}
-	},
-
-	refresh: function() {
-		var options = this.options;
-		this._processPanels();
-
-		// Was collapsed or no panel
-		if ( ( options.active === false && options.collapsible === true ) ||
-				!this.headers.length ) {
-			options.active = false;
-			this.active = $();
-
-		// active false only when collapsible is true
-		} else if ( options.active === false ) {
-			this._activate( 0 );
-
-		// was active, but active panel is gone
-		} else if ( this.active.length && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) {
-
-			// all remaining panel are disabled
-			if ( this.headers.length === this.headers.find( ".ui-state-disabled" ).length ) {
-				options.active = false;
-				this.active = $();
-
-			// activate previous panel
-			} else {
-				this._activate( Math.max( 0, options.active - 1 ) );
-			}
-
-		// was active, active panel still exists
-		} else {
-
-			// make sure active index is correct
-			options.active = this.headers.index( this.active );
-		}
-
-		this._destroyIcons();
-
-		this._refresh();
-	},
-
-	_processPanels: function() {
-		var prevHeaders = this.headers,
-			prevPanels = this.panels;
-
-		this.headers = this.element.find( this.options.header );
-		this._addClass( this.headers, "ui-accordion-header ui-accordion-header-collapsed",
-			"ui-state-default" );
-
-		this.panels = this.headers.next().filter( ":not(.ui-accordion-content-active)" ).hide();
-		this._addClass( this.panels, "ui-accordion-content", "ui-helper-reset ui-widget-content" );
-
-		// Avoid memory leaks (#10056)
-		if ( prevPanels ) {
-			this._off( prevHeaders.not( this.headers ) );
-			this._off( prevPanels.not( this.panels ) );
-		}
-	},
-
-	_refresh: function() {
-		var maxHeight,
-			options = this.options,
-			heightStyle = options.heightStyle,
-			parent = this.element.parent();
-
-		this.active = this._findActive( options.active );
-		this._addClass( this.active, "ui-accordion-header-active", "ui-state-active" )
-			._removeClass( this.active, "ui-accordion-header-collapsed" );
-		this._addClass( this.active.next(), "ui-accordion-content-active" );
-		this.active.next().show();
-
-		this.headers
-			.attr( "role", "tab" )
-			.each( function() {
-				var header = $( this ),
-					headerId = header.uniqueId().attr( "id" ),
-					panel = header.next(),
-					panelId = panel.uniqueId().attr( "id" );
-				header.attr( "aria-controls", panelId );
-				panel.attr( "aria-labelledby", headerId );
-			} )
-			.next()
-				.attr( "role", "tabpanel" );
-
-		this.headers
-			.not( this.active )
-				.attr( {
-					"aria-selected": "false",
-					"aria-expanded": "false",
-					tabIndex: -1
-				} )
-				.next()
-					.attr( {
-						"aria-hidden": "true"
-					} )
-					.hide();
-
-		// Make sure at least one header is in the tab order
-		if ( !this.active.length ) {
-			this.headers.eq( 0 ).attr( "tabIndex", 0 );
-		} else {
-			this.active.attr( {
-				"aria-selected": "true",
-				"aria-expanded": "true",
-				tabIndex: 0
-			} )
-				.next()
-					.attr( {
-						"aria-hidden": "false"
-					} );
-		}
-
-		this._createIcons();
-
-		this._setupEvents( options.event );
-
-		if ( heightStyle === "fill" ) {
-			maxHeight = parent.height();
-			this.element.siblings( ":visible" ).each( function() {
-				var elem = $( this ),
-					position = elem.css( "position" );
-
-				if ( position === "absolute" || position === "fixed" ) {
-					return;
-				}
-				maxHeight -= elem.outerHeight( true );
-			} );
-
-			this.headers.each( function() {
-				maxHeight -= $( this ).outerHeight( true );
-			} );
-
-			this.headers.next()
-				.each( function() {
-					$( this ).height( Math.max( 0, maxHeight -
-						$( this ).innerHeight() + $( this ).height() ) );
-				} )
-				.css( "overflow", "auto" );
-		} else if ( heightStyle === "auto" ) {
-			maxHeight = 0;
-			this.headers.next()
-				.each( function() {
-					var isVisible = $( this ).is( ":visible" );
-					if ( !isVisible ) {
-						$( this ).show();
-					}
-					maxHeight = Math.max( maxHeight, $( this ).css( "height", "" ).height() );
-					if ( !isVisible ) {
-						$( this ).hide();
-					}
-				} )
-				.height( maxHeight );
-		}
-	},
-
-	_activate: function( index ) {
-		var active = this._findActive( index )[ 0 ];
-
-		// Trying to activate the already active panel
-		if ( active === this.active[ 0 ] ) {
-			return;
-		}
-
-		// Trying to collapse, simulate a click on the currently active header
-		active = active || this.active[ 0 ];
-
-		this._eventHandler( {
-			target: active,
-			currentTarget: active,
-			preventDefault: $.noop
-		} );
-	},
-
-	_findActive: function( selector ) {
-		return typeof selector === "number" ? this.headers.eq( selector ) : $();
-	},
-
-	_setupEvents: function( event ) {
-		var events = {
-			keydown: "_keydown"
-		};
-		if ( event ) {
-			$.each( event.split( " " ), function( index, eventName ) {
-				events[ eventName ] = "_eventHandler";
-			} );
-		}
-
-		this._off( this.headers.add( this.headers.next() ) );
-		this._on( this.headers, events );
-		this._on( this.headers.next(), { keydown: "_panelKeyDown" } );
-		this._hoverable( this.headers );
-		this._focusable( this.headers );
-	},
-
-	_eventHandler: function( event ) {
-		var activeChildren, clickedChildren,
-			options = this.options,
-			active = this.active,
-			clicked = $( event.currentTarget ),
-			clickedIsActive = clicked[ 0 ] === active[ 0 ],
-			collapsing = clickedIsActive && options.collapsible,
-			toShow = collapsing ? $() : clicked.next(),
-			toHide = active.next(),
-			eventData = {
-				oldHeader: active,
-				oldPanel: toHide,
-				newHeader: collapsing ? $() : clicked,
-				newPanel: toShow
-			};
-
-		event.preventDefault();
-
-		if (
-
-				// click on active header, but not collapsible
-				( clickedIsActive && !options.collapsible ) ||
-
-				// allow canceling activation
-				( this._trigger( "beforeActivate", event, eventData ) === false ) ) {
-			return;
-		}
-
-		options.active = collapsing ? false : this.headers.index( clicked );
-
-		// When the call to ._toggle() comes after the class changes
-		// it causes a very odd bug in IE 8 (see #6720)
-		this.active = clickedIsActive ? $() : clicked;
-		this._toggle( eventData );
-
-		// Switch classes
-		// corner classes on the previously active header stay after the animation
-		this._removeClass( active, "ui-accordion-header-active", "ui-state-active" );
-		if ( options.icons ) {
-			activeChildren = active.children( ".ui-accordion-header-icon" );
-			this._removeClass( activeChildren, null, options.icons.activeHeader )
-				._addClass( activeChildren, null, options.icons.header );
-		}
-
-		if ( !clickedIsActive ) {
-			this._removeClass( clicked, "ui-accordion-header-collapsed" )
-				._addClass( clicked, "ui-accordion-header-active", "ui-state-active" );
-			if ( options.icons ) {
-				clickedChildren = clicked.children( ".ui-accordion-header-icon" );
-				this._removeClass( clickedChildren, null, options.icons.header )
-					._addClass( clickedChildren, null, options.icons.activeHeader );
-			}
-
-			this._addClass( clicked.next(), "ui-accordion-content-active" );
-		}
-	},
-
-	_toggle: function( data ) {
-		var toShow = data.newPanel,
-			toHide = this.prevShow.length ? this.prevShow : data.oldPanel;
-
-		// Handle activating a panel during the animation for another activation
-		this.prevShow.add( this.prevHide ).stop( true, true );
-		this.prevShow = toShow;
-		this.prevHide = toHide;
-
-		if ( this.options.animate ) {
-			this._animate( toShow, toHide, data );
-		} else {
-			toHide.hide();
-			toShow.show();
-			this._toggleComplete( data );
-		}
-
-		toHide.attr( {
-			"aria-hidden": "true"
-		} );
-		toHide.prev().attr( {
-			"aria-selected": "false",
-			"aria-expanded": "false"
-		} );
-
-		// if we're switching panels, remove the old header from the tab order
-		// if we're opening from collapsed state, remove the previous header from the tab order
-		// if we're collapsing, then keep the collapsing header in the tab order
-		if ( toShow.length && toHide.length ) {
-			toHide.prev().attr( {
-				"tabIndex": -1,
-				"aria-expanded": "false"
-			} );
-		} else if ( toShow.length ) {
-			this.headers.filter( function() {
-				return parseInt( $( this ).attr( "tabIndex" ), 10 ) === 0;
-			} )
-				.attr( "tabIndex", -1 );
-		}
-
-		toShow
-			.attr( "aria-hidden", "false" )
-			.prev()
-				.attr( {
-					"aria-selected": "true",
-					"aria-expanded": "true",
-					tabIndex: 0
-				} );
-	},
-
-	_animate: function( toShow, toHide, data ) {
-		var total, easing, duration,
-			that = this,
-			adjust = 0,
-			boxSizing = toShow.css( "box-sizing" ),
-			down = toShow.length &&
-				( !toHide.length || ( toShow.index() < toHide.index() ) ),
-			animate = this.options.animate || {},
-			options = down && animate.down || animate,
-			complete = function() {
-				that._toggleComplete( data );
-			};
-
-		if ( typeof options === "number" ) {
-			duration = options;
-		}
-		if ( typeof options === "string" ) {
-			easing = options;
-		}
-
-		// fall back from options to animation in case of partial down settings
-		easing = easing || options.easing || animate.easing;
-		duration = duration || options.duration || animate.duration;
-
-		if ( !toHide.length ) {
-			return toShow.animate( this.showProps, duration, easing, complete );
-		}
-		if ( !toShow.length ) {
-			return toHide.animate( this.hideProps, duration, easing, complete );
-		}
-
-		total = toShow.show().outerHeight();
-		toHide.animate( this.hideProps, {
-			duration: duration,
-			easing: easing,
-			step: function( now, fx ) {
-				fx.now = Math.round( now );
-			}
-		} );
-		toShow
-			.hide()
-			.animate( this.showProps, {
-				duration: duration,
-				easing: easing,
-				complete: complete,
-				step: function( now, fx ) {
-					fx.now = Math.round( now );
-					if ( fx.prop !== "height" ) {
-						if ( boxSizing === "content-box" ) {
-							adjust += fx.now;
-						}
-					} else if ( that.options.heightStyle !== "content" ) {
-						fx.now = Math.round( total - toHide.outerHeight() - adjust );
-						adjust = 0;
-					}
-				}
-			} );
-	},
-
-	_toggleComplete: function( data ) {
-		var toHide = data.oldPanel,
-			prev = toHide.prev();
-
-		this._removeClass( toHide, "ui-accordion-content-active" );
-		this._removeClass( prev, "ui-accordion-header-active" )
-			._addClass( prev, "ui-accordion-header-collapsed" );
-
-		// Work around for rendering bug in IE (#5421)
-		if ( toHide.length ) {
-			toHide.parent()[ 0 ].className = toHide.parent()[ 0 ].className;
-		}
-		this._trigger( "activate", null, data );
-	}
-} );
-
-
-
-
-}));
Index: admin/js/jquery/jquery.autocomplete.js
===================================================================
--- admin/js/jquery/jquery.autocomplete.js	(revision 2114)
+++ 	(revision )
@@ -1,848 +1,0 @@
-/*
- * jQuery Autocomplete plugin 1.2.3
- *
- * Copyright (c) 2009 Jörn Zaefferer
- *
- * Dual licensed under the MIT and GPL licenses:
- *   http://www.opensource.org/licenses/mit-license.php
- *   http://www.gnu.org/licenses/gpl.html
- *
- * With small modifications by Alfonso Gómez-Arzola.
- * See changelog for details.
- *
- */
-
-;(function($) {
-
-$.fn.extend({
-	autocomplete: function(urlOrData, options) {
-		var isUrl = typeof urlOrData == "string";
-		options = $.extend({}, $.Autocompleter.defaults, {
-			url: isUrl ? urlOrData : null,
-			data: isUrl ? null : urlOrData,
-			delay: isUrl ? $.Autocompleter.defaults.delay : 10,
-			max: options && !options.scroll ? 10 : 150,
-			noRecord: "No Records."
-		}, options);
-
-		// if highlight is set to false, replace it with a do-nothing function
-		options.highlight = options.highlight || function(value) { return value; };
-
-		// if the formatMatch option is not specified, then use formatItem for backwards compatibility
-		options.formatMatch = options.formatMatch || options.formatItem;
-
-		return this.each(function() {
-			new $.Autocompleter(this, options);
-		});
-	},
-	result: function(handler) {
-		return this.bind("result", handler);
-	},
-	search: function(handler) {
-		return this.trigger("search", [handler]);
-	},
-	flushCache: function() {
-		return this.trigger("flushCache");
-	},
-	setOptions: function(options){
-		return this.trigger("setOptions", [options]);
-	},
-	unautocomplete: function() {
-		return this.trigger("unautocomplete");
-	}
-});
-
-$.Autocompleter = function(input, options) {
-
-	var KEY = {
-		UP: 38,
-		DOWN: 40,
-		DEL: 46,
-		TAB: 9,
-		RETURN: 13,
-		ESC: 27,
-		COMMA: 188,
-		PAGEUP: 33,
-		PAGEDOWN: 34,
-		BACKSPACE: 8
-	};
-
-	var globalFailure = null;
-	if(options.failure != null && typeof options.failure == "function") {
-	  globalFailure = options.failure;
-	}
-
-	// Create $ object for input element
-	var $input = $(input).attr("autocomplete", "off").addClass(options.inputClass);
-
-	var timeout;
-	var previousValue = "";
-	var cache = $.Autocompleter.Cache(options);
-	var hasFocus = 0;
-	var lastKeyPressCode;
-	var config = {
-		mouseDownOnSelect: false
-	};
-	var select = $.Autocompleter.Select(options, input, selectCurrent, config);
-
-	var blockSubmit;
-
-	// prevent form submit in opera when selecting with return key
-  navigator.userAgent.indexOf("Opera") != -1 && $(input.form).bind("submit.autocomplete", function() {
-		if (blockSubmit) {
-			blockSubmit = false;
-			return false;
-		}
-	});
-
-	// older versions of opera don't trigger keydown multiple times while pressed, others don't work with keypress at all
-	$input.bind((navigator.userAgent.indexOf("Opera") != -1 && !'KeyboardEvent' in window ? "keypress" : "keydown") + ".autocomplete", function(event) {
-		// a keypress means the input has focus
-		// avoids issue where input had focus before the autocomplete was applied
-		hasFocus = 1;
-		// track last key pressed
-		lastKeyPressCode = event.keyCode;
-		switch(event.keyCode) {
-
-			case KEY.UP:
-				if ( select.visible() ) {
-					event.preventDefault();
-					select.prev();
-				} else {
-					onChange(0, true);
-				}
-				break;
-
-			case KEY.DOWN:
-				if ( select.visible() ) {
-					event.preventDefault();
-					select.next();
-				} else {
-					onChange(0, true);
-				}
-				break;
-
-			case KEY.PAGEUP:
-				if ( select.visible() ) {
-  				event.preventDefault();
-					select.pageUp();
-				} else {
-					onChange(0, true);
-				}
-				break;
-
-			case KEY.PAGEDOWN:
-				if ( select.visible() ) {
-  				event.preventDefault();
-					select.pageDown();
-				} else {
-					onChange(0, true);
-				}
-				break;
-
-			// matches also semicolon
-			case options.multiple && $.trim(options.multipleSeparator) == "," && KEY.COMMA:
-			case KEY.TAB:
-			case KEY.RETURN:
-				if( selectCurrent() ) {
-					// stop default to prevent a form submit, Opera needs special handling
-					event.preventDefault();
-					blockSubmit = true;
-					return false;
-				}
-				break;
-
-			case KEY.ESC:
-				select.hide();
-				break;
-
-			default:
-				clearTimeout(timeout);
-				timeout = setTimeout(onChange, options.delay);
-				break;
-		}
-	}).focus(function(){
-		// track whether the field has focus, we shouldn't process any
-		// results if the field no longer has focus
-		hasFocus++;
-	}).blur(function() {
-	  hasFocus = 0;
-		if (!config.mouseDownOnSelect) {
-			hideResults();
-		}
-	}).click(function() {
-		// show select when clicking in a focused field
-		// but if clickFire is true, don't require field
-		// to be focused to begin with; just show select
-		if( options.clickFire ) {
-		  if ( !select.visible() ) {
-  			onChange(0, true);
-  		}
-		} else {
-		  if ( hasFocus++ > 1 && !select.visible() ) {
-  			onChange(0, true);
-  		}
-		}
-	}).bind("search", function() {
-		// TODO why not just specifying both arguments?
-		var fn = (arguments.length > 1) ? arguments[1] : null;
-		function findValueCallback(q, data) {
-			var result;
-			if( data && data.length ) {
-				for (var i=0; i < data.length; i++) {
-					if( data[i].result.toLowerCase() == q.toLowerCase() ) {
-						result = data[i];
-						break;
-					}
-				}
-			}
-			if( typeof fn == "function" ) fn(result);
-			else $input.trigger("result", result && [result.data, result.value]);
-		}
-		$.each(trimWords($input.val()), function(i, value) {
-			request(value, findValueCallback, findValueCallback);
-		});
-	}).bind("flushCache", function() {
-		cache.flush();
-	}).bind("setOptions", function() {
-		$.extend(true, options, arguments[1]);
-		// if we've updated the data, repopulate
-		if ( "data" in arguments[1] )
-			cache.populate();
-	}).bind("unautocomplete", function() {
-		select.unbind();
-		$input.unbind();
-		$(input.form).unbind(".autocomplete");
-	});
-
-
-	function selectCurrent() {
-		var selected = select.selected();
-		if( !selected )
-			return false;
-
-		var v = selected.result;
-		previousValue = v;
-
-		if ( options.multiple ) {
-			var words = trimWords($input.val());
-			if ( words.length > 1 ) {
-				var seperator = options.multipleSeparator.length;
-				var cursorAt = $(input).selection().start;
-				var wordAt, progress = 0;
-				$.each(words, function(i, word) {
-					progress += word.length;
-					if (cursorAt <= progress) {
-						wordAt = i;
-						return false;
-					}
-					progress += seperator;
-				});
-				words[wordAt] = v;
-				// TODO this should set the cursor to the right position, but it gets overriden somewhere
-				//$.Autocompleter.Selection(input, progress + seperator, progress + seperator);
-				v = words.join( options.multipleSeparator );
-			}
-			v += options.multipleSeparator;
-		}
-
-		$input.val(v);
-		hideResultsNow();
-		$input.trigger("result", [selected.data, selected.value]);
-		return true;
-	}
-
-	function onChange(crap, skipPrevCheck) {
-		if( lastKeyPressCode == KEY.DEL ) {
-			select.hide();
-			return;
-		}
-
-		var currentValue = $input.val();
-
-		if ( !skipPrevCheck && currentValue == previousValue )
-			return;
-
-		previousValue = currentValue;
-
-		currentValue = lastWord(currentValue);
-		if ( currentValue.length >= options.minChars) {
-			$input.addClass(options.loadingClass);
-			if (!options.matchCase)
-				currentValue = currentValue.toLowerCase();
-			request(currentValue, receiveData, hideResultsNow);
-		} else {
-			stopLoading();
-			select.hide();
-		}
-	};
-
-	function trimWords(value) {
-		if (!value)
-			return [""];
-		if (!options.multiple)
-			return [$.trim(value)];
-		return $.map(value.split(options.multipleSeparator), function(word) {
-			return $.trim(value).length ? $.trim(word) : null;
-		});
-	}
-
-	function lastWord(value) {
-		if ( !options.multiple )
-			return value;
-		var words = trimWords(value);
-		if (words.length == 1)
-			return words[0];
-		var cursorAt = $(input).selection().start;
-		if (cursorAt == value.length) {
-			words = trimWords(value)
-		} else {
-			words = trimWords(value.replace(value.substring(cursorAt), ""));
-		}
-		return words[words.length - 1];
-	}
-
-	// fills in the input box w/the first match (assumed to be the best match)
-	// q: the term entered
-	// sValue: the first matching result
-	function autoFill(q, sValue){
-		// autofill in the complete box w/the first match as long as the user hasn't entered in more data
-		// if the last user key pressed was backspace, don't autofill
-		if( options.autoFill && (lastWord($input.val()).toLowerCase() == q.toLowerCase()) && lastKeyPressCode != KEY.BACKSPACE ) {
-			// fill in the value (keep the case the user has typed)
-			$input.val($input.val() + sValue.substring(lastWord(previousValue).length));
-			// select the portion of the value not typed by the user (so the next character will erase)
-			$(input).selection(previousValue.length, previousValue.length + sValue.length);
-		}
-	};
-
-	function hideResults() {
-		clearTimeout(timeout);
-		timeout = setTimeout(hideResultsNow, 200);
-	};
-
-	function hideResultsNow() {
-		var wasVisible = select.visible();
-		select.hide();
-		clearTimeout(timeout);
-		stopLoading();
-		if (options.mustMatch) {
-			// call search and run callback
-			$input.search(
-				function (result){
-					// if no value found, clear the input box
-					if( !result ) {
-						if (options.multiple) {
-							var words = trimWords($input.val()).slice(0, -1);
-							$input.val( words.join(options.multipleSeparator) + (words.length ? options.multipleSeparator : "") );
-						}
-						else {
-							$input.val( "" );
-							$input.trigger("result", null);
-						}
-					}
-				}
-			);
-		}
-	};
-
-	function receiveData(q, data) {
-		if ( data && data.length && hasFocus ) {
-			stopLoading();
-			select.display(data, q);
-			autoFill(q, data[0].value);
-			select.show();
-		} else {
-			hideResultsNow();
-		}
-	};
-
-	function request(term, success, failure) {
-		if (!options.matchCase)
-			term = term.toLowerCase();
-		var data = cache.load(term);
-		// recieve the cached data
-		if (data) {
-			if(data.length)	{
-				success(term, data);
-			}
-			else{
-				var parsed = options.parse && options.parse(options.noRecord) || parse(options.noRecord);	
-				success(term,parsed);
-			}
-		// if an AJAX url has been supplied, try loading the data now
-		} else if( (typeof options.url == "string") && (options.url.length > 0) ){
-
-			var extraParams = {
-				timestamp: +new Date()
-			};
-			$.each(options.extraParams, function(key, param) {
-				extraParams[key] = typeof param == "function" ? param() : param;
-			});
-
-			$.ajax({
-				// try to leverage ajaxQueue plugin to abort previous requests
-				mode: "abort",
-				// limit abortion to this input
-				port: "autocomplete" + input.name,
-				dataType: options.dataType,
-				url: options.url,
-				data: $.extend({
-					q: lastWord(term),
-					limit: options.max
-				}, extraParams),
-				success: function(data) {
-					var parsed = options.parse && options.parse(data) || parse(data);
-					cache.add(term, parsed);
-					success(term, parsed);
-				}
-			});
-		} else {
-			// if we have a failure, we need to empty the list -- this prevents the the [TAB] key from selecting the last successful match
-			select.emptyList();
-			if(globalFailure != null) {
-        globalFailure();
-      }
-      else {
-        failure(term);
-			}
-		}
-	};
-
-	function parse(data) {
-		var parsed = [];
-		var rows = data.split("\n");
-		for (var i=0; i < rows.length; i++) {
-			var row = $.trim(rows[i]);
-			if (row) {
-				row = row.split("|");
-				parsed[parsed.length] = {
-					data: row,
-					value: row[0],
-					result: options.formatResult && options.formatResult(row, row[0]) || row[0]
-				};
-			}
-		}
-		return parsed;
-	};
-
-	function stopLoading() {
-		$input.removeClass(options.loadingClass);
-	};
-
-};
-
-$.Autocompleter.defaults = {
-	inputClass: "ac_input",
-	resultsClass: "ac_results",
-	loadingClass: "ac_loading",
-	minChars: 1,
-	delay: 400,
-	matchCase: false,
-	matchSubset: true,
-	matchContains: false,
-	cacheLength: 100,
-	max: 1000,
-	mustMatch: false,
-	extraParams: {},
-	selectFirst: true,
-	formatItem: function(row) { return row[0]; },
-	formatMatch: null,
-	autoFill: false,
-	width: 0,
-	multiple: false,
-	multipleSeparator: " ",
-	inputFocus: true,
-	clickFire: false,
-	highlight: function(value, term) {
-		return value.replace(new RegExp("(?![^&;]+;)(?!<[^<>]*)(" + term.replace(/([\^\$\(\)\[\]\{\}\*\.\+\?\|\\])/gi, "\\$1") + ")(?![^<>]*>)(?![^&;]+;)", "gi"), "<strong>$1</strong>");
-	},
-    scroll: true,
-    scrollHeight: 180,
-    scrollJumpPosition: true
-};
-
-$.Autocompleter.Cache = function(options) {
-
-	var data = {};
-	var length = 0;
-
-	function matchSubset(s, sub) {
-		if (!options.matchCase)
-			s = s.toLowerCase();
-		var i = s.indexOf(sub);
-		if (options.matchContains == "word"){
-			i = s.toLowerCase().search("\\b" + sub.toLowerCase());
-		}
-		if (i == -1) return false;
-		return i == 0 || options.matchContains;
-	};
-
-	function add(q, value) {
-		if (length > options.cacheLength){
-			flush();
-		}
-		if (!data[q]){
-			length++;
-		}
-		data[q] = value;
-	}
-
-	function populate(){
-		if( !options.data ) return false;
-		// track the matches
-		var stMatchSets = {},
-			nullData = 0;
-
-		// no url was specified, we need to adjust the cache length to make sure it fits the local data store
-		if( !options.url ) options.cacheLength = 1;
-
-		// track all options for minChars = 0
-		stMatchSets[""] = [];
-
-		// loop through the array and create a lookup structure
-		for ( var i = 0, ol = options.data.length; i < ol; i++ ) {
-			var rawValue = options.data[i];
-			// if rawValue is a string, make an array otherwise just reference the array
-			rawValue = (typeof rawValue == "string") ? [rawValue] : rawValue;
-
-			var value = options.formatMatch(rawValue, i+1, options.data.length);
-			if ( typeof(value) === 'undefined' || value === false )
-				continue;
-
-			var firstChar = value.charAt(0).toLowerCase();
-			// if no lookup array for this character exists, look it up now
-			if( !stMatchSets[firstChar] )
-				stMatchSets[firstChar] = [];
-
-			// if the match is a string
-			var row = {
-				value: value,
-				data: rawValue,
-				result: options.formatResult && options.formatResult(rawValue) || value
-			};
-
-			// push the current match into the set list
-			stMatchSets[firstChar].push(row);
-
-			// keep track of minChars zero items
-			if ( nullData++ < options.max ) {
-				stMatchSets[""].push(row);
-			}
-		};
-
-		// add the data items to the cache
-		$.each(stMatchSets, function(i, value) {
-			// increase the cache size
-			options.cacheLength++;
-			// add to the cache
-			add(i, value);
-		});
-	}
-
-	// populate any existing data
-	setTimeout(populate, 25);
-
-	function flush(){
-		data = {};
-		length = 0;
-	}
-
-	return {
-		flush: flush,
-		add: add,
-		populate: populate,
-		load: function(q) {
-			if (!options.cacheLength || !length)
-				return null;
-			/*
-			 * if dealing w/local data and matchContains than we must make sure
-			 * to loop through all the data collections looking for matches
-			 */
-			if( !options.url && options.matchContains ){
-				// track all matches
-				var csub = [];
-				// loop through all the data grids for matches
-				for( var k in data ){
-					// don't search through the stMatchSets[""] (minChars: 0) cache
-					// this prevents duplicates
-					if( k.length > 0 ){
-						var c = data[k];
-						$.each(c, function(i, x) {
-							// if we've got a match, add it to the array
-							if (matchSubset(x.value, q)) {
-								csub.push(x);
-							}
-						});
-					}
-				}
-				return csub;
-			} else
-			// if the exact item exists, use it
-			if (data[q]){
-				return data[q];
-			} else
-			if (options.matchSubset) {
-				for (var i = q.length - 1; i >= options.minChars; i--) {
-					var c = data[q.substr(0, i)];
-					if (c) {
-						var csub = [];
-						$.each(c, function(i, x) {
-							if (matchSubset(x.value, q)) {
-								csub[csub.length] = x;
-							}
-						});
-						return csub;
-					}
-				}
-			}
-			return null;
-		}
-	};
-};
-
-$.Autocompleter.Select = function (options, input, select, config) {
-	var CLASSES = {
-		ACTIVE: "ac_over"
-	};
-
-	var listItems,
-		active = -1,
-		data,
-		term = "",
-		needsInit = true,
-		element,
-		list;
-
-	// Create results
-	function init() {
-		if (!needsInit)
-			return;
-		element = $("<div/>")
-		.hide()
-		.addClass(options.resultsClass)
-		.css("position", "absolute")
-		.appendTo(document.body)
-		.hover(function(event) {
-		  // Browsers except FF do not fire mouseup event on scrollbars, resulting in mouseDownOnSelect remaining true, and results list not always hiding.
-		  if($(this).is(":visible")) {
-		    input.focus();
-		  }
-		  config.mouseDownOnSelect = false;
-		});
-
-		list = $("<ul/>").appendTo(element).mouseover( function(event) {
-			if(target(event).nodeName && target(event).nodeName.toUpperCase() == 'LI') {
-	            active = $("li", list).removeClass(CLASSES.ACTIVE).index(target(event));
-			    $(target(event)).addClass(CLASSES.ACTIVE);
-	        }
-		}).click(function(event) {
-			$(target(event)).addClass(CLASSES.ACTIVE);
-			select();
-			if( options.inputFocus )
-			  input.focus();
-			return false;
-		}).mousedown(function() {
-			config.mouseDownOnSelect = true;
-		}).mouseup(function() {
-			config.mouseDownOnSelect = false;
-		});
-
-		if( options.width > 0 )
-			element.css("width", options.width);
-
-		needsInit = false;
-	}
-
-	function target(event) {
-		var element = event.target;
-		while(element && element.tagName != "LI")
-			element = element.parentNode;
-		// more fun with IE, sometimes event.target is empty, just ignore it then
-		if(!element)
-			return [];
-		return element;
-	}
-
-	function moveSelect(step) {
-		listItems.slice(active, active + 1).removeClass(CLASSES.ACTIVE);
-		movePosition(step);
-        var activeItem = listItems.slice(active, active + 1).addClass(CLASSES.ACTIVE);
-        if(options.scroll) {
-            var offset = 0;
-            listItems.slice(0, active).each(function() {
-				offset += this.offsetHeight;
-			});
-            if((offset + activeItem[0].offsetHeight - list.scrollTop()) > list[0].clientHeight) {
-                list.scrollTop(offset + activeItem[0].offsetHeight - list.innerHeight());
-            } else if(offset < list.scrollTop()) {
-                list.scrollTop(offset);
-            }
-        }
-	};
-
-	function movePosition(step) {
-		if (options.scrollJumpPosition || (!options.scrollJumpPosition && !((step < 0 && active == 0) || (step > 0 && active == listItems.size() - 1)) )) {
-			active += step;
-			if (active < 0) {
-				active = listItems.size() - 1;
-			} else if (active >= listItems.size()) {
-				active = 0;
-			}
-		}
-	}
-
-
-	function limitNumberOfItems(available) {
-		return options.max && options.max < available
-			? options.max
-			: available;
-	}
-
-	function fillList() {
-		list.empty();
-		var max = limitNumberOfItems(data.length);
-		for (var i=0; i < max; i++) {
-			if (!data[i])
-				continue;
-			var formatted = options.formatItem(data[i].data, i+1, max, data[i].value, term);
-			if ( formatted === false )
-				continue;
-			var li = $("<li/>").html( options.highlight(formatted, term) ).addClass(i%2 == 0 ? "ac_even" : "ac_odd").appendTo(list)[0];
-			$.data(li, "ac_data", data[i]);
-		}
-		listItems = list.find("li");
-		if ( options.selectFirst ) {
-			listItems.slice(0, 1).addClass(CLASSES.ACTIVE);
-			active = 0;
-		}
-		// apply bgiframe if available
-		if ( $.fn.bgiframe )
-			list.bgiframe();
-	}
-
-	return {
-		display: function(d, q) {
-			init();
-			data = d;
-			term = q;
-			fillList();
-		},
-		next: function() {
-			moveSelect(1);
-		},
-		prev: function() {
-			moveSelect(-1);
-		},
-		pageUp: function() {
-			if (active != 0 && active - 8 < 0) {
-				moveSelect( -active );
-			} else {
-				moveSelect(-8);
-			}
-		},
-		pageDown: function() {
-			if (active != listItems.size() - 1 && active + 8 > listItems.size()) {
-				moveSelect( listItems.size() - 1 - active );
-			} else {
-				moveSelect(8);
-			}
-		},
-		hide: function() {
-			element && element.hide();
-			listItems && listItems.removeClass(CLASSES.ACTIVE);
-			active = -1;
-		},
-		visible : function() {
-			return element && element.is(":visible");
-		},
-		current: function() {
-			return this.visible() && (listItems.filter("." + CLASSES.ACTIVE)[0] || options.selectFirst && listItems[0]);
-		},
-		show: function() {
-			var offset = $(input).offset();
-			element.css({
-				width: typeof options.width == "string" || options.width > 0 ? options.width : $(input).width(),
-				top: offset.top + input.offsetHeight,
-				left: offset.left
-			}).show();
-            if(options.scroll) {
-                list.scrollTop(0);
-                list.css({
-					maxHeight: options.scrollHeight,
-					overflow: 'auto'
-				});
-
-                if(navigator.userAgent.indexOf("MSIE") != -1 && typeof document.body.style.maxHeight === "undefined") {
-					var listHeight = 0;
-					listItems.each(function() {
-						listHeight += this.offsetHeight;
-					});
-					var scrollbarsVisible = listHeight > options.scrollHeight;
-                    list.css('height', scrollbarsVisible ? options.scrollHeight : listHeight );
-					if (!scrollbarsVisible) {
-						// IE doesn't recalculate width when scrollbar disappears
-						listItems.width( list.width() - parseInt(listItems.css("padding-left")) - parseInt(listItems.css("padding-right")) );
-					}
-                }
-
-            }
-		},
-		selected: function() {
-			var selected = listItems && listItems.filter("." + CLASSES.ACTIVE).removeClass(CLASSES.ACTIVE);
-			return selected && selected.length && $.data(selected[0], "ac_data");
-		},
-		emptyList: function (){
-			list && list.empty();
-		},
-		unbind: function() {
-			element && element.remove();
-		}
-	};
-};
-
-$.fn.selection = function(start, end) {
-	if (start !== undefined) {
-		return this.each(function() {
-			if( this.createTextRange ){
-				var selRange = this.createTextRange();
-				if (end === undefined || start == end) {
-					selRange.move("character", start);
-					selRange.select();
-				} else {
-					selRange.collapse(true);
-					selRange.moveStart("character", start);
-					selRange.moveEnd("character", end);
-					selRange.select();
-				}
-			} else if( this.setSelectionRange ){
-				this.setSelectionRange(start, end);
-			} else if( this.selectionStart ){
-				this.selectionStart = start;
-				this.selectionEnd = end;
-			}
-		});
-	}
-	var field = this[0];
-	if ( field.createTextRange ) {
-		var range = document.selection.createRange(),
-			orig = field.value,
-			teststring = "<->",
-			textLength = range.text.length;
-		range.text = teststring;
-		var caretAt = field.value.indexOf(teststring);
-		field.value = orig;
-		this.selection(caretAt, caretAt + textLength);
-		return {
-			start: caretAt,
-			end: caretAt + textLength
-		}
-	} else if( field.selectionStart !== undefined ){
-		return {
-			start: field.selectionStart,
-			end: field.selectionEnd
-		}
-	}
-};
-
-})(jQuery);
Index: admin/js/jquery/jquery.bgFade.js
===================================================================
--- admin/js/jquery/jquery.bgFade.js	(revision 0)
+++ admin/js/jquery/jquery.bgFade.js	(revision 0)
@@ -0,0 +1,70 @@
+jQuery.fn.backgroundFade = function(s,callback) {
+	var defaults = {
+		sColor: [255,0,0],
+		eColor: [255,255,255],
+		fColor: null,
+		steps: 200,
+		intervals: 5,
+		powr: 4
+	},
+	
+	params = jQuery.extend(defaults,s);
+	
+	return this.each(function() {
+		this.bgFade_sColor = jQuery.backgroundFade.parseHexColor(params.sColor);
+		this.bgFade_eColor = jQuery.backgroundFade.parseHexColor(params.eColor);
+		this.bgFade_fColor = params.fColor ? params.fColor : jQuery(this).css('backgroundColor');
+		this.bgFade_steps = params.steps;
+		this.bgFade_intervals = params.intervals;
+		this.bgFade_powr = params.powr;
+		this.bgFade_fn = callback;
+		
+		jQuery.backgroundFade.doFade(this);
+	});
+};
+
+jQuery.backgroundFade = {
+	parseHexColor: function(c) {
+		if (c.constructor == String && c.substr(0,1) == '#') {
+			return [parseInt(c.substr(1,2),16),parseInt(c.substr(3,2),16),parseInt(c.substr(5,2),16)];
+		}
+		return c;
+	},
+	
+	easeInOut: function(minValue,maxValue,totalSteps,actualStep,powr) {
+		var delta = maxValue - minValue;
+		var stepp = minValue+(Math.pow(((1 / totalSteps)*actualStep),powr)*delta);
+		return Math.ceil(stepp);
+	},
+	
+	doFade: function(e) {
+		if (e.bgFadeInt) window.clearInterval(e.bgFadeInt);
+		var act_step = 0;
+		
+		e.bgFadeInt = window.setInterval(function() {
+			e.style.backgroundColor =
+			"rgb("+
+			jQuery.backgroundFade.easeInOut(e.bgFade_sColor[0],e.bgFade_eColor[0],
+				e.bgFade_steps,act_step,e.bgFade_powr)+","+
+			jQuery.backgroundFade.easeInOut(e.bgFade_sColor[1],e.bgFade_eColor[1],
+				e.bgFade_steps,act_step,e.bgFade_powr)+","+
+			jQuery.backgroundFade.easeInOut(e.bgFade_sColor[2],e.bgFade_eColor[2],
+				e.bgFade_steps,act_step,e.bgFade_powr)+")";
+			
+			act_step++;
+			if (act_step > e.bgFade_steps) {
+				window.clearInterval(e.bgFadeInt);
+				e.bgFade_sColor = undefined;
+				e.bgFade_eColor = undefined;
+				e.bgFade_fColor = undefined;
+				e.bgFade_steps = undefined;
+				e.bgFade_intervals = undefined;
+				e.bgFade_powr = undefined;
+				if (typeof(e.bgFade_fn) == 'function') {
+					e.bgFade_fn.call(e);
+				}
+				e.style.backgroundColor = e.bgFade_fColor;
+			}
+		},e.bgFade_intervals);
+	}
+};
Index: admin/js/jquery/jquery.candyUpload.js
===================================================================
--- admin/js/jquery/jquery.candyUpload.js	(revision 0)
+++ admin/js/jquery/jquery.candyUpload.js	(revision 0)
@@ -0,0 +1,644 @@
+(function($) {
+	// We need to create a global SWFUpload object to store instances
+	window.SWFUpload = {
+		instances: new Array(),
+		movieCount: 0,
+		version: "2.2.0 Beta 2",
+		QUEUE_ERROR: {
+			QUEUE_LIMIT_EXCEEDED:	-100,
+			FILE_EXCEEDS_SIZE_LIMIT:	-110,
+			ZERO_BYTE_FILE:		-120,
+			INVALID_FILETYPE:		-130
+		},
+		UPLOAD_ERROR: {
+			HTTP_ERROR:				-200,
+			MISSING_UPLOAD_URL:			-210,
+			IO_ERROR:					-220,
+			SECURITY_ERROR:			-230,
+			UPLOAD_LIMIT_EXCEEDED:		-240,
+			UPLOAD_FAILED:				-250,
+			SPECIFIED_FILE_ID_NOT_FOUND:	-260,
+			FILE_VALIDATION_FAILED:		-270,
+			FILE_CANCELLED:			-280,
+			UPLOAD_STOPPED:			-290
+		},
+		FILE_STATUS: {
+			QUEUED:		-1,
+			IN_PROGRESS:	-2,
+			ERROR:		-3,
+			COMPLETE:		-4,
+			CANCELLED:	-5
+		},
+		BUTTON_ACTION: {
+			SELECT_FILE:	-100,
+			SELECT_FILES:	-110,
+			START_UPLOAD:	-120
+		},
+		CURSOR: {
+			ARROW:	-1,
+			HAND:	-2
+		},
+		WINDOW_MODE: {
+			WINDOW:		'window',
+			TRANSPARENT:	'transparent',
+			OPAQUE:		'opaque'
+		}
+	};
+	
+	$.uploader = function(settings,callbacks) {
+		return new $._uploader(settings,callbacks);
+	};
+	
+	$._uploader = function(settings,callbacks) {
+		var defaults = {
+			debug: false,
+			upload_url: '',
+			flash_movie: '',
+			movie_name: null,
+			params: null,
+			use_query_string: null,
+			requeue_on_error: false,
+			file_types: '*.*',
+			file_types_description: 'All files',
+			file_size_limit: 0,
+			file_upload_limit: 0,
+			file_queue_limit: -1,
+			target_element: null
+		};
+		this.params = $.extend(defaults,settings);
+		
+		var default_callbacks = {
+			flashReady: function() {},
+			fileDialogComplete: function() {},
+			fileDialogStart: function() {},
+			fileQueued: function() {},
+			fileQueueError: function() {},
+			uploadStart: function() {},
+			uploadProgress: function() {},
+			uploadError: function() {},
+			uploadSuccess: function() {},
+			uploadComplete: function() {},
+			debug: function() {}
+		};
+		this.callbacks = $.extend(default_callbacks,callbacks);
+		
+		return this.build();
+	};
+	
+	$._uploader.prototype = {
+		log: function(msg) {
+			if (!this.params.debug) { return; }
+			try {
+				console.log(msg);
+			} catch(e) {}
+		},
+		
+		/* Constructor */
+		build: function(settings) {
+			if (!this.params.upload_url || !this.params.movie_name) {
+				throw('Configuration error. Please make sure you specified movie_name and upload_url options.');
+			}
+			
+			if ($.browser.opera) {
+				return this;
+			}
+			
+			// Get a real bytes size limit (if we want to reuse it somewhere)
+			this.params.file_size_limit = this.getFileSizeLimit(this.params.file_size_limit);
+			
+			// Flash vars
+			var fv = new Array();
+			this.addFlashVar(fv,'debugEnabled',this.params.debug);
+			this.addFlashVar(fv,'movieName',this.params.movie_name);
+			this.addFlashVar(fv,'uploadURL',this.params.upload_url);
+			this.addFlashVar(fv,'fileTypes',this.params.file_types);
+			this.addFlashVar(fv,'fileTypesDescription',this.params.file_types_description);
+			this.addFlashVar(fv,'params',this.params.params);
+			this.addFlashVar(fv,'fileSizeLimit',this.params.file_size_limit + 'b');
+			this.addFlashVar(fv,'fileUploadLimit',this.params.file_upload_limit);
+			this.addFlashVar(fv,'fileQueueLimit',this.params.file_queue_limit);
+			this.addFlashVar(fv,'requeueOnError',this.params.requeue_on_error);
+			this.addFlashVar(fv,'buttonImageURL','');
+			this.addFlashVar(fv,'buttonWidth',500);
+			this.addFlashVar(fv,'buttonHeight',500);
+			this.addFlashVar(fv,'buttonText','');
+			this.addFlashVar(fv,'buttonTextTopPadding',0);
+			this.addFlashVar(fv,'buttonTextLeftPadding',0);
+			this.addFlashVar(fv,'buttonTextStyle','');
+			this.addFlashVar(fv,'buttonAction',this.params.upload_limit == 1 ? -100 : -110);
+			this.addFlashVar(fv,'buttonDisabled',false);
+			this.addFlashVar(fv,'buttonCursor',-2);
+			this.addFlashVar(fv,'button_window_mode','window');
+			
+			// Create SWFUpload Instance
+			this.flashBind();
+			
+			// Flash object
+			var flash =
+			'<object id="' + this.params.movie_name + '" data="' + this.params.flash_movie + '" ' +
+			'type="application/x-shockwave-flash" width="10" height="10">' +
+			'<param name="movie" value="' + this.params.flash_movie + '" />'+
+			'<param name="wmode" value="transparent" />'+
+			'<param name="menu" value="false" />'+
+			'<param name="allowScriptAccess" value="always" />'+
+			'<param name="flashvars" value="' + fv.join('&amp;') + '" />'+
+			'</object>';
+			
+			// Flash container
+			this.container = $('<span></span>');
+			if (this.params.target_element == null) {
+				this.container.css({
+					display: 'block',
+					position: 'absolute',
+					left: $(document).scrollLeft()+'px',
+					top: $(document).scrollTop()+'px',
+					width: '30px',
+					height: '30px',
+					background: '#f00'
+				});
+				
+				$('body').append(this.container);
+			} else {
+				$(this.params.target_element).append(this.container);
+				this.container.css({
+					display: 'block',
+					position: 'absolute',
+					top: 0,
+					left: 0,
+					zIndex: 1
+				});
+			}
+			this.container[0].innerHTML = flash;
+			this.movie = document.getElementById(this.params.movie_name);
+			
+			return this;
+		},
+		
+		addFlashVar: function(fv,n,v) {
+			if (v != null) {
+				fv.push(n + '=' + encodeURIComponent(v));
+			}
+		},
+		
+		// Bind flash events to callbacks.events
+		flashBind: function() {
+			_this = this;
+			var events = {
+				flashReady: function() {
+					if (window[_this.params.movie_name] == undefined) {
+						window[_this.params.movie_name] = _this.movie;
+					}
+					_this.flashBindEvent('flashReady',arguments);
+				},
+				fileDialogComplete: function() { _this.flashBindEvent('fileDialogComplete',arguments); },
+				fileDialogStart: function() { _this.flashBindEvent('fileDialogStart',arguments); },
+				fileQueued: function(file_object) { _this.flashBindEvent('fileQueued',arguments); },
+				fileQueueError: function(file_object,error_code,error_msg) { _this.flashBindEvent('fileQueueError',arguments); },
+				uploadStart: function() { _this.flashBindEvent('uploadStart',arguments); },
+				uploadProgress: function() { _this.flashBindEvent('uploadProgress',arguments); },
+				uploadError: function() { _this.flashBindEvent('uploadError',arguments); },
+				uploadSuccess: function() { _this.flashBindEvent('uploadSuccess',arguments); },
+				uploadComplete: function() { _this.flashBindEvent('uploadComplete',arguments); },
+				debug: function() { _this.flashBindEvent('debug',arguments); }
+			};
+			window.SWFUpload.instances[this.params.movie_name] = events;
+			window.SWFUpload.movieCount++;
+		},
+		
+		// Each flash event is called as callbacks.events([arg],...) with this = uploader object
+		flashEventQueue: [],
+		flashBindEvent: function(evt,a) {
+			a = a || new Array();
+			
+			var _this = this;
+			if ($.isFunction(this.callbacks[evt])) {
+				// Queue the event
+				this.flashEventQueue.push(function () {
+						this.callbacks[evt].apply(this,a);
+				});
+				
+				// Execute the next queued event
+				setTimeout(function () {
+					_this.flashExecuteNextEvent();
+				},0);
+			} else if (this.callbacks[evt] !== null) {
+				throw 'Event handler ' + evt + ' is unknown or is not a function';
+			}
+
+		},
+		flashExecuteNextEvent: function() {
+			var f = this.flashEventQueue ? this.flashEventQueue.shift() : null;
+			if ($.isFunction(f)) {
+				f.apply(this);
+			}
+		},
+		
+		destroy: function() {
+			try {
+				this.StopUpload();
+				$(this.movie).remove();
+				SWFUpload.instances[this.params.movie_name] = null;
+				SWFUpload.movieCount--;
+				delete SWFUpload.instances[this.movieName];
+				delete window[this.movieName];
+				
+				return true;
+			} catch(e) {
+				return false;
+			}
+		},
+		
+		// Flash uploader functions
+		StartUpload: function(file_id) {
+			return this.movie.StartUpload(file_id);
+		},
+		ReturnUploadStart: function(value) {
+			return this.movie.ReturnUploadStart(value);
+		},
+		StopUpload: function() {
+			return this.movie.StopUpload();
+		},
+		CancelUpload: function(file_id) {
+			return this.movie.CancelUpload(file_id);
+		},
+		GetStats: function() {
+			return this.movie.GetStats();
+		},
+		SetStats: function(stats) {
+			return this.movie.SetStats(stats);
+		},
+		GetFile: function(file_id) {
+			return this.movie.GetFile(file_id);
+		},
+		GetFileByIndex: function(file_index) {
+			return this.movie.GetFileByIndex(file_index);
+		},
+		
+		// Size formater, that's better
+		getFileSizeLimit: function(size) {
+			var value = 0;
+			var unit = 'kb';
+			
+			size = $.trim(size.toLowerCase());
+			
+			var values = size.match(/^\d+/);
+			if (values != null && values.length > 0) {
+				value = parseInt(values[0]);
+			}
+			
+			var units = size.match(/(b|kb|mb|gb)/);
+			if (units != null && units.length > 0) {
+				unit = units[0];
+			}
+			
+			var multiplier = 1024;
+			if (unit === "b") {
+				multiplier = 1;
+			} else if (unit === "mb") {
+				multiplier = 1048576;
+			} else if (unit === "gb") {
+				multiplier = 1073741824;
+			}
+			
+			return value * multiplier;
+		}
+	};
+})(jQuery);
+
+(function($) {
+	$.fn.candyUpload = function(settings,callbacks) {
+		new $._candyUpload(this,settings,callbacks);
+		return this;
+	};
+	
+	$._candyUpload = function(target,settings,callbacks) {
+		var defaults = {
+			debug: false,
+			upload_url: '',
+			params: null,
+			flash_movie: '',
+			file_types: '*.*',
+			file_types_description: 'All files',
+			file_size_limit: 0,
+			file_upload_limit: 0,
+			file_queue_limit: -1,
+			
+			callbacks: {} // Put here all callbacks you want, named as in $.uploader events
+		};
+		this.params = $.extend(defaults,settings);
+		this.params.movie_name = 'SWFU-' + (window.SWFUpload.instances.length + 1);
+		this.target = target;
+		
+		// Create controls
+		this.createControls();
+		
+		this.target.hide().after(this.ctrl.block).hide();
+		this.params.target_element = this.ctrl.btn_browse.parent().get(0);
+		
+		// Uploader init
+		var _this = this;
+		this.upldr = $.uploader(this.params,{
+			debug: function(msg) {
+				$('body').append('<pre class="debug">' + msg + '</pre>');
+				_this.bindEvent('debug',arguments);
+			},
+			flashReady: function() {
+				_this.initControls(this);
+				_this.bindEvent('flashReady',arguments);
+				
+				this.movie.style.width = _this.ctrl.btn_browse.width()+'px';
+				this.movie.style.height = _this.ctrl.btn_browse.height()+'px';
+			},
+			fileDialogComplete: function(num_ref_files,num_queue_files) {
+				_this.bindEvent('fileDialogComplete',arguments);
+			},
+			fileDialogStart: function() {
+				_this.bindEvent('fileQueued',arguments);
+			},
+			fileQueued: function(o) {
+				_this.appendFile(this,o);
+				_this.refreshControls(this);
+				_this.bindEvent('fileQueued',arguments);
+			},
+			fileQueueError: function(o,code,msg) {
+				var codes = window.SWFUpload.QUEUE_ERROR;
+				switch (code) {
+					case codes.QUEUE_LIMIT_EXCEEDED:
+						_this.queueErrorMsg(_this.locales.limit_exceeded);
+						break;
+					case codes.FILE_EXCEEDS_SIZE_LIMIT:
+						_this.queueErrorMsg(_this.locales.size_limit_exceeded);
+						break;
+					case codes.ZERO_BYTE_FILE:
+					case codes.INVALID_FILETYPE:
+						_this.queueErrorMsg(msg);
+						break;
+				}
+				_this.bindEvent('fileQueueError',arguments);
+			},
+			uploadStart: function() {
+				this.ReturnUploadStart(true);
+				_this.bindEvent('uploadStart',arguments);
+			},
+			uploadProgress: function(o,bytes,total) {
+				_this.fileProgressBar(o.id,bytes,total);
+				_this.bindEvent('uploadProgress',arguments);
+			},
+			uploadError: function(o,code,msg) {
+				var codes = window.SWFUpload.UPLOAD_ERROR;
+				switch (code) {
+					case codes.FILE_CANCELLED:
+						_this.fileErrorMsg(o.id,_this.locales.canceled);
+						break;
+					case codes.HTTP_ERROR:
+						_this.fileErrorMsg(o.id,_this.locales.http_error + ' ' + msg);
+						break;
+					case codes.MISSING_UPLOAD_URL:
+					case codes.IO_ERROR:
+					case codes.SECURITY_ERROR:
+					case codes.UPLOAD_LIMIT_EXCEEDED:
+					case codes.UPLOAD_FAILED:
+					case codes.SPECIFIED_FILE_ID_NOT_FOUND:
+					case codes.FILE_VALIDATION_FAILED:
+					case codes.FILE_CANCELLED:
+					case codes.UPLOAD_STOPPED:
+						_this.fileErrorMsg(o.id,_this.locales.error + ' ' + msg);
+						break;
+				}
+				_this.refreshControls(this);
+				_this.removeFileCancel(o);
+				_this.bindEvent('uploadError',arguments);
+			},
+			uploadSuccess: function(o,data) {
+				_this.fileProgressBar(o.id,1,1);
+				_this.refreshControls(this);
+				_this.removeFileCancel(o);
+				_this.bindEvent('uploadSuccess',arguments);
+			},
+			uploadComplete: function(o) {
+				// Once completed, start next queued upload
+				this.StartUpload();
+				_this.refreshControls(this);
+				_this.bindEvent('uploadComplete',arguments);
+			}
+		});
+	};
+	
+	$._candyUpload.prototype = {
+		locales: {
+			max_file_size: 'Maximum file size allowed:',
+			limit_exceeded: 'Limit exceeded.',
+			size_limit_exceeded: 'File size exceeds allowed limit.',
+			canceled: 'Canceled.',
+			http_error: 'HTTP Error:',
+			error: 'Error:',
+			choose_file: 'Choose file',
+			choose_files: 'Choose files',
+			cancel: 'Cancel',
+			clean: 'Clean',
+			upload: 'Upload',
+			no_file_in_queue: 'No file in queue.',
+			file_in_queue: '1 file in queue.',
+			files_in_queue: '%d files in queue.',
+			queue_error: 'Queue error:'
+		},
+		ctrl: {
+			block: $('<div class="cu-ctrl"></div>'),
+			files: null
+		},
+		
+		createControls: function() {
+			this.ctrl.btn_browse = $('<a href="#">&nbsp;</a>').click(function() {
+				return false;
+			});
+			
+			this.ctrl.btn_cancel = $('<a href="#">' + this.locales.cancel + '</a>').click(function() {
+				return false;
+			});
+			
+			this.ctrl.btn_clean = $('<a href="#">' + this.locales.clean + '</a>').click(function() {
+				return false;
+			});
+			
+			this.ctrl.btn_upload = $('<a href="#">' + this.locales.upload + '</a>').click(function() {
+				return false;
+			});
+			
+			this.ctrl.msg = $('<div class="cu-msg">' + this.locales.no_file_in_queue + '</div>').appendTo(this.ctrl.block);
+			
+			var btn = $('<div class="cu-btn"></div>').appendTo(this.ctrl.block);
+			var brw = $('<span class="cu-btn-browse"></span>').append(this.ctrl.btn_browse).appendTo(btn);
+			$('<span class="cu-btn-upload"></span>').append(this.ctrl.btn_upload).appendTo(btn).hide();
+			$('<span class="cu-btn-cancel"></span>').append(this.ctrl.btn_cancel).appendTo(btn).hide();
+			$('<span class="cu-btn-clean"></span>').append(this.ctrl.btn_clean).appendTo(btn).hide();
+			
+			this.bindEvent('createControls');
+		},
+		
+		initControls: function(upldr) {
+			if (this.params.file_queue_limit == 1) {
+				this.ctrl.btn_browse.text(this.locales.choose_file);
+			} else {
+				this.ctrl.btn_browse.text(this.locales.choose_files);
+			}
+			
+			var _this = this;
+			
+			this.ctrl.btn_cancel.click(function() {
+				_this.cancelQueue(upldr);
+				return false;
+			});
+			
+			this.ctrl.btn_clean.click(function() {
+				_this.cleanQueue(upldr);
+				return false;
+			});
+			
+			this.ctrl.btn_upload.click(function() {
+				_this.uploadQueue(upldr);
+				return false;
+			});
+			
+			var size = this.formatSize(upldr.params.file_size_limit);
+			$('<div class="cu-maxsize">' + this.locales.max_file_size + ' ' + size + '</div>').appendTo(this.ctrl.block);
+		},
+		
+		refreshControls: function(upldr) {
+			if (!this.ctrl.files || this.ctrl.files.length == 0) {
+				return;
+			}
+			
+			var stats = upldr.GetStats();
+			
+			if (stats.files_queued > 0) {
+				this.ctrl.btn_cancel.parent().show();
+				this.ctrl.btn_upload.parent().show();
+				if (this.params.file_queue_limit > 0 && this.params.file_queue_limit == stats.files_queued) {
+					this.ctrl.btn_browse.hide();
+				} else {
+					this.ctrl.btn_browse.show();
+				}
+				if (stats.files_queued > 1) {
+					var msg = this.locales.files_in_queue.replace(/%d/,stats.files_queued);
+				} else {
+					var msg = this.locales.file_in_queue;
+				}
+			} else {
+				this.ctrl.btn_browse.show();
+				this.ctrl.btn_cancel.parent().hide();
+				this.ctrl.btn_upload.parent().hide();
+				var msg = this.locales.no_file_in_queue;
+			}
+			
+			this.ctrl.msg.removeClass('cu-error').text(msg);
+			
+			if (stats.successful_uploads > 0 || stats.upload_errors > 0 || stats.upload_cancelled > 0) {
+				this.ctrl.btn_clean.parent().show();
+			} else {
+				this.ctrl.btn_clean.parent().hide();
+			}
+		},
+		
+		removeFileCancel: function(o) {
+			$('#' + o.id + ' span.cu-filecancel',this.ctrl.files).remove();
+		},
+		
+		appendFile: function(upldr,o) {
+			if (!this.ctrl.files) {
+				this.ctrl.files = $('<div class="cu-files"></div>');
+				this.ctrl.msg.after(this.ctrl.files);
+			}
+			
+			var fileblock = $('<div class="cu-file" id="' + o.id + '">' +
+					'<div class="cu-fileinfo"><span class="cu-filename">' + o.name + '</span> ' + 
+					'<span class="cu-filesize">(' + this.formatSize(o.size) + ')</span> ' +
+					'<span class="cu-filecancel"><a href="#">cancel</a></span> ' +
+					'<span class="cu-filemsg"></span>' +
+					'</div>');
+			
+			$('span.cu-filecancel a',fileblock).click(function() {
+				upldr.CancelUpload(o.id);
+				return false;
+			});
+			this.ctrl.files.append(fileblock);
+		},
+		
+		fileProgressBar: function(file_id,bytes,total) {
+			var bar = $('#' + file_id + ' div.cu-progress>div',this.ctrl.files);
+			if (bar.length == 0) {
+				$('#' + file_id,this.ctrl.files).append('<div class="cu-progress"><div>&nbsp;</div></div>');
+				bar = $('#' + file_id + ' div.cu-progress>div',this.ctrl.files);
+			}
+			
+			var percent = Math.round((bytes * 100) / total);
+			bar.css('width',percent+'%').text(percent + '%');
+		},
+		
+		fileMsg: function(file_id,msg,error) {
+			error = error || false;
+			var span = $('#' + file_id + ' span.cu-filemsg',this.ctrl.files).attr('class','cu-filemsg');
+			if (error) {
+				span.addClass('cu-error');
+			}
+			span.text(msg);
+		},
+		
+		fileErrorMsg: function(file_id,msg) {
+			this.fileMsg(file_id,msg,true);
+		},
+		
+		cancelQueue: function(upldr) {
+			if (!this.ctrl.files || this.ctrl.files.length == 0) {
+				return;
+			}
+			
+			this.ctrl.files.children('div').each(function() {
+				upldr.CancelUpload(this.id);
+			});
+		},
+		
+		uploadQueue: function(upldr) {
+			if (!this.ctrl.files || this.ctrl.files.length == 0) {
+				return;
+			}
+			
+			upldr.StartUpload();
+		},
+		
+		cleanQueue: function(upldr) {
+			var _this = this;
+			var e = $('div.cu-file',this.ctrl.files).not(':has(span.cu-filecancel a)');
+			
+			e.filter(':last').slideUp(200,function() {
+				$(this).remove();
+				if (e.length == 1) {
+					upldr.SetStats({successful_uploads:0, upload_errors:0, upload_cancelled:0});
+					_this.refreshControls(upldr);
+				} else if (e.length > 1) {
+					_this.cleanQueue(upldr);
+				}
+			});
+		},
+		
+		queueErrorMsg: function(msg) {
+			this.ctrl.msg.addClass('cu-error').text(this.locales.queue_error + ' ' + msg);
+		},
+		
+		formatSize: function(s) {
+			var a_size = Array('B', 'KB', 'MB', 'GB', 'TB');
+			var i_index = 0;
+			while (s > 1024) {
+				i_index++;
+				s/=1024;
+			}
+			return (Math.round(s * 100) /100) + ' ' + a_size[i_index];
+		},
+		
+		bindEvent: function(evt,a) {
+			if (this.params.callbacks[evt] != undefined && $.isFunction(this.params.callbacks[evt])) {
+				a = a || new Array();
+				this.params.callbacks[evt].apply(this,a);
+			}
+		}
+	};
+})(jQuery);
Index: admin/js/jquery/jquery.js
===================================================================
--- admin/js/jquery/jquery.js	(revision 3528)
+++ admin/js/jquery/jquery.js	(revision 0)
@@ -1,107 +1,200 @@
 /*!
- * jQuery JavaScript Library v2.2.4
+ * jQuery JavaScript Library v1.4.2
  * http://jquery.com/
+ *
+ * Copyright 2010, John Resig
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
  *
  * Includes Sizzle.js
  * http://sizzlejs.com/
+ * Copyright 2010, The Dojo Foundation
+ * Released under the MIT, BSD, and GPL Licenses.
  *
- * Copyright jQuery Foundation and other contributors
- * Released under the MIT license
- * http://jquery.org/license
- *
- * Date: 2016-05-20T17:23Z
+ * Date: Sat Feb 13 22:33:48 2010 -0500
  */
-
-(function( global, factory ) {
-
-	if ( typeof module === "object" && typeof module.exports === "object" ) {
-		// For CommonJS and CommonJS-like environments where a proper `window`
-		// is present, execute the factory and get jQuery.
-		// For environments that do not have a `window` with a `document`
-		// (such as Node.js), expose a factory as module.exports.
-		// This accentuates the need for the creation of a real `window`.
-		// e.g. var jQuery = require("jquery")(window);
-		// See ticket #14549 for more info.
-		module.exports = global.document ?
-			factory( global, true ) :
-			function( w ) {
-				if ( !w.document ) {
-					throw new Error( "jQuery requires a window with a document" );
-				}
-				return factory( w );
-			};
-	} else {
-		factory( global );
-	}
-
-// Pass this if window is not defined yet
-}(typeof window !== "undefined" ? window : this, function( window, noGlobal ) {
-
-// Support: Firefox 18+
-// Can't be in strict mode, several libs including ASP.NET trace
-// the stack via arguments.caller.callee and Firefox dies if
-// you try to trace through "use strict" call chains. (#13335)
-//"use strict";
-var arr = [];
-
-var document = window.document;
-
-var slice = arr.slice;
-
-var concat = arr.concat;
-
-var push = arr.push;
-
-var indexOf = arr.indexOf;
-
-var class2type = {};
-
-var toString = class2type.toString;
-
-var hasOwn = class2type.hasOwnProperty;
-
-var support = {};
-
-
-
-var
-	version = "2.2.4",
-
-	// Define a local copy of jQuery
-	jQuery = function( selector, context ) {
-
+(function( window, undefined ) {
+
+// Define a local copy of jQuery
+var jQuery = function( selector, context ) {
 		// The jQuery object is actually just the init constructor 'enhanced'
-		// Need init if jQuery is called (just allow error to be thrown if not included)
 		return new jQuery.fn.init( selector, context );
 	},
 
-	// Support: Android<4.1
-	// Make sure we trim BOM and NBSP
-	rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,
-
-	// Matches dashed string for camelizing
-	rmsPrefix = /^-ms-/,
-	rdashAlpha = /-([\da-z])/gi,
-
-	// Used by jQuery.camelCase as callback to replace()
-	fcamelCase = function( all, letter ) {
-		return letter.toUpperCase();
-	};
+	// Map over jQuery in case of overwrite
+	_jQuery = window.jQuery,
+
+	// Map over the $ in case of overwrite
+	_$ = window.$,
+
+	// Use the correct document accordingly with window argument (sandbox)
+	document = window.document,
+
+	// A central reference to the root jQuery(document)
+	rootjQuery,
+
+	// A simple way to check for HTML strings or ID strings
+	// (both of which we optimize for)
+	quickExpr = /^[^<]*(<[\w\W]+>)[^>]*$|^#([\w-]+)$/,
+
+	// Is it a simple selector
+	isSimple = /^.[^:#\[\.,]*$/,
+
+	// Check if a string has a non-whitespace character in it
+	rnotwhite = /\S/,
+
+	// Used for trimming whitespace
+	rtrim = /^(\s|\u00A0)+|(\s|\u00A0)+$/g,
+
+	// Match a standalone tag
+	rsingleTag = /^<(\w+)\s*\/?>(?:<\/\1>)?$/,
+
+	// Keep a UserAgent string for use with jQuery.browser
+	userAgent = navigator.userAgent,
+
+	// For matching the engine and version of the browser
+	browserMatch,
+	
+	// Has the ready events already been bound?
+	readyBound = false,
+	
+	// The functions to execute on DOM ready
+	readyList = [],
+
+	// The ready event handler
+	DOMContentLoaded,
+
+	// Save a reference to some core methods
+	toString = Object.prototype.toString,
+	hasOwnProperty = Object.prototype.hasOwnProperty,
+	push = Array.prototype.push,
+	slice = Array.prototype.slice,
+	indexOf = Array.prototype.indexOf;
 
 jQuery.fn = jQuery.prototype = {
-
-	// The current version of jQuery being used
-	jquery: version,
-
-	constructor: jQuery,
+	init: function( selector, context ) {
+		var match, elem, ret, doc;
+
+		// Handle $(""), $(null), or $(undefined)
+		if ( !selector ) {
+			return this;
+		}
+
+		// Handle $(DOMElement)
+		if ( selector.nodeType ) {
+			this.context = this[0] = selector;
+			this.length = 1;
+			return this;
+		}
+		
+		// The body element only exists once, optimize finding it
+		if ( selector === "body" && !context ) {
+			this.context = document;
+			this[0] = document.body;
+			this.selector = "body";
+			this.length = 1;
+			return this;
+		}
+
+		// Handle HTML strings
+		if ( typeof selector === "string" ) {
+			// Are we dealing with HTML string or an ID?
+			match = quickExpr.exec( selector );
+
+			// Verify a match, and that no context was specified for #id
+			if ( match && (match[1] || !context) ) {
+
+				// HANDLE: $(html) -> $(array)
+				if ( match[1] ) {
+					doc = (context ? context.ownerDocument || context : document);
+
+					// If a single string is passed in and it's a single tag
+					// just do a createElement and skip the rest
+					ret = rsingleTag.exec( selector );
+
+					if ( ret ) {
+						if ( jQuery.isPlainObject( context ) ) {
+							selector = [ document.createElement( ret[1] ) ];
+							jQuery.fn.attr.call( selector, context, true );
+
+						} else {
+							selector = [ doc.createElement( ret[1] ) ];
+						}
+
+					} else {
+						ret = buildFragment( [ match[1] ], [ doc ] );
+						selector = (ret.cacheable ? ret.fragment.cloneNode(true) : ret.fragment).childNodes;
+					}
+					
+					return jQuery.merge( this, selector );
+					
+				// HANDLE: $("#id")
+				} else {
+					elem = document.getElementById( match[2] );
+
+					if ( elem ) {
+						// Handle the case where IE and Opera return items
+						// by name instead of ID
+						if ( elem.id !== match[2] ) {
+							return rootjQuery.find( selector );
+						}
+
+						// Otherwise, we inject the element directly into the jQuery object
+						this.length = 1;
+						this[0] = elem;
+					}
+
+					this.context = document;
+					this.selector = selector;
+					return this;
+				}
+
+			// HANDLE: $("TAG")
+			} else if ( !context && /^\w+$/.test( selector ) ) {
+				this.selector = selector;
+				this.context = document;
+				selector = document.getElementsByTagName( selector );
+				return jQuery.merge( this, selector );
+
+			// HANDLE: $(expr, $(...))
+			} else if ( !context || context.jquery ) {
+				return (context || rootjQuery).find( selector );
+
+			// HANDLE: $(expr, context)
+			// (which is just equivalent to: $(context).find(expr)
+			} else {
+				return jQuery( context ).find( selector );
+			}
+
+		// HANDLE: $(function)
+		// Shortcut for document ready
+		} else if ( jQuery.isFunction( selector ) ) {
+			return rootjQuery.ready( selector );
+		}
+
+		if (selector.selector !== undefined) {
+			this.selector = selector.selector;
+			this.context = selector.context;
+		}
+
+		return jQuery.makeArray( selector, this );
+	},
 
 	// Start with an empty selector
 	selector: "",
 
+	// The current version of jQuery being used
+	jquery: "1.4.2",
+
 	// The default length of a jQuery object is 0
 	length: 0,
 
+	// The number of elements contained in the matched element set
+	size: function() {
+		return this.length;
+	},
+
 	toArray: function() {
-		return slice.call( this );
+		return slice.call( this, 0 );
 	},
 
@@ -109,23 +202,36 @@
 	// Get the whole matched element set as a clean array
 	get: function( num ) {
-		return num != null ?
-
-			// Return just the one element from the set
-			( num < 0 ? this[ num + this.length ] : this[ num ] ) :
-
-			// Return all the elements in a clean array
-			slice.call( this );
+		return num == null ?
+
+			// Return a 'clean' array
+			this.toArray() :
+
+			// Return just the object
+			( num < 0 ? this.slice(num)[ 0 ] : this[ num ] );
 	},
 
 	// Take an array of elements and push it onto the stack
 	// (returning the new matched element set)
-	pushStack: function( elems ) {
-
+	pushStack: function( elems, name, selector ) {
 		// Build a new jQuery matched element set
-		var ret = jQuery.merge( this.constructor(), elems );
+		var ret = jQuery();
+
+		if ( jQuery.isArray( elems ) ) {
+			push.apply( ret, elems );
+		
+		} else {
+			jQuery.merge( ret, elems );
+		}
 
 		// Add the old object onto the stack (as a reference)
 		ret.prevObject = this;
+
 		ret.context = this.context;
+
+		if ( name === "find" ) {
+			ret.selector = this.selector + (this.selector ? " " : "") + selector;
+		} else if ( name ) {
+			ret.selector = this.selector + "." + name + "(" + selector + ")";
+		}
 
 		// Return the newly-formed element set
@@ -134,16 +240,32 @@
 
 	// Execute a callback for every element in the matched set.
-	each: function( callback ) {
-		return jQuery.each( this, callback );
-	},
-
-	map: function( callback ) {
-		return this.pushStack( jQuery.map( this, function( elem, i ) {
-			return callback.call( elem, i, elem );
-		} ) );
-	},
-
-	slice: function() {
-		return this.pushStack( slice.apply( this, arguments ) );
+	// (You can seed the arguments with an array of args, but this is
+	// only used internally.)
+	each: function( callback, args ) {
+		return jQuery.each( this, callback, args );
+	},
+	
+	ready: function( fn ) {
+		// Attach the listeners
+		jQuery.bindReady();
+
+		// If the DOM is already ready
+		if ( jQuery.isReady ) {
+			// Execute the function immediately
+			fn.call( document, jQuery );
+
+		// Otherwise, remember the function for later
+		} else if ( readyList ) {
+			// Add the function to the wait list
+			readyList.push( fn );
+		}
+
+		return this;
+	},
+	
+	eq: function( i ) {
+		return i === -1 ?
+			this.slice( i ) :
+			this.slice( i, +i + 1 );
 	},
 
@@ -156,12 +278,17 @@
 	},
 
-	eq: function( i ) {
-		var len = this.length,
-			j = +i + ( i < 0 ? len : 0 );
-		return this.pushStack( j >= 0 && j < len ? [ this[ j ] ] : [] );
-	},
-
+	slice: function() {
+		return this.pushStack( slice.apply( this, arguments ),
+			"slice", slice.call(arguments).join(",") );
+	},
+
+	map: function( callback ) {
+		return this.pushStack( jQuery.map(this, function( elem, i ) {
+			return callback.call( elem, i, elem );
+		}));
+	},
+	
 	end: function() {
-		return this.prevObject || this.constructor();
+		return this.prevObject || jQuery(null);
 	},
 
@@ -169,40 +296,37 @@
 	// Behaves like an Array's method, not like a jQuery method.
 	push: push,
-	sort: arr.sort,
-	splice: arr.splice
+	sort: [].sort,
+	splice: [].splice
 };
 
+// Give the init function the jQuery prototype for later instantiation
+jQuery.fn.init.prototype = jQuery.fn;
+
 jQuery.extend = jQuery.fn.extend = function() {
-	var options, name, src, copy, copyIsArray, clone,
-		target = arguments[ 0 ] || {},
-		i = 1,
-		length = arguments.length,
-		deep = false;
+	// copy reference to target object
+	var target = arguments[0] || {}, i = 1, length = arguments.length, deep = false, options, name, src, copy;
 
 	// Handle a deep copy situation
 	if ( typeof target === "boolean" ) {
 		deep = target;
-
-		// Skip the boolean and the target
-		target = arguments[ i ] || {};
-		i++;
+		target = arguments[1] || {};
+		// skip the boolean and the target
+		i = 2;
 	}
 
 	// Handle case when target is a string or something (possible in deep copy)
-	if ( typeof target !== "object" && !jQuery.isFunction( target ) ) {
+	if ( typeof target !== "object" && !jQuery.isFunction(target) ) {
 		target = {};
 	}
 
-	// Extend jQuery itself if only one argument is passed
-	if ( i === length ) {
+	// extend jQuery itself if only one argument is passed
+	if ( length === i ) {
 		target = this;
-		i--;
+		--i;
 	}
 
 	for ( ; i < length; i++ ) {
-
 		// Only deal with non-null/undefined values
-		if ( ( options = arguments[ i ] ) != null ) {
-
+		if ( (options = arguments[ i ]) != null ) {
 			// Extend the base object
 			for ( name in options ) {
@@ -215,15 +339,8 @@
 				}
 
-				// Recurse if we're merging plain objects or arrays
-				if ( deep && copy && ( jQuery.isPlainObject( copy ) ||
-					( copyIsArray = jQuery.isArray( copy ) ) ) ) {
-
-					if ( copyIsArray ) {
-						copyIsArray = false;
-						clone = src && jQuery.isArray( src ) ? src : [];
-
-					} else {
-						clone = src && jQuery.isPlainObject( src ) ? src : {};
-					}
+				// Recurse if we're merging object literal values or arrays
+				if ( deep && copy && ( jQuery.isPlainObject(copy) || jQuery.isArray(copy) ) ) {
+					var clone = src && ( jQuery.isPlainObject(src) || jQuery.isArray(src) ) ? src
+						: jQuery.isArray(copy) ? [] : {};
 
 					// Never move original objects, clone them
@@ -242,159 +359,246 @@
 };
 
-jQuery.extend( {
-
-	// Unique for each copy of jQuery on the page
-	expando: "jQuery" + ( version + Math.random() ).replace( /\D/g, "" ),
-
-	// Assume jQuery is ready without the ready module
-	isReady: true,
-
+jQuery.extend({
+	noConflict: function( deep ) {
+		window.$ = _$;
+
+		if ( deep ) {
+			window.jQuery = _jQuery;
+		}
+
+		return jQuery;
+	},
+	
+	// Is the DOM ready to be used? Set to true once it occurs.
+	isReady: false,
+	
+	// Handle when the DOM is ready
+	ready: function() {
+		// Make sure that the DOM is not already loaded
+		if ( !jQuery.isReady ) {
+			// Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443).
+			if ( !document.body ) {
+				return setTimeout( jQuery.ready, 13 );
+			}
+
+			// Remember that the DOM is ready
+			jQuery.isReady = true;
+
+			// If there are functions bound, to execute
+			if ( readyList ) {
+				// Execute all of them
+				var fn, i = 0;
+				while ( (fn = readyList[ i++ ]) ) {
+					fn.call( document, jQuery );
+				}
+
+				// Reset the list of functions
+				readyList = null;
+			}
+
+			// Trigger any bound ready events
+			if ( jQuery.fn.triggerHandler ) {
+				jQuery( document ).triggerHandler( "ready" );
+			}
+		}
+	},
+	
+	bindReady: function() {
+		if ( readyBound ) {
+			return;
+		}
+
+		readyBound = true;
+
+		// Catch cases where $(document).ready() is called after the
+		// browser event has already occurred.
+		if ( document.readyState === "complete" ) {
+			return jQuery.ready();
+		}
+
+		// Mozilla, Opera and webkit nightlies currently support this event
+		if ( document.addEventListener ) {
+			// Use the handy event callback
+			document.addEventListener( "DOMContentLoaded", DOMContentLoaded, false );
+			
+			// A fallback to window.onload, that will always work
+			window.addEventListener( "load", jQuery.ready, false );
+
+		// If IE event model is used
+		} else if ( document.attachEvent ) {
+			// ensure firing before onload,
+			// maybe late but safe also for iframes
+			document.attachEvent("onreadystatechange", DOMContentLoaded);
+			
+			// A fallback to window.onload, that will always work
+			window.attachEvent( "onload", jQuery.ready );
+
+			// If IE and not a frame
+			// continually check to see if the document is ready
+			var toplevel = false;
+
+			try {
+				toplevel = window.frameElement == null;
+			} catch(e) {}
+
+			if ( document.documentElement.doScroll && toplevel ) {
+				doScrollCheck();
+			}
+		}
+	},
+
+	// See test/unit/core.js for details concerning isFunction.
+	// Since version 1.3, DOM methods and functions like alert
+	// aren't supported. They return false on IE (#2968).
+	isFunction: function( obj ) {
+		return toString.call(obj) === "[object Function]";
+	},
+
+	isArray: function( obj ) {
+		return toString.call(obj) === "[object Array]";
+	},
+
+	isPlainObject: function( obj ) {
+		// Must be an Object.
+		// Because of IE, we also have to check the presence of the constructor property.
+		// Make sure that DOM nodes and window objects don't pass through, as well
+		if ( !obj || toString.call(obj) !== "[object Object]" || obj.nodeType || obj.setInterval ) {
+			return false;
+		}
+		
+		// Not own constructor property must be Object
+		if ( obj.constructor
+			&& !hasOwnProperty.call(obj, "constructor")
+			&& !hasOwnProperty.call(obj.constructor.prototype, "isPrototypeOf") ) {
+			return false;
+		}
+		
+		// Own properties are enumerated firstly, so to speed up,
+		// if last one is own, then all properties are own.
+	
+		var key;
+		for ( key in obj ) {}
+		
+		return key === undefined || hasOwnProperty.call( obj, key );
+	},
+
+	isEmptyObject: function( obj ) {
+		for ( var name in obj ) {
+			return false;
+		}
+		return true;
+	},
+	
 	error: function( msg ) {
-		throw new Error( msg );
+		throw msg;
+	},
+	
+	parseJSON: function( data ) {
+		if ( typeof data !== "string" || !data ) {
+			return null;
+		}
+
+		// Make sure leading/trailing whitespace is removed (IE can't handle it)
+		data = jQuery.trim( data );
+		
+		// Make sure the incoming data is actual JSON
+		// Logic borrowed from http://json.org/json2.js
+		if ( /^[\],:{}\s]*$/.test(data.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, "@")
+			.replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, "]")
+			.replace(/(?:^|:|,)(?:\s*\[)+/g, "")) ) {
+
+			// Try to use the native JSON parser first
+			return window.JSON && window.JSON.parse ?
+				window.JSON.parse( data ) :
+				(new Function("return " + data))();
+
+		} else {
+			jQuery.error( "Invalid JSON: " + data );
+		}
 	},
 
 	noop: function() {},
 
-	isFunction: function( obj ) {
-		return jQuery.type( obj ) === "function";
-	},
-
-	isArray: Array.isArray,
-
-	isWindow: function( obj ) {
-		return obj != null && obj === obj.window;
-	},
-
-	isNumeric: function( obj ) {
-
-		// parseFloat NaNs numeric-cast false positives (null|true|false|"")
-		// ...but misinterprets leading-number strings, particularly hex literals ("0x...")
-		// subtraction forces infinities to NaN
-		// adding 1 corrects loss of precision from parseFloat (#15100)
-		var realStringObj = obj && obj.toString();
-		return !jQuery.isArray( obj ) && ( realStringObj - parseFloat( realStringObj ) + 1 ) >= 0;
-	},
-
-	isPlainObject: function( obj ) {
-		var key;
-
-		// Not plain objects:
-		// - Any object or value whose internal [[Class]] property is not "[object Object]"
-		// - DOM nodes
-		// - window
-		if ( jQuery.type( obj ) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) {
-			return false;
-		}
-
-		// Not own constructor property must be Object
-		if ( obj.constructor &&
-				!hasOwn.call( obj, "constructor" ) &&
-				!hasOwn.call( obj.constructor.prototype || {}, "isPrototypeOf" ) ) {
-			return false;
-		}
-
-		// Own properties are enumerated firstly, so to speed up,
-		// if last one is own, then all properties are own
-		for ( key in obj ) {}
-
-		return key === undefined || hasOwn.call( obj, key );
-	},
-
-	isEmptyObject: function( obj ) {
-		var name;
-		for ( name in obj ) {
-			return false;
-		}
-		return true;
-	},
-
-	type: function( obj ) {
-		if ( obj == null ) {
-			return obj + "";
-		}
-
-		// Support: Android<4.0, iOS<6 (functionish RegExp)
-		return typeof obj === "object" || typeof obj === "function" ?
-			class2type[ toString.call( obj ) ] || "object" :
-			typeof obj;
-	},
-
-	// Evaluates a script in a global context
-	globalEval: function( code ) {
-		var script,
-			indirect = eval;
-
-		code = jQuery.trim( code );
-
-		if ( code ) {
-
-			// If the code includes a valid, prologue position
-			// strict mode pragma, execute code by injecting a
-			// script tag into the document.
-			if ( code.indexOf( "use strict" ) === 1 ) {
-				script = document.createElement( "script" );
-				script.text = code;
-				document.head.appendChild( script ).parentNode.removeChild( script );
+	// Evalulates a script in a global context
+	globalEval: function( data ) {
+		if ( data && rnotwhite.test(data) ) {
+			// Inspired by code by Andrea Giammarchi
+			// http://webreflection.blogspot.com/2007/08/global-scope-evaluation-and-dom.html
+			var head = document.getElementsByTagName("head")[0] || document.documentElement,
+				script = document.createElement("script");
+
+			script.type = "text/javascript";
+
+			if ( jQuery.support.scriptEval ) {
+				script.appendChild( document.createTextNode( data ) );
 			} else {
-
-				// Otherwise, avoid the DOM node creation, insertion
-				// and removal by using an indirect global eval
-
-				indirect( code );
-			}
-		}
-	},
-
-	// Convert dashed to camelCase; used by the css and data modules
-	// Support: IE9-11+
-	// Microsoft forgot to hump their vendor prefix (#9572)
-	camelCase: function( string ) {
-		return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase );
+				script.text = data;
+			}
+
+			// Use insertBefore instead of appendChild to circumvent an IE6 bug.
+			// This arises when a base node is used (#2709).
+			head.insertBefore( script, head.firstChild );
+			head.removeChild( script );
+		}
 	},
 
 	nodeName: function( elem, name ) {
-		return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase();
-	},
-
-	each: function( obj, callback ) {
-		var length, i = 0;
-
-		if ( isArrayLike( obj ) ) {
-			length = obj.length;
-			for ( ; i < length; i++ ) {
-				if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) {
-					break;
-				}
-			}
+		return elem.nodeName && elem.nodeName.toUpperCase() === name.toUpperCase();
+	},
+
+	// args is for internal usage only
+	each: function( object, callback, args ) {
+		var name, i = 0,
+			length = object.length,
+			isObj = length === undefined || jQuery.isFunction(object);
+
+		if ( args ) {
+			if ( isObj ) {
+				for ( name in object ) {
+					if ( callback.apply( object[ name ], args ) === false ) {
+						break;
+					}
+				}
+			} else {
+				for ( ; i < length; ) {
+					if ( callback.apply( object[ i++ ], args ) === false ) {
+						break;
+					}
+				}
+			}
+
+		// A special, fast, case for the most common use of each
 		} else {
-			for ( i in obj ) {
-				if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) {
-					break;
-				}
-			}
-		}
-
-		return obj;
-	},
-
-	// Support: Android<4.1
+			if ( isObj ) {
+				for ( name in object ) {
+					if ( callback.call( object[ name ], name, object[ name ] ) === false ) {
+						break;
+					}
+				}
+			} else {
+				for ( var value = object[0];
+					i < length && callback.call( value, i, value ) !== false; value = object[++i] ) {}
+			}
+		}
+
+		return object;
+	},
+
 	trim: function( text ) {
-		return text == null ?
-			"" :
-			( text + "" ).replace( rtrim, "" );
+		return (text || "").replace( rtrim, "" );
 	},
 
 	// results is for internal usage only
-	makeArray: function( arr, results ) {
+	makeArray: function( array, results ) {
 		var ret = results || [];
 
-		if ( arr != null ) {
-			if ( isArrayLike( Object( arr ) ) ) {
-				jQuery.merge( ret,
-					typeof arr === "string" ?
-					[ arr ] : arr
-				);
+		if ( array != null ) {
+			// The window, strings (and functions) also have 'length'
+			// The extra typeof function check is to prevent crashes
+			// in Safari 2 (See: #3039)
+			if ( array.length == null || typeof array === "string" || jQuery.isFunction(array) || (typeof array !== "function" && array.setInterval) ) {
+				push.call( ret, array );
 			} else {
-				push.call( ret, arr );
+				jQuery.merge( ret, array );
 			}
 		}
@@ -403,15 +607,30 @@
 	},
 
-	inArray: function( elem, arr, i ) {
-		return arr == null ? -1 : indexOf.call( arr, elem, i );
+	inArray: function( elem, array ) {
+		if ( array.indexOf ) {
+			return array.indexOf( elem );
+		}
+
+		for ( var i = 0, length = array.length; i < length; i++ ) {
+			if ( array[ i ] === elem ) {
+				return i;
+			}
+		}
+
+		return -1;
 	},
 
 	merge: function( first, second ) {
-		var len = +second.length,
-			j = 0,
-			i = first.length;
-
-		for ( ; j < len; j++ ) {
-			first[ i++ ] = second[ j ];
+		var i = first.length, j = 0;
+
+		if ( typeof second.length === "number" ) {
+			for ( var l = second.length; j < l; j++ ) {
+				first[ i++ ] = second[ j ];
+			}
+		
+		} else {
+			while ( second[j] !== undefined ) {
+				first[ i++ ] = second[ j++ ];
+			}
 		}
 
@@ -421,53 +640,33 @@
 	},
 
-	grep: function( elems, callback, invert ) {
-		var callbackInverse,
-			matches = [],
-			i = 0,
-			length = elems.length,
-			callbackExpect = !invert;
+	grep: function( elems, callback, inv ) {
+		var ret = [];
 
 		// Go through the array, only saving the items
 		// that pass the validator function
-		for ( ; i < length; i++ ) {
-			callbackInverse = !callback( elems[ i ], i );
-			if ( callbackInverse !== callbackExpect ) {
-				matches.push( elems[ i ] );
-			}
-		}
-
-		return matches;
+		for ( var i = 0, length = elems.length; i < length; i++ ) {
+			if ( !inv !== !callback( elems[ i ], i ) ) {
+				ret.push( elems[ i ] );
+			}
+		}
+
+		return ret;
 	},
 
 	// arg is for internal usage only
 	map: function( elems, callback, arg ) {
-		var length, value,
-			i = 0,
-			ret = [];
-
-		// Go through the array, translating each of the items to their new values
-		if ( isArrayLike( elems ) ) {
-			length = elems.length;
-			for ( ; i < length; i++ ) {
-				value = callback( elems[ i ], i, arg );
-
-				if ( value != null ) {
-					ret.push( value );
-				}
-			}
-
-		// Go through every key on the object,
-		} else {
-			for ( i in elems ) {
-				value = callback( elems[ i ], i, arg );
-
-				if ( value != null ) {
-					ret.push( value );
-				}
-			}
-		}
-
-		// Flatten any nested arrays
-		return concat.apply( [], ret );
+		var ret = [], value;
+
+		// Go through the array, translating each of the items to their
+		// new value (or values).
+		for ( var i = 0, length = elems.length; i < length; i++ ) {
+			value = callback( elems[ i ], i, arg );
+
+			if ( value != null ) {
+				ret[ ret.length ] = value;
+			}
+		}
+
+		return ret.concat.apply( [], ret );
 	},
 
@@ -475,3581 +674,466 @@
 	guid: 1,
 
-	// Bind a function to a context, optionally partially applying any
-	// arguments.
-	proxy: function( fn, context ) {
-		var tmp, args, proxy;
-
-		if ( typeof context === "string" ) {
-			tmp = fn[ context ];
-			context = fn;
-			fn = tmp;
-		}
-
-		// Quick check to determine if target is callable, in the spec
-		// this throws a TypeError, but we will just return undefined.
-		if ( !jQuery.isFunction( fn ) ) {
-			return undefined;
-		}
-
-		// Simulated bind
-		args = slice.call( arguments, 2 );
-		proxy = function() {
-			return fn.apply( context || this, args.concat( slice.call( arguments ) ) );
-		};
+	proxy: function( fn, proxy, thisObject ) {
+		if ( arguments.length === 2 ) {
+			if ( typeof proxy === "string" ) {
+				thisObject = fn;
+				fn = thisObject[ proxy ];
+				proxy = undefined;
+
+			} else if ( proxy && !jQuery.isFunction( proxy ) ) {
+				thisObject = proxy;
+				proxy = undefined;
+			}
+		}
+
+		if ( !proxy && fn ) {
+			proxy = function() {
+				return fn.apply( thisObject || this, arguments );
+			};
+		}
 
 		// Set the guid of unique handler to the same of original handler, so it can be removed
-		proxy.guid = fn.guid = fn.guid || jQuery.guid++;
-
+		if ( fn ) {
+			proxy.guid = fn.guid = fn.guid || proxy.guid || jQuery.guid++;
+		}
+
+		// So proxy can be declared as an argument
 		return proxy;
 	},
 
-	now: Date.now,
-
-	// jQuery.support is not used in Core but other projects attach their
-	// properties to it so it needs to exist.
-	support: support
-} );
-
-// JSHint would error on this code due to the Symbol not being defined in ES5.
-// Defining this global in .jshintrc would create a danger of using the global
-// unguarded in another place, it seems safer to just disable JSHint for these
-// three lines.
-/* jshint ignore: start */
-if ( typeof Symbol === "function" ) {
-	jQuery.fn[ Symbol.iterator ] = arr[ Symbol.iterator ];
+	// Use of jQuery.browser is frowned upon.
+	// More details: http://docs.jquery.com/Utilities/jQuery.browser
+	uaMatch: function( ua ) {
+		ua = ua.toLowerCase();
+
+		var match = /(webkit)[ \/]([\w.]+)/.exec( ua ) ||
+			/(opera)(?:.*version)?[ \/]([\w.]+)/.exec( ua ) ||
+			/(msie) ([\w.]+)/.exec( ua ) ||
+			!/compatible/.test( ua ) && /(mozilla)(?:.*? rv:([\w.]+))?/.exec( ua ) ||
+		  	[];
+
+		return { browser: match[1] || "", version: match[2] || "0" };
+	},
+
+	browser: {}
+});
+
+browserMatch = jQuery.uaMatch( userAgent );
+if ( browserMatch.browser ) {
+	jQuery.browser[ browserMatch.browser ] = true;
+	jQuery.browser.version = browserMatch.version;
 }
-/* jshint ignore: end */
-
-// Populate the class2type map
-jQuery.each( "Boolean Number String Function Array Date RegExp Object Error Symbol".split( " " ),
-function( i, name ) {
-	class2type[ "[object " + name + "]" ] = name.toLowerCase();
-} );
-
-function isArrayLike( obj ) {
-
-	// Support: iOS 8.2 (not reproducible in simulator)
-	// `in` check used to prevent JIT error (gh-2145)
-	// hasOwn isn't used here due to false negatives
-	// regarding Nodelist length in IE
-	var length = !!obj && "length" in obj && obj.length,
-		type = jQuery.type( obj );
-
-	if ( type === "function" || jQuery.isWindow( obj ) ) {
-		return false;
-	}
-
-	return type === "array" || length === 0 ||
-		typeof length === "number" && length > 0 && ( length - 1 ) in obj;
+
+// Deprecated, use jQuery.browser.webkit instead
+if ( jQuery.browser.webkit ) {
+	jQuery.browser.safari = true;
 }
-var Sizzle =
-/*!
- * Sizzle CSS Selector Engine v2.2.1
- * http://sizzlejs.com/
- *
- * Copyright jQuery Foundation and other contributors
- * Released under the MIT license
- * http://jquery.org/license
- *
- * Date: 2015-10-17
- */
-(function( window ) {
-
-var i,
-	support,
-	Expr,
-	getText,
-	isXML,
-	tokenize,
-	compile,
-	select,
-	outermostContext,
-	sortInput,
-	hasDuplicate,
-
-	// Local document vars
-	setDocument,
-	document,
-	docElem,
-	documentIsHTML,
-	rbuggyQSA,
-	rbuggyMatches,
-	matches,
-	contains,
-
-	// Instance-specific data
-	expando = "sizzle" + 1 * new Date(),
-	preferredDoc = window.document,
-	dirruns = 0,
-	done = 0,
-	classCache = createCache(),
-	tokenCache = createCache(),
-	compilerCache = createCache(),
-	sortOrder = function( a, b ) {
-		if ( a === b ) {
-			hasDuplicate = true;
-		}
-		return 0;
-	},
-
-	// General-purpose constants
-	MAX_NEGATIVE = 1 << 31,
-
-	// Instance methods
-	hasOwn = ({}).hasOwnProperty,
-	arr = [],
-	pop = arr.pop,
-	push_native = arr.push,
-	push = arr.push,
-	slice = arr.slice,
-	// Use a stripped-down indexOf as it's faster than native
-	// http://jsperf.com/thor-indexof-vs-for/5
-	indexOf = function( list, elem ) {
-		var i = 0,
-			len = list.length;
-		for ( ; i < len; i++ ) {
-			if ( list[i] === elem ) {
-				return i;
-			}
-		}
-		return -1;
-	},
-
-	booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",
-
-	// Regular expressions
-
-	// http://www.w3.org/TR/css3-selectors/#whitespace
-	whitespace = "[\\x20\\t\\r\\n\\f]",
-
-	// http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier
-	identifier = "(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",
-
-	// Attribute selectors: http://www.w3.org/TR/selectors/#attribute-selectors
-	attributes = "\\[" + whitespace + "*(" + identifier + ")(?:" + whitespace +
-		// Operator (capture 2)
-		"*([*^$|!~]?=)" + whitespace +
-		// "Attribute values must be CSS identifiers [capture 5] or strings [capture 3 or capture 4]"
-		"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|(" + identifier + "))|)" + whitespace +
-		"*\\]",
-
-	pseudos = ":(" + identifier + ")(?:\\((" +
-		// To reduce the number of selectors needing tokenize in the preFilter, prefer arguments:
-		// 1. quoted (capture 3; capture 4 or capture 5)
-		"('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|" +
-		// 2. simple (capture 6)
-		"((?:\\\\.|[^\\\\()[\\]]|" + attributes + ")*)|" +
-		// 3. anything else (capture 2)
-		".*" +
-		")\\)|)",
-
-	// Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter
-	rwhitespace = new RegExp( whitespace + "+", "g" ),
-	rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g" ),
-
-	rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ),
-	rcombinators = new RegExp( "^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace + "*" ),
-
-	rattributeQuotes = new RegExp( "=" + whitespace + "*([^\\]'\"]*?)" + whitespace + "*\\]", "g" ),
-
-	rpseudo = new RegExp( pseudos ),
-	ridentifier = new RegExp( "^" + identifier + "$" ),
-
-	matchExpr = {
-		"ID": new RegExp( "^#(" + identifier + ")" ),
-		"CLASS": new RegExp( "^\\.(" + identifier + ")" ),
-		"TAG": new RegExp( "^(" + identifier + "|[*])" ),
-		"ATTR": new RegExp( "^" + attributes ),
-		"PSEUDO": new RegExp( "^" + pseudos ),
-		"CHILD": new RegExp( "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + whitespace +
-			"*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + whitespace +
-			"*(\\d+)|))" + whitespace + "*\\)|)", "i" ),
-		"bool": new RegExp( "^(?:" + booleans + ")$", "i" ),
-		// For use in libraries implementing .is()
-		// We use this for POS matching in `select`
-		"needsContext": new RegExp( "^" + whitespace + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" +
-			whitespace + "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" )
-	},
-
-	rinputs = /^(?:input|select|textarea|button)$/i,
-	rheader = /^h\d$/i,
-
-	rnative = /^[^{]+\{\s*\[native \w/,
-
-	// Easily-parseable/retrievable ID or TAG or CLASS selectors
-	rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,
-
-	rsibling = /[+~]/,
-	rescape = /'|\\/g,
-
-	// CSS escapes http://www.w3.org/TR/CSS21/syndata.html#escaped-characters
-	runescape = new RegExp( "\\\\([\\da-f]{1,6}" + whitespace + "?|(" + whitespace + ")|.)", "ig" ),
-	funescape = function( _, escaped, escapedWhitespace ) {
-		var high = "0x" + escaped - 0x10000;
-		// NaN means non-codepoint
-		// Support: Firefox<24
-		// Workaround erroneous numeric interpretation of +"0x"
-		return high !== high || escapedWhitespace ?
-			escaped :
-			high < 0 ?
-				// BMP codepoint
-				String.fromCharCode( high + 0x10000 ) :
-				// Supplemental Plane codepoint (surrogate pair)
-				String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 );
-	},
-
-	// Used for iframes
-	// See setDocument()
-	// Removing the function wrapper causes a "Permission Denied"
-	// error in IE
-	unloadHandler = function() {
-		setDocument();
-	};
-
-// Optimize for push.apply( _, NodeList )
-try {
-	push.apply(
-		(arr = slice.call( preferredDoc.childNodes )),
-		preferredDoc.childNodes
-	);
-	// Support: Android<4.0
-	// Detect silently failing push.apply
-	arr[ preferredDoc.childNodes.length ].nodeType;
-} catch ( e ) {
-	push = { apply: arr.length ?
-
-		// Leverage slice if possible
-		function( target, els ) {
-			push_native.apply( target, slice.call(els) );
-		} :
-
-		// Support: IE<9
-		// Otherwise append directly
-		function( target, els ) {
-			var j = target.length,
-				i = 0;
-			// Can't trust NodeList.length
-			while ( (target[j++] = els[i++]) ) {}
-			target.length = j - 1;
-		}
+
+if ( indexOf ) {
+	jQuery.inArray = function( elem, array ) {
+		return indexOf.call( array, elem );
 	};
 }
 
-function Sizzle( selector, context, results, seed ) {
-	var m, i, elem, nid, nidselect, match, groups, newSelector,
-		newContext = context && context.ownerDocument,
-
-		// nodeType defaults to 9, since context defaults to document
-		nodeType = context ? context.nodeType : 9;
-
-	results = results || [];
-
-	// Return early from calls with invalid selector or context
-	if ( typeof selector !== "string" || !selector ||
-		nodeType !== 1 && nodeType !== 9 && nodeType !== 11 ) {
-
-		return results;
-	}
-
-	// Try to shortcut find operations (as opposed to filters) in HTML documents
-	if ( !seed ) {
-
-		if ( ( context ? context.ownerDocument || context : preferredDoc ) !== document ) {
-			setDocument( context );
-		}
-		context = context || document;
-
-		if ( documentIsHTML ) {
-
-			// If the selector is sufficiently simple, try using a "get*By*" DOM method
-			// (excepting DocumentFragment context, where the methods don't exist)
-			if ( nodeType !== 11 && (match = rquickExpr.exec( selector )) ) {
-
-				// ID selector
-				if ( (m = match[1]) ) {
-
-					// Document context
-					if ( nodeType === 9 ) {
-						if ( (elem = context.getElementById( m )) ) {
-
-							// Support: IE, Opera, Webkit
-							// TODO: identify versions
-							// getElementById can match elements by name instead of ID
-							if ( elem.id === m ) {
-								results.push( elem );
-								return results;
-							}
-						} else {
-							return results;
-						}
-
-					// Element context
-					} else {
-
-						// Support: IE, Opera, Webkit
-						// TODO: identify versions
-						// getElementById can match elements by name instead of ID
-						if ( newContext && (elem = newContext.getElementById( m )) &&
-							contains( context, elem ) &&
-							elem.id === m ) {
-
-							results.push( elem );
-							return results;
-						}
-					}
-
-				// Type selector
-				} else if ( match[2] ) {
-					push.apply( results, context.getElementsByTagName( selector ) );
-					return results;
-
-				// Class selector
-				} else if ( (m = match[3]) && support.getElementsByClassName &&
-					context.getElementsByClassName ) {
-
-					push.apply( results, context.getElementsByClassName( m ) );
-					return results;
-				}
-			}
-
-			// Take advantage of querySelectorAll
-			if ( support.qsa &&
-				!compilerCache[ selector + " " ] &&
-				(!rbuggyQSA || !rbuggyQSA.test( selector )) ) {
-
-				if ( nodeType !== 1 ) {
-					newContext = context;
-					newSelector = selector;
-
-				// qSA looks outside Element context, which is not what we want
-				// Thanks to Andrew Dupont for this workaround technique
-				// Support: IE <=8
-				// Exclude object elements
-				} else if ( context.nodeName.toLowerCase() !== "object" ) {
-
-					// Capture the context ID, setting it first if necessary
-					if ( (nid = context.getAttribute( "id" )) ) {
-						nid = nid.replace( rescape, "\\$&" );
-					} else {
-						context.setAttribute( "id", (nid = expando) );
-					}
-
-					// Prefix every selector in the list
-					groups = tokenize( selector );
-					i = groups.length;
-					nidselect = ridentifier.test( nid ) ? "#" + nid : "[id='" + nid + "']";
-					while ( i-- ) {
-						groups[i] = nidselect + " " + toSelector( groups[i] );
-					}
-					newSelector = groups.join( "," );
-
-					// Expand context for sibling selectors
-					newContext = rsibling.test( selector ) && testContext( context.parentNode ) ||
-						context;
-				}
-
-				if ( newSelector ) {
-					try {
-						push.apply( results,
-							newContext.querySelectorAll( newSelector )
-						);
-						return results;
-					} catch ( qsaError ) {
-					} finally {
-						if ( nid === expando ) {
-							context.removeAttribute( "id" );
-						}
-					}
-				}
-			}
-		}
-	}
-
-	// All others
-	return select( selector.replace( rtrim, "$1" ), context, results, seed );
-}
-
-/**
- * Create key-value caches of limited size
- * @returns {function(string, object)} Returns the Object data after storing it on itself with
- *	property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength)
- *	deleting the oldest entry
- */
-function createCache() {
-	var keys = [];
-
-	function cache( key, value ) {
-		// Use (key + " ") to avoid collision with native prototype properties (see Issue #157)
-		if ( keys.push( key + " " ) > Expr.cacheLength ) {
-			// Only keep the most recent entries
-			delete cache[ keys.shift() ];
-		}
-		return (cache[ key + " " ] = value);
-	}
-	return cache;
-}
-
-/**
- * Mark a function for special use by Sizzle
- * @param {Function} fn The function to mark
- */
-function markFunction( fn ) {
-	fn[ expando ] = true;
-	return fn;
-}
-
-/**
- * Support testing using an element
- * @param {Function} fn Passed the created div and expects a boolean result
- */
-function assert( fn ) {
-	var div = document.createElement("div");
-
-	try {
-		return !!fn( div );
-	} catch (e) {
-		return false;
-	} finally {
-		// Remove from its parent by default
-		if ( div.parentNode ) {
-			div.parentNode.removeChild( div );
-		}
-		// release memory in IE
-		div = null;
-	}
-}
-
-/**
- * Adds the same handler for all of the specified attrs
- * @param {String} attrs Pipe-separated list of attributes
- * @param {Function} handler The method that will be applied
- */
-function addHandle( attrs, handler ) {
-	var arr = attrs.split("|"),
-		i = arr.length;
-
-	while ( i-- ) {
-		Expr.attrHandle[ arr[i] ] = handler;
-	}
-}
-
-/**
- * Checks document order of two siblings
- * @param {Element} a
- * @param {Element} b
- * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b
- */
-function siblingCheck( a, b ) {
-	var cur = b && a,
-		diff = cur && a.nodeType === 1 && b.nodeType === 1 &&
-			( ~b.sourceIndex || MAX_NEGATIVE ) -
-			( ~a.sourceIndex || MAX_NEGATIVE );
-
-	// Use IE sourceIndex if available on both nodes
-	if ( diff ) {
-		return diff;
-	}
-
-	// Check if b follows a
-	if ( cur ) {
-		while ( (cur = cur.nextSibling) ) {
-			if ( cur === b ) {
-				return -1;
-			}
-		}
-	}
-
-	return a ? 1 : -1;
-}
-
-/**
- * Returns a function to use in pseudos for input types
- * @param {String} type
- */
-function createInputPseudo( type ) {
-	return function( elem ) {
-		var name = elem.nodeName.toLowerCase();
-		return name === "input" && elem.type === type;
+// All jQuery objects should point back to these
+rootjQuery = jQuery(document);
+
+// Cleanup functions for the document ready method
+if ( document.addEventListener ) {
+	DOMContentLoaded = function() {
+		document.removeEventListener( "DOMContentLoaded", DOMContentLoaded, false );
+		jQuery.ready();
+	};
+
+} else if ( document.attachEvent ) {
+	DOMContentLoaded = function() {
+		// Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443).
+		if ( document.readyState === "complete" ) {
+			document.detachEvent( "onreadystatechange", DOMContentLoaded );
+			jQuery.ready();
+		}
 	};
 }
 
-/**
- * Returns a function to use in pseudos for buttons
- * @param {String} type
- */
-function createButtonPseudo( type ) {
-	return function( elem ) {
-		var name = elem.nodeName.toLowerCase();
-		return (name === "input" || name === "button") && elem.type === type;
-	};
-}
-
-/**
- * Returns a function to use in pseudos for positionals
- * @param {Function} fn
- */
-function createPositionalPseudo( fn ) {
-	return markFunction(function( argument ) {
-		argument = +argument;
-		return markFunction(function( seed, matches ) {
-			var j,
-				matchIndexes = fn( [], seed.length, argument ),
-				i = matchIndexes.length;
-
-			// Match elements found at the specified indexes
-			while ( i-- ) {
-				if ( seed[ (j = matchIndexes[i]) ] ) {
-					seed[j] = !(matches[j] = seed[j]);
-				}
-			}
-		});
-	});
-}
-
-/**
- * Checks a node for validity as a Sizzle context
- * @param {Element|Object=} context
- * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value
- */
-function testContext( context ) {
-	return context && typeof context.getElementsByTagName !== "undefined" && context;
-}
-
-// Expose support vars for convenience
-support = Sizzle.support = {};
-
-/**
- * Detects XML nodes
- * @param {Element|Object} elem An element or a document
- * @returns {Boolean} True iff elem is a non-HTML XML node
- */
-isXML = Sizzle.isXML = function( elem ) {
-	// documentElement is verified for cases where it doesn't yet exist
-	// (such as loading iframes in IE - #4833)
-	var documentElement = elem && (elem.ownerDocument || elem).documentElement;
-	return documentElement ? documentElement.nodeName !== "HTML" : false;
-};
-
-/**
- * Sets document-related variables once based on the current document
- * @param {Element|Object} [doc] An element or document object to use to set the document
- * @returns {Object} Returns the current document
- */
-setDocument = Sizzle.setDocument = function( node ) {
-	var hasCompare, parent,
-		doc = node ? node.ownerDocument || node : preferredDoc;
-
-	// Return early if doc is invalid or already selected
-	if ( doc === document || doc.nodeType !== 9 || !doc.documentElement ) {
-		return document;
-	}
-
-	// Update global variables
-	document = doc;
-	docElem = document.documentElement;
-	documentIsHTML = !isXML( document );
-
-	// Support: IE 9-11, Edge
-	// Accessing iframe documents after unload throws "permission denied" errors (jQuery #13936)
-	if ( (parent = document.defaultView) && parent.top !== parent ) {
-		// Support: IE 11
-		if ( parent.addEventListener ) {
-			parent.addEventListener( "unload", unloadHandler, false );
-
-		// Support: IE 9 - 10 only
-		} else if ( parent.attachEvent ) {
-			parent.attachEvent( "onunload", unloadHandler );
-		}
-	}
-
-	/* Attributes
-	---------------------------------------------------------------------- */
-
-	// Support: IE<8
-	// Verify that getAttribute really returns attributes and not properties
-	// (excepting IE8 booleans)
-	support.attributes = assert(function( div ) {
-		div.className = "i";
-		return !div.getAttribute("className");
-	});
-
-	/* getElement(s)By*
-	---------------------------------------------------------------------- */
-
-	// Check if getElementsByTagName("*") returns only elements
-	support.getElementsByTagName = assert(function( div ) {
-		div.appendChild( document.createComment("") );
-		return !div.getElementsByTagName("*").length;
-	});
-
-	// Support: IE<9
-	support.getElementsByClassName = rnative.test( document.getElementsByClassName );
-
-	// Support: IE<10
-	// Check if getElementById returns elements by name
-	// The broken getElementById methods don't pick up programatically-set names,
-	// so use a roundabout getElementsByName test
-	support.getById = assert(function( div ) {
-		docElem.appendChild( div ).id = expando;
-		return !document.getElementsByName || !document.getElementsByName( expando ).length;
-	});
-
-	// ID find and filter
-	if ( support.getById ) {
-		Expr.find["ID"] = function( id, context ) {
-			if ( typeof context.getElementById !== "undefined" && documentIsHTML ) {
-				var m = context.getElementById( id );
-				return m ? [ m ] : [];
-			}
-		};
-		Expr.filter["ID"] = function( id ) {
-			var attrId = id.replace( runescape, funescape );
-			return function( elem ) {
-				return elem.getAttribute("id") === attrId;
-			};
-		};
-	} else {
-		// Support: IE6/7
-		// getElementById is not reliable as a find shortcut
-		delete Expr.find["ID"];
-
-		Expr.filter["ID"] =  function( id ) {
-			var attrId = id.replace( runescape, funescape );
-			return function( elem ) {
-				var node = typeof elem.getAttributeNode !== "undefined" &&
-					elem.getAttributeNode("id");
-				return node && node.value === attrId;
-			};
-		};
-	}
-
-	// Tag
-	Expr.find["TAG"] = support.getElementsByTagName ?
-		function( tag, context ) {
-			if ( typeof context.getElementsByTagName !== "undefined" ) {
-				return context.getElementsByTagName( tag );
-
-			// DocumentFragment nodes don't have gEBTN
-			} else if ( support.qsa ) {
-				return context.querySelectorAll( tag );
-			}
-		} :
-
-		function( tag, context ) {
-			var elem,
-				tmp = [],
-				i = 0,
-				// By happy coincidence, a (broken) gEBTN appears on DocumentFragment nodes too
-				results = context.getElementsByTagName( tag );
-
-			// Filter out possible comments
-			if ( tag === "*" ) {
-				while ( (elem = results[i++]) ) {
-					if ( elem.nodeType === 1 ) {
-						tmp.push( elem );
-					}
-				}
-
-				return tmp;
-			}
-			return results;
-		};
-
-	// Class
-	Expr.find["CLASS"] = support.getElementsByClassName && function( className, context ) {
-		if ( typeof context.getElementsByClassName !== "undefined" && documentIsHTML ) {
-			return context.getElementsByClassName( className );
-		}
-	};
-
-	/* QSA/matchesSelector
-	---------------------------------------------------------------------- */
-
-	// QSA and matchesSelector support
-
-	// matchesSelector(:active) reports false when true (IE9/Opera 11.5)
-	rbuggyMatches = [];
-
-	// qSa(:focus) reports false when true (Chrome 21)
-	// We allow this because of a bug in IE8/9 that throws an error
-	// whenever `document.activeElement` is accessed on an iframe
-	// So, we allow :focus to pass through QSA all the time to avoid the IE error
-	// See http://bugs.jquery.com/ticket/13378
-	rbuggyQSA = [];
-
-	if ( (support.qsa = rnative.test( document.querySelectorAll )) ) {
-		// Build QSA regex
-		// Regex strategy adopted from Diego Perini
-		assert(function( div ) {
-			// Select is set to empty string on purpose
-			// This is to test IE's treatment of not explicitly
-			// setting a boolean content attribute,
-			// since its presence should be enough
-			// http://bugs.jquery.com/ticket/12359
-			docElem.appendChild( div ).innerHTML = "<a id='" + expando + "'></a>" +
-				"<select id='" + expando + "-\r\\' msallowcapture=''>" +
-				"<option selected=''></option></select>";
-
-			// Support: IE8, Opera 11-12.16
-			// Nothing should be selected when empty strings follow ^= or $= or *=
-			// The test attribute must be unknown in Opera but "safe" for WinRT
-			// http://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section
-			if ( div.querySelectorAll("[msallowcapture^='']").length ) {
-				rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:''|\"\")" );
-			}
-
-			// Support: IE8
-			// Boolean attributes and "value" are not treated correctly
-			if ( !div.querySelectorAll("[selected]").length ) {
-				rbuggyQSA.push( "\\[" + whitespace + "*(?:value|" + booleans + ")" );
-			}
-
-			// Support: Chrome<29, Android<4.4, Safari<7.0+, iOS<7.0+, PhantomJS<1.9.8+
-			if ( !div.querySelectorAll( "[id~=" + expando + "-]" ).length ) {
-				rbuggyQSA.push("~=");
-			}
-
-			// Webkit/Opera - :checked should return selected option elements
-			// http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
-			// IE8 throws error here and will not see later tests
-			if ( !div.querySelectorAll(":checked").length ) {
-				rbuggyQSA.push(":checked");
-			}
-
-			// Support: Safari 8+, iOS 8+
-			// https://bugs.webkit.org/show_bug.cgi?id=136851
-			// In-page `selector#id sibing-combinator selector` fails
-			if ( !div.querySelectorAll( "a#" + expando + "+*" ).length ) {
-				rbuggyQSA.push(".#.+[+~]");
-			}
-		});
-
-		assert(function( div ) {
-			// Support: Windows 8 Native Apps
-			// The type and name attributes are restricted during .innerHTML assignment
-			var input = document.createElement("input");
-			input.setAttribute( "type", "hidden" );
-			div.appendChild( input ).setAttribute( "name", "D" );
-
-			// Support: IE8
-			// Enforce case-sensitivity of name attribute
-			if ( div.querySelectorAll("[name=d]").length ) {
-				rbuggyQSA.push( "name" + whitespace + "*[*^$|!~]?=" );
-			}
-
-			// FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled)
-			// IE8 throws error here and will not see later tests
-			if ( !div.querySelectorAll(":enabled").length ) {
-				rbuggyQSA.push( ":enabled", ":disabled" );
-			}
-
-			// Opera 10-11 does not throw on post-comma invalid pseudos
-			div.querySelectorAll("*,:x");
-			rbuggyQSA.push(",.*:");
-		});
-	}
-
-	if ( (support.matchesSelector = rnative.test( (matches = docElem.matches ||
-		docElem.webkitMatchesSelector ||
-		docElem.mozMatchesSelector ||
-		docElem.oMatchesSelector ||
-		docElem.msMatchesSelector) )) ) {
-
-		assert(function( div ) {
-			// Check to see if it's possible to do matchesSelector
-			// on a disconnected node (IE 9)
-			support.disconnectedMatch = matches.call( div, "div" );
-
-			// This should fail with an exception
-			// Gecko does not error, returns false instead
-			matches.call( div, "[s!='']:x" );
-			rbuggyMatches.push( "!=", pseudos );
-		});
-	}
-
-	rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join("|") );
-	rbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join("|") );
-
-	/* Contains
-	---------------------------------------------------------------------- */
-	hasCompare = rnative.test( docElem.compareDocumentPosition );
-
-	// Element contains another
-	// Purposefully self-exclusive
-	// As in, an element does not contain itself
-	contains = hasCompare || rnative.test( docElem.contains ) ?
-		function( a, b ) {
-			var adown = a.nodeType === 9 ? a.documentElement : a,
-				bup = b && b.parentNode;
-			return a === bup || !!( bup && bup.nodeType === 1 && (
-				adown.contains ?
-					adown.contains( bup ) :
-					a.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16
-			));
-		} :
-		function( a, b ) {
-			if ( b ) {
-				while ( (b = b.parentNode) ) {
-					if ( b === a ) {
-						return true;
-					}
-				}
-			}
-			return false;
-		};
-
-	/* Sorting
-	---------------------------------------------------------------------- */
-
-	// Document order sorting
-	sortOrder = hasCompare ?
-	function( a, b ) {
-
-		// Flag for duplicate removal
-		if ( a === b ) {
-			hasDuplicate = true;
-			return 0;
-		}
-
-		// Sort on method existence if only one input has compareDocumentPosition
-		var compare = !a.compareDocumentPosition - !b.compareDocumentPosition;
-		if ( compare ) {
-			return compare;
-		}
-
-		// Calculate position if both inputs belong to the same document
-		compare = ( a.ownerDocument || a ) === ( b.ownerDocument || b ) ?
-			a.compareDocumentPosition( b ) :
-
-			// Otherwise we know they are disconnected
-			1;
-
-		// Disconnected nodes
-		if ( compare & 1 ||
-			(!support.sortDetached && b.compareDocumentPosition( a ) === compare) ) {
-
-			// Choose the first element that is related to our preferred document
-			if ( a === document || a.ownerDocument === preferredDoc && contains(preferredDoc, a) ) {
-				return -1;
-			}
-			if ( b === document || b.ownerDocument === preferredDoc && contains(preferredDoc, b) ) {
-				return 1;
-			}
-
-			// Maintain original order
-			return sortInput ?
-				( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) :
-				0;
-		}
-
-		return compare & 4 ? -1 : 1;
-	} :
-	function( a, b ) {
-		// Exit early if the nodes are identical
-		if ( a === b ) {
-			hasDuplicate = true;
-			return 0;
-		}
-
-		var cur,
-			i = 0,
-			aup = a.parentNode,
-			bup = b.parentNode,
-			ap = [ a ],
-			bp = [ b ];
-
-		// Parentless nodes are either documents or disconnected
-		if ( !aup || !bup ) {
-			return a === document ? -1 :
-				b === document ? 1 :
-				aup ? -1 :
-				bup ? 1 :
-				sortInput ?
-				( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) :
-				0;
-
-		// If the nodes are siblings, we can do a quick check
-		} else if ( aup === bup ) {
-			return siblingCheck( a, b );
-		}
-
-		// Otherwise we need full lists of their ancestors for comparison
-		cur = a;
-		while ( (cur = cur.parentNode) ) {
-			ap.unshift( cur );
-		}
-		cur = b;
-		while ( (cur = cur.parentNode) ) {
-			bp.unshift( cur );
-		}
-
-		// Walk down the tree looking for a discrepancy
-		while ( ap[i] === bp[i] ) {
-			i++;
-		}
-
-		return i ?
-			// Do a sibling check if the nodes have a common ancestor
-			siblingCheck( ap[i], bp[i] ) :
-
-			// Otherwise nodes in our document sort first
-			ap[i] === preferredDoc ? -1 :
-			bp[i] === preferredDoc ? 1 :
-			0;
-	};
-
-	return document;
-};
-
-Sizzle.matches = function( expr, elements ) {
-	return Sizzle( expr, null, null, elements );
-};
-
-Sizzle.matchesSelector = function( elem, expr ) {
-	// Set document vars if needed
-	if ( ( elem.ownerDocument || elem ) !== document ) {
-		setDocument( elem );
-	}
-
-	// Make sure that attribute selectors are quoted
-	expr = expr.replace( rattributeQuotes, "='$1']" );
-
-	if ( support.matchesSelector && documentIsHTML &&
-		!compilerCache[ expr + " " ] &&
-		( !rbuggyMatches || !rbuggyMatches.test( expr ) ) &&
-		( !rbuggyQSA     || !rbuggyQSA.test( expr ) ) ) {
-
-		try {
-			var ret = matches.call( elem, expr );
-
-			// IE 9's matchesSelector returns false on disconnected nodes
-			if ( ret || support.disconnectedMatch ||
-					// As well, disconnected nodes are said to be in a document
-					// fragment in IE 9
-					elem.document && elem.document.nodeType !== 11 ) {
-				return ret;
-			}
-		} catch (e) {}
-	}
-
-	return Sizzle( expr, document, null, [ elem ] ).length > 0;
-};
-
-Sizzle.contains = function( context, elem ) {
-	// Set document vars if needed
-	if ( ( context.ownerDocument || context ) !== document ) {
-		setDocument( context );
-	}
-	return contains( context, elem );
-};
-
-Sizzle.attr = function( elem, name ) {
-	// Set document vars if needed
-	if ( ( elem.ownerDocument || elem ) !== document ) {
-		setDocument( elem );
-	}
-
-	var fn = Expr.attrHandle[ name.toLowerCase() ],
-		// Don't get fooled by Object.prototype properties (jQuery #13807)
-		val = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ?
-			fn( elem, name, !documentIsHTML ) :
-			undefined;
-
-	return val !== undefined ?
-		val :
-		support.attributes || !documentIsHTML ?
-			elem.getAttribute( name ) :
-			(val = elem.getAttributeNode(name)) && val.specified ?
-				val.value :
-				null;
-};
-
-Sizzle.error = function( msg ) {
-	throw new Error( "Syntax error, unrecognized expression: " + msg );
-};
-
-/**
- * Document sorting and removing duplicates
- * @param {ArrayLike} results
- */
-Sizzle.uniqueSort = function( results ) {
-	var elem,
-		duplicates = [],
-		j = 0,
-		i = 0;
-
-	// Unless we *know* we can detect duplicates, assume their presence
-	hasDuplicate = !support.detectDuplicates;
-	sortInput = !support.sortStable && results.slice( 0 );
-	results.sort( sortOrder );
-
-	if ( hasDuplicate ) {
-		while ( (elem = results[i++]) ) {
-			if ( elem === results[ i ] ) {
-				j = duplicates.push( i );
-			}
-		}
-		while ( j-- ) {
-			results.splice( duplicates[ j ], 1 );
-		}
-	}
-
-	// Clear input after sorting to release objects
-	// See https://github.com/jquery/sizzle/pull/225
-	sortInput = null;
-
-	return results;
-};
-
-/**
- * Utility function for retrieving the text value of an array of DOM nodes
- * @param {Array|Element} elem
- */
-getText = Sizzle.getText = function( elem ) {
-	var node,
-		ret = "",
-		i = 0,
-		nodeType = elem.nodeType;
-
-	if ( !nodeType ) {
-		// If no nodeType, this is expected to be an array
-		while ( (node = elem[i++]) ) {
-			// Do not traverse comment nodes
-			ret += getText( node );
-		}
-	} else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) {
-		// Use textContent for elements
-		// innerText usage removed for consistency of new lines (jQuery #11153)
-		if ( typeof elem.textContent === "string" ) {
-			return elem.textContent;
-		} else {
-			// Traverse its children
-			for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {
-				ret += getText( elem );
-			}
-		}
-	} else if ( nodeType === 3 || nodeType === 4 ) {
-		return elem.nodeValue;
-	}
-	// Do not include comment or processing instruction nodes
-
-	return ret;
-};
-
-Expr = Sizzle.selectors = {
-
-	// Can be adjusted by the user
-	cacheLength: 50,
-
-	createPseudo: markFunction,
-
-	match: matchExpr,
-
-	attrHandle: {},
-
-	find: {},
-
-	relative: {
-		">": { dir: "parentNode", first: true },
-		" ": { dir: "parentNode" },
-		"+": { dir: "previousSibling", first: true },
-		"~": { dir: "previousSibling" }
-	},
-
-	preFilter: {
-		"ATTR": function( match ) {
-			match[1] = match[1].replace( runescape, funescape );
-
-			// Move the given value to match[3] whether quoted or unquoted
-			match[3] = ( match[3] || match[4] || match[5] || "" ).replace( runescape, funescape );
-
-			if ( match[2] === "~=" ) {
-				match[3] = " " + match[3] + " ";
-			}
-
-			return match.slice( 0, 4 );
-		},
-
-		"CHILD": function( match ) {
-			/* matches from matchExpr["CHILD"]
-				1 type (only|nth|...)
-				2 what (child|of-type)
-				3 argument (even|odd|\d*|\d*n([+-]\d+)?|...)
-				4 xn-component of xn+y argument ([+-]?\d*n|)
-				5 sign of xn-component
-				6 x of xn-component
-				7 sign of y-component
-				8 y of y-component
-			*/
-			match[1] = match[1].toLowerCase();
-
-			if ( match[1].slice( 0, 3 ) === "nth" ) {
-				// nth-* requires argument
-				if ( !match[3] ) {
-					Sizzle.error( match[0] );
-				}
-
-				// numeric x and y parameters for Expr.filter.CHILD
-				// remember that false/true cast respectively to 0/1
-				match[4] = +( match[4] ? match[5] + (match[6] || 1) : 2 * ( match[3] === "even" || match[3] === "odd" ) );
-				match[5] = +( ( match[7] + match[8] ) || match[3] === "odd" );
-
-			// other types prohibit arguments
-			} else if ( match[3] ) {
-				Sizzle.error( match[0] );
-			}
-
-			return match;
-		},
-
-		"PSEUDO": function( match ) {
-			var excess,
-				unquoted = !match[6] && match[2];
-
-			if ( matchExpr["CHILD"].test( match[0] ) ) {
-				return null;
-			}
-
-			// Accept quoted arguments as-is
-			if ( match[3] ) {
-				match[2] = match[4] || match[5] || "";
-
-			// Strip excess characters from unquoted arguments
-			} else if ( unquoted && rpseudo.test( unquoted ) &&
-				// Get excess from tokenize (recursively)
-				(excess = tokenize( unquoted, true )) &&
-				// advance to the next closing parenthesis
-				(excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length) ) {
-
-				// excess is a negative index
-				match[0] = match[0].slice( 0, excess );
-				match[2] = unquoted.slice( 0, excess );
-			}
-
-			// Return only captures needed by the pseudo filter method (type and argument)
-			return match.slice( 0, 3 );
-		}
-	},
-
-	filter: {
-
-		"TAG": function( nodeNameSelector ) {
-			var nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase();
-			return nodeNameSelector === "*" ?
-				function() { return true; } :
-				function( elem ) {
-					return elem.nodeName && elem.nodeName.toLowerCase() === nodeName;
-				};
-		},
-
-		"CLASS": function( className ) {
-			var pattern = classCache[ className + " " ];
-
-			return pattern ||
-				(pattern = new RegExp( "(^|" + whitespace + ")" + className + "(" + whitespace + "|$)" )) &&
-				classCache( className, function( elem ) {
-					return pattern.test( typeof elem.className === "string" && elem.className || typeof elem.getAttribute !== "undefined" && elem.getAttribute("class") || "" );
-				});
-		},
-
-		"ATTR": function( name, operator, check ) {
-			return function( elem ) {
-				var result = Sizzle.attr( elem, name );
-
-				if ( result == null ) {
-					return operator === "!=";
-				}
-				if ( !operator ) {
-					return true;
-				}
-
-				result += "";
-
-				return operator === "=" ? result === check :
-					operator === "!=" ? result !== check :
-					operator === "^=" ? check && result.indexOf( check ) === 0 :
-					operator === "*=" ? check && result.indexOf( check ) > -1 :
-					operator === "$=" ? check && result.slice( -check.length ) === check :
-					operator === "~=" ? ( " " + result.replace( rwhitespace, " " ) + " " ).indexOf( check ) > -1 :
-					operator === "|=" ? result === check || result.slice( 0, check.length + 1 ) === check + "-" :
-					false;
-			};
-		},
-
-		"CHILD": function( type, what, argument, first, last ) {
-			var simple = type.slice( 0, 3 ) !== "nth",
-				forward = type.slice( -4 ) !== "last",
-				ofType = what === "of-type";
-
-			return first === 1 && last === 0 ?
-
-				// Shortcut for :nth-*(n)
-				function( elem ) {
-					return !!elem.parentNode;
-				} :
-
-				function( elem, context, xml ) {
-					var cache, uniqueCache, outerCache, node, nodeIndex, start,
-						dir = simple !== forward ? "nextSibling" : "previousSibling",
-						parent = elem.parentNode,
-						name = ofType && elem.nodeName.toLowerCase(),
-						useCache = !xml && !ofType,
-						diff = false;
-
-					if ( parent ) {
-
-						// :(first|last|only)-(child|of-type)
-						if ( simple ) {
-							while ( dir ) {
-								node = elem;
-								while ( (node = node[ dir ]) ) {
-									if ( ofType ?
-										node.nodeName.toLowerCase() === name :
-										node.nodeType === 1 ) {
-
-										return false;
-									}
-								}
-								// Reverse direction for :only-* (if we haven't yet done so)
-								start = dir = type === "only" && !start && "nextSibling";
-							}
-							return true;
-						}
-
-						start = [ forward ? parent.firstChild : parent.lastChild ];
-
-						// non-xml :nth-child(...) stores cache data on `parent`
-						if ( forward && useCache ) {
-
-							// Seek `elem` from a previously-cached index
-
-							// ...in a gzip-friendly way
-							node = parent;
-							outerCache = node[ expando ] || (node[ expando ] = {});
-
-							// Support: IE <9 only
-							// Defend against cloned attroperties (jQuery gh-1709)
-							uniqueCache = outerCache[ node.uniqueID ] ||
-								(outerCache[ node.uniqueID ] = {});
-
-							cache = uniqueCache[ type ] || [];
-							nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ];
-							diff = nodeIndex && cache[ 2 ];
-							node = nodeIndex && parent.childNodes[ nodeIndex ];
-
-							while ( (node = ++nodeIndex && node && node[ dir ] ||
-
-								// Fallback to seeking `elem` from the start
-								(diff = nodeIndex = 0) || start.pop()) ) {
-
-								// When found, cache indexes on `parent` and break
-								if ( node.nodeType === 1 && ++diff && node === elem ) {
-									uniqueCache[ type ] = [ dirruns, nodeIndex, diff ];
-									break;
-								}
-							}
-
-						} else {
-							// Use previously-cached element index if available
-							if ( useCache ) {
-								// ...in a gzip-friendly way
-								node = elem;
-								outerCache = node[ expando ] || (node[ expando ] = {});
-
-								// Support: IE <9 only
-								// Defend against cloned attroperties (jQuery gh-1709)
-								uniqueCache = outerCache[ node.uniqueID ] ||
-									(outerCache[ node.uniqueID ] = {});
-
-								cache = uniqueCache[ type ] || [];
-								nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ];
-								diff = nodeIndex;
-							}
-
-							// xml :nth-child(...)
-							// or :nth-last-child(...) or :nth(-last)?-of-type(...)
-							if ( diff === false ) {
-								// Use the same loop as above to seek `elem` from the start
-								while ( (node = ++nodeIndex && node && node[ dir ] ||
-									(diff = nodeIndex = 0) || start.pop()) ) {
-
-									if ( ( ofType ?
-										node.nodeName.toLowerCase() === name :
-										node.nodeType === 1 ) &&
-										++diff ) {
-
-										// Cache the index of each encountered element
-										if ( useCache ) {
-											outerCache = node[ expando ] || (node[ expando ] = {});
-
-											// Support: IE <9 only
-											// Defend against cloned attroperties (jQuery gh-1709)
-											uniqueCache = outerCache[ node.uniqueID ] ||
-												(outerCache[ node.uniqueID ] = {});
-
-											uniqueCache[ type ] = [ dirruns, diff ];
-										}
-
-										if ( node === elem ) {
-											break;
-										}
-									}
-								}
-							}
-						}
-
-						// Incorporate the offset, then check against cycle size
-						diff -= last;
-						return diff === first || ( diff % first === 0 && diff / first >= 0 );
-					}
-				};
-		},
-
-		"PSEUDO": function( pseudo, argument ) {
-			// pseudo-class names are case-insensitive
-			// http://www.w3.org/TR/selectors/#pseudo-classes
-			// Prioritize by case sensitivity in case custom pseudos are added with uppercase letters
-			// Remember that setFilters inherits from pseudos
-			var args,
-				fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] ||
-					Sizzle.error( "unsupported pseudo: " + pseudo );
-
-			// The user may use createPseudo to indicate that
-			// arguments are needed to create the filter function
-			// just as Sizzle does
-			if ( fn[ expando ] ) {
-				return fn( argument );
-			}
-
-			// But maintain support for old signatures
-			if ( fn.length > 1 ) {
-				args = [ pseudo, pseudo, "", argument ];
-				return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ?
-					markFunction(function( seed, matches ) {
-						var idx,
-							matched = fn( seed, argument ),
-							i = matched.length;
-						while ( i-- ) {
-							idx = indexOf( seed, matched[i] );
-							seed[ idx ] = !( matches[ idx ] = matched[i] );
-						}
-					}) :
-					function( elem ) {
-						return fn( elem, 0, args );
-					};
-			}
-
-			return fn;
-		}
-	},
-
-	pseudos: {
-		// Potentially complex pseudos
-		"not": markFunction(function( selector ) {
-			// Trim the selector passed to compile
-			// to avoid treating leading and trailing
-			// spaces as combinators
-			var input = [],
-				results = [],
-				matcher = compile( selector.replace( rtrim, "$1" ) );
-
-			return matcher[ expando ] ?
-				markFunction(function( seed, matches, context, xml ) {
-					var elem,
-						unmatched = matcher( seed, null, xml, [] ),
-						i = seed.length;
-
-					// Match elements unmatched by `matcher`
-					while ( i-- ) {
-						if ( (elem = unmatched[i]) ) {
-							seed[i] = !(matches[i] = elem);
-						}
-					}
-				}) :
-				function( elem, context, xml ) {
-					input[0] = elem;
-					matcher( input, null, xml, results );
-					// Don't keep the element (issue #299)
-					input[0] = null;
-					return !results.pop();
-				};
-		}),
-
-		"has": markFunction(function( selector ) {
-			return function( elem ) {
-				return Sizzle( selector, elem ).length > 0;
-			};
-		}),
-
-		"contains": markFunction(function( text ) {
-			text = text.replace( runescape, funescape );
-			return function( elem ) {
-				return ( elem.textContent || elem.innerText || getText( elem ) ).indexOf( text ) > -1;
-			};
-		}),
-
-		// "Whether an element is represented by a :lang() selector
-		// is based solely on the element's language value
-		// being equal to the identifier C,
-		// or beginning with the identifier C immediately followed by "-".
-		// The matching of C against the element's language value is performed case-insensitively.
-		// The identifier C does not have to be a valid language name."
-		// http://www.w3.org/TR/selectors/#lang-pseudo
-		"lang": markFunction( function( lang ) {
-			// lang value must be a valid identifier
-			if ( !ridentifier.test(lang || "") ) {
-				Sizzle.error( "unsupported lang: " + lang );
-			}
-			lang = lang.replace( runescape, funescape ).toLowerCase();
-			return function( elem ) {
-				var elemLang;
-				do {
-					if ( (elemLang = documentIsHTML ?
-						elem.lang :
-						elem.getAttribute("xml:lang") || elem.getAttribute("lang")) ) {
-
-						elemLang = elemLang.toLowerCase();
-						return elemLang === lang || elemLang.indexOf( lang + "-" ) === 0;
-					}
-				} while ( (elem = elem.parentNode) && elem.nodeType === 1 );
-				return false;
-			};
-		}),
-
-		// Miscellaneous
-		"target": function( elem ) {
-			var hash = window.location && window.location.hash;
-			return hash && hash.slice( 1 ) === elem.id;
-		},
-
-		"root": function( elem ) {
-			return elem === docElem;
-		},
-
-		"focus": function( elem ) {
-			return elem === document.activeElement && (!document.hasFocus || document.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex);
-		},
-
-		// Boolean properties
-		"enabled": function( elem ) {
-			return elem.disabled === false;
-		},
-
-		"disabled": function( elem ) {
-			return elem.disabled === true;
-		},
-
-		"checked": function( elem ) {
-			// In CSS3, :checked should return both checked and selected elements
-			// http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
-			var nodeName = elem.nodeName.toLowerCase();
-			return (nodeName === "input" && !!elem.checked) || (nodeName === "option" && !!elem.selected);
-		},
-
-		"selected": function( elem ) {
-			// Accessing this property makes selected-by-default
-			// options in Safari work properly
-			if ( elem.parentNode ) {
-				elem.parentNode.selectedIndex;
-			}
-
-			return elem.selected === true;
-		},
-
-		// Contents
-		"empty": function( elem ) {
-			// http://www.w3.org/TR/selectors/#empty-pseudo
-			// :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5),
-			//   but not by others (comment: 8; processing instruction: 7; etc.)
-			// nodeType < 6 works because attributes (2) do not appear as children
-			for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {
-				if ( elem.nodeType < 6 ) {
-					return false;
-				}
-			}
-			return true;
-		},
-
-		"parent": function( elem ) {
-			return !Expr.pseudos["empty"]( elem );
-		},
-
-		// Element/input types
-		"header": function( elem ) {
-			return rheader.test( elem.nodeName );
-		},
-
-		"input": function( elem ) {
-			return rinputs.test( elem.nodeName );
-		},
-
-		"button": function( elem ) {
-			var name = elem.nodeName.toLowerCase();
-			return name === "input" && elem.type === "button" || name === "button";
-		},
-
-		"text": function( elem ) {
-			var attr;
-			return elem.nodeName.toLowerCase() === "input" &&
-				elem.type === "text" &&
-
-				// Support: IE<8
-				// New HTML5 attribute values (e.g., "search") appear with elem.type === "text"
-				( (attr = elem.getAttribute("type")) == null || attr.toLowerCase() === "text" );
-		},
-
-		// Position-in-collection
-		"first": createPositionalPseudo(function() {
-			return [ 0 ];
-		}),
-
-		"last": createPositionalPseudo(function( matchIndexes, length ) {
-			return [ length - 1 ];
-		}),
-
-		"eq": createPositionalPseudo(function( matchIndexes, length, argument ) {
-			return [ argument < 0 ? argument + length : argument ];
-		}),
-
-		"even": createPositionalPseudo(function( matchIndexes, length ) {
-			var i = 0;
-			for ( ; i < length; i += 2 ) {
-				matchIndexes.push( i );
-			}
-			return matchIndexes;
-		}),
-
-		"odd": createPositionalPseudo(function( matchIndexes, length ) {
-			var i = 1;
-			for ( ; i < length; i += 2 ) {
-				matchIndexes.push( i );
-			}
-			return matchIndexes;
-		}),
-
-		"lt": createPositionalPseudo(function( matchIndexes, length, argument ) {
-			var i = argument < 0 ? argument + length : argument;
-			for ( ; --i >= 0; ) {
-				matchIndexes.push( i );
-			}
-			return matchIndexes;
-		}),
-
-		"gt": createPositionalPseudo(function( matchIndexes, length, argument ) {
-			var i = argument < 0 ? argument + length : argument;
-			for ( ; ++i < length; ) {
-				matchIndexes.push( i );
-			}
-			return matchIndexes;
-		})
-	}
-};
-
-Expr.pseudos["nth"] = Expr.pseudos["eq"];
-
-// Add button/input type pseudos
-for ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) {
-	Expr.pseudos[ i ] = createInputPseudo( i );
-}
-for ( i in { submit: true, reset: true } ) {
-	Expr.pseudos[ i ] = createButtonPseudo( i );
-}
-
-// Easy API for creating new setFilters
-function setFilters() {}
-setFilters.prototype = Expr.filters = Expr.pseudos;
-Expr.setFilters = new setFilters();
-
-tokenize = Sizzle.tokenize = function( selector, parseOnly ) {
-	var matched, match, tokens, type,
-		soFar, groups, preFilters,
-		cached = tokenCache[ selector + " " ];
-
-	if ( cached ) {
-		return parseOnly ? 0 : cached.slice( 0 );
-	}
-
-	soFar = selector;
-	groups = [];
-	preFilters = Expr.preFilter;
-
-	while ( soFar ) {
-
-		// Comma and first run
-		if ( !matched || (match = rcomma.exec( soFar )) ) {
-			if ( match ) {
-				// Don't consume trailing commas as valid
-				soFar = soFar.slice( match[0].length ) || soFar;
-			}
-			groups.push( (tokens = []) );
-		}
-
-		matched = false;
-
-		// Combinators
-		if ( (match = rcombinators.exec( soFar )) ) {
-			matched = match.shift();
-			tokens.push({
-				value: matched,
-				// Cast descendant combinators to space
-				type: match[0].replace( rtrim, " " )
-			});
-			soFar = soFar.slice( matched.length );
-		}
-
-		// Filters
-		for ( type in Expr.filter ) {
-			if ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] ||
-				(match = preFilters[ type ]( match ))) ) {
-				matched = match.shift();
-				tokens.push({
-					value: matched,
-					type: type,
-					matches: match
-				});
-				soFar = soFar.slice( matched.length );
-			}
-		}
-
-		if ( !matched ) {
-			break;
-		}
-	}
-
-	// Return the length of the invalid excess
-	// if we're just parsing
-	// Otherwise, throw an error or return tokens
-	return parseOnly ?
-		soFar.length :
-		soFar ?
-			Sizzle.error( selector ) :
-			// Cache the tokens
-			tokenCache( selector, groups ).slice( 0 );
-};
-
-function toSelector( tokens ) {
-	var i = 0,
-		len = tokens.length,
-		selector = "";
-	for ( ; i < len; i++ ) {
-		selector += tokens[i].value;
-	}
-	return selector;
-}
-
-function addCombinator( matcher, combinator, base ) {
-	var dir = combinator.dir,
-		checkNonElements = base && dir === "parentNode",
-		doneName = done++;
-
-	return combinator.first ?
-		// Check against closest ancestor/preceding element
-		function( elem, context, xml ) {
-			while ( (elem = elem[ dir ]) ) {
-				if ( elem.nodeType === 1 || checkNonElements ) {
-					return matcher( elem, context, xml );
-				}
-			}
-		} :
-
-		// Check against all ancestor/preceding elements
-		function( elem, context, xml ) {
-			var oldCache, uniqueCache, outerCache,
-				newCache = [ dirruns, doneName ];
-
-			// We can't set arbitrary data on XML nodes, so they don't benefit from combinator caching
-			if ( xml ) {
-				while ( (elem = elem[ dir ]) ) {
-					if ( elem.nodeType === 1 || checkNonElements ) {
-						if ( matcher( elem, context, xml ) ) {
-							return true;
-						}
-					}
-				}
-			} else {
-				while ( (elem = elem[ dir ]) ) {
-					if ( elem.nodeType === 1 || checkNonElements ) {
-						outerCache = elem[ expando ] || (elem[ expando ] = {});
-
-						// Support: IE <9 only
-						// Defend against cloned attroperties (jQuery gh-1709)
-						uniqueCache = outerCache[ elem.uniqueID ] || (outerCache[ elem.uniqueID ] = {});
-
-						if ( (oldCache = uniqueCache[ dir ]) &&
-							oldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) {
-
-							// Assign to newCache so results back-propagate to previous elements
-							return (newCache[ 2 ] = oldCache[ 2 ]);
-						} else {
-							// Reuse newcache so results back-propagate to previous elements
-							uniqueCache[ dir ] = newCache;
-
-							// A match means we're done; a fail means we have to keep checking
-							if ( (newCache[ 2 ] = matcher( elem, context, xml )) ) {
-								return true;
-							}
-						}
-					}
-				}
-			}
-		};
-}
-
-function elementMatcher( matchers ) {
-	return matchers.length > 1 ?
-		function( elem, context, xml ) {
-			var i = matchers.length;
-			while ( i-- ) {
-				if ( !matchers[i]( elem, context, xml ) ) {
-					return false;
-				}
-			}
-			return true;
-		} :
-		matchers[0];
-}
-
-function multipleContexts( selector, contexts, results ) {
-	var i = 0,
-		len = contexts.length;
-	for ( ; i < len; i++ ) {
-		Sizzle( selector, contexts[i], results );
-	}
-	return results;
-}
-
-function condense( unmatched, map, filter, context, xml ) {
-	var elem,
-		newUnmatched = [],
-		i = 0,
-		len = unmatched.length,
-		mapped = map != null;
-
-	for ( ; i < len; i++ ) {
-		if ( (elem = unmatched[i]) ) {
-			if ( !filter || filter( elem, context, xml ) ) {
-				newUnmatched.push( elem );
-				if ( mapped ) {
-					map.push( i );
-				}
-			}
-		}
-	}
-
-	return newUnmatched;
-}
-
-function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) {
-	if ( postFilter && !postFilter[ expando ] ) {
-		postFilter = setMatcher( postFilter );
-	}
-	if ( postFinder && !postFinder[ expando ] ) {
-		postFinder = setMatcher( postFinder, postSelector );
-	}
-	return markFunction(function( seed, results, context, xml ) {
-		var temp, i, elem,
-			preMap = [],
-			postMap = [],
-			preexisting = results.length,
-
-			// Get initial elements from seed or context
-			elems = seed || multipleContexts( selector || "*", context.nodeType ? [ context ] : context, [] ),
-
-			// Prefilter to get matcher input, preserving a map for seed-results synchronization
-			matcherIn = preFilter && ( seed || !selector ) ?
-				condense( elems, preMap, preFilter, context, xml ) :
-				elems,
-
-			matcherOut = matcher ?
-				// If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results,
-				postFinder || ( seed ? preFilter : preexisting || postFilter ) ?
-
-					// ...intermediate processing is necessary
-					[] :
-
-					// ...otherwise use results directly
-					results :
-				matcherIn;
-
-		// Find primary matches
-		if ( matcher ) {
-			matcher( matcherIn, matcherOut, context, xml );
-		}
-
-		// Apply postFilter
-		if ( postFilter ) {
-			temp = condense( matcherOut, postMap );
-			postFilter( temp, [], context, xml );
-
-			// Un-match failing elements by moving them back to matcherIn
-			i = temp.length;
-			while ( i-- ) {
-				if ( (elem = temp[i]) ) {
-					matcherOut[ postMap[i] ] = !(matcherIn[ postMap[i] ] = elem);
-				}
-			}
-		}
-
-		if ( seed ) {
-			if ( postFinder || preFilter ) {
-				if ( postFinder ) {
-					// Get the final matcherOut by condensing this intermediate into postFinder contexts
-					temp = [];
-					i = matcherOut.length;
-					while ( i-- ) {
-						if ( (elem = matcherOut[i]) ) {
-							// Restore matcherIn since elem is not yet a final match
-							temp.push( (matcherIn[i] = elem) );
-						}
-					}
-					postFinder( null, (matcherOut = []), temp, xml );
-				}
-
-				// Move matched elements from seed to results to keep them synchronized
-				i = matcherOut.length;
-				while ( i-- ) {
-					if ( (elem = matcherOut[i]) &&
-						(temp = postFinder ? indexOf( seed, elem ) : preMap[i]) > -1 ) {
-
-						seed[temp] = !(results[temp] = elem);
-					}
-				}
-			}
-
-		// Add elements to results, through postFinder if defined
-		} else {
-			matcherOut = condense(
-				matcherOut === results ?
-					matcherOut.splice( preexisting, matcherOut.length ) :
-					matcherOut
-			);
-			if ( postFinder ) {
-				postFinder( null, results, matcherOut, xml );
-			} else {
-				push.apply( results, matcherOut );
-			}
-		}
-	});
-}
-
-function matcherFromTokens( tokens ) {
-	var checkContext, matcher, j,
-		len = tokens.length,
-		leadingRelative = Expr.relative[ tokens[0].type ],
-		implicitRelative = leadingRelative || Expr.relative[" "],
-		i = leadingRelative ? 1 : 0,
-
-		// The foundational matcher ensures that elements are reachable from top-level context(s)
-		matchContext = addCombinator( function( elem ) {
-			return elem === checkContext;
-		}, implicitRelative, true ),
-		matchAnyContext = addCombinator( function( elem ) {
-			return indexOf( checkContext, elem ) > -1;
-		}, implicitRelative, true ),
-		matchers = [ function( elem, context, xml ) {
-			var ret = ( !leadingRelative && ( xml || context !== outermostContext ) ) || (
-				(checkContext = context).nodeType ?
-					matchContext( elem, context, xml ) :
-					matchAnyContext( elem, context, xml ) );
-			// Avoid hanging onto element (issue #299)
-			checkContext = null;
-			return ret;
-		} ];
-
-	for ( ; i < len; i++ ) {
-		if ( (matcher = Expr.relative[ tokens[i].type ]) ) {
-			matchers = [ addCombinator(elementMatcher( matchers ), matcher) ];
-		} else {
-			matcher = Expr.filter[ tokens[i].type ].apply( null, tokens[i].matches );
-
-			// Return special upon seeing a positional matcher
-			if ( matcher[ expando ] ) {
-				// Find the next relative operator (if any) for proper handling
-				j = ++i;
-				for ( ; j < len; j++ ) {
-					if ( Expr.relative[ tokens[j].type ] ) {
-						break;
-					}
-				}
-				return setMatcher(
-					i > 1 && elementMatcher( matchers ),
-					i > 1 && toSelector(
-						// If the preceding token was a descendant combinator, insert an implicit any-element `*`
-						tokens.slice( 0, i - 1 ).concat({ value: tokens[ i - 2 ].type === " " ? "*" : "" })
-					).replace( rtrim, "$1" ),
-					matcher,
-					i < j && matcherFromTokens( tokens.slice( i, j ) ),
-					j < len && matcherFromTokens( (tokens = tokens.slice( j )) ),
-					j < len && toSelector( tokens )
-				);
-			}
-			matchers.push( matcher );
-		}
-	}
-
-	return elementMatcher( matchers );
-}
-
-function matcherFromGroupMatchers( elementMatchers, setMatchers ) {
-	var bySet = setMatchers.length > 0,
-		byElement = elementMatchers.length > 0,
-		superMatcher = function( seed, context, xml, results, outermost ) {
-			var elem, j, matcher,
-				matchedCount = 0,
-				i = "0",
-				unmatched = seed && [],
-				setMatched = [],
-				contextBackup = outermostContext,
-				// We must always have either seed elements or outermost context
-				elems = seed || byElement && Expr.find["TAG"]( "*", outermost ),
-				// Use integer dirruns iff this is the outermost matcher
-				dirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.random() || 0.1),
-				len = elems.length;
-
-			if ( outermost ) {
-				outermostContext = context === document || context || outermost;
-			}
-
-			// Add elements passing elementMatchers directly to results
-			// Support: IE<9, Safari
-			// Tolerate NodeList properties (IE: "length"; Safari: <number>) matching elements by id
-			for ( ; i !== len && (elem = elems[i]) != null; i++ ) {
-				if ( byElement && elem ) {
-					j = 0;
-					if ( !context && elem.ownerDocument !== document ) {
-						setDocument( elem );
-						xml = !documentIsHTML;
-					}
-					while ( (matcher = elementMatchers[j++]) ) {
-						if ( matcher( elem, context || document, xml) ) {
-							results.push( elem );
-							break;
-						}
-					}
-					if ( outermost ) {
-						dirruns = dirrunsUnique;
-					}
-				}
-
-				// Track unmatched elements for set filters
-				if ( bySet ) {
-					// They will have gone through all possible matchers
-					if ( (elem = !matcher && elem) ) {
-						matchedCount--;
-					}
-
-					// Lengthen the array for every element, matched or not
-					if ( seed ) {
-						unmatched.push( elem );
-					}
-				}
-			}
-
-			// `i` is now the count of elements visited above, and adding it to `matchedCount`
-			// makes the latter nonnegative.
-			matchedCount += i;
-
-			// Apply set filters to unmatched elements
-			// NOTE: This can be skipped if there are no unmatched elements (i.e., `matchedCount`
-			// equals `i`), unless we didn't visit _any_ elements in the above loop because we have
-			// no element matchers and no seed.
-			// Incrementing an initially-string "0" `i` allows `i` to remain a string only in that
-			// case, which will result in a "00" `matchedCount` that differs from `i` but is also
-			// numerically zero.
-			if ( bySet && i !== matchedCount ) {
-				j = 0;
-				while ( (matcher = setMatchers[j++]) ) {
-					matcher( unmatched, setMatched, context, xml );
-				}
-
-				if ( seed ) {
-					// Reintegrate element matches to eliminate the need for sorting
-					if ( matchedCount > 0 ) {
-						while ( i-- ) {
-							if ( !(unmatched[i] || setMatched[i]) ) {
-								setMatched[i] = pop.call( results );
-							}
-						}
-					}
-
-					// Discard index placeholder values to get only actual matches
-					setMatched = condense( setMatched );
-				}
-
-				// Add matches to results
-				push.apply( results, setMatched );
-
-				// Seedless set matches succeeding multiple successful matchers stipulate sorting
-				if ( outermost && !seed && setMatched.length > 0 &&
-					( matchedCount + setMatchers.length ) > 1 ) {
-
-					Sizzle.uniqueSort( results );
-				}
-			}
-
-			// Override manipulation of globals by nested matchers
-			if ( outermost ) {
-				dirruns = dirrunsUnique;
-				outermostContext = contextBackup;
-			}
-
-			return unmatched;
-		};
-
-	return bySet ?
-		markFunction( superMatcher ) :
-		superMatcher;
-}
-
-compile = Sizzle.compile = function( selector, match /* Internal Use Only */ ) {
-	var i,
-		setMatchers = [],
-		elementMatchers = [],
-		cached = compilerCache[ selector + " " ];
-
-	if ( !cached ) {
-		// Generate a function of recursive functions that can be used to check each element
-		if ( !match ) {
-			match = tokenize( selector );
-		}
-		i = match.length;
-		while ( i-- ) {
-			cached = matcherFromTokens( match[i] );
-			if ( cached[ expando ] ) {
-				setMatchers.push( cached );
-			} else {
-				elementMatchers.push( cached );
-			}
-		}
-
-		// Cache the compiled function
-		cached = compilerCache( selector, matcherFromGroupMatchers( elementMatchers, setMatchers ) );
-
-		// Save selector and tokenization
-		cached.selector = selector;
-	}
-	return cached;
-};
-
-/**
- * A low-level selection function that works with Sizzle's compiled
- *  selector functions
- * @param {String|Function} selector A selector or a pre-compiled
- *  selector function built with Sizzle.compile
- * @param {Element} context
- * @param {Array} [results]
- * @param {Array} [seed] A set of elements to match against
- */
-select = Sizzle.select = function( selector, context, results, seed ) {
-	var i, tokens, token, type, find,
-		compiled = typeof selector === "function" && selector,
-		match = !seed && tokenize( (selector = compiled.selector || selector) );
-
-	results = results || [];
-
-	// Try to minimize operations if there is only one selector in the list and no seed
-	// (the latter of which guarantees us context)
-	if ( match.length === 1 ) {
-
-		// Reduce context if the leading compound selector is an ID
-		tokens = match[0] = match[0].slice( 0 );
-		if ( tokens.length > 2 && (token = tokens[0]).type === "ID" &&
-				support.getById && context.nodeType === 9 && documentIsHTML &&
-				Expr.relative[ tokens[1].type ] ) {
-
-			context = ( Expr.find["ID"]( token.matches[0].replace(runescape, funescape), context ) || [] )[0];
-			if ( !context ) {
-				return results;
-
-			// Precompiled matchers will still verify ancestry, so step up a level
-			} else if ( compiled ) {
-				context = context.parentNode;
-			}
-
-			selector = selector.slice( tokens.shift().value.length );
-		}
-
-		// Fetch a seed set for right-to-left matching
-		i = matchExpr["needsContext"].test( selector ) ? 0 : tokens.length;
-		while ( i-- ) {
-			token = tokens[i];
-
-			// Abort if we hit a combinator
-			if ( Expr.relative[ (type = token.type) ] ) {
-				break;
-			}
-			if ( (find = Expr.find[ type ]) ) {
-				// Search, expanding context for leading sibling combinators
-				if ( (seed = find(
-					token.matches[0].replace( runescape, funescape ),
-					rsibling.test( tokens[0].type ) && testContext( context.parentNode ) || context
-				)) ) {
-
-					// If seed is empty or no tokens remain, we can return early
-					tokens.splice( i, 1 );
-					selector = seed.length && toSelector( tokens );
-					if ( !selector ) {
-						push.apply( results, seed );
-						return results;
-					}
-
-					break;
-				}
-			}
-		}
-	}
-
-	// Compile and execute a filtering function if one is not provided
-	// Provide `match` to avoid retokenization if we modified the selector above
-	( compiled || compile( selector, match ) )(
-		seed,
-		context,
-		!documentIsHTML,
-		results,
-		!context || rsibling.test( selector ) && testContext( context.parentNode ) || context
-	);
-	return results;
-};
-
-// One-time assignments
-
-// Sort stability
-support.sortStable = expando.split("").sort( sortOrder ).join("") === expando;
-
-// Support: Chrome 14-35+
-// Always assume duplicates if they aren't passed to the comparison function
-support.detectDuplicates = !!hasDuplicate;
-
-// Initialize against the default document
-setDocument();
-
-// Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27)
-// Detached nodes confoundingly follow *each other*
-support.sortDetached = assert(function( div1 ) {
-	// Should return 1, but returns 4 (following)
-	return div1.compareDocumentPosition( document.createElement("div") ) & 1;
-});
-
-// Support: IE<8
-// Prevent attribute/property "interpolation"
-// http://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx
-if ( !assert(function( div ) {
-	div.innerHTML = "<a href='#'></a>";
-	return div.firstChild.getAttribute("href") === "#" ;
-}) ) {
-	addHandle( "type|href|height|width", function( elem, name, isXML ) {
-		if ( !isXML ) {
-			return elem.getAttribute( name, name.toLowerCase() === "type" ? 1 : 2 );
-		}
-	});
-}
-
-// Support: IE<9
-// Use defaultValue in place of getAttribute("value")
-if ( !support.attributes || !assert(function( div ) {
-	div.innerHTML = "<input/>";
-	div.firstChild.setAttribute( "value", "" );
-	return div.firstChild.getAttribute( "value" ) === "";
-}) ) {
-	addHandle( "value", function( elem, name, isXML ) {
-		if ( !isXML && elem.nodeName.toLowerCase() === "input" ) {
-			return elem.defaultValue;
-		}
-	});
-}
-
-// Support: IE<9
-// Use getAttributeNode to fetch booleans when getAttribute lies
-if ( !assert(function( div ) {
-	return div.getAttribute("disabled") == null;
-}) ) {
-	addHandle( booleans, function( elem, name, isXML ) {
-		var val;
-		if ( !isXML ) {
-			return elem[ name ] === true ? name.toLowerCase() :
-					(val = elem.getAttributeNode( name )) && val.specified ?
-					val.value :
-				null;
-		}
-	});
-}
-
-return Sizzle;
-
-})( window );
-
-
-
-jQuery.find = Sizzle;
-jQuery.expr = Sizzle.selectors;
-jQuery.expr[ ":" ] = jQuery.expr.pseudos;
-jQuery.uniqueSort = jQuery.unique = Sizzle.uniqueSort;
-jQuery.text = Sizzle.getText;
-jQuery.isXMLDoc = Sizzle.isXML;
-jQuery.contains = Sizzle.contains;
-
-
-
-var dir = function( elem, dir, until ) {
-	var matched = [],
-		truncate = until !== undefined;
-
-	while ( ( elem = elem[ dir ] ) && elem.nodeType !== 9 ) {
-		if ( elem.nodeType === 1 ) {
-			if ( truncate && jQuery( elem ).is( until ) ) {
-				break;
-			}
-			matched.push( elem );
-		}
-	}
-	return matched;
-};
-
-
-var siblings = function( n, elem ) {
-	var matched = [];
-
-	for ( ; n; n = n.nextSibling ) {
-		if ( n.nodeType === 1 && n !== elem ) {
-			matched.push( n );
-		}
-	}
-
-	return matched;
-};
-
-
-var rneedsContext = jQuery.expr.match.needsContext;
-
-var rsingleTag = ( /^<([\w-]+)\s*\/?>(?:<\/\1>|)$/ );
-
-
-
-var risSimple = /^.[^:#\[\.,]*$/;
-
-// Implement the identical functionality for filter and not
-function winnow( elements, qualifier, not ) {
-	if ( jQuery.isFunction( qualifier ) ) {
-		return jQuery.grep( elements, function( elem, i ) {
-			/* jshint -W018 */
-			return !!qualifier.call( elem, i, elem ) !== not;
-		} );
-
-	}
-
-	if ( qualifier.nodeType ) {
-		return jQuery.grep( elements, function( elem ) {
-			return ( elem === qualifier ) !== not;
-		} );
-
-	}
-
-	if ( typeof qualifier === "string" ) {
-		if ( risSimple.test( qualifier ) ) {
-			return jQuery.filter( qualifier, elements, not );
-		}
-
-		qualifier = jQuery.filter( qualifier, elements );
-	}
-
-	return jQuery.grep( elements, function( elem ) {
-		return ( indexOf.call( qualifier, elem ) > -1 ) !== not;
-	} );
-}
-
-jQuery.filter = function( expr, elems, not ) {
-	var elem = elems[ 0 ];
-
-	if ( not ) {
-		expr = ":not(" + expr + ")";
-	}
-
-	return elems.length === 1 && elem.nodeType === 1 ?
-		jQuery.find.matchesSelector( elem, expr ) ? [ elem ] : [] :
-		jQuery.find.matches( expr, jQuery.grep( elems, function( elem ) {
-			return elem.nodeType === 1;
-		} ) );
-};
-
-jQuery.fn.extend( {
-	find: function( selector ) {
-		var i,
-			len = this.length,
-			ret = [],
-			self = this;
-
-		if ( typeof selector !== "string" ) {
-			return this.pushStack( jQuery( selector ).filter( function() {
-				for ( i = 0; i < len; i++ ) {
-					if ( jQuery.contains( self[ i ], this ) ) {
-						return true;
-					}
-				}
-			} ) );
-		}
-
-		for ( i = 0; i < len; i++ ) {
-			jQuery.find( selector, self[ i ], ret );
-		}
-
-		// Needed because $( selector, context ) becomes $( context ).find( selector )
-		ret = this.pushStack( len > 1 ? jQuery.unique( ret ) : ret );
-		ret.selector = this.selector ? this.selector + " " + selector : selector;
-		return ret;
-	},
-	filter: function( selector ) {
-		return this.pushStack( winnow( this, selector || [], false ) );
-	},
-	not: function( selector ) {
-		return this.pushStack( winnow( this, selector || [], true ) );
-	},
-	is: function( selector ) {
-		return !!winnow(
-			this,
-
-			// If this is a positional/relative selector, check membership in the returned set
-			// so $("p:first").is("p:last") won't return true for a doc with two "p".
-			typeof selector === "string" && rneedsContext.test( selector ) ?
-				jQuery( selector ) :
-				selector || [],
-			false
-		).length;
-	}
-} );
-
-
-// Initialize a jQuery object
-
-
-// A central reference to the root jQuery(document)
-var rootjQuery,
-
-	// A simple way to check for HTML strings
-	// Prioritize #id over <tag> to avoid XSS via location.hash (#9521)
-	// Strict HTML recognition (#11290: must start with <)
-	rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,
-
-	init = jQuery.fn.init = function( selector, context, root ) {
-		var match, elem;
-
-		// HANDLE: $(""), $(null), $(undefined), $(false)
-		if ( !selector ) {
-			return this;
-		}
-
-		// Method init() accepts an alternate rootjQuery
-		// so migrate can support jQuery.sub (gh-2101)
-		root = root || rootjQuery;
-
-		// Handle HTML strings
-		if ( typeof selector === "string" ) {
-			if ( selector[ 0 ] === "<" &&
-				selector[ selector.length - 1 ] === ">" &&
-				selector.length >= 3 ) {
-
-				// Assume that strings that start and end with <> are HTML and skip the regex check
-				match = [ null, selector, null ];
-
-			} else {
-				match = rquickExpr.exec( selector );
-			}
-
-			// Match html or make sure no context is specified for #id
-			if ( match && ( match[ 1 ] || !context ) ) {
-
-				// HANDLE: $(html) -> $(array)
-				if ( match[ 1 ] ) {
-					context = context instanceof jQuery ? context[ 0 ] : context;
-
-					// Option to run scripts is true for back-compat
-					// Intentionally let the error be thrown if parseHTML is not present
-					jQuery.merge( this, jQuery.parseHTML(
-						match[ 1 ],
-						context && context.nodeType ? context.ownerDocument || context : document,
-						true
-					) );
-
-					// HANDLE: $(html, props)
-					if ( rsingleTag.test( match[ 1 ] ) && jQuery.isPlainObject( context ) ) {
-						for ( match in context ) {
-
-							// Properties of context are called as methods if possible
-							if ( jQuery.isFunction( this[ match ] ) ) {
-								this[ match ]( context[ match ] );
-
-							// ...and otherwise set as attributes
-							} else {
-								this.attr( match, context[ match ] );
-							}
-						}
-					}
-
-					return this;
-
-				// HANDLE: $(#id)
-				} else {
-					elem = document.getElementById( match[ 2 ] );
-
-					// Support: Blackberry 4.6
-					// gEBID returns nodes no longer in the document (#6963)
-					if ( elem && elem.parentNode ) {
-
-						// Inject the element directly into the jQuery object
-						this.length = 1;
-						this[ 0 ] = elem;
-					}
-
-					this.context = document;
-					this.selector = selector;
-					return this;
-				}
-
-			// HANDLE: $(expr, $(...))
-			} else if ( !context || context.jquery ) {
-				return ( context || root ).find( selector );
-
-			// HANDLE: $(expr, context)
-			// (which is just equivalent to: $(context).find(expr)
-			} else {
-				return this.constructor( context ).find( selector );
-			}
-
-		// HANDLE: $(DOMElement)
-		} else if ( selector.nodeType ) {
-			this.context = this[ 0 ] = selector;
-			this.length = 1;
-			return this;
-
-		// HANDLE: $(function)
-		// Shortcut for document ready
-		} else if ( jQuery.isFunction( selector ) ) {
-			return root.ready !== undefined ?
-				root.ready( selector ) :
-
-				// Execute immediately if ready is not present
-				selector( jQuery );
-		}
-
-		if ( selector.selector !== undefined ) {
-			this.selector = selector.selector;
-			this.context = selector.context;
-		}
-
-		return jQuery.makeArray( selector, this );
-	};
-
-// Give the init function the jQuery prototype for later instantiation
-init.prototype = jQuery.fn;
-
-// Initialize central reference
-rootjQuery = jQuery( document );
-
-
-var rparentsprev = /^(?:parents|prev(?:Until|All))/,
-
-	// Methods guaranteed to produce a unique set when starting from a unique set
-	guaranteedUnique = {
-		children: true,
-		contents: true,
-		next: true,
-		prev: true
-	};
-
-jQuery.fn.extend( {
-	has: function( target ) {
-		var targets = jQuery( target, this ),
-			l = targets.length;
-
-		return this.filter( function() {
-			var i = 0;
-			for ( ; i < l; i++ ) {
-				if ( jQuery.contains( this, targets[ i ] ) ) {
-					return true;
-				}
-			}
-		} );
-	},
-
-	closest: function( selectors, context ) {
-		var cur,
-			i = 0,
-			l = this.length,
-			matched = [],
-			pos = rneedsContext.test( selectors ) || typeof selectors !== "string" ?
-				jQuery( selectors, context || this.context ) :
-				0;
-
-		for ( ; i < l; i++ ) {
-			for ( cur = this[ i ]; cur && cur !== context; cur = cur.parentNode ) {
-
-				// Always skip document fragments
-				if ( cur.nodeType < 11 && ( pos ?
-					pos.index( cur ) > -1 :
-
-					// Don't pass non-elements to Sizzle
-					cur.nodeType === 1 &&
-						jQuery.find.matchesSelector( cur, selectors ) ) ) {
-
-					matched.push( cur );
-					break;
-				}
-			}
-		}
-
-		return this.pushStack( matched.length > 1 ? jQuery.uniqueSort( matched ) : matched );
-	},
-
-	// Determine the position of an element within the set
-	index: function( elem ) {
-
-		// No argument, return index in parent
-		if ( !elem ) {
-			return ( this[ 0 ] && this[ 0 ].parentNode ) ? this.first().prevAll().length : -1;
-		}
-
-		// Index in selector
-		if ( typeof elem === "string" ) {
-			return indexOf.call( jQuery( elem ), this[ 0 ] );
-		}
-
-		// Locate the position of the desired element
-		return indexOf.call( this,
-
-			// If it receives a jQuery object, the first element is used
-			elem.jquery ? elem[ 0 ] : elem
-		);
-	},
-
-	add: function( selector, context ) {
-		return this.pushStack(
-			jQuery.uniqueSort(
-				jQuery.merge( this.get(), jQuery( selector, context ) )
-			)
-		);
-	},
-
-	addBack: function( selector ) {
-		return this.add( selector == null ?
-			this.prevObject : this.prevObject.filter( selector )
-		);
-	}
-} );
-
-function sibling( cur, dir ) {
-	while ( ( cur = cur[ dir ] ) && cur.nodeType !== 1 ) {}
-	return cur;
-}
-
-jQuery.each( {
-	parent: function( elem ) {
-		var parent = elem.parentNode;
-		return parent && parent.nodeType !== 11 ? parent : null;
-	},
-	parents: function( elem ) {
-		return dir( elem, "parentNode" );
-	},
-	parentsUntil: function( elem, i, until ) {
-		return dir( elem, "parentNode", until );
-	},
-	next: function( elem ) {
-		return sibling( elem, "nextSibling" );
-	},
-	prev: function( elem ) {
-		return sibling( elem, "previousSibling" );
-	},
-	nextAll: function( elem ) {
-		return dir( elem, "nextSibling" );
-	},
-	prevAll: function( elem ) {
-		return dir( elem, "previousSibling" );
-	},
-	nextUntil: function( elem, i, until ) {
-		return dir( elem, "nextSibling", until );
-	},
-	prevUntil: function( elem, i, until ) {
-		return dir( elem, "previousSibling", until );
-	},
-	siblings: function( elem ) {
-		return siblings( ( elem.parentNode || {} ).firstChild, elem );
-	},
-	children: function( elem ) {
-		return siblings( elem.firstChild );
-	},
-	contents: function( elem ) {
-		return elem.contentDocument || jQuery.merge( [], elem.childNodes );
-	}
-}, function( name, fn ) {
-	jQuery.fn[ name ] = function( until, selector ) {
-		var matched = jQuery.map( this, fn, until );
-
-		if ( name.slice( -5 ) !== "Until" ) {
-			selector = until;
-		}
-
-		if ( selector && typeof selector === "string" ) {
-			matched = jQuery.filter( selector, matched );
-		}
-
-		if ( this.length > 1 ) {
-
-			// Remove duplicates
-			if ( !guaranteedUnique[ name ] ) {
-				jQuery.uniqueSort( matched );
-			}
-
-			// Reverse order for parents* and prev-derivatives
-			if ( rparentsprev.test( name ) ) {
-				matched.reverse();
-			}
-		}
-
-		return this.pushStack( matched );
-	};
-} );
-var rnotwhite = ( /\S+/g );
-
-
-
-// Convert String-formatted options into Object-formatted ones
-function createOptions( options ) {
-	var object = {};
-	jQuery.each( options.match( rnotwhite ) || [], function( _, flag ) {
-		object[ flag ] = true;
-	} );
-	return object;
-}
-
-/*
- * Create a callback list using the following parameters:
- *
- *	options: an optional list of space-separated options that will change how
- *			the callback list behaves or a more traditional option object
- *
- * By default a callback list will act like an event callback list and can be
- * "fired" multiple times.
- *
- * Possible options:
- *
- *	once:			will ensure the callback list can only be fired once (like a Deferred)
- *
- *	memory:			will keep track of previous values and will call any callback added
- *					after the list has been fired right away with the latest "memorized"
- *					values (like a Deferred)
- *
- *	unique:			will ensure a callback can only be added once (no duplicate in the list)
- *
- *	stopOnFalse:	interrupt callings when a callback returns false
- *
- */
-jQuery.Callbacks = function( options ) {
-
-	// Convert options from String-formatted to Object-formatted if needed
-	// (we check in cache first)
-	options = typeof options === "string" ?
-		createOptions( options ) :
-		jQuery.extend( {}, options );
-
-	var // Flag to know if list is currently firing
-		firing,
-
-		// Last fire value for non-forgettable lists
-		memory,
-
-		// Flag to know if list was already fired
-		fired,
-
-		// Flag to prevent firing
-		locked,
-
-		// Actual callback list
-		list = [],
-
-		// Queue of execution data for repeatable lists
-		queue = [],
-
-		// Index of currently firing callback (modified by add/remove as needed)
-		firingIndex = -1,
-
-		// Fire callbacks
-		fire = function() {
-
-			// Enforce single-firing
-			locked = options.once;
-
-			// Execute callbacks for all pending executions,
-			// respecting firingIndex overrides and runtime changes
-			fired = firing = true;
-			for ( ; queue.length; firingIndex = -1 ) {
-				memory = queue.shift();
-				while ( ++firingIndex < list.length ) {
-
-					// Run callback and check for early termination
-					if ( list[ firingIndex ].apply( memory[ 0 ], memory[ 1 ] ) === false &&
-						options.stopOnFalse ) {
-
-						// Jump to end and forget the data so .add doesn't re-fire
-						firingIndex = list.length;
-						memory = false;
-					}
-				}
-			}
-
-			// Forget the data if we're done with it
-			if ( !options.memory ) {
-				memory = false;
-			}
-
-			firing = false;
-
-			// Clean up if we're done firing for good
-			if ( locked ) {
-
-				// Keep an empty list if we have data for future add calls
-				if ( memory ) {
-					list = [];
-
-				// Otherwise, this object is spent
-				} else {
-					list = "";
-				}
-			}
-		},
-
-		// Actual Callbacks object
-		self = {
-
-			// Add a callback or a collection of callbacks to the list
-			add: function() {
-				if ( list ) {
-
-					// If we have memory from a past run, we should fire after adding
-					if ( memory && !firing ) {
-						firingIndex = list.length - 1;
-						queue.push( memory );
-					}
-
-					( function add( args ) {
-						jQuery.each( args, function( _, arg ) {
-							if ( jQuery.isFunction( arg ) ) {
-								if ( !options.unique || !self.has( arg ) ) {
-									list.push( arg );
-								}
-							} else if ( arg && arg.length && jQuery.type( arg ) !== "string" ) {
-
-								// Inspect recursively
-								add( arg );
-							}
-						} );
-					} )( arguments );
-
-					if ( memory && !firing ) {
-						fire();
-					}
-				}
-				return this;
-			},
-
-			// Remove a callback from the list
-			remove: function() {
-				jQuery.each( arguments, function( _, arg ) {
-					var index;
-					while ( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) {
-						list.splice( index, 1 );
-
-						// Handle firing indexes
-						if ( index <= firingIndex ) {
-							firingIndex--;
-						}
-					}
-				} );
-				return this;
-			},
-
-			// Check if a given callback is in the list.
-			// If no argument is given, return whether or not list has callbacks attached.
-			has: function( fn ) {
-				return fn ?
-					jQuery.inArray( fn, list ) > -1 :
-					list.length > 0;
-			},
-
-			// Remove all callbacks from the list
-			empty: function() {
-				if ( list ) {
-					list = [];
-				}
-				return this;
-			},
-
-			// Disable .fire and .add
-			// Abort any current/pending executions
-			// Clear all callbacks and values
-			disable: function() {
-				locked = queue = [];
-				list = memory = "";
-				return this;
-			},
-			disabled: function() {
-				return !list;
-			},
-
-			// Disable .fire
-			// Also disable .add unless we have memory (since it would have no effect)
-			// Abort any pending executions
-			lock: function() {
-				locked = queue = [];
-				if ( !memory ) {
-					list = memory = "";
-				}
-				return this;
-			},
-			locked: function() {
-				return !!locked;
-			},
-
-			// Call all callbacks with the given context and arguments
-			fireWith: function( context, args ) {
-				if ( !locked ) {
-					args = args || [];
-					args = [ context, args.slice ? args.slice() : args ];
-					queue.push( args );
-					if ( !firing ) {
-						fire();
-					}
-				}
-				return this;
-			},
-
-			// Call all the callbacks with the given arguments
-			fire: function() {
-				self.fireWith( this, arguments );
-				return this;
-			},
-
-			// To know if the callbacks have already been called at least once
-			fired: function() {
-				return !!fired;
-			}
-		};
-
-	return self;
-};
-
-
-jQuery.extend( {
-
-	Deferred: function( func ) {
-		var tuples = [
-
-				// action, add listener, listener list, final state
-				[ "resolve", "done", jQuery.Callbacks( "once memory" ), "resolved" ],
-				[ "reject", "fail", jQuery.Callbacks( "once memory" ), "rejected" ],
-				[ "notify", "progress", jQuery.Callbacks( "memory" ) ]
-			],
-			state = "pending",
-			promise = {
-				state: function() {
-					return state;
-				},
-				always: function() {
-					deferred.done( arguments ).fail( arguments );
-					return this;
-				},
-				then: function( /* fnDone, fnFail, fnProgress */ ) {
-					var fns = arguments;
-					return jQuery.Deferred( function( newDefer ) {
-						jQuery.each( tuples, function( i, tuple ) {
-							var fn = jQuery.isFunction( fns[ i ] ) && fns[ i ];
-
-							// deferred[ done | fail | progress ] for forwarding actions to newDefer
-							deferred[ tuple[ 1 ] ]( function() {
-								var returned = fn && fn.apply( this, arguments );
-								if ( returned && jQuery.isFunction( returned.promise ) ) {
-									returned.promise()
-										.progress( newDefer.notify )
-										.done( newDefer.resolve )
-										.fail( newDefer.reject );
-								} else {
-									newDefer[ tuple[ 0 ] + "With" ](
-										this === promise ? newDefer.promise() : this,
-										fn ? [ returned ] : arguments
-									);
-								}
-							} );
-						} );
-						fns = null;
-					} ).promise();
-				},
-
-				// Get a promise for this deferred
-				// If obj is provided, the promise aspect is added to the object
-				promise: function( obj ) {
-					return obj != null ? jQuery.extend( obj, promise ) : promise;
-				}
-			},
-			deferred = {};
-
-		// Keep pipe for back-compat
-		promise.pipe = promise.then;
-
-		// Add list-specific methods
-		jQuery.each( tuples, function( i, tuple ) {
-			var list = tuple[ 2 ],
-				stateString = tuple[ 3 ];
-
-			// promise[ done | fail | progress ] = list.add
-			promise[ tuple[ 1 ] ] = list.add;
-
-			// Handle state
-			if ( stateString ) {
-				list.add( function() {
-
-					// state = [ resolved | rejected ]
-					state = stateString;
-
-				// [ reject_list | resolve_list ].disable; progress_list.lock
-				}, tuples[ i ^ 1 ][ 2 ].disable, tuples[ 2 ][ 2 ].lock );
-			}
-
-			// deferred[ resolve | reject | notify ]
-			deferred[ tuple[ 0 ] ] = function() {
-				deferred[ tuple[ 0 ] + "With" ]( this === deferred ? promise : this, arguments );
-				return this;
-			};
-			deferred[ tuple[ 0 ] + "With" ] = list.fireWith;
-		} );
-
-		// Make the deferred a promise
-		promise.promise( deferred );
-
-		// Call given func if any
-		if ( func ) {
-			func.call( deferred, deferred );
-		}
-
-		// All done!
-		return deferred;
-	},
-
-	// Deferred helper
-	when: function( subordinate /* , ..., subordinateN */ ) {
-		var i = 0,
-			resolveValues = slice.call( arguments ),
-			length = resolveValues.length,
-
-			// the count of uncompleted subordinates
-			remaining = length !== 1 ||
-				( subordinate && jQuery.isFunction( subordinate.promise ) ) ? length : 0,
-
-			// the master Deferred.
-			// If resolveValues consist of only a single Deferred, just use that.
-			deferred = remaining === 1 ? subordinate : jQuery.Deferred(),
-
-			// Update function for both resolve and progress values
-			updateFunc = function( i, contexts, values ) {
-				return function( value ) {
-					contexts[ i ] = this;
-					values[ i ] = arguments.length > 1 ? slice.call( arguments ) : value;
-					if ( values === progressValues ) {
-						deferred.notifyWith( contexts, values );
-					} else if ( !( --remaining ) ) {
-						deferred.resolveWith( contexts, values );
-					}
-				};
-			},
-
-			progressValues, progressContexts, resolveContexts;
-
-		// Add listeners to Deferred subordinates; treat others as resolved
-		if ( length > 1 ) {
-			progressValues = new Array( length );
-			progressContexts = new Array( length );
-			resolveContexts = new Array( length );
-			for ( ; i < length; i++ ) {
-				if ( resolveValues[ i ] && jQuery.isFunction( resolveValues[ i ].promise ) ) {
-					resolveValues[ i ].promise()
-						.progress( updateFunc( i, progressContexts, progressValues ) )
-						.done( updateFunc( i, resolveContexts, resolveValues ) )
-						.fail( deferred.reject );
-				} else {
-					--remaining;
-				}
-			}
-		}
-
-		// If we're not waiting on anything, resolve the master
-		if ( !remaining ) {
-			deferred.resolveWith( resolveContexts, resolveValues );
-		}
-
-		return deferred.promise();
-	}
-} );
-
-
-// The deferred used on DOM ready
-var readyList;
-
-jQuery.fn.ready = function( fn ) {
-
-	// Add the callback
-	jQuery.ready.promise().done( fn );
-
-	return this;
-};
-
-jQuery.extend( {
-
-	// Is the DOM ready to be used? Set to true once it occurs.
-	isReady: false,
-
-	// A counter to track how many items to wait for before
-	// the ready event fires. See #6781
-	readyWait: 1,
-
-	// Hold (or release) the ready event
-	holdReady: function( hold ) {
-		if ( hold ) {
-			jQuery.readyWait++;
-		} else {
-			jQuery.ready( true );
-		}
-	},
-
-	// Handle when the DOM is ready
-	ready: function( wait ) {
-
-		// Abort if there are pending holds or we're already ready
-		if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) {
-			return;
-		}
-
-		// Remember that the DOM is ready
-		jQuery.isReady = true;
-
-		// If a normal DOM Ready event fired, decrement, and wait if need be
-		if ( wait !== true && --jQuery.readyWait > 0 ) {
-			return;
-		}
-
-		// If there are functions bound, to execute
-		readyList.resolveWith( document, [ jQuery ] );
-
-		// Trigger any bound ready events
-		if ( jQuery.fn.triggerHandler ) {
-			jQuery( document ).triggerHandler( "ready" );
-			jQuery( document ).off( "ready" );
-		}
-	}
-} );
-
-/**
- * The ready event handler and self cleanup method
- */
-function completed() {
-	document.removeEventListener( "DOMContentLoaded", completed );
-	window.removeEventListener( "load", completed );
+// The DOM ready check for Internet Explorer
+function doScrollCheck() {
+	if ( jQuery.isReady ) {
+		return;
+	}
+
+	try {
+		// If IE is used, use the trick by Diego Perini
+		// http://javascript.nwbox.com/IEContentLoaded/
+		document.documentElement.doScroll("left");
+	} catch( error ) {
+		setTimeout( doScrollCheck, 1 );
+		return;
+	}
+
+	// and execute any waiting functions
 	jQuery.ready();
 }
 
-jQuery.ready.promise = function( obj ) {
-	if ( !readyList ) {
-
-		readyList = jQuery.Deferred();
-
-		// Catch cases where $(document).ready() is called
-		// after the browser event has already occurred.
-		// Support: IE9-10 only
-		// Older IE sometimes signals "interactive" too soon
-		if ( document.readyState === "complete" ||
-			( document.readyState !== "loading" && !document.documentElement.doScroll ) ) {
-
-			// Handle it asynchronously to allow scripts the opportunity to delay ready
-			window.setTimeout( jQuery.ready );
-
+function evalScript( i, elem ) {
+	if ( elem.src ) {
+		jQuery.ajax({
+			url: elem.src,
+			async: false,
+			dataType: "script"
+		});
+	} else {
+		jQuery.globalEval( elem.text || elem.textContent || elem.innerHTML || "" );
+	}
+
+	if ( elem.parentNode ) {
+		elem.parentNode.removeChild( elem );
+	}
+}
+
+// Mutifunctional method to get and set values to a collection
+// The value/s can be optionally by executed if its a function
+function access( elems, key, value, exec, fn, pass ) {
+	var length = elems.length;
+	
+	// Setting many attributes
+	if ( typeof key === "object" ) {
+		for ( var k in key ) {
+			access( elems, k, key[k], exec, fn, value );
+		}
+		return elems;
+	}
+	
+	// Setting one attribute
+	if ( value !== undefined ) {
+		// Optionally, function values get executed if exec is true
+		exec = !pass && exec && jQuery.isFunction(value);
+		
+		for ( var i = 0; i < length; i++ ) {
+			fn( elems[i], key, exec ? value.call( elems[i], i, fn( elems[i], key ) ) : value, pass );
+		}
+		
+		return elems;
+	}
+	
+	// Getting an attribute
+	return length ? fn( elems[0], key ) : undefined;
+}
+
+function now() {
+	return (new Date).getTime();
+}
+(function() {
+
+	jQuery.support = {};
+
+	var root = document.documentElement,
+		script = document.createElement("script"),
+		div = document.createElement("div"),
+		id = "script" + now();
+
+	div.style.display = "none";
+	div.innerHTML = "   <link/><table></table><a href='/a' style='color:red;float:left;opacity:.55;'>a</a><input type='checkbox'/>";
+
+	var all = div.getElementsByTagName("*"),
+		a = div.getElementsByTagName("a")[0];
+
+	// Can't get basic test support
+	if ( !all || !all.length || !a ) {
+		return;
+	}
+
+	jQuery.support = {
+		// IE strips leading whitespace when .innerHTML is used
+		leadingWhitespace: div.firstChild.nodeType === 3,
+
+		// Make sure that tbody elements aren't automatically inserted
+		// IE will insert them into empty tables
+		tbody: !div.getElementsByTagName("tbody").length,
+
+		// Make sure that link elements get serialized correctly by innerHTML
+		// This requires a wrapper element in IE
+		htmlSerialize: !!div.getElementsByTagName("link").length,
+
+		// Get the style information from getAttribute
+		// (IE uses .cssText insted)
+		style: /red/.test( a.getAttribute("style") ),
+
+		// Make sure that URLs aren't manipulated
+		// (IE normalizes it by default)
+		hrefNormalized: a.getAttribute("href") === "/a",
+
+		// Make sure that element opacity exists
+		// (IE uses filter instead)
+		// Use a regex to work around a WebKit issue. See #5145
+		opacity: /^0.55$/.test( a.style.opacity ),
+
+		// Verify style float existence
+		// (IE uses styleFloat instead of cssFloat)
+		cssFloat: !!a.style.cssFloat,
+
+		// Make sure that if no value is specified for a checkbox
+		// that it defaults to "on".
+		// (WebKit defaults to "" instead)
+		checkOn: div.getElementsByTagName("input")[0].value === "on",
+
+		// Make sure that a selected-by-default option has a working selected property.
+		// (WebKit defaults to false instead of true, IE too, if it's in an optgroup)
+		optSelected: document.createElement("select").appendChild( document.createElement("option") ).selected,
+
+		parentNode: div.removeChild( div.appendChild( document.createElement("div") ) ).parentNode === null,
+
+		// Will be defined later
+		deleteExpando: true,
+		checkClone: false,
+		scriptEval: false,
+		noCloneEvent: true,
+		boxModel: null
+	};
+
+	script.type = "text/javascript";
+	try {
+		script.appendChild( document.createTextNode( "window." + id + "=1;" ) );
+	} catch(e) {}
+
+	root.insertBefore( script, root.firstChild );
+
+	// Make sure that the execution of code works by injecting a script
+	// tag with appendChild/createTextNode
+	// (IE doesn't support this, fails, and uses .text instead)
+	if ( window[ id ] ) {
+		jQuery.support.scriptEval = true;
+		delete window[ id ];
+	}
+
+	// Test to see if it's possible to delete an expando from an element
+	// Fails in Internet Explorer
+	try {
+		delete script.test;
+	
+	} catch(e) {
+		jQuery.support.deleteExpando = false;
+	}
+
+	root.removeChild( script );
+
+	if ( div.attachEvent && div.fireEvent ) {
+		div.attachEvent("onclick", function click() {
+			// Cloning a node shouldn't copy over any
+			// bound event handlers (IE does this)
+			jQuery.support.noCloneEvent = false;
+			div.detachEvent("onclick", click);
+		});
+		div.cloneNode(true).fireEvent("onclick");
+	}
+
+	div = document.createElement("div");
+	div.innerHTML = "<input type='radio' name='radiotest' checked='checked'/>";
+
+	var fragment = document.createDocumentFragment();
+	fragment.appendChild( div.firstChild );
+
+	// WebKit doesn't clone checked state correctly in fragments
+	jQuery.support.checkClone = fragment.cloneNode(true).cloneNode(true).lastChild.checked;
+
+	// Figure out if the W3C box model works as expected
+	// document.body must exist before we can do this
+	jQuery(function() {
+		var div = document.createElement("div");
+		div.style.width = div.style.paddingLeft = "1px";
+
+		document.body.appendChild( div );
+		jQuery.boxModel = jQuery.support.boxModel = div.offsetWidth === 2;
+		document.body.removeChild( div ).style.display = 'none';
+
+		div = null;
+	});
+
+	// Technique from Juriy Zaytsev
+	// http://thinkweb2.com/projects/prototype/detecting-event-support-without-browser-sniffing/
+	var eventSupported = function( eventName ) { 
+		var el = document.createElement("div"); 
+		eventName = "on" + eventName; 
+
+		var isSupported = (eventName in el); 
+		if ( !isSupported ) { 
+			el.setAttribute(eventName, "return;"); 
+			isSupported = typeof el[eventName] === "function"; 
+		} 
+		el = null; 
+
+		return isSupported; 
+	};
+	
+	jQuery.support.submitBubbles = eventSupported("submit");
+	jQuery.support.changeBubbles = eventSupported("change");
+
+	// release memory in IE
+	root = script = div = all = a = null;
+})();
+
+jQuery.props = {
+	"for": "htmlFor",
+	"class": "className",
+	readonly: "readOnly",
+	maxlength: "maxLength",
+	cellspacing: "cellSpacing",
+	rowspan: "rowSpan",
+	colspan: "colSpan",
+	tabindex: "tabIndex",
+	usemap: "useMap",
+	frameborder: "frameBorder"
+};
+var expando = "jQuery" + now(), uuid = 0, windowData = {};
+
+jQuery.extend({
+	cache: {},
+	
+	expando:expando,
+
+	// The following elements throw uncatchable exceptions if you
+	// attempt to add expando properties to them.
+	noData: {
+		"embed": true,
+		"object": true,
+		"applet": true
+	},
+
+	data: function( elem, name, data ) {
+		if ( elem.nodeName && jQuery.noData[elem.nodeName.toLowerCase()] ) {
+			return;
+		}
+
+		elem = elem == window ?
+			windowData :
+			elem;
+
+		var id = elem[ expando ], cache = jQuery.cache, thisCache;
+
+		if ( !id && typeof name === "string" && data === undefined ) {
+			return null;
+		}
+
+		// Compute a unique ID for the element
+		if ( !id ) { 
+			id = ++uuid;
+		}
+
+		// Avoid generating a new cache unless none exists and we
+		// want to manipulate it.
+		if ( typeof name === "object" ) {
+			elem[ expando ] = id;
+			thisCache = cache[ id ] = jQuery.extend(true, {}, name);
+
+		} else if ( !cache[ id ] ) {
+			elem[ expando ] = id;
+			cache[ id ] = {};
+		}
+
+		thisCache = cache[ id ];
+
+		// Prevent overriding the named cache with undefined values
+		if ( data !== undefined ) {
+			thisCache[ name ] = data;
+		}
+
+		return typeof name === "string" ? thisCache[ name ] : thisCache;
+	},
+
+	removeData: function( elem, name ) {
+		if ( elem.nodeName && jQuery.noData[elem.nodeName.toLowerCase()] ) {
+			return;
+		}
+
+		elem = elem == window ?
+			windowData :
+			elem;
+
+		var id = elem[ expando ], cache = jQuery.cache, thisCache = cache[ id ];
+
+		// If we want to remove a specific section of the element's data
+		if ( name ) {
+			if ( thisCache ) {
+				// Remove the section of cache data
+				delete thisCache[ name ];
+
+				// If we've removed all the data, remove the element's cache
+				if ( jQuery.isEmptyObject(thisCache) ) {
+					jQuery.removeData( elem );
+				}
+			}
+
+		// Otherwise, we want to remove all of the element's data
 		} else {
-
-			// Use the handy event callback
-			document.addEventListener( "DOMContentLoaded", completed );
-
-			// A fallback to window.onload, that will always work
-			window.addEventListener( "load", completed );
-		}
-	}
-	return readyList.promise( obj );
-};
-
-// Kick off the DOM ready check even if the user does not
-jQuery.ready.promise();
-
-
-
-
-// Multifunctional method to get and set values of a collection
-// The value/s can optionally be executed if it's a function
-var access = function( elems, fn, key, value, chainable, emptyGet, raw ) {
-	var i = 0,
-		len = elems.length,
-		bulk = key == null;
-
-	// Sets many values
-	if ( jQuery.type( key ) === "object" ) {
-		chainable = true;
-		for ( i in key ) {
-			access( elems, fn, i, key[ i ], true, emptyGet, raw );
-		}
-
-	// Sets one value
-	} else if ( value !== undefined ) {
-		chainable = true;
-
-		if ( !jQuery.isFunction( value ) ) {
-			raw = true;
-		}
-
-		if ( bulk ) {
-
-			// Bulk operations run against the entire set
-			if ( raw ) {
-				fn.call( elems, value );
-				fn = null;
-
-			// ...except when executing function values
-			} else {
-				bulk = fn;
-				fn = function( elem, key, value ) {
-					return bulk.call( jQuery( elem ), value );
-				};
-			}
-		}
-
-		if ( fn ) {
-			for ( ; i < len; i++ ) {
-				fn(
-					elems[ i ], key, raw ?
-					value :
-					value.call( elems[ i ], i, fn( elems[ i ], key ) )
-				);
-			}
-		}
-	}
-
-	return chainable ?
-		elems :
-
-		// Gets
-		bulk ?
-			fn.call( elems ) :
-			len ? fn( elems[ 0 ], key ) : emptyGet;
-};
-var acceptData = function( owner ) {
-
-	// Accepts only:
-	//  - Node
-	//    - Node.ELEMENT_NODE
-	//    - Node.DOCUMENT_NODE
-	//  - Object
-	//    - Any
-	/* jshint -W018 */
-	return owner.nodeType === 1 || owner.nodeType === 9 || !( +owner.nodeType );
-};
-
-
-
-
-function Data() {
-	this.expando = jQuery.expando + Data.uid++;
-}
-
-Data.uid = 1;
-
-Data.prototype = {
-
-	register: function( owner, initial ) {
-		var value = initial || {};
-
-		// If it is a node unlikely to be stringify-ed or looped over
-		// use plain assignment
-		if ( owner.nodeType ) {
-			owner[ this.expando ] = value;
-
-		// Otherwise secure it in a non-enumerable, non-writable property
-		// configurability must be true to allow the property to be
-		// deleted with the delete operator
+			if ( jQuery.support.deleteExpando ) {
+				delete elem[ jQuery.expando ];
+
+			} else if ( elem.removeAttribute ) {
+				elem.removeAttribute( jQuery.expando );
+			}
+
+			// Completely remove the data cache
+			delete cache[ id ];
+		}
+	}
+});
+
+jQuery.fn.extend({
+	data: function( key, value ) {
+		if ( typeof key === "undefined" && this.length ) {
+			return jQuery.data( this[0] );
+
+		} else if ( typeof key === "object" ) {
+			return this.each(function() {
+				jQuery.data( this, key );
+			});
+		}
+
+		var parts = key.split(".");
+		parts[1] = parts[1] ? "." + parts[1] : "";
+
+		if ( value === undefined ) {
+			var data = this.triggerHandler("getData" + parts[1] + "!", [parts[0]]);
+
+			if ( data === undefined && this.length ) {
+				data = jQuery.data( this[0], key );
+			}
+			return data === undefined && parts[1] ?
+				this.data( parts[0] ) :
+				data;
 		} else {
-			Object.defineProperty( owner, this.expando, {
-				value: value,
-				writable: true,
-				configurable: true
-			} );
-		}
-		return owner[ this.expando ];
-	},
-	cache: function( owner ) {
-
-		// We can accept data for non-element nodes in modern browsers,
-		// but we should not, see #8335.
-		// Always return an empty object.
-		if ( !acceptData( owner ) ) {
-			return {};
-		}
-
-		// Check if the owner object already has a cache
-		var value = owner[ this.expando ];
-
-		// If not, create one
-		if ( !value ) {
-			value = {};
-
-			// We can accept data for non-element nodes in modern browsers,
-			// but we should not, see #8335.
-			// Always return an empty object.
-			if ( acceptData( owner ) ) {
-
-				// If it is a node unlikely to be stringify-ed or looped over
-				// use plain assignment
-				if ( owner.nodeType ) {
-					owner[ this.expando ] = value;
-
-				// Otherwise secure it in a non-enumerable property
-				// configurable must be true to allow the property to be
-				// deleted when data is removed
-				} else {
-					Object.defineProperty( owner, this.expando, {
-						value: value,
-						configurable: true
-					} );
-				}
-			}
-		}
-
-		return value;
-	},
-	set: function( owner, data, value ) {
-		var prop,
-			cache = this.cache( owner );
-
-		// Handle: [ owner, key, value ] args
-		if ( typeof data === "string" ) {
-			cache[ data ] = value;
-
-		// Handle: [ owner, { properties } ] args
+			return this.trigger("setData" + parts[1] + "!", [parts[0], value]).each(function() {
+				jQuery.data( this, key, value );
+			});
+		}
+	},
+
+	removeData: function( key ) {
+		return this.each(function() {
+			jQuery.removeData( this, key );
+		});
+	}
+});
+jQuery.extend({
+	queue: function( elem, type, data ) {
+		if ( !elem ) {
+			return;
+		}
+
+		type = (type || "fx") + "queue";
+		var q = jQuery.data( elem, type );
+
+		// Speed up dequeue by getting out quickly if this is just a lookup
+		if ( !data ) {
+			return q || [];
+		}
+
+		if ( !q || jQuery.isArray(data) ) {
+			q = jQuery.data( elem, type, jQuery.makeArray(data) );
+
 		} else {
-
-			// Copy the properties one-by-one to the cache object
-			for ( prop in data ) {
-				cache[ prop ] = data[ prop ];
-			}
-		}
-		return cache;
-	},
-	get: function( owner, key ) {
-		return key === undefined ?
-			this.cache( owner ) :
-			owner[ this.expando ] && owner[ this.expando ][ key ];
-	},
-	access: function( owner, key, value ) {
-		var stored;
-
-		// In cases where either:
-		//
-		//   1. No key was specified
-		//   2. A string key was specified, but no value provided
-		//
-		// Take the "read" path and allow the get method to determine
-		// which value to return, respectively either:
-		//
-		//   1. The entire cache object
-		//   2. The data stored at the key
-		//
-		if ( key === undefined ||
-				( ( key && typeof key === "string" ) && value === undefined ) ) {
-
-			stored = this.get( owner, key );
-
-			return stored !== undefined ?
-				stored : this.get( owner, jQuery.camelCase( key ) );
-		}
-
-		// When the key is not a string, or both a key and value
-		// are specified, set or extend (existing objects) with either:
-		//
-		//   1. An object of properties
-		//   2. A key and value
-		//
-		this.set( owner, key, value );
-
-		// Since the "set" path can have two possible entry points
-		// return the expected data based on which path was taken[*]
-		return value !== undefined ? value : key;
-	},
-	remove: function( owner, key ) {
-		var i, name, camel,
-			cache = owner[ this.expando ];
-
-		if ( cache === undefined ) {
-			return;
-		}
-
-		if ( key === undefined ) {
-			this.register( owner );
-
-		} else {
-
-			// Support array or space separated string of keys
-			if ( jQuery.isArray( key ) ) {
-
-				// If "name" is an array of keys...
-				// When data is initially created, via ("key", "val") signature,
-				// keys will be converted to camelCase.
-				// Since there is no way to tell _how_ a key was added, remove
-				// both plain key and camelCase key. #12786
-				// This will only penalize the array argument path.
-				name = key.concat( key.map( jQuery.camelCase ) );
-			} else {
-				camel = jQuery.camelCase( key );
-
-				// Try the string as a key before any manipulation
-				if ( key in cache ) {
-					name = [ key, camel ];
-				} else {
-
-					// If a key with the spaces exists, use it.
-					// Otherwise, create an array by matching non-whitespace
-					name = camel;
-					name = name in cache ?
-						[ name ] : ( name.match( rnotwhite ) || [] );
-				}
-			}
-
-			i = name.length;
-
-			while ( i-- ) {
-				delete cache[ name[ i ] ];
-			}
-		}
-
-		// Remove the expando if there's no more data
-		if ( key === undefined || jQuery.isEmptyObject( cache ) ) {
-
-			// Support: Chrome <= 35-45+
-			// Webkit & Blink performance suffers when deleting properties
-			// from DOM nodes, so set to undefined instead
-			// https://code.google.com/p/chromium/issues/detail?id=378607
-			if ( owner.nodeType ) {
-				owner[ this.expando ] = undefined;
-			} else {
-				delete owner[ this.expando ];
-			}
-		}
-	},
-	hasData: function( owner ) {
-		var cache = owner[ this.expando ];
-		return cache !== undefined && !jQuery.isEmptyObject( cache );
-	}
-};
-var dataPriv = new Data();
-
-var dataUser = new Data();
-
-
-
-//	Implementation Summary
-//
-//	1. Enforce API surface and semantic compatibility with 1.9.x branch
-//	2. Improve the module's maintainability by reducing the storage
-//		paths to a single mechanism.
-//	3. Use the same single mechanism to support "private" and "user" data.
-//	4. _Never_ expose "private" data to user code (TODO: Drop _data, _removeData)
-//	5. Avoid exposing implementation details on user objects (eg. expando properties)
-//	6. Provide a clear path for implementation upgrade to WeakMap in 2014
-
-var rbrace = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,
-	rmultiDash = /[A-Z]/g;
-
-function dataAttr( elem, key, data ) {
-	var name;
-
-	// If nothing was found internally, try to fetch any
-	// data from the HTML5 data-* attribute
-	if ( data === undefined && elem.nodeType === 1 ) {
-		name = "data-" + key.replace( rmultiDash, "-$&" ).toLowerCase();
-		data = elem.getAttribute( name );
-
-		if ( typeof data === "string" ) {
-			try {
-				data = data === "true" ? true :
-					data === "false" ? false :
-					data === "null" ? null :
-
-					// Only convert to a number if it doesn't change the string
-					+data + "" === data ? +data :
-					rbrace.test( data ) ? jQuery.parseJSON( data ) :
-					data;
-			} catch ( e ) {}
-
-			// Make sure we set the data so it isn't changed later
-			dataUser.set( elem, key, data );
-		} else {
-			data = undefined;
-		}
-	}
-	return data;
-}
-
-jQuery.extend( {
-	hasData: function( elem ) {
-		return dataUser.hasData( elem ) || dataPriv.hasData( elem );
-	},
-
-	data: function( elem, name, data ) {
-		return dataUser.access( elem, name, data );
-	},
-
-	removeData: function( elem, name ) {
-		dataUser.remove( elem, name );
-	},
-
-	// TODO: Now that all calls to _data and _removeData have been replaced
-	// with direct calls to dataPriv methods, these can be deprecated.
-	_data: function( elem, name, data ) {
-		return dataPriv.access( elem, name, data );
-	},
-
-	_removeData: function( elem, name ) {
-		dataPriv.remove( elem, name );
-	}
-} );
-
-jQuery.fn.extend( {
-	data: function( key, value ) {
-		var i, name, data,
-			elem = this[ 0 ],
-			attrs = elem && elem.attributes;
-
-		// Gets all values
-		if ( key === undefined ) {
-			if ( this.length ) {
-				data = dataUser.get( elem );
-
-				if ( elem.nodeType === 1 && !dataPriv.get( elem, "hasDataAttrs" ) ) {
-					i = attrs.length;
-					while ( i-- ) {
-
-						// Support: IE11+
-						// The attrs elements can be null (#14894)
-						if ( attrs[ i ] ) {
-							name = attrs[ i ].name;
-							if ( name.indexOf( "data-" ) === 0 ) {
-								name = jQuery.camelCase( name.slice( 5 ) );
-								dataAttr( elem, name, data[ name ] );
-							}
-						}
-					}
-					dataPriv.set( elem, "hasDataAttrs", true );
-				}
-			}
-
-			return data;
-		}
-
-		// Sets multiple values
-		if ( typeof key === "object" ) {
-			return this.each( function() {
-				dataUser.set( this, key );
-			} );
-		}
-
-		return access( this, function( value ) {
-			var data, camelKey;
-
-			// The calling jQuery object (element matches) is not empty
-			// (and therefore has an element appears at this[ 0 ]) and the
-			// `value` parameter was not undefined. An empty jQuery object
-			// will result in `undefined` for elem = this[ 0 ] which will
-			// throw an exception if an attempt to read a data cache is made.
-			if ( elem && value === undefined ) {
-
-				// Attempt to get data from the cache
-				// with the key as-is
-				data = dataUser.get( elem, key ) ||
-
-					// Try to find dashed key if it exists (gh-2779)
-					// This is for 2.2.x only
-					dataUser.get( elem, key.replace( rmultiDash, "-$&" ).toLowerCase() );
-
-				if ( data !== undefined ) {
-					return data;
-				}
-
-				camelKey = jQuery.camelCase( key );
-
-				// Attempt to get data from the cache
-				// with the key camelized
-				data = dataUser.get( elem, camelKey );
-				if ( data !== undefined ) {
-					return data;
-				}
-
-				// Attempt to "discover" the data in
-				// HTML5 custom data-* attrs
-				data = dataAttr( elem, camelKey, undefined );
-				if ( data !== undefined ) {
-					return data;
-				}
-
-				// We tried really hard, but the data doesn't exist.
-				return;
-			}
-
-			// Set the data...
-			camelKey = jQuery.camelCase( key );
-			this.each( function() {
-
-				// First, attempt to store a copy or reference of any
-				// data that might've been store with a camelCased key.
-				var data = dataUser.get( this, camelKey );
-
-				// For HTML5 data-* attribute interop, we have to
-				// store property names with dashes in a camelCase form.
-				// This might not apply to all properties...*
-				dataUser.set( this, camelKey, value );
-
-				// *... In the case of properties that might _actually_
-				// have dashes, we need to also store a copy of that
-				// unchanged property.
-				if ( key.indexOf( "-" ) > -1 && data !== undefined ) {
-					dataUser.set( this, key, value );
-				}
-			} );
-		}, null, value, arguments.length > 1, null, true );
-	},
-
-	removeData: function( key ) {
-		return this.each( function() {
-			dataUser.remove( this, key );
-		} );
-	}
-} );
-
-
-jQuery.extend( {
-	queue: function( elem, type, data ) {
-		var queue;
-
-		if ( elem ) {
-			type = ( type || "fx" ) + "queue";
-			queue = dataPriv.get( elem, type );
-
-			// Speed up dequeue by getting out quickly if this is just a lookup
-			if ( data ) {
-				if ( !queue || jQuery.isArray( data ) ) {
-					queue = dataPriv.access( elem, type, jQuery.makeArray( data ) );
-				} else {
-					queue.push( data );
-				}
-			}
-			return queue || [];
-		}
+			q.push( data );
+		}
+
+		return q;
 	},
 
@@ -4057,549 +1141,518 @@
 		type = type || "fx";
 
-		var queue = jQuery.queue( elem, type ),
-			startLength = queue.length,
-			fn = queue.shift(),
-			hooks = jQuery._queueHooks( elem, type ),
-			next = function() {
-				jQuery.dequeue( elem, type );
-			};
+		var queue = jQuery.queue( elem, type ), fn = queue.shift();
 
 		// If the fx queue is dequeued, always remove the progress sentinel
 		if ( fn === "inprogress" ) {
 			fn = queue.shift();
-			startLength--;
 		}
 
 		if ( fn ) {
-
 			// Add a progress sentinel to prevent the fx queue from being
 			// automatically dequeued
 			if ( type === "fx" ) {
-				queue.unshift( "inprogress" );
-			}
-
-			// Clear up the last queue stop function
-			delete hooks.stop;
-			fn.call( elem, next, hooks );
-		}
-
-		if ( !startLength && hooks ) {
-			hooks.empty.fire();
-		}
-	},
-
-	// Not public - generate a queueHooks object, or return the current one
-	_queueHooks: function( elem, type ) {
-		var key = type + "queueHooks";
-		return dataPriv.get( elem, key ) || dataPriv.access( elem, key, {
-			empty: jQuery.Callbacks( "once memory" ).add( function() {
-				dataPriv.remove( elem, [ type + "queue", key ] );
-			} )
-		} );
-	}
-} );
-
-jQuery.fn.extend( {
+				queue.unshift("inprogress");
+			}
+
+			fn.call(elem, function() {
+				jQuery.dequeue(elem, type);
+			});
+		}
+	}
+});
+
+jQuery.fn.extend({
 	queue: function( type, data ) {
-		var setter = 2;
-
 		if ( typeof type !== "string" ) {
 			data = type;
 			type = "fx";
-			setter--;
-		}
-
-		if ( arguments.length < setter ) {
-			return jQuery.queue( this[ 0 ], type );
-		}
-
-		return data === undefined ?
-			this :
-			this.each( function() {
-				var queue = jQuery.queue( this, type, data );
-
-				// Ensure a hooks for this queue
-				jQuery._queueHooks( this, type );
-
-				if ( type === "fx" && queue[ 0 ] !== "inprogress" ) {
-					jQuery.dequeue( this, type );
-				}
-			} );
+		}
+
+		if ( data === undefined ) {
+			return jQuery.queue( this[0], type );
+		}
+		return this.each(function( i, elem ) {
+			var queue = jQuery.queue( this, type, data );
+
+			if ( type === "fx" && queue[0] !== "inprogress" ) {
+				jQuery.dequeue( this, type );
+			}
+		});
 	},
 	dequeue: function( type ) {
-		return this.each( function() {
+		return this.each(function() {
 			jQuery.dequeue( this, type );
-		} );
-	},
+		});
+	},
+
+	// Based off of the plugin by Clint Helfers, with permission.
+	// http://blindsignals.com/index.php/2009/07/jquery-delay/
+	delay: function( time, type ) {
+		time = jQuery.fx ? jQuery.fx.speeds[time] || time : time;
+		type = type || "fx";
+
+		return this.queue( type, function() {
+			var elem = this;
+			setTimeout(function() {
+				jQuery.dequeue( elem, type );
+			}, time );
+		});
+	},
+
 	clearQueue: function( type ) {
 		return this.queue( type || "fx", [] );
-	},
-
-	// Get a promise resolved when queues of a certain type
-	// are emptied (fx is the type by default)
-	promise: function( type, obj ) {
-		var tmp,
-			count = 1,
-			defer = jQuery.Deferred(),
-			elements = this,
-			i = this.length,
-			resolve = function() {
-				if ( !( --count ) ) {
-					defer.resolveWith( elements, [ elements ] );
-				}
-			};
-
-		if ( typeof type !== "string" ) {
-			obj = type;
-			type = undefined;
-		}
-		type = type || "fx";
-
-		while ( i-- ) {
-			tmp = dataPriv.get( elements[ i ], type + "queueHooks" );
-			if ( tmp && tmp.empty ) {
-				count++;
-				tmp.empty.add( resolve );
-			}
-		}
-		resolve();
-		return defer.promise( obj );
-	}
-} );
-var pnum = ( /[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/ ).source;
-
-var rcssNum = new RegExp( "^(?:([+-])=|)(" + pnum + ")([a-z%]*)$", "i" );
-
-
-var cssExpand = [ "Top", "Right", "Bottom", "Left" ];
-
-var isHidden = function( elem, el ) {
-
-		// isHidden might be called from jQuery#filter function;
-		// in that case, element will be second argument
-		elem = el || elem;
-		return jQuery.css( elem, "display" ) === "none" ||
-			!jQuery.contains( elem.ownerDocument, elem );
+	}
+});
+var rclass = /[\n\t]/g,
+	rspace = /\s+/,
+	rreturn = /\r/g,
+	rspecialurl = /href|src|style/,
+	rtype = /(button|input)/i,
+	rfocusable = /(button|input|object|select|textarea)/i,
+	rclickable = /^(a|area)$/i,
+	rradiocheck = /radio|checkbox/;
+
+jQuery.fn.extend({
+	attr: function( name, value ) {
+		return access( this, name, value, true, jQuery.attr );
+	},
+
+	removeAttr: function( name, fn ) {
+		return this.each(function(){
+			jQuery.attr( this, name, "" );
+			if ( this.nodeType === 1 ) {
+				this.removeAttribute( name );
+			}
+		});
+	},
+
+	addClass: function( value ) {
+		if ( jQuery.isFunction(value) ) {
+			return this.each(function(i) {
+				var self = jQuery(this);
+				self.addClass( value.call(this, i, self.attr("class")) );
+			});
+		}
+
+		if ( value && typeof value === "string" ) {
+			var classNames = (value || "").split( rspace );
+
+			for ( var i = 0, l = this.length; i < l; i++ ) {
+				var elem = this[i];
+
+				if ( elem.nodeType === 1 ) {
+					if ( !elem.className ) {
+						elem.className = value;
+
+					} else {
+						var className = " " + elem.className + " ", setClass = elem.className;
+						for ( var c = 0, cl = classNames.length; c < cl; c++ ) {
+							if ( className.indexOf( " " + classNames[c] + " " ) < 0 ) {
+								setClass += " " + classNames[c];
+							}
+						}
+						elem.className = jQuery.trim( setClass );
+					}
+				}
+			}
+		}
+
+		return this;
+	},
+
+	removeClass: function( value ) {
+		if ( jQuery.isFunction(value) ) {
+			return this.each(function(i) {
+				var self = jQuery(this);
+				self.removeClass( value.call(this, i, self.attr("class")) );
+			});
+		}
+
+		if ( (value && typeof value === "string") || value === undefined ) {
+			var classNames = (value || "").split(rspace);
+
+			for ( var i = 0, l = this.length; i < l; i++ ) {
+				var elem = this[i];
+
+				if ( elem.nodeType === 1 && elem.className ) {
+					if ( value ) {
+						var className = (" " + elem.className + " ").replace(rclass, " ");
+						for ( var c = 0, cl = classNames.length; c < cl; c++ ) {
+							className = className.replace(" " + classNames[c] + " ", " ");
+						}
+						elem.className = jQuery.trim( className );
+
+					} else {
+						elem.className = "";
+					}
+				}
+			}
+		}
+
+		return this;
+	},
+
+	toggleClass: function( value, stateVal ) {
+		var type = typeof value, isBool = typeof stateVal === "boolean";
+
+		if ( jQuery.isFunction( value ) ) {
+			return this.each(function(i) {
+				var self = jQuery(this);
+				self.toggleClass( value.call(this, i, self.attr("class"), stateVal), stateVal );
+			});
+		}
+
+		return this.each(function() {
+			if ( type === "string" ) {
+				// toggle individual class names
+				var className, i = 0, self = jQuery(this),
+					state = stateVal,
+					classNames = value.split( rspace );
+
+				while ( (className = classNames[ i++ ]) ) {
+					// check each className given, space seperated list
+					state = isBool ? state : !self.hasClass( className );
+					self[ state ? "addClass" : "removeClass" ]( className );
+				}
+
+			} else if ( type === "undefined" || type === "boolean" ) {
+				if ( this.className ) {
+					// store className if set
+					jQuery.data( this, "__className__", this.className );
+				}
+
+				// toggle whole className
+				this.className = this.className || value === false ? "" : jQuery.data( this, "__className__" ) || "";
+			}
+		});
+	},
+
+	hasClass: function( selector ) {
+		var className = " " + selector + " ";
+		for ( var i = 0, l = this.length; i < l; i++ ) {
+			if ( (" " + this[i].className + " ").replace(rclass, " ").indexOf( className ) > -1 ) {
+				return true;
+			}
+		}
+
+		return false;
+	},
+
+	val: function( value ) {
+		if ( value === undefined ) {
+			var elem = this[0];
+
+			if ( elem ) {
+				if ( jQuery.nodeName( elem, "option" ) ) {
+					return (elem.attributes.value || {}).specified ? elem.value : elem.text;
+				}
+
+				// We need to handle select boxes special
+				if ( jQuery.nodeName( elem, "select" ) ) {
+					var index = elem.selectedIndex,
+						values = [],
+						options = elem.options,
+						one = elem.type === "select-one";
+
+					// Nothing was selected
+					if ( index < 0 ) {
+						return null;
+					}
+
+					// Loop through all the selected options
+					for ( var i = one ? index : 0, max = one ? index + 1 : options.length; i < max; i++ ) {
+						var option = options[ i ];
+
+						if ( option.selected ) {
+							// Get the specifc value for the option
+							value = jQuery(option).val();
+
+							// We don't need an array for one selects
+							if ( one ) {
+								return value;
+							}
+
+							// Multi-Selects return an array
+							values.push( value );
+						}
+					}
+
+					return values;
+				}
+
+				// Handle the case where in Webkit "" is returned instead of "on" if a value isn't specified
+				if ( rradiocheck.test( elem.type ) && !jQuery.support.checkOn ) {
+					return elem.getAttribute("value") === null ? "on" : elem.value;
+				}
+				
+
+				// Everything else, we just grab the value
+				return (elem.value || "").replace(rreturn, "");
+
+			}
+
+			return undefined;
+		}
+
+		var isFunction = jQuery.isFunction(value);
+
+		return this.each(function(i) {
+			var self = jQuery(this), val = value;
+
+			if ( this.nodeType !== 1 ) {
+				return;
+			}
+
+			if ( isFunction ) {
+				val = value.call(this, i, self.val());
+			}
+
+			// Typecast each time if the value is a Function and the appended
+			// value is therefore different each time.
+			if ( typeof val === "number" ) {
+				val += "";
+			}
+
+			if ( jQuery.isArray(val) && rradiocheck.test( this.type ) ) {
+				this.checked = jQuery.inArray( self.val(), val ) >= 0;
+
+			} else if ( jQuery.nodeName( this, "select" ) ) {
+				var values = jQuery.makeArray(val);
+
+				jQuery( "option", this ).each(function() {
+					this.selected = jQuery.inArray( jQuery(this).val(), values ) >= 0;
+				});
+
+				if ( !values.length ) {
+					this.selectedIndex = -1;
+				}
+
+			} else {
+				this.value = val;
+			}
+		});
+	}
+});
+
+jQuery.extend({
+	attrFn: {
+		val: true,
+		css: true,
+		html: true,
+		text: true,
+		data: true,
+		width: true,
+		height: true,
+		offset: true
+	},
+		
+	attr: function( elem, name, value, pass ) {
+		// don't set attributes on text and comment nodes
+		if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 ) {
+			return undefined;
+		}
+
+		if ( pass && name in jQuery.attrFn ) {
+			return jQuery(elem)[name](value);
+		}
+
+		var notxml = elem.nodeType !== 1 || !jQuery.isXMLDoc( elem ),
+			// Whether we are setting (or getting)
+			set = value !== undefined;
+
+		// Try to normalize/fix the name
+		name = notxml && jQuery.props[ name ] || name;
+
+		// Only do all the following if this is a node (faster for style)
+		if ( elem.nodeType === 1 ) {
+			// These attributes require special treatment
+			var special = rspecialurl.test( name );
+
+			// Safari mis-reports the default selected property of an option
+			// Accessing the parent's selectedIndex property fixes it
+			if ( name === "selected" && !jQuery.support.optSelected ) {
+				var parent = elem.parentNode;
+				if ( parent ) {
+					parent.selectedIndex;
+	
+					// Make sure that it also works with optgroups, see #5701
+					if ( parent.parentNode ) {
+						parent.parentNode.selectedIndex;
+					}
+				}
+			}
+
+			// If applicable, access the attribute via the DOM 0 way
+			if ( name in elem && notxml && !special ) {
+				if ( set ) {
+					// We can't allow the type property to be changed (since it causes problems in IE)
+					if ( name === "type" && rtype.test( elem.nodeName ) && elem.parentNode ) {
+						jQuery.error( "type property can't be changed" );
+					}
+
+					elem[ name ] = value;
+				}
+
+				// browsers index elements by id/name on forms, give priority to attributes.
+				if ( jQuery.nodeName( elem, "form" ) && elem.getAttributeNode(name) ) {
+					return elem.getAttributeNode( name ).nodeValue;
+				}
+
+				// elem.tabIndex doesn't always return the correct value when it hasn't been explicitly set
+				// http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/
+				if ( name === "tabIndex" ) {
+					var attributeNode = elem.getAttributeNode( "tabIndex" );
+
+					return attributeNode && attributeNode.specified ?
+						attributeNode.value :
+						rfocusable.test( elem.nodeName ) || rclickable.test( elem.nodeName ) && elem.href ?
+							0 :
+							undefined;
+				}
+
+				return elem[ name ];
+			}
+
+			if ( !jQuery.support.style && notxml && name === "style" ) {
+				if ( set ) {
+					elem.style.cssText = "" + value;
+				}
+
+				return elem.style.cssText;
+			}
+
+			if ( set ) {
+				// convert the value to a string (all browsers do this but IE) see #1070
+				elem.setAttribute( name, "" + value );
+			}
+
+			var attr = !jQuery.support.hrefNormalized && notxml && special ?
+					// Some attributes require a special call on IE
+					elem.getAttribute( name, 2 ) :
+					elem.getAttribute( name );
+
+			// Non-existent attributes return null, we normalize to undefined
+			return attr === null ? undefined : attr;
+		}
+
+		// elem is actually elem.style ... set the style
+		// Using attr for specific style information is now deprecated. Use style instead.
+		return jQuery.style( elem, name, value );
+	}
+});
+var rnamespaces = /\.(.*)$/,
+	fcleanup = function( nm ) {
+		return nm.replace(/[^\w\s\.\|`]/g, function( ch ) {
+			return "\\" + ch;
+		});
 	};
 
-
-
-function adjustCSS( elem, prop, valueParts, tween ) {
-	var adjusted,
-		scale = 1,
-		maxIterations = 20,
-		currentValue = tween ?
-			function() { return tween.cur(); } :
-			function() { return jQuery.css( elem, prop, "" ); },
-		initial = currentValue(),
-		unit = valueParts && valueParts[ 3 ] || ( jQuery.cssNumber[ prop ] ? "" : "px" ),
-
-		// Starting value computation is required for potential unit mismatches
-		initialInUnit = ( jQuery.cssNumber[ prop ] || unit !== "px" && +initial ) &&
-			rcssNum.exec( jQuery.css( elem, prop ) );
-
-	if ( initialInUnit && initialInUnit[ 3 ] !== unit ) {
-
-		// Trust units reported by jQuery.css
-		unit = unit || initialInUnit[ 3 ];
-
-		// Make sure we update the tween properties later on
-		valueParts = valueParts || [];
-
-		// Iteratively approximate from a nonzero starting point
-		initialInUnit = +initial || 1;
-
-		do {
-
-			// If previous iteration zeroed out, double until we get *something*.
-			// Use string for doubling so we don't accidentally see scale as unchanged below
-			scale = scale || ".5";
-
-			// Adjust and apply
-			initialInUnit = initialInUnit / scale;
-			jQuery.style( elem, prop, initialInUnit + unit );
-
-		// Update scale, tolerating zero or NaN from tween.cur()
-		// Break the loop if scale is unchanged or perfect, or if we've just had enough.
-		} while (
-			scale !== ( scale = currentValue() / initial ) && scale !== 1 && --maxIterations
-		);
-	}
-
-	if ( valueParts ) {
-		initialInUnit = +initialInUnit || +initial || 0;
-
-		// Apply relative offset (+=/-=) if specified
-		adjusted = valueParts[ 1 ] ?
-			initialInUnit + ( valueParts[ 1 ] + 1 ) * valueParts[ 2 ] :
-			+valueParts[ 2 ];
-		if ( tween ) {
-			tween.unit = unit;
-			tween.start = initialInUnit;
-			tween.end = adjusted;
-		}
-	}
-	return adjusted;
-}
-var rcheckableType = ( /^(?:checkbox|radio)$/i );
-
-var rtagName = ( /<([\w:-]+)/ );
-
-var rscriptType = ( /^$|\/(?:java|ecma)script/i );
-
-
-
-// We have to close these tags to support XHTML (#13200)
-var wrapMap = {
-
-	// Support: IE9
-	option: [ 1, "<select multiple='multiple'>", "</select>" ],
-
-	// XHTML parsers do not magically insert elements in the
-	// same way that tag soup parsers do. So we cannot shorten
-	// this by omitting <tbody> or other required elements.
-	thead: [ 1, "<table>", "</table>" ],
-	col: [ 2, "<table><colgroup>", "</colgroup></table>" ],
-	tr: [ 2, "<table><tbody>", "</tbody></table>" ],
-	td: [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ],
-
-	_default: [ 0, "", "" ]
-};
-
-// Support: IE9
-wrapMap.optgroup = wrapMap.option;
-
-wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;
-wrapMap.th = wrapMap.td;
-
-
-function getAll( context, tag ) {
-
-	// Support: IE9-11+
-	// Use typeof to avoid zero-argument method invocation on host objects (#15151)
-	var ret = typeof context.getElementsByTagName !== "undefined" ?
-			context.getElementsByTagName( tag || "*" ) :
-			typeof context.querySelectorAll !== "undefined" ?
-				context.querySelectorAll( tag || "*" ) :
-			[];
-
-	return tag === undefined || tag && jQuery.nodeName( context, tag ) ?
-		jQuery.merge( [ context ], ret ) :
-		ret;
-}
-
-
-// Mark scripts as having already been evaluated
-function setGlobalEval( elems, refElements ) {
-	var i = 0,
-		l = elems.length;
-
-	for ( ; i < l; i++ ) {
-		dataPriv.set(
-			elems[ i ],
-			"globalEval",
-			!refElements || dataPriv.get( refElements[ i ], "globalEval" )
-		);
-	}
-}
-
-
-var rhtml = /<|&#?\w+;/;
-
-function buildFragment( elems, context, scripts, selection, ignored ) {
-	var elem, tmp, tag, wrap, contains, j,
-		fragment = context.createDocumentFragment(),
-		nodes = [],
-		i = 0,
-		l = elems.length;
-
-	for ( ; i < l; i++ ) {
-		elem = elems[ i ];
-
-		if ( elem || elem === 0 ) {
-
-			// Add nodes directly
-			if ( jQuery.type( elem ) === "object" ) {
-
-				// Support: Android<4.1, PhantomJS<2
-				// push.apply(_, arraylike) throws on ancient WebKit
-				jQuery.merge( nodes, elem.nodeType ? [ elem ] : elem );
-
-			// Convert non-html into a text node
-			} else if ( !rhtml.test( elem ) ) {
-				nodes.push( context.createTextNode( elem ) );
-
-			// Convert html into DOM nodes
-			} else {
-				tmp = tmp || fragment.appendChild( context.createElement( "div" ) );
-
-				// Deserialize a standard representation
-				tag = ( rtagName.exec( elem ) || [ "", "" ] )[ 1 ].toLowerCase();
-				wrap = wrapMap[ tag ] || wrapMap._default;
-				tmp.innerHTML = wrap[ 1 ] + jQuery.htmlPrefilter( elem ) + wrap[ 2 ];
-
-				// Descend through wrappers to the right content
-				j = wrap[ 0 ];
-				while ( j-- ) {
-					tmp = tmp.lastChild;
-				}
-
-				// Support: Android<4.1, PhantomJS<2
-				// push.apply(_, arraylike) throws on ancient WebKit
-				jQuery.merge( nodes, tmp.childNodes );
-
-				// Remember the top-level container
-				tmp = fragment.firstChild;
-
-				// Ensure the created nodes are orphaned (#12392)
-				tmp.textContent = "";
-			}
-		}
-	}
-
-	// Remove wrapper from fragment
-	fragment.textContent = "";
-
-	i = 0;
-	while ( ( elem = nodes[ i++ ] ) ) {
-
-		// Skip elements already in the context collection (trac-4087)
-		if ( selection && jQuery.inArray( elem, selection ) > -1 ) {
-			if ( ignored ) {
-				ignored.push( elem );
-			}
-			continue;
-		}
-
-		contains = jQuery.contains( elem.ownerDocument, elem );
-
-		// Append to fragment
-		tmp = getAll( fragment.appendChild( elem ), "script" );
-
-		// Preserve script evaluation history
-		if ( contains ) {
-			setGlobalEval( tmp );
-		}
-
-		// Capture executables
-		if ( scripts ) {
-			j = 0;
-			while ( ( elem = tmp[ j++ ] ) ) {
-				if ( rscriptType.test( elem.type || "" ) ) {
-					scripts.push( elem );
-				}
-			}
-		}
-	}
-
-	return fragment;
-}
-
-
-( function() {
-	var fragment = document.createDocumentFragment(),
-		div = fragment.appendChild( document.createElement( "div" ) ),
-		input = document.createElement( "input" );
-
-	// Support: Android 4.0-4.3, Safari<=5.1
-	// Check state lost if the name is set (#11217)
-	// Support: Windows Web Apps (WWA)
-	// `name` and `type` must use .setAttribute for WWA (#14901)
-	input.setAttribute( "type", "radio" );
-	input.setAttribute( "checked", "checked" );
-	input.setAttribute( "name", "t" );
-
-	div.appendChild( input );
-
-	// Support: Safari<=5.1, Android<4.2
-	// Older WebKit doesn't clone checked state correctly in fragments
-	support.checkClone = div.cloneNode( true ).cloneNode( true ).lastChild.checked;
-
-	// Support: IE<=11+
-	// Make sure textarea (and checkbox) defaultValue is properly cloned
-	div.innerHTML = "<textarea>x</textarea>";
-	support.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue;
-} )();
-
-
-var
-	rkeyEvent = /^key/,
-	rmouseEvent = /^(?:mouse|pointer|contextmenu|drag|drop)|click/,
-	rtypenamespace = /^([^.]*)(?:\.(.+)|)/;
-
-function returnTrue() {
-	return true;
-}
-
-function returnFalse() {
-	return false;
-}
-
-// Support: IE9
-// See #13393 for more info
-function safeActiveElement() {
-	try {
-		return document.activeElement;
-	} catch ( err ) { }
-}
-
-function on( elem, types, selector, data, fn, one ) {
-	var origFn, type;
-
-	// Types can be a map of types/handlers
-	if ( typeof types === "object" ) {
-
-		// ( types-Object, selector, data )
-		if ( typeof selector !== "string" ) {
-
-			// ( types-Object, data )
-			data = data || selector;
-			selector = undefined;
-		}
-		for ( type in types ) {
-			on( elem, type, selector, data, types[ type ], one );
-		}
-		return elem;
-	}
-
-	if ( data == null && fn == null ) {
-
-		// ( types, fn )
-		fn = selector;
-		data = selector = undefined;
-	} else if ( fn == null ) {
-		if ( typeof selector === "string" ) {
-
-			// ( types, selector, fn )
-			fn = data;
-			data = undefined;
-		} else {
-
-			// ( types, data, fn )
-			fn = data;
-			data = selector;
-			selector = undefined;
-		}
-	}
-	if ( fn === false ) {
-		fn = returnFalse;
-	} else if ( !fn ) {
-		return elem;
-	}
-
-	if ( one === 1 ) {
-		origFn = fn;
-		fn = function( event ) {
-
-			// Can use an empty set, since event contains the info
-			jQuery().off( event );
-			return origFn.apply( this, arguments );
-		};
-
-		// Use same guid so caller can remove using origFn
-		fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ );
-	}
-	return elem.each( function() {
-		jQuery.event.add( this, types, fn, data, selector );
-	} );
-}
-
 /*
- * Helper functions for managing events -- not part of the public interface.
- * Props to Dean Edwards' addEvent library for many of the ideas.
+ * A number of helper functions used for managing events.
+ * Many of the ideas behind this code originated from
+ * Dean Edwards' addEvent library.
  */
 jQuery.event = {
 
-	global: {},
-
-	add: function( elem, types, handler, data, selector ) {
-
-		var handleObjIn, eventHandle, tmp,
-			events, t, handleObj,
-			special, handlers, type, namespaces, origType,
-			elemData = dataPriv.get( elem );
-
-		// Don't attach events to noData or text/comment nodes (but allow plain objects)
-		if ( !elemData ) {
+	// Bind an event to an element
+	// Original by Dean Edwards
+	add: function( elem, types, handler, data ) {
+		if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
 			return;
 		}
 
-		// Caller can pass in an object of custom data in lieu of the handler
+		// For whatever reason, IE has trouble passing the window object
+		// around, causing it to be cloned in the process
+		if ( elem.setInterval && ( elem !== window && !elem.frameElement ) ) {
+			elem = window;
+		}
+
+		var handleObjIn, handleObj;
+
 		if ( handler.handler ) {
 			handleObjIn = handler;
 			handler = handleObjIn.handler;
-			selector = handleObjIn.selector;
-		}
-
-		// Make sure that the handler has a unique ID, used to find/remove it later
+		}
+
+		// Make sure that the function being executed has a unique ID
 		if ( !handler.guid ) {
 			handler.guid = jQuery.guid++;
 		}
 
-		// Init the element's event structure and main handler, if this is the first
-		if ( !( events = elemData.events ) ) {
-			events = elemData.events = {};
-		}
-		if ( !( eventHandle = elemData.handle ) ) {
-			eventHandle = elemData.handle = function( e ) {
-
-				// Discard the second event of a jQuery.event.trigger() and
-				// when an event is called after a page has unloaded
-				return typeof jQuery !== "undefined" && jQuery.event.triggered !== e.type ?
-					jQuery.event.dispatch.apply( elem, arguments ) : undefined;
+		// Init the element's event structure
+		var elemData = jQuery.data( elem );
+
+		// If no elemData is found then we must be trying to bind to one of the
+		// banned noData elements
+		if ( !elemData ) {
+			return;
+		}
+
+		var events = elemData.events = elemData.events || {},
+			eventHandle = elemData.handle, eventHandle;
+
+		if ( !eventHandle ) {
+			elemData.handle = eventHandle = function() {
+				// Handle the second event of a trigger and when
+				// an event is called after a page has unloaded
+				return typeof jQuery !== "undefined" && !jQuery.event.triggered ?
+					jQuery.event.handle.apply( eventHandle.elem, arguments ) :
+					undefined;
 			};
 		}
 
+		// Add elem as a property of the handle function
+		// This is to prevent a memory leak with non-native events in IE.
+		eventHandle.elem = elem;
+
 		// Handle multiple events separated by a space
-		types = ( types || "" ).match( rnotwhite ) || [ "" ];
-		t = types.length;
-		while ( t-- ) {
-			tmp = rtypenamespace.exec( types[ t ] ) || [];
-			type = origType = tmp[ 1 ];
-			namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort();
-
-			// There *must* be a type, no attaching namespace-only handlers
-			if ( !type ) {
-				continue;
-			}
-
-			// If event changes its type, use the special event handlers for the changed type
-			special = jQuery.event.special[ type ] || {};
-
-			// If selector defined, determine special event api type, otherwise given type
-			type = ( selector ? special.delegateType : special.bindType ) || type;
-
-			// Update special based on newly reset type
-			special = jQuery.event.special[ type ] || {};
-
-			// handleObj is passed to all event handlers
-			handleObj = jQuery.extend( {
-				type: type,
-				origType: origType,
-				data: data,
-				handler: handler,
-				guid: handler.guid,
-				selector: selector,
-				needsContext: selector && jQuery.expr.match.needsContext.test( selector ),
-				namespace: namespaces.join( "." )
-			}, handleObjIn );
-
-			// Init the event handler queue if we're the first
-			if ( !( handlers = events[ type ] ) ) {
+		// jQuery(...).bind("mouseover mouseout", fn);
+		types = types.split(" ");
+
+		var type, i = 0, namespaces;
+
+		while ( (type = types[ i++ ]) ) {
+			handleObj = handleObjIn ?
+				jQuery.extend({}, handleObjIn) :
+				{ handler: handler, data: data };
+
+			// Namespaced event handlers
+			if ( type.indexOf(".") > -1 ) {
+				namespaces = type.split(".");
+				type = namespaces.shift();
+				handleObj.namespace = namespaces.slice(0).sort().join(".");
+
+			} else {
+				namespaces = [];
+				handleObj.namespace = "";
+			}
+
+			handleObj.type = type;
+			handleObj.guid = handler.guid;
+
+			// Get the current list of functions bound to this event
+			var handlers = events[ type ],
+				special = jQuery.event.special[ type ] || {};
+
+			// Init the event handler queue
+			if ( !handlers ) {
 				handlers = events[ type ] = [];
-				handlers.delegateCount = 0;
-
-				// Only use addEventListener if the special events handler returns false
-				if ( !special.setup ||
-					special.setup.call( elem, data, namespaces, eventHandle ) === false ) {
-
+
+				// Check for a special event handler
+				// Only use addEventListener/attachEvent if the special
+				// events handler returns false
+				if ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) {
+					// Bind the global event handler to the element
 					if ( elem.addEventListener ) {
-						elem.addEventListener( type, eventHandle );
+						elem.addEventListener( type, eventHandle, false );
+
+					} else if ( elem.attachEvent ) {
+						elem.attachEvent( "on" + type, eventHandle );
 					}
 				}
 			}
-
-			if ( special.add ) {
-				special.add.call( elem, handleObj );
+			
+			if ( special.add ) { 
+				special.add.call( elem, handleObj ); 
 
 				if ( !handleObj.handler.guid ) {
@@ -4608,146 +1661,292 @@
 			}
 
-			// Add to the element's handler list, delegates in front
-			if ( selector ) {
-				handlers.splice( handlers.delegateCount++, 0, handleObj );
-			} else {
-				handlers.push( handleObj );
-			}
-
-			// Keep track of which events have ever been used, for event optimization
+			// Add the function to the element's handler list
+			handlers.push( handleObj );
+
+			// Keep track of which events have been used, for global triggering
 			jQuery.event.global[ type ] = true;
 		}
 
-	},
+		// Nullify elem to prevent memory leaks in IE
+		elem = null;
+	},
+
+	global: {},
 
 	// Detach an event or set of events from an element
-	remove: function( elem, types, handler, selector, mappedTypes ) {
-
-		var j, origCount, tmp,
-			events, t, handleObj,
-			special, handlers, type, namespaces, origType,
-			elemData = dataPriv.hasData( elem ) && dataPriv.get( elem );
-
-		if ( !elemData || !( events = elemData.events ) ) {
+	remove: function( elem, types, handler, pos ) {
+		// don't do events on text and comment nodes
+		if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
 			return;
 		}
 
-		// Once for each type.namespace in types; type may be omitted
-		types = ( types || "" ).match( rnotwhite ) || [ "" ];
-		t = types.length;
-		while ( t-- ) {
-			tmp = rtypenamespace.exec( types[ t ] ) || [];
-			type = origType = tmp[ 1 ];
-			namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort();
-
-			// Unbind all events (on this namespace, if provided) for the element
-			if ( !type ) {
-				for ( type in events ) {
-					jQuery.event.remove( elem, type + types[ t ], handler, selector, true );
-				}
+		var ret, type, fn, i = 0, all, namespaces, namespace, special, eventType, handleObj, origType,
+			elemData = jQuery.data( elem ),
+			events = elemData && elemData.events;
+
+		if ( !elemData || !events ) {
+			return;
+		}
+
+		// types is actually an event object here
+		if ( types && types.type ) {
+			handler = types.handler;
+			types = types.type;
+		}
+
+		// Unbind all events for the element
+		if ( !types || typeof types === "string" && types.charAt(0) === "." ) {
+			types = types || "";
+
+			for ( type in events ) {
+				jQuery.event.remove( elem, type + types );
+			}
+
+			return;
+		}
+
+		// Handle multiple events separated by a space
+		// jQuery(...).unbind("mouseover mouseout", fn);
+		types = types.split(" ");
+
+		while ( (type = types[ i++ ]) ) {
+			origType = type;
+			handleObj = null;
+			all = type.indexOf(".") < 0;
+			namespaces = [];
+
+			if ( !all ) {
+				// Namespaced event handlers
+				namespaces = type.split(".");
+				type = namespaces.shift();
+
+				namespace = new RegExp("(^|\\.)" + 
+					jQuery.map( namespaces.slice(0).sort(), fcleanup ).join("\\.(?:.*\\.)?") + "(\\.|$)")
+			}
+
+			eventType = events[ type ];
+
+			if ( !eventType ) {
 				continue;
 			}
 
+			if ( !handler ) {
+				for ( var j = 0; j < eventType.length; j++ ) {
+					handleObj = eventType[ j ];
+
+					if ( all || namespace.test( handleObj.namespace ) ) {
+						jQuery.event.remove( elem, origType, handleObj.handler, j );
+						eventType.splice( j--, 1 );
+					}
+				}
+
+				continue;
+			}
+
 			special = jQuery.event.special[ type ] || {};
-			type = ( selector ? special.delegateType : special.bindType ) || type;
-			handlers = events[ type ] || [];
-			tmp = tmp[ 2 ] &&
-				new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" );
-
-			// Remove matching events
-			origCount = j = handlers.length;
-			while ( j-- ) {
-				handleObj = handlers[ j ];
-
-				if ( ( mappedTypes || origType === handleObj.origType ) &&
-					( !handler || handler.guid === handleObj.guid ) &&
-					( !tmp || tmp.test( handleObj.namespace ) ) &&
-					( !selector || selector === handleObj.selector ||
-						selector === "**" && handleObj.selector ) ) {
-					handlers.splice( j, 1 );
-
-					if ( handleObj.selector ) {
-						handlers.delegateCount--;
+
+			for ( var j = pos || 0; j < eventType.length; j++ ) {
+				handleObj = eventType[ j ];
+
+				if ( handler.guid === handleObj.guid ) {
+					// remove the given handler for the given type
+					if ( all || namespace.test( handleObj.namespace ) ) {
+						if ( pos == null ) {
+							eventType.splice( j--, 1 );
+						}
+
+						if ( special.remove ) {
+							special.remove.call( elem, handleObj );
+						}
 					}
-					if ( special.remove ) {
-						special.remove.call( elem, handleObj );
+
+					if ( pos != null ) {
+						break;
 					}
 				}
 			}
 
-			// Remove generic event handler if we removed something and no more handlers exist
-			// (avoids potential for endless recursion during removal of special event handlers)
-			if ( origCount && !handlers.length ) {
-				if ( !special.teardown ||
-					special.teardown.call( elem, namespaces, elemData.handle ) === false ) {
-
-					jQuery.removeEvent( elem, type, elemData.handle );
-				}
-
+			// remove generic event handler if no more handlers exist
+			if ( eventType.length === 0 || pos != null && eventType.length === 1 ) {
+				if ( !special.teardown || special.teardown.call( elem, namespaces ) === false ) {
+					removeEvent( elem, type, elemData.handle );
+				}
+
+				ret = null;
 				delete events[ type ];
 			}
 		}
 
-		// Remove data and the expando if it's no longer used
+		// Remove the expando if it's no longer used
 		if ( jQuery.isEmptyObject( events ) ) {
-			dataPriv.remove( elem, "handle events" );
-		}
-	},
-
-	dispatch: function( event ) {
-
-		// Make a writable jQuery.Event from the native event object
-		event = jQuery.event.fix( event );
-
-		var i, j, ret, matched, handleObj,
-			handlerQueue = [],
-			args = slice.call( arguments ),
-			handlers = ( dataPriv.get( this, "events" ) || {} )[ event.type ] || [],
-			special = jQuery.event.special[ event.type ] || {};
-
-		// Use the fix-ed jQuery.Event rather than the (read-only) native event
-		args[ 0 ] = event;
-		event.delegateTarget = this;
-
-		// Call the preDispatch hook for the mapped type, and let it bail if desired
-		if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) {
-			return;
-		}
-
-		// Determine handlers
-		handlerQueue = jQuery.event.handlers.call( this, event, handlers );
-
-		// Run delegates first; they may want to stop propagation beneath us
-		i = 0;
-		while ( ( matched = handlerQueue[ i++ ] ) && !event.isPropagationStopped() ) {
-			event.currentTarget = matched.elem;
-
-			j = 0;
-			while ( ( handleObj = matched.handlers[ j++ ] ) &&
-				!event.isImmediatePropagationStopped() ) {
-
-				// Triggered event must either 1) have no namespace, or 2) have namespace(s)
-				// a subset or equal to those in the bound event (both can have no namespace).
-				if ( !event.rnamespace || event.rnamespace.test( handleObj.namespace ) ) {
-
+			var handle = elemData.handle;
+			if ( handle ) {
+				handle.elem = null;
+			}
+
+			delete elemData.events;
+			delete elemData.handle;
+
+			if ( jQuery.isEmptyObject( elemData ) ) {
+				jQuery.removeData( elem );
+			}
+		}
+	},
+
+	// bubbling is internal
+	trigger: function( event, data, elem /*, bubbling */ ) {
+		// Event object or event type
+		var type = event.type || event,
+			bubbling = arguments[3];
+
+		if ( !bubbling ) {
+			event = typeof event === "object" ?
+				// jQuery.Event object
+				event[expando] ? event :
+				// Object literal
+				jQuery.extend( jQuery.Event(type), event ) :
+				// Just the event type (string)
+				jQuery.Event(type);
+
+			if ( type.indexOf("!") >= 0 ) {
+				event.type = type = type.slice(0, -1);
+				event.exclusive = true;
+			}
+
+			// Handle a global trigger
+			if ( !elem ) {
+				// Don't bubble custom events when global (to avoid too much overhead)
+				event.stopPropagation();
+
+				// Only trigger if we've ever bound an event for it
+				if ( jQuery.event.global[ type ] ) {
+					jQuery.each( jQuery.cache, function() {
+						if ( this.events && this.events[type] ) {
+							jQuery.event.trigger( event, data, this.handle.elem );
+						}
+					});
+				}
+			}
+
+			// Handle triggering a single element
+
+			// don't do events on text and comment nodes
+			if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 ) {
+				return undefined;
+			}
+
+			// Clean up in case it is reused
+			event.result = undefined;
+			event.target = elem;
+
+			// Clone the incoming data, if any
+			data = jQuery.makeArray( data );
+			data.unshift( event );
+		}
+
+		event.currentTarget = elem;
+
+		// Trigger the event, it is assumed that "handle" is a function
+		var handle = jQuery.data( elem, "handle" );
+		if ( handle ) {
+			handle.apply( elem, data );
+		}
+
+		var parent = elem.parentNode || elem.ownerDocument;
+
+		// Trigger an inline bound script
+		try {
+			if ( !(elem && elem.nodeName && jQuery.noData[elem.nodeName.toLowerCase()]) ) {
+				if ( elem[ "on" + type ] && elem[ "on" + type ].apply( elem, data ) === false ) {
+					event.result = false;
+				}
+			}
+
+		// prevent IE from throwing an error for some elements with some event types, see #3533
+		} catch (e) {}
+
+		if ( !event.isPropagationStopped() && parent ) {
+			jQuery.event.trigger( event, data, parent, true );
+
+		} else if ( !event.isDefaultPrevented() ) {
+			var target = event.target, old,
+				isClick = jQuery.nodeName(target, "a") && type === "click",
+				special = jQuery.event.special[ type ] || {};
+
+			if ( (!special._default || special._default.call( elem, event ) === false) && 
+				!isClick && !(target && target.nodeName && jQuery.noData[target.nodeName.toLowerCase()]) ) {
+
+				try {
+					if ( target[ type ] ) {
+						// Make sure that we don't accidentally re-trigger the onFOO events
+						old = target[ "on" + type ];
+
+						if ( old ) {
+							target[ "on" + type ] = null;
+						}
+
+						jQuery.event.triggered = true;
+						target[ type ]();
+					}
+
+				// prevent IE from throwing an error for some elements with some event types, see #3533
+				} catch (e) {}
+
+				if ( old ) {
+					target[ "on" + type ] = old;
+				}
+
+				jQuery.event.triggered = false;
+			}
+		}
+	},
+
+	handle: function( event ) {
+		var all, handlers, namespaces, namespace, events;
+
+		event = arguments[0] = jQuery.event.fix( event || window.event );
+		event.currentTarget = this;
+
+		// Namespaced event handlers
+		all = event.type.indexOf(".") < 0 && !event.exclusive;
+
+		if ( !all ) {
+			namespaces = event.type.split(".");
+			event.type = namespaces.shift();
+			namespace = new RegExp("(^|\\.)" + namespaces.slice(0).sort().join("\\.(?:.*\\.)?") + "(\\.|$)");
+		}
+
+		var events = jQuery.data(this, "events"), handlers = events[ event.type ];
+
+		if ( events && handlers ) {
+			// Clone the handlers to prevent manipulation
+			handlers = handlers.slice(0);
+
+			for ( var j = 0, l = handlers.length; j < l; j++ ) {
+				var handleObj = handlers[ j ];
+
+				// Filter the functions by class
+				if ( all || namespace.test( handleObj.namespace ) ) {
+					// Pass in a reference to the handler function itself
+					// So that we can later remove it
+					event.handler = handleObj.handler;
+					event.data = handleObj.data;
 					event.handleObj = handleObj;
-					event.data = handleObj.data;
-
-					ret = ( ( jQuery.event.special[ handleObj.origType ] || {} ).handle ||
-						handleObj.handler ).apply( matched.elem, args );
+	
+					var ret = handleObj.handler.apply( this, arguments );
 
 					if ( ret !== undefined ) {
-						if ( ( event.result = ret ) === false ) {
+						event.result = ret;
+						if ( ret === false ) {
 							event.preventDefault();
 							event.stopPropagation();
 						}
 					}
-				}
-			}
-		}
-
-		// Call the postDispatch hook for the mapped type
-		if ( special.postDispatch ) {
-			special.postDispatch.call( this, event );
+
+					if ( event.isImmediatePropagationStopped() ) {
+						break;
+					}
+				}
+			}
 		}
 
@@ -4755,196 +1954,110 @@
 	},
 
-	handlers: function( event, handlers ) {
-		var i, matches, sel, handleObj,
-			handlerQueue = [],
-			delegateCount = handlers.delegateCount,
-			cur = event.target;
-
-		// Support (at least): Chrome, IE9
-		// Find delegate handlers
-		// Black-hole SVG <use> instance trees (#13180)
-		//
-		// Support: Firefox<=42+
-		// Avoid non-left-click in FF but don't block IE radio events (#3861, gh-2343)
-		if ( delegateCount && cur.nodeType &&
-			( event.type !== "click" || isNaN( event.button ) || event.button < 1 ) ) {
-
-			for ( ; cur !== this; cur = cur.parentNode || this ) {
-
-				// Don't check non-elements (#13208)
-				// Don't process clicks on disabled elements (#6911, #8165, #11382, #11764)
-				if ( cur.nodeType === 1 && ( cur.disabled !== true || event.type !== "click" ) ) {
-					matches = [];
-					for ( i = 0; i < delegateCount; i++ ) {
-						handleObj = handlers[ i ];
-
-						// Don't conflict with Object.prototype properties (#13203)
-						sel = handleObj.selector + " ";
-
-						if ( matches[ sel ] === undefined ) {
-							matches[ sel ] = handleObj.needsContext ?
-								jQuery( sel, this ).index( cur ) > -1 :
-								jQuery.find( sel, this, null, [ cur ] ).length;
-						}
-						if ( matches[ sel ] ) {
-							matches.push( handleObj );
-						}
-					}
-					if ( matches.length ) {
-						handlerQueue.push( { elem: cur, handlers: matches } );
-					}
-				}
-			}
-		}
-
-		// Add the remaining (directly-bound) handlers
-		if ( delegateCount < handlers.length ) {
-			handlerQueue.push( { elem: this, handlers: handlers.slice( delegateCount ) } );
-		}
-
-		return handlerQueue;
-	},
-
-	// Includes some event props shared by KeyEvent and MouseEvent
-	props: ( "altKey bubbles cancelable ctrlKey currentTarget detail eventPhase " +
-		"metaKey relatedTarget shiftKey target timeStamp view which" ).split( " " ),
-
-	fixHooks: {},
-
-	keyHooks: {
-		props: "char charCode key keyCode".split( " " ),
-		filter: function( event, original ) {
-
-			// Add which for key events
-			if ( event.which == null ) {
-				event.which = original.charCode != null ? original.charCode : original.keyCode;
-			}
-
+	props: "altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode layerX layerY metaKey newValue offsetX offsetY originalTarget pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target toElement view wheelDelta which".split(" "),
+
+	fix: function( event ) {
+		if ( event[ expando ] ) {
 			return event;
 		}
-	},
-
-	mouseHooks: {
-		props: ( "button buttons clientX clientY offsetX offsetY pageX pageY " +
-			"screenX screenY toElement" ).split( " " ),
-		filter: function( event, original ) {
-			var eventDoc, doc, body,
-				button = original.button;
-
-			// Calculate pageX/Y if missing and clientX/Y available
-			if ( event.pageX == null && original.clientX != null ) {
-				eventDoc = event.target.ownerDocument || document;
-				doc = eventDoc.documentElement;
-				body = eventDoc.body;
-
-				event.pageX = original.clientX +
-					( doc && doc.scrollLeft || body && body.scrollLeft || 0 ) -
-					( doc && doc.clientLeft || body && body.clientLeft || 0 );
-				event.pageY = original.clientY +
-					( doc && doc.scrollTop  || body && body.scrollTop  || 0 ) -
-					( doc && doc.clientTop  || body && body.clientTop  || 0 );
-			}
-
-			// Add which for click: 1 === left; 2 === middle; 3 === right
-			// Note: button is not normalized, so don't use it
-			if ( !event.which && button !== undefined ) {
-				event.which = ( button & 1 ? 1 : ( button & 2 ? 3 : ( button & 4 ? 2 : 0 ) ) );
-			}
-
-			return event;
-		}
-	},
-
-	fix: function( event ) {
-		if ( event[ jQuery.expando ] ) {
-			return event;
-		}
-
-		// Create a writable copy of the event object and normalize some properties
-		var i, prop, copy,
-			type = event.type,
-			originalEvent = event,
-			fixHook = this.fixHooks[ type ];
-
-		if ( !fixHook ) {
-			this.fixHooks[ type ] = fixHook =
-				rmouseEvent.test( type ) ? this.mouseHooks :
-				rkeyEvent.test( type ) ? this.keyHooks :
-				{};
-		}
-		copy = fixHook.props ? this.props.concat( fixHook.props ) : this.props;
-
-		event = new jQuery.Event( originalEvent );
-
-		i = copy.length;
-		while ( i-- ) {
-			prop = copy[ i ];
+
+		// store a copy of the original event object
+		// and "clone" to set read-only properties
+		var originalEvent = event;
+		event = jQuery.Event( originalEvent );
+
+		for ( var i = this.props.length, prop; i; ) {
+			prop = this.props[ --i ];
 			event[ prop ] = originalEvent[ prop ];
 		}
 
-		// Support: Cordova 2.5 (WebKit) (#13255)
-		// All events should have a target; Cordova deviceready doesn't
+		// Fix target property, if necessary
 		if ( !event.target ) {
-			event.target = document;
-		}
-
-		// Support: Safari 6.0+, Chrome<28
-		// Target should not be a text node (#504, #13143)
+			event.target = event.srcElement || document; // Fixes #1925 where srcElement might not be defined either
+		}
+
+		// check if target is a textnode (safari)
 		if ( event.target.nodeType === 3 ) {
 			event.target = event.target.parentNode;
 		}
 
-		return fixHook.filter ? fixHook.filter( event, originalEvent ) : event;
-	},
+		// Add relatedTarget, if necessary
+		if ( !event.relatedTarget && event.fromElement ) {
+			event.relatedTarget = event.fromElement === event.target ? event.toElement : event.fromElement;
+		}
+
+		// Calculate pageX/Y if missing and clientX/Y available
+		if ( event.pageX == null && event.clientX != null ) {
+			var doc = document.documentElement, body = document.body;
+			event.pageX = event.clientX + (doc && doc.scrollLeft || body && body.scrollLeft || 0) - (doc && doc.clientLeft || body && body.clientLeft || 0);
+			event.pageY = event.clientY + (doc && doc.scrollTop  || body && body.scrollTop  || 0) - (doc && doc.clientTop  || body && body.clientTop  || 0);
+		}
+
+		// Add which for key events
+		if ( !event.which && ((event.charCode || event.charCode === 0) ? event.charCode : event.keyCode) ) {
+			event.which = event.charCode || event.keyCode;
+		}
+
+		// Add metaKey to non-Mac browsers (use ctrl for PC's and Meta for Macs)
+		if ( !event.metaKey && event.ctrlKey ) {
+			event.metaKey = event.ctrlKey;
+		}
+
+		// Add which for click: 1 === left; 2 === middle; 3 === right
+		// Note: button is not normalized, so don't use it
+		if ( !event.which && event.button !== undefined ) {
+			event.which = (event.button & 1 ? 1 : ( event.button & 2 ? 3 : ( event.button & 4 ? 2 : 0 ) ));
+		}
+
+		return event;
+	},
+
+	// Deprecated, use jQuery.guid instead
+	guid: 1E8,
+
+	// Deprecated, use jQuery.proxy instead
+	proxy: jQuery.proxy,
 
 	special: {
-		load: {
-
-			// Prevent triggered image.load events from bubbling to window.load
-			noBubble: true
+		ready: {
+			// Make sure the ready event is setup
+			setup: jQuery.bindReady,
+			teardown: jQuery.noop
 		},
-		focus: {
-
-			// Fire native event if possible so blur/focus sequence is correct
-			trigger: function() {
-				if ( this !== safeActiveElement() && this.focus ) {
-					this.focus();
-					return false;
-				}
+
+		live: {
+			add: function( handleObj ) {
+				jQuery.event.add( this, handleObj.origType, jQuery.extend({}, handleObj, {handler: liveHandler}) ); 
 			},
-			delegateType: "focusin"
+
+			remove: function( handleObj ) {
+				var remove = true,
+					type = handleObj.origType.replace(rnamespaces, "");
+				
+				jQuery.each( jQuery.data(this, "events").live || [], function() {
+					if ( type === this.origType.replace(rnamespaces, "") ) {
+						remove = false;
+						return false;
+					}
+				});
+
+				if ( remove ) {
+					jQuery.event.remove( this, handleObj.origType, liveHandler );
+				}
+			}
+
 		},
-		blur: {
-			trigger: function() {
-				if ( this === safeActiveElement() && this.blur ) {
-					this.blur();
-					return false;
-				}
+
+		beforeunload: {
+			setup: function( data, namespaces, eventHandle ) {
+				// We only want to do this special case on windows
+				if ( this.setInterval ) {
+					this.onbeforeunload = eventHandle;
+				}
+
+				return false;
 			},
-			delegateType: "focusout"
-		},
-		click: {
-
-			// For checkbox, fire native event so checked state will be right
-			trigger: function() {
-				if ( this.type === "checkbox" && this.click && jQuery.nodeName( this, "input" ) ) {
-					this.click();
-					return false;
-				}
-			},
-
-			// For cross-browser consistency, don't fire native .click() on links
-			_default: function( event ) {
-				return jQuery.nodeName( event.target, "a" );
-			}
-		},
-
-		beforeunload: {
-			postDispatch: function( event ) {
-
-				// Support: Firefox 20+
-				// Firefox doesn't alert if the returnValue field is not set.
-				if ( event.result !== undefined && event.originalEvent ) {
-					event.originalEvent.returnValue = event.result;
+			teardown: function( namespaces, eventHandle ) {
+				if ( this.onbeforeunload === eventHandle ) {
+					this.onbeforeunload = null;
 				}
 			}
@@ -4953,17 +2066,16 @@
 };
 
-jQuery.removeEvent = function( elem, type, handle ) {
-
-	// This "if" is needed for plain objects
-	if ( elem.removeEventListener ) {
-		elem.removeEventListener( type, handle );
-	}
-};
-
-jQuery.Event = function( src, props ) {
-
+var removeEvent = document.removeEventListener ?
+	function( elem, type, handle ) {
+		elem.removeEventListener( type, handle, false );
+	} : 
+	function( elem, type, handle ) {
+		elem.detachEvent( "on" + type, handle );
+	};
+
+jQuery.Event = function( src ) {
 	// Allow instantiation without the 'new' keyword
-	if ( !( this instanceof jQuery.Event ) ) {
-		return new jQuery.Event( src, props );
+	if ( !this.preventDefault ) {
+		return new jQuery.Event( src );
 	}
 
@@ -4972,15 +2084,4 @@
 		this.originalEvent = src;
 		this.type = src.type;
-
-		// Events bubbling up the document may have been marked as prevented
-		// by a handler lower down the tree; reflect the correct value.
-		this.isDefaultPrevented = src.defaultPrevented ||
-				src.defaultPrevented === undefined &&
-
-				// Support: Android<4.0
-				src.returnValue === false ?
-			returnTrue :
-			returnFalse;
-
 	// Event type
 	} else {
@@ -4988,564 +2089,2300 @@
 	}
 
-	// Put explicitly provided properties onto the event object
-	if ( props ) {
-		jQuery.extend( this, props );
-	}
-
-	// Create a timestamp if incoming event doesn't have one
-	this.timeStamp = src && src.timeStamp || jQuery.now();
+	// timeStamp is buggy for some events on Firefox(#3843)
+	// So we won't rely on the native value
+	this.timeStamp = now();
 
 	// Mark it as fixed
-	this[ jQuery.expando ] = true;
+	this[ expando ] = true;
 };
+
+function returnFalse() {
+	return false;
+}
+function returnTrue() {
+	return true;
+}
 
 // jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding
 // http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html
 jQuery.Event.prototype = {
-	constructor: jQuery.Event,
+	preventDefault: function() {
+		this.isDefaultPrevented = returnTrue;
+
+		var e = this.originalEvent;
+		if ( !e ) {
+			return;
+		}
+		
+		// if preventDefault exists run it on the original event
+		if ( e.preventDefault ) {
+			e.preventDefault();
+		}
+		// otherwise set the returnValue property of the original event to false (IE)
+		e.returnValue = false;
+	},
+	stopPropagation: function() {
+		this.isPropagationStopped = returnTrue;
+
+		var e = this.originalEvent;
+		if ( !e ) {
+			return;
+		}
+		// if stopPropagation exists run it on the original event
+		if ( e.stopPropagation ) {
+			e.stopPropagation();
+		}
+		// otherwise set the cancelBubble property of the original event to true (IE)
+		e.cancelBubble = true;
+	},
+	stopImmediatePropagation: function() {
+		this.isImmediatePropagationStopped = returnTrue;
+		this.stopPropagation();
+	},
 	isDefaultPrevented: returnFalse,
 	isPropagationStopped: returnFalse,
-	isImmediatePropagationStopped: returnFalse,
-	isSimulated: false,
-
-	preventDefault: function() {
-		var e = this.originalEvent;
-
-		this.isDefaultPrevented = returnTrue;
-
-		if ( e && !this.isSimulated ) {
-			e.preventDefault();
-		}
-	},
-	stopPropagation: function() {
-		var e = this.originalEvent;
-
-		this.isPropagationStopped = returnTrue;
-
-		if ( e && !this.isSimulated ) {
-			e.stopPropagation();
-		}
-	},
-	stopImmediatePropagation: function() {
-		var e = this.originalEvent;
-
-		this.isImmediatePropagationStopped = returnTrue;
-
-		if ( e && !this.isSimulated ) {
-			e.stopImmediatePropagation();
-		}
-
-		this.stopPropagation();
-	}
+	isImmediatePropagationStopped: returnFalse
 };
 
-// Create mouseenter/leave events using mouseover/out and event-time checks
-// so that event delegation works in jQuery.
-// Do the same for pointerenter/pointerleave and pointerover/pointerout
-//
-// Support: Safari 7 only
-// Safari sends mouseenter too often; see:
-// https://code.google.com/p/chromium/issues/detail?id=470258
-// for the description of the bug (it existed in older Chrome versions as well).
-jQuery.each( {
+// Checks if an event happened on an element within another element
+// Used in jQuery.event.special.mouseenter and mouseleave handlers
+var withinElement = function( event ) {
+	// Check if mouse(over|out) are still within the same parent element
+	var parent = event.relatedTarget;
+
+	// Firefox sometimes assigns relatedTarget a XUL element
+	// which we cannot access the parentNode property of
+	try {
+		// Traverse up the tree
+		while ( parent && parent !== this ) {
+			parent = parent.parentNode;
+		}
+
+		if ( parent !== this ) {
+			// set the correct event type
+			event.type = event.data;
+
+			// handle event if we actually just moused on to a non sub-element
+			jQuery.event.handle.apply( this, arguments );
+		}
+
+	// assuming we've left the element since we most likely mousedover a xul element
+	} catch(e) { }
+},
+
+// In case of event delegation, we only need to rename the event.type,
+// liveHandler will take care of the rest.
+delegate = function( event ) {
+	event.type = event.data;
+	jQuery.event.handle.apply( this, arguments );
+};
+
+// Create mouseenter and mouseleave events
+jQuery.each({
 	mouseenter: "mouseover",
-	mouseleave: "mouseout",
-	pointerenter: "pointerover",
-	pointerleave: "pointerout"
+	mouseleave: "mouseout"
 }, function( orig, fix ) {
 	jQuery.event.special[ orig ] = {
-		delegateType: fix,
-		bindType: fix,
-
-		handle: function( event ) {
-			var ret,
-				target = this,
-				related = event.relatedTarget,
-				handleObj = event.handleObj;
-
-			// For mouseenter/leave call the handler if related is outside the target.
-			// NB: No relatedTarget if the mouse left/entered the browser window
-			if ( !related || ( related !== target && !jQuery.contains( target, related ) ) ) {
-				event.type = handleObj.origType;
-				ret = handleObj.handler.apply( this, arguments );
-				event.type = fix;
-			}
-			return ret;
+		setup: function( data ) {
+			jQuery.event.add( this, fix, data && data.selector ? delegate : withinElement, orig );
+		},
+		teardown: function( data ) {
+			jQuery.event.remove( this, fix, data && data.selector ? delegate : withinElement );
 		}
 	};
-} );
-
-jQuery.fn.extend( {
-	on: function( types, selector, data, fn ) {
-		return on( this, types, selector, data, fn );
-	},
-	one: function( types, selector, data, fn ) {
-		return on( this, types, selector, data, fn, 1 );
-	},
-	off: function( types, selector, fn ) {
-		var handleObj, type;
-		if ( types && types.preventDefault && types.handleObj ) {
-
-			// ( event )  dispatched jQuery.Event
-			handleObj = types.handleObj;
-			jQuery( types.delegateTarget ).off(
-				handleObj.namespace ?
-					handleObj.origType + "." + handleObj.namespace :
-					handleObj.origType,
-				handleObj.selector,
-				handleObj.handler
-			);
+});
+
+// submit delegation
+if ( !jQuery.support.submitBubbles ) {
+
+	jQuery.event.special.submit = {
+		setup: function( data, namespaces ) {
+			if ( this.nodeName.toLowerCase() !== "form" ) {
+				jQuery.event.add(this, "click.specialSubmit", function( e ) {
+					var elem = e.target, type = elem.type;
+
+					if ( (type === "submit" || type === "image") && jQuery( elem ).closest("form").length ) {
+						return trigger( "submit", this, arguments );
+					}
+				});
+	 
+				jQuery.event.add(this, "keypress.specialSubmit", function( e ) {
+					var elem = e.target, type = elem.type;
+
+					if ( (type === "text" || type === "password") && jQuery( elem ).closest("form").length && e.keyCode === 13 ) {
+						return trigger( "submit", this, arguments );
+					}
+				});
+
+			} else {
+				return false;
+			}
+		},
+
+		teardown: function( namespaces ) {
+			jQuery.event.remove( this, ".specialSubmit" );
+		}
+	};
+
+}
+
+// change delegation, happens here so we have bind.
+if ( !jQuery.support.changeBubbles ) {
+
+	var formElems = /textarea|input|select/i,
+
+	changeFilters,
+
+	getVal = function( elem ) {
+		var type = elem.type, val = elem.value;
+
+		if ( type === "radio" || type === "checkbox" ) {
+			val = elem.checked;
+
+		} else if ( type === "select-multiple" ) {
+			val = elem.selectedIndex > -1 ?
+				jQuery.map( elem.options, function( elem ) {
+					return elem.selected;
+				}).join("-") :
+				"";
+
+		} else if ( elem.nodeName.toLowerCase() === "select" ) {
+			val = elem.selectedIndex;
+		}
+
+		return val;
+	},
+
+	testChange = function testChange( e ) {
+		var elem = e.target, data, val;
+
+		if ( !formElems.test( elem.nodeName ) || elem.readOnly ) {
+			return;
+		}
+
+		data = jQuery.data( elem, "_change_data" );
+		val = getVal(elem);
+
+		// the current data will be also retrieved by beforeactivate
+		if ( e.type !== "focusout" || elem.type !== "radio" ) {
+			jQuery.data( elem, "_change_data", val );
+		}
+		
+		if ( data === undefined || val === data ) {
+			return;
+		}
+
+		if ( data != null || val ) {
+			e.type = "change";
+			return jQuery.event.trigger( e, arguments[1], elem );
+		}
+	};
+
+	jQuery.event.special.change = {
+		filters: {
+			focusout: testChange, 
+
+			click: function( e ) {
+				var elem = e.target, type = elem.type;
+
+				if ( type === "radio" || type === "checkbox" || elem.nodeName.toLowerCase() === "select" ) {
+					return testChange.call( this, e );
+				}
+			},
+
+			// Change has to be called before submit
+			// Keydown will be called before keypress, which is used in submit-event delegation
+			keydown: function( e ) {
+				var elem = e.target, type = elem.type;
+
+				if ( (e.keyCode === 13 && elem.nodeName.toLowerCase() !== "textarea") ||
+					(e.keyCode === 32 && (type === "checkbox" || type === "radio")) ||
+					type === "select-multiple" ) {
+					return testChange.call( this, e );
+				}
+			},
+
+			// Beforeactivate happens also before the previous element is blurred
+			// with this event you can't trigger a change event, but you can store
+			// information/focus[in] is not needed anymore
+			beforeactivate: function( e ) {
+				var elem = e.target;
+				jQuery.data( elem, "_change_data", getVal(elem) );
+			}
+		},
+
+		setup: function( data, namespaces ) {
+			if ( this.type === "file" ) {
+				return false;
+			}
+
+			for ( var type in changeFilters ) {
+				jQuery.event.add( this, type + ".specialChange", changeFilters[type] );
+			}
+
+			return formElems.test( this.nodeName );
+		},
+
+		teardown: function( namespaces ) {
+			jQuery.event.remove( this, ".specialChange" );
+
+			return formElems.test( this.nodeName );
+		}
+	};
+
+	changeFilters = jQuery.event.special.change.filters;
+}
+
+function trigger( type, elem, args ) {
+	args[0].type = type;
+	return jQuery.event.handle.apply( elem, args );
+}
+
+// Create "bubbling" focus and blur events
+if ( document.addEventListener ) {
+	jQuery.each({ focus: "focusin", blur: "focusout" }, function( orig, fix ) {
+		jQuery.event.special[ fix ] = {
+			setup: function() {
+				this.addEventListener( orig, handler, true );
+			}, 
+			teardown: function() { 
+				this.removeEventListener( orig, handler, true );
+			}
+		};
+
+		function handler( e ) { 
+			e = jQuery.event.fix( e );
+			e.type = fix;
+			return jQuery.event.handle.call( this, e );
+		}
+	});
+}
+
+jQuery.each(["bind", "one"], function( i, name ) {
+	jQuery.fn[ name ] = function( type, data, fn ) {
+		// Handle object literals
+		if ( typeof type === "object" ) {
+			for ( var key in type ) {
+				this[ name ](key, data, type[key], fn);
+			}
 			return this;
 		}
-		if ( typeof types === "object" ) {
-
-			// ( types-object [, selector] )
-			for ( type in types ) {
-				this.off( type, selector, types[ type ] );
-			}
-			return this;
-		}
-		if ( selector === false || typeof selector === "function" ) {
-
-			// ( types [, fn] )
-			fn = selector;
-			selector = undefined;
-		}
-		if ( fn === false ) {
-			fn = returnFalse;
-		}
-		return this.each( function() {
-			jQuery.event.remove( this, types, fn, selector );
-		} );
-	}
-} );
-
-
-var
-	rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:-]+)[^>]*)\/>/gi,
-
-	// Support: IE 10-11, Edge 10240+
-	// In IE/Edge using regex groups here causes severe slowdowns.
-	// See https://connect.microsoft.com/IE/feedback/details/1736512/
-	rnoInnerhtml = /<script|<style|<link/i,
-
-	// checked="checked" or checked
-	rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i,
-	rscriptTypeMasked = /^true\/(.*)/,
-	rcleanScript = /^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g;
-
-// Manipulating tables requires a tbody
-function manipulationTarget( elem, content ) {
-	return jQuery.nodeName( elem, "table" ) &&
-		jQuery.nodeName( content.nodeType !== 11 ? content : content.firstChild, "tr" ) ?
-
-		elem.getElementsByTagName( "tbody" )[ 0 ] ||
-			elem.appendChild( elem.ownerDocument.createElement( "tbody" ) ) :
-		elem;
+		
+		if ( jQuery.isFunction( data ) ) {
+			fn = data;
+			data = undefined;
+		}
+
+		var handler = name === "one" ? jQuery.proxy( fn, function( event ) {
+			jQuery( this ).unbind( event, handler );
+			return fn.apply( this, arguments );
+		}) : fn;
+
+		if ( type === "unload" && name !== "one" ) {
+			this.one( type, data, fn );
+
+		} else {
+			for ( var i = 0, l = this.length; i < l; i++ ) {
+				jQuery.event.add( this[i], type, handler, data );
+			}
+		}
+
+		return this;
+	};
+});
+
+jQuery.fn.extend({
+	unbind: function( type, fn ) {
+		// Handle object literals
+		if ( typeof type === "object" && !type.preventDefault ) {
+			for ( var key in type ) {
+				this.unbind(key, type[key]);
+			}
+
+		} else {
+			for ( var i = 0, l = this.length; i < l; i++ ) {
+				jQuery.event.remove( this[i], type, fn );
+			}
+		}
+
+		return this;
+	},
+	
+	delegate: function( selector, types, data, fn ) {
+		return this.live( types, data, fn, selector );
+	},
+	
+	undelegate: function( selector, types, fn ) {
+		if ( arguments.length === 0 ) {
+				return this.unbind( "live" );
+		
+		} else {
+			return this.die( types, null, fn, selector );
+		}
+	},
+	
+	trigger: function( type, data ) {
+		return this.each(function() {
+			jQuery.event.trigger( type, data, this );
+		});
+	},
+
+	triggerHandler: function( type, data ) {
+		if ( this[0] ) {
+			var event = jQuery.Event( type );
+			event.preventDefault();
+			event.stopPropagation();
+			jQuery.event.trigger( event, data, this[0] );
+			return event.result;
+		}
+	},
+
+	toggle: function( fn ) {
+		// Save reference to arguments for access in closure
+		var args = arguments, i = 1;
+
+		// link all the functions, so any of them can unbind this click handler
+		while ( i < args.length ) {
+			jQuery.proxy( fn, args[ i++ ] );
+		}
+
+		return this.click( jQuery.proxy( fn, function( event ) {
+			// Figure out which function to execute
+			var lastToggle = ( jQuery.data( this, "lastToggle" + fn.guid ) || 0 ) % i;
+			jQuery.data( this, "lastToggle" + fn.guid, lastToggle + 1 );
+
+			// Make sure that clicks stop
+			event.preventDefault();
+
+			// and execute the function
+			return args[ lastToggle ].apply( this, arguments ) || false;
+		}));
+	},
+
+	hover: function( fnOver, fnOut ) {
+		return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver );
+	}
+});
+
+var liveMap = {
+	focus: "focusin",
+	blur: "focusout",
+	mouseenter: "mouseover",
+	mouseleave: "mouseout"
+};
+
+jQuery.each(["live", "die"], function( i, name ) {
+	jQuery.fn[ name ] = function( types, data, fn, origSelector /* Internal Use Only */ ) {
+		var type, i = 0, match, namespaces, preType,
+			selector = origSelector || this.selector,
+			context = origSelector ? this : jQuery( this.context );
+
+		if ( jQuery.isFunction( data ) ) {
+			fn = data;
+			data = undefined;
+		}
+
+		types = (types || "").split(" ");
+
+		while ( (type = types[ i++ ]) != null ) {
+			match = rnamespaces.exec( type );
+			namespaces = "";
+
+			if ( match )  {
+				namespaces = match[0];
+				type = type.replace( rnamespaces, "" );
+			}
+
+			if ( type === "hover" ) {
+				types.push( "mouseenter" + namespaces, "mouseleave" + namespaces );
+				continue;
+			}
+
+			preType = type;
+
+			if ( type === "focus" || type === "blur" ) {
+				types.push( liveMap[ type ] + namespaces );
+				type = type + namespaces;
+
+			} else {
+				type = (liveMap[ type ] || type) + namespaces;
+			}
+
+			if ( name === "live" ) {
+				// bind live handler
+				context.each(function(){
+					jQuery.event.add( this, liveConvert( type, selector ),
+						{ data: data, selector: selector, handler: fn, origType: type, origHandler: fn, preType: preType } );
+				});
+
+			} else {
+				// unbind live handler
+				context.unbind( liveConvert( type, selector ), fn );
+			}
+		}
+		
+		return this;
+	}
+});
+
+function liveHandler( event ) {
+	var stop, elems = [], selectors = [], args = arguments,
+		related, match, handleObj, elem, j, i, l, data,
+		events = jQuery.data( this, "events" );
+
+	// Make sure we avoid non-left-click bubbling in Firefox (#3861)
+	if ( event.liveFired === this || !events || !events.live || event.button && event.type === "click" ) {
+		return;
+	}
+
+	event.liveFired = this;
+
+	var live = events.live.slice(0);
+
+	for ( j = 0; j < live.length; j++ ) {
+		handleObj = live[j];
+
+		if ( handleObj.origType.replace( rnamespaces, "" ) === event.type ) {
+			selectors.push( handleObj.selector );
+
+		} else {
+			live.splice( j--, 1 );
+		}
+	}
+
+	match = jQuery( event.target ).closest( selectors, event.currentTarget );
+
+	for ( i = 0, l = match.length; i < l; i++ ) {
+		for ( j = 0; j < live.length; j++ ) {
+			handleObj = live[j];
+
+			if ( match[i].selector === handleObj.selector ) {
+				elem = match[i].elem;
+				related = null;
+
+				// Those two events require additional checking
+				if ( handleObj.preType === "mouseenter" || handleObj.preType === "mouseleave" ) {
+					related = jQuery( event.relatedTarget ).closest( handleObj.selector )[0];
+				}
+
+				if ( !related || related !== elem ) {
+					elems.push({ elem: elem, handleObj: handleObj });
+				}
+			}
+		}
+	}
+
+	for ( i = 0, l = elems.length; i < l; i++ ) {
+		match = elems[i];
+		event.currentTarget = match.elem;
+		event.data = match.handleObj.data;
+		event.handleObj = match.handleObj;
+
+		if ( match.handleObj.origHandler.apply( match.elem, args ) === false ) {
+			stop = false;
+			break;
+		}
+	}
+
+	return stop;
 }
 
-// Replace/restore the type attribute of script elements for safe DOM manipulation
-function disableScript( elem ) {
-	elem.type = ( elem.getAttribute( "type" ) !== null ) + "/" + elem.type;
-	return elem;
+function liveConvert( type, selector ) {
+	return "live." + (type && type !== "*" ? type + "." : "") + selector.replace(/\./g, "`").replace(/ /g, "&");
 }
-function restoreScript( elem ) {
-	var match = rscriptTypeMasked.exec( elem.type );
-
-	if ( match ) {
-		elem.type = match[ 1 ];
+
+jQuery.each( ("blur focus focusin focusout load resize scroll unload click dblclick " +
+	"mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " +
+	"change select submit keydown keypress keyup error").split(" "), function( i, name ) {
+
+	// Handle event binding
+	jQuery.fn[ name ] = function( fn ) {
+		return fn ? this.bind( name, fn ) : this.trigger( name );
+	};
+
+	if ( jQuery.attrFn ) {
+		jQuery.attrFn[ name ] = true;
+	}
+});
+
+// Prevent memory leaks in IE
+// Window isn't included so as not to unbind existing unload events
+// More info:
+//  - http://isaacschlueter.com/2006/10/msie-memory-leaks/
+if ( window.attachEvent && !window.addEventListener ) {
+	window.attachEvent("onunload", function() {
+		for ( var id in jQuery.cache ) {
+			if ( jQuery.cache[ id ].handle ) {
+				// Try/Catch is to handle iframes being unloaded, see #4280
+				try {
+					jQuery.event.remove( jQuery.cache[ id ].handle.elem );
+				} catch(e) {}
+			}
+		}
+	});
+}
+/*!
+ * Sizzle CSS Selector Engine - v1.0
+ *  Copyright 2009, The Dojo Foundation
+ *  Released under the MIT, BSD, and GPL Licenses.
+ *  More information: http://sizzlejs.com/
+ */
+(function(){
+
+var chunker = /((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^[\]]*\]|['"][^'"]*['"]|[^[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,
+	done = 0,
+	toString = Object.prototype.toString,
+	hasDuplicate = false,
+	baseHasDuplicate = true;
+
+// Here we check if the JavaScript engine is using some sort of
+// optimization where it does not always call our comparision
+// function. If that is the case, discard the hasDuplicate value.
+//   Thus far that includes Google Chrome.
+[0, 0].sort(function(){
+	baseHasDuplicate = false;
+	return 0;
+});
+
+var Sizzle = function(selector, context, results, seed) {
+	results = results || [];
+	var origContext = context = context || document;
+
+	if ( context.nodeType !== 1 && context.nodeType !== 9 ) {
+		return [];
+	}
+	
+	if ( !selector || typeof selector !== "string" ) {
+		return results;
+	}
+
+	var parts = [], m, set, checkSet, extra, prune = true, contextXML = isXML(context),
+		soFar = selector;
+	
+	// Reset the position of the chunker regexp (start from head)
+	while ( (chunker.exec(""), m = chunker.exec(soFar)) !== null ) {
+		soFar = m[3];
+		
+		parts.push( m[1] );
+		
+		if ( m[2] ) {
+			extra = m[3];
+			break;
+		}
+	}
+
+	if ( parts.length > 1 && origPOS.exec( selector ) ) {
+		if ( parts.length === 2 && Expr.relative[ parts[0] ] ) {
+			set = posProcess( parts[0] + parts[1], context );
+		} else {
+			set = Expr.relative[ parts[0] ] ?
+				[ context ] :
+				Sizzle( parts.shift(), context );
+
+			while ( parts.length ) {
+				selector = parts.shift();
+
+				if ( Expr.relative[ selector ] ) {
+					selector += parts.shift();
+				}
+				
+				set = posProcess( selector, set );
+			}
+		}
 	} else {
-		elem.removeAttribute( "type" );
-	}
-
-	return elem;
-}
-
-function cloneCopyEvent( src, dest ) {
-	var i, l, type, pdataOld, pdataCur, udataOld, udataCur, events;
-
-	if ( dest.nodeType !== 1 ) {
-		return;
-	}
-
-	// 1. Copy private data: events, handlers, etc.
-	if ( dataPriv.hasData( src ) ) {
-		pdataOld = dataPriv.access( src );
-		pdataCur = dataPriv.set( dest, pdataOld );
-		events = pdataOld.events;
-
-		if ( events ) {
-			delete pdataCur.handle;
-			pdataCur.events = {};
-
-			for ( type in events ) {
-				for ( i = 0, l = events[ type ].length; i < l; i++ ) {
-					jQuery.event.add( dest, type, events[ type ][ i ] );
-				}
-			}
-		}
-	}
-
-	// 2. Copy user data
-	if ( dataUser.hasData( src ) ) {
-		udataOld = dataUser.access( src );
-		udataCur = jQuery.extend( {}, udataOld );
-
-		dataUser.set( dest, udataCur );
-	}
-}
-
-// Fix IE bugs, see support tests
-function fixInput( src, dest ) {
-	var nodeName = dest.nodeName.toLowerCase();
-
-	// Fails to persist the checked state of a cloned checkbox or radio button.
-	if ( nodeName === "input" && rcheckableType.test( src.type ) ) {
-		dest.checked = src.checked;
-
-	// Fails to return the selected option to the default selected state when cloning options
-	} else if ( nodeName === "input" || nodeName === "textarea" ) {
-		dest.defaultValue = src.defaultValue;
-	}
-}
-
-function domManip( collection, args, callback, ignored ) {
-
-	// Flatten any nested arrays
-	args = concat.apply( [], args );
-
-	var fragment, first, scripts, hasScripts, node, doc,
-		i = 0,
-		l = collection.length,
-		iNoClone = l - 1,
-		value = args[ 0 ],
-		isFunction = jQuery.isFunction( value );
-
-	// We can't cloneNode fragments that contain checked, in WebKit
-	if ( isFunction ||
-			( l > 1 && typeof value === "string" &&
-				!support.checkClone && rchecked.test( value ) ) ) {
-		return collection.each( function( index ) {
-			var self = collection.eq( index );
-			if ( isFunction ) {
-				args[ 0 ] = value.call( this, index, self.html() );
-			}
-			domManip( self, args, callback, ignored );
-		} );
-	}
-
-	if ( l ) {
-		fragment = buildFragment( args, collection[ 0 ].ownerDocument, false, collection, ignored );
-		first = fragment.firstChild;
-
-		if ( fragment.childNodes.length === 1 ) {
-			fragment = first;
-		}
-
-		// Require either new content or an interest in ignored elements to invoke the callback
-		if ( first || ignored ) {
-			scripts = jQuery.map( getAll( fragment, "script" ), disableScript );
-			hasScripts = scripts.length;
-
-			// Use the original fragment for the last item
-			// instead of the first because it can end up
-			// being emptied incorrectly in certain situations (#8070).
-			for ( ; i < l; i++ ) {
-				node = fragment;
-
-				if ( i !== iNoClone ) {
-					node = jQuery.clone( node, true, true );
-
-					// Keep references to cloned scripts for later restoration
-					if ( hasScripts ) {
-
-						// Support: Android<4.1, PhantomJS<2
-						// push.apply(_, arraylike) throws on ancient WebKit
-						jQuery.merge( scripts, getAll( node, "script" ) );
+		// Take a shortcut and set the context if the root selector is an ID
+		// (but not if it'll be faster if the inner selector is an ID)
+		if ( !seed && parts.length > 1 && context.nodeType === 9 && !contextXML &&
+				Expr.match.ID.test(parts[0]) && !Expr.match.ID.test(parts[parts.length - 1]) ) {
+			var ret = Sizzle.find( parts.shift(), context, contextXML );
+			context = ret.expr ? Sizzle.filter( ret.expr, ret.set )[0] : ret.set[0];
+		}
+
+		if ( context ) {
+			var ret = seed ?
+				{ expr: parts.pop(), set: makeArray(seed) } :
+				Sizzle.find( parts.pop(), parts.length === 1 && (parts[0] === "~" || parts[0] === "+") && context.parentNode ? context.parentNode : context, contextXML );
+			set = ret.expr ? Sizzle.filter( ret.expr, ret.set ) : ret.set;
+
+			if ( parts.length > 0 ) {
+				checkSet = makeArray(set);
+			} else {
+				prune = false;
+			}
+
+			while ( parts.length ) {
+				var cur = parts.pop(), pop = cur;
+
+				if ( !Expr.relative[ cur ] ) {
+					cur = "";
+				} else {
+					pop = parts.pop();
+				}
+
+				if ( pop == null ) {
+					pop = context;
+				}
+
+				Expr.relative[ cur ]( checkSet, pop, contextXML );
+			}
+		} else {
+			checkSet = parts = [];
+		}
+	}
+
+	if ( !checkSet ) {
+		checkSet = set;
+	}
+
+	if ( !checkSet ) {
+		Sizzle.error( cur || selector );
+	}
+
+	if ( toString.call(checkSet) === "[object Array]" ) {
+		if ( !prune ) {
+			results.push.apply( results, checkSet );
+		} else if ( context && context.nodeType === 1 ) {
+			for ( var i = 0; checkSet[i] != null; i++ ) {
+				if ( checkSet[i] && (checkSet[i] === true || checkSet[i].nodeType === 1 && contains(context, checkSet[i])) ) {
+					results.push( set[i] );
+				}
+			}
+		} else {
+			for ( var i = 0; checkSet[i] != null; i++ ) {
+				if ( checkSet[i] && checkSet[i].nodeType === 1 ) {
+					results.push( set[i] );
+				}
+			}
+		}
+	} else {
+		makeArray( checkSet, results );
+	}
+
+	if ( extra ) {
+		Sizzle( extra, origContext, results, seed );
+		Sizzle.uniqueSort( results );
+	}
+
+	return results;
+};
+
+Sizzle.uniqueSort = function(results){
+	if ( sortOrder ) {
+		hasDuplicate = baseHasDuplicate;
+		results.sort(sortOrder);
+
+		if ( hasDuplicate ) {
+			for ( var i = 1; i < results.length; i++ ) {
+				if ( results[i] === results[i-1] ) {
+					results.splice(i--, 1);
+				}
+			}
+		}
+	}
+
+	return results;
+};
+
+Sizzle.matches = function(expr, set){
+	return Sizzle(expr, null, null, set);
+};
+
+Sizzle.find = function(expr, context, isXML){
+	var set, match;
+
+	if ( !expr ) {
+		return [];
+	}
+
+	for ( var i = 0, l = Expr.order.length; i < l; i++ ) {
+		var type = Expr.order[i], match;
+		
+		if ( (match = Expr.leftMatch[ type ].exec( expr )) ) {
+			var left = match[1];
+			match.splice(1,1);
+
+			if ( left.substr( left.length - 1 ) !== "\\" ) {
+				match[1] = (match[1] || "").replace(/\\/g, "");
+				set = Expr.find[ type ]( match, context, isXML );
+				if ( set != null ) {
+					expr = expr.replace( Expr.match[ type ], "" );
+					break;
+				}
+			}
+		}
+	}
+
+	if ( !set ) {
+		set = context.getElementsByTagName("*");
+	}
+
+	return {set: set, expr: expr};
+};
+
+Sizzle.filter = function(expr, set, inplace, not){
+	var old = expr, result = [], curLoop = set, match, anyFound,
+		isXMLFilter = set && set[0] && isXML(set[0]);
+
+	while ( expr && set.length ) {
+		for ( var type in Expr.filter ) {
+			if ( (match = Expr.leftMatch[ type ].exec( expr )) != null && match[2] ) {
+				var filter = Expr.filter[ type ], found, item, left = match[1];
+				anyFound = false;
+
+				match.splice(1,1);
+
+				if ( left.substr( left.length - 1 ) === "\\" ) {
+					continue;
+				}
+
+				if ( curLoop === result ) {
+					result = [];
+				}
+
+				if ( Expr.preFilter[ type ] ) {
+					match = Expr.preFilter[ type ]( match, curLoop, inplace, result, not, isXMLFilter );
+
+					if ( !match ) {
+						anyFound = found = true;
+					} else if ( match === true ) {
+						continue;
 					}
 				}
 
-				callback.call( collection[ i ], node, i );
-			}
-
-			if ( hasScripts ) {
-				doc = scripts[ scripts.length - 1 ].ownerDocument;
-
-				// Reenable scripts
-				jQuery.map( scripts, restoreScript );
-
-				// Evaluate executable scripts on first document insertion
-				for ( i = 0; i < hasScripts; i++ ) {
-					node = scripts[ i ];
-					if ( rscriptType.test( node.type || "" ) &&
-						!dataPriv.access( node, "globalEval" ) &&
-						jQuery.contains( doc, node ) ) {
-
-						if ( node.src ) {
-
-							// Optional AJAX dependency, but won't run scripts if not present
-							if ( jQuery._evalUrl ) {
-								jQuery._evalUrl( node.src );
-							}
-						} else {
-							jQuery.globalEval( node.textContent.replace( rcleanScript, "" ) );
-						}
-					}
-				}
-			}
-		}
-	}
-
-	return collection;
-}
-
-function remove( elem, selector, keepData ) {
-	var node,
-		nodes = selector ? jQuery.filter( selector, elem ) : elem,
-		i = 0;
-
-	for ( ; ( node = nodes[ i ] ) != null; i++ ) {
-		if ( !keepData && node.nodeType === 1 ) {
-			jQuery.cleanData( getAll( node ) );
-		}
-
-		if ( node.parentNode ) {
-			if ( keepData && jQuery.contains( node.ownerDocument, node ) ) {
-				setGlobalEval( getAll( node, "script" ) );
-			}
-			node.parentNode.removeChild( node );
-		}
-	}
-
-	return elem;
-}
-
-jQuery.extend( {
-	htmlPrefilter: function( html ) {
-		return html.replace( rxhtmlTag, "<$1></$2>" );
-	},
-
-	clone: function( elem, dataAndEvents, deepDataAndEvents ) {
-		var i, l, srcElements, destElements,
-			clone = elem.cloneNode( true ),
-			inPage = jQuery.contains( elem.ownerDocument, elem );
-
-		// Fix IE cloning issues
-		if ( !support.noCloneChecked && ( elem.nodeType === 1 || elem.nodeType === 11 ) &&
-				!jQuery.isXMLDoc( elem ) ) {
-
-			// We eschew Sizzle here for performance reasons: http://jsperf.com/getall-vs-sizzle/2
-			destElements = getAll( clone );
-			srcElements = getAll( elem );
-
-			for ( i = 0, l = srcElements.length; i < l; i++ ) {
-				fixInput( srcElements[ i ], destElements[ i ] );
-			}
-		}
-
-		// Copy the events from the original to the clone
-		if ( dataAndEvents ) {
-			if ( deepDataAndEvents ) {
-				srcElements = srcElements || getAll( elem );
-				destElements = destElements || getAll( clone );
-
-				for ( i = 0, l = srcElements.length; i < l; i++ ) {
-					cloneCopyEvent( srcElements[ i ], destElements[ i ] );
-				}
-			} else {
-				cloneCopyEvent( elem, clone );
-			}
-		}
-
-		// Preserve script evaluation history
-		destElements = getAll( clone, "script" );
-		if ( destElements.length > 0 ) {
-			setGlobalEval( destElements, !inPage && getAll( elem, "script" ) );
-		}
-
-		// Return the cloned set
-		return clone;
-	},
-
-	cleanData: function( elems ) {
-		var data, elem, type,
-			special = jQuery.event.special,
-			i = 0;
-
-		for ( ; ( elem = elems[ i ] ) !== undefined; i++ ) {
-			if ( acceptData( elem ) ) {
-				if ( ( data = elem[ dataPriv.expando ] ) ) {
-					if ( data.events ) {
-						for ( type in data.events ) {
-							if ( special[ type ] ) {
-								jQuery.event.remove( elem, type );
-
-							// This is a shortcut to avoid jQuery.event.remove's overhead
-							} else {
-								jQuery.removeEvent( elem, type, data.handle );
+				if ( match ) {
+					for ( var i = 0; (item = curLoop[i]) != null; i++ ) {
+						if ( item ) {
+							found = filter( item, match, i, curLoop );
+							var pass = not ^ !!found;
+
+							if ( inplace && found != null ) {
+								if ( pass ) {
+									anyFound = true;
+								} else {
+									curLoop[i] = false;
+								}
+							} else if ( pass ) {
+								result.push( item );
+								anyFound = true;
 							}
 						}
 					}
-
-					// Support: Chrome <= 35-45+
-					// Assign undefined instead of using delete, see Data#remove
-					elem[ dataPriv.expando ] = undefined;
-				}
-				if ( elem[ dataUser.expando ] ) {
-
-					// Support: Chrome <= 35-45+
-					// Assign undefined instead of using delete, see Data#remove
-					elem[ dataUser.expando ] = undefined;
-				}
-			}
-		}
-	}
-} );
-
-jQuery.fn.extend( {
-
-	// Keep domManip exposed until 3.0 (gh-2225)
-	domManip: domManip,
-
-	detach: function( selector ) {
-		return remove( this, selector, true );
-	},
-
-	remove: function( selector ) {
-		return remove( this, selector );
-	},
-
-	text: function( value ) {
-		return access( this, function( value ) {
-			return value === undefined ?
-				jQuery.text( this ) :
-				this.empty().each( function() {
-					if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {
-						this.textContent = value;
+				}
+
+				if ( found !== undefined ) {
+					if ( !inplace ) {
+						curLoop = result;
 					}
-				} );
-		}, null, value, arguments.length );
-	},
-
-	append: function() {
-		return domManip( this, arguments, function( elem ) {
-			if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {
-				var target = manipulationTarget( this, elem );
-				target.appendChild( elem );
-			}
-		} );
-	},
-
-	prepend: function() {
-		return domManip( this, arguments, function( elem ) {
-			if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {
-				var target = manipulationTarget( this, elem );
-				target.insertBefore( elem, target.firstChild );
-			}
-		} );
-	},
-
-	before: function() {
-		return domManip( this, arguments, function( elem ) {
-			if ( this.parentNode ) {
-				this.parentNode.insertBefore( elem, this );
-			}
-		} );
-	},
-
-	after: function() {
-		return domManip( this, arguments, function( elem ) {
-			if ( this.parentNode ) {
-				this.parentNode.insertBefore( elem, this.nextSibling );
-			}
-		} );
-	},
-
-	empty: function() {
-		var elem,
-			i = 0;
-
-		for ( ; ( elem = this[ i ] ) != null; i++ ) {
-			if ( elem.nodeType === 1 ) {
-
-				// Prevent memory leaks
-				jQuery.cleanData( getAll( elem, false ) );
-
-				// Remove any remaining nodes
-				elem.textContent = "";
-			}
-		}
-
-		return this;
-	},
-
-	clone: function( dataAndEvents, deepDataAndEvents ) {
-		dataAndEvents = dataAndEvents == null ? false : dataAndEvents;
-		deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents;
-
-		return this.map( function() {
-			return jQuery.clone( this, dataAndEvents, deepDataAndEvents );
-		} );
-	},
-
-	html: function( value ) {
-		return access( this, function( value ) {
-			var elem = this[ 0 ] || {},
-				i = 0,
-				l = this.length;
-
-			if ( value === undefined && elem.nodeType === 1 ) {
-				return elem.innerHTML;
-			}
-
-			// See if we can take a shortcut and just use innerHTML
-			if ( typeof value === "string" && !rnoInnerhtml.test( value ) &&
-				!wrapMap[ ( rtagName.exec( value ) || [ "", "" ] )[ 1 ].toLowerCase() ] ) {
-
-				value = jQuery.htmlPrefilter( value );
-
-				try {
-					for ( ; i < l; i++ ) {
-						elem = this[ i ] || {};
-
-						// Remove element nodes and prevent memory leaks
-						if ( elem.nodeType === 1 ) {
-							jQuery.cleanData( getAll( elem, false ) );
-							elem.innerHTML = value;
+
+					expr = expr.replace( Expr.match[ type ], "" );
+
+					if ( !anyFound ) {
+						return [];
+					}
+
+					break;
+				}
+			}
+		}
+
+		// Improper expression
+		if ( expr === old ) {
+			if ( anyFound == null ) {
+				Sizzle.error( expr );
+			} else {
+				break;
+			}
+		}
+
+		old = expr;
+	}
+
+	return curLoop;
+};
+
+Sizzle.error = function( msg ) {
+	throw "Syntax error, unrecognized expression: " + msg;
+};
+
+var Expr = Sizzle.selectors = {
+	order: [ "ID", "NAME", "TAG" ],
+	match: {
+		ID: /#((?:[\w\u00c0-\uFFFF-]|\\.)+)/,
+		CLASS: /\.((?:[\w\u00c0-\uFFFF-]|\\.)+)/,
+		NAME: /\[name=['"]*((?:[\w\u00c0-\uFFFF-]|\\.)+)['"]*\]/,
+		ATTR: /\[\s*((?:[\w\u00c0-\uFFFF-]|\\.)+)\s*(?:(\S?=)\s*(['"]*)(.*?)\3|)\s*\]/,
+		TAG: /^((?:[\w\u00c0-\uFFFF\*-]|\\.)+)/,
+		CHILD: /:(only|nth|last|first)-child(?:\((even|odd|[\dn+-]*)\))?/,
+		POS: /:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^-]|$)/,
+		PSEUDO: /:((?:[\w\u00c0-\uFFFF-]|\\.)+)(?:\((['"]?)((?:\([^\)]+\)|[^\(\)]*)+)\2\))?/
+	},
+	leftMatch: {},
+	attrMap: {
+		"class": "className",
+		"for": "htmlFor"
+	},
+	attrHandle: {
+		href: function(elem){
+			return elem.getAttribute("href");
+		}
+	},
+	relative: {
+		"+": function(checkSet, part){
+			var isPartStr = typeof part === "string",
+				isTag = isPartStr && !/\W/.test(part),
+				isPartStrNotTag = isPartStr && !isTag;
+
+			if ( isTag ) {
+				part = part.toLowerCase();
+			}
+
+			for ( var i = 0, l = checkSet.length, elem; i < l; i++ ) {
+				if ( (elem = checkSet[i]) ) {
+					while ( (elem = elem.previousSibling) && elem.nodeType !== 1 ) {}
+
+					checkSet[i] = isPartStrNotTag || elem && elem.nodeName.toLowerCase() === part ?
+						elem || false :
+						elem === part;
+				}
+			}
+
+			if ( isPartStrNotTag ) {
+				Sizzle.filter( part, checkSet, true );
+			}
+		},
+		">": function(checkSet, part){
+			var isPartStr = typeof part === "string";
+
+			if ( isPartStr && !/\W/.test(part) ) {
+				part = part.toLowerCase();
+
+				for ( var i = 0, l = checkSet.length; i < l; i++ ) {
+					var elem = checkSet[i];
+					if ( elem ) {
+						var parent = elem.parentNode;
+						checkSet[i] = parent.nodeName.toLowerCase() === part ? parent : false;
+					}
+				}
+			} else {
+				for ( var i = 0, l = checkSet.length; i < l; i++ ) {
+					var elem = checkSet[i];
+					if ( elem ) {
+						checkSet[i] = isPartStr ?
+							elem.parentNode :
+							elem.parentNode === part;
+					}
+				}
+
+				if ( isPartStr ) {
+					Sizzle.filter( part, checkSet, true );
+				}
+			}
+		},
+		"": function(checkSet, part, isXML){
+			var doneName = done++, checkFn = dirCheck;
+
+			if ( typeof part === "string" && !/\W/.test(part) ) {
+				var nodeCheck = part = part.toLowerCase();
+				checkFn = dirNodeCheck;
+			}
+
+			checkFn("parentNode", part, doneName, checkSet, nodeCheck, isXML);
+		},
+		"~": function(checkSet, part, isXML){
+			var doneName = done++, checkFn = dirCheck;
+
+			if ( typeof part === "string" && !/\W/.test(part) ) {
+				var nodeCheck = part = part.toLowerCase();
+				checkFn = dirNodeCheck;
+			}
+
+			checkFn("previousSibling", part, doneName, checkSet, nodeCheck, isXML);
+		}
+	},
+	find: {
+		ID: function(match, context, isXML){
+			if ( typeof context.getElementById !== "undefined" && !isXML ) {
+				var m = context.getElementById(match[1]);
+				return m ? [m] : [];
+			}
+		},
+		NAME: function(match, context){
+			if ( typeof context.getElementsByName !== "undefined" ) {
+				var ret = [], results = context.getElementsByName(match[1]);
+
+				for ( var i = 0, l = results.length; i < l; i++ ) {
+					if ( results[i].getAttribute("name") === match[1] ) {
+						ret.push( results[i] );
+					}
+				}
+
+				return ret.length === 0 ? null : ret;
+			}
+		},
+		TAG: function(match, context){
+			return context.getElementsByTagName(match[1]);
+		}
+	},
+	preFilter: {
+		CLASS: function(match, curLoop, inplace, result, not, isXML){
+			match = " " + match[1].replace(/\\/g, "") + " ";
+
+			if ( isXML ) {
+				return match;
+			}
+
+			for ( var i = 0, elem; (elem = curLoop[i]) != null; i++ ) {
+				if ( elem ) {
+					if ( not ^ (elem.className && (" " + elem.className + " ").replace(/[\t\n]/g, " ").indexOf(match) >= 0) ) {
+						if ( !inplace ) {
+							result.push( elem );
+						}
+					} else if ( inplace ) {
+						curLoop[i] = false;
+					}
+				}
+			}
+
+			return false;
+		},
+		ID: function(match){
+			return match[1].replace(/\\/g, "");
+		},
+		TAG: function(match, curLoop){
+			return match[1].toLowerCase();
+		},
+		CHILD: function(match){
+			if ( match[1] === "nth" ) {
+				// parse equations like 'even', 'odd', '5', '2n', '3n+2', '4n-1', '-n+6'
+				var test = /(-?)(\d*)n((?:\+|-)?\d*)/.exec(
+					match[2] === "even" && "2n" || match[2] === "odd" && "2n+1" ||
+					!/\D/.test( match[2] ) && "0n+" + match[2] || match[2]);
+
+				// calculate the numbers (first)n+(last) including if they are negative
+				match[2] = (test[1] + (test[2] || 1)) - 0;
+				match[3] = test[3] - 0;
+			}
+
+			// TODO: Move to normal caching system
+			match[0] = done++;
+
+			return match;
+		},
+		ATTR: function(match, curLoop, inplace, result, not, isXML){
+			var name = match[1].replace(/\\/g, "");
+			
+			if ( !isXML && Expr.attrMap[name] ) {
+				match[1] = Expr.attrMap[name];
+			}
+
+			if ( match[2] === "~=" ) {
+				match[4] = " " + match[4] + " ";
+			}
+
+			return match;
+		},
+		PSEUDO: function(match, curLoop, inplace, result, not){
+			if ( match[1] === "not" ) {
+				// If we're dealing with a complex expression, or a simple one
+				if ( ( chunker.exec(match[3]) || "" ).length > 1 || /^\w/.test(match[3]) ) {
+					match[3] = Sizzle(match[3], null, null, curLoop);
+				} else {
+					var ret = Sizzle.filter(match[3], curLoop, inplace, true ^ not);
+					if ( !inplace ) {
+						result.push.apply( result, ret );
+					}
+					return false;
+				}
+			} else if ( Expr.match.POS.test( match[0] ) || Expr.match.CHILD.test( match[0] ) ) {
+				return true;
+			}
+			
+			return match;
+		},
+		POS: function(match){
+			match.unshift( true );
+			return match;
+		}
+	},
+	filters: {
+		enabled: function(elem){
+			return elem.disabled === false && elem.type !== "hidden";
+		},
+		disabled: function(elem){
+			return elem.disabled === true;
+		},
+		checked: function(elem){
+			return elem.checked === true;
+		},
+		selected: function(elem){
+			// Accessing this property makes selected-by-default
+			// options in Safari work properly
+			elem.parentNode.selectedIndex;
+			return elem.selected === true;
+		},
+		parent: function(elem){
+			return !!elem.firstChild;
+		},
+		empty: function(elem){
+			return !elem.firstChild;
+		},
+		has: function(elem, i, match){
+			return !!Sizzle( match[3], elem ).length;
+		},
+		header: function(elem){
+			return /h\d/i.test( elem.nodeName );
+		},
+		text: function(elem){
+			return "text" === elem.type;
+		},
+		radio: function(elem){
+			return "radio" === elem.type;
+		},
+		checkbox: function(elem){
+			return "checkbox" === elem.type;
+		},
+		file: function(elem){
+			return "file" === elem.type;
+		},
+		password: function(elem){
+			return "password" === elem.type;
+		},
+		submit: function(elem){
+			return "submit" === elem.type;
+		},
+		image: function(elem){
+			return "image" === elem.type;
+		},
+		reset: function(elem){
+			return "reset" === elem.type;
+		},
+		button: function(elem){
+			return "button" === elem.type || elem.nodeName.toLowerCase() === "button";
+		},
+		input: function(elem){
+			return /input|select|textarea|button/i.test(elem.nodeName);
+		}
+	},
+	setFilters: {
+		first: function(elem, i){
+			return i === 0;
+		},
+		last: function(elem, i, match, array){
+			return i === array.length - 1;
+		},
+		even: function(elem, i){
+			return i % 2 === 0;
+		},
+		odd: function(elem, i){
+			return i % 2 === 1;
+		},
+		lt: function(elem, i, match){
+			return i < match[3] - 0;
+		},
+		gt: function(elem, i, match){
+			return i > match[3] - 0;
+		},
+		nth: function(elem, i, match){
+			return match[3] - 0 === i;
+		},
+		eq: function(elem, i, match){
+			return match[3] - 0 === i;
+		}
+	},
+	filter: {
+		PSEUDO: function(elem, match, i, array){
+			var name = match[1], filter = Expr.filters[ name ];
+
+			if ( filter ) {
+				return filter( elem, i, match, array );
+			} else if ( name === "contains" ) {
+				return (elem.textContent || elem.innerText || getText([ elem ]) || "").indexOf(match[3]) >= 0;
+			} else if ( name === "not" ) {
+				var not = match[3];
+
+				for ( var i = 0, l = not.length; i < l; i++ ) {
+					if ( not[i] === elem ) {
+						return false;
+					}
+				}
+
+				return true;
+			} else {
+				Sizzle.error( "Syntax error, unrecognized expression: " + name );
+			}
+		},
+		CHILD: function(elem, match){
+			var type = match[1], node = elem;
+			switch (type) {
+				case 'only':
+				case 'first':
+					while ( (node = node.previousSibling) )	 {
+						if ( node.nodeType === 1 ) { 
+							return false; 
 						}
 					}
-
-					elem = 0;
-
-				// If using innerHTML throws an exception, use the fallback method
-				} catch ( e ) {}
-			}
-
-			if ( elem ) {
+					if ( type === "first" ) { 
+						return true; 
+					}
+					node = elem;
+				case 'last':
+					while ( (node = node.nextSibling) )	 {
+						if ( node.nodeType === 1 ) { 
+							return false; 
+						}
+					}
+					return true;
+				case 'nth':
+					var first = match[2], last = match[3];
+
+					if ( first === 1 && last === 0 ) {
+						return true;
+					}
+					
+					var doneName = match[0],
+						parent = elem.parentNode;
+	
+					if ( parent && (parent.sizcache !== doneName || !elem.nodeIndex) ) {
+						var count = 0;
+						for ( node = parent.firstChild; node; node = node.nextSibling ) {
+							if ( node.nodeType === 1 ) {
+								node.nodeIndex = ++count;
+							}
+						} 
+						parent.sizcache = doneName;
+					}
+					
+					var diff = elem.nodeIndex - last;
+					if ( first === 0 ) {
+						return diff === 0;
+					} else {
+						return ( diff % first === 0 && diff / first >= 0 );
+					}
+			}
+		},
+		ID: function(elem, match){
+			return elem.nodeType === 1 && elem.getAttribute("id") === match;
+		},
+		TAG: function(elem, match){
+			return (match === "*" && elem.nodeType === 1) || elem.nodeName.toLowerCase() === match;
+		},
+		CLASS: function(elem, match){
+			return (" " + (elem.className || elem.getAttribute("class")) + " ")
+				.indexOf( match ) > -1;
+		},
+		ATTR: function(elem, match){
+			var name = match[1],
+				result = Expr.attrHandle[ name ] ?
+					Expr.attrHandle[ name ]( elem ) :
+					elem[ name ] != null ?
+						elem[ name ] :
+						elem.getAttribute( name ),
+				value = result + "",
+				type = match[2],
+				check = match[4];
+
+			return result == null ?
+				type === "!=" :
+				type === "=" ?
+				value === check :
+				type === "*=" ?
+				value.indexOf(check) >= 0 :
+				type === "~=" ?
+				(" " + value + " ").indexOf(check) >= 0 :
+				!check ?
+				value && result !== false :
+				type === "!=" ?
+				value !== check :
+				type === "^=" ?
+				value.indexOf(check) === 0 :
+				type === "$=" ?
+				value.substr(value.length - check.length) === check :
+				type === "|=" ?
+				value === check || value.substr(0, check.length + 1) === check + "-" :
+				false;
+		},
+		POS: function(elem, match, i, array){
+			var name = match[2], filter = Expr.setFilters[ name ];
+
+			if ( filter ) {
+				return filter( elem, i, match, array );
+			}
+		}
+	}
+};
+
+var origPOS = Expr.match.POS;
+
+for ( var type in Expr.match ) {
+	Expr.match[ type ] = new RegExp( Expr.match[ type ].source + /(?![^\[]*\])(?![^\(]*\))/.source );
+	Expr.leftMatch[ type ] = new RegExp( /(^(?:.|\r|\n)*?)/.source + Expr.match[ type ].source.replace(/\\(\d+)/g, function(all, num){
+		return "\\" + (num - 0 + 1);
+	}));
+}
+
+var makeArray = function(array, results) {
+	array = Array.prototype.slice.call( array, 0 );
+
+	if ( results ) {
+		results.push.apply( results, array );
+		return results;
+	}
+	
+	return array;
+};
+
+// Perform a simple check to determine if the browser is capable of
+// converting a NodeList to an array using builtin methods.
+// Also verifies that the returned array holds DOM nodes
+// (which is not the case in the Blackberry browser)
+try {
+	Array.prototype.slice.call( document.documentElement.childNodes, 0 )[0].nodeType;
+
+// Provide a fallback method if it does not work
+} catch(e){
+	makeArray = function(array, results) {
+		var ret = results || [];
+
+		if ( toString.call(array) === "[object Array]" ) {
+			Array.prototype.push.apply( ret, array );
+		} else {
+			if ( typeof array.length === "number" ) {
+				for ( var i = 0, l = array.length; i < l; i++ ) {
+					ret.push( array[i] );
+				}
+			} else {
+				for ( var i = 0; array[i]; i++ ) {
+					ret.push( array[i] );
+				}
+			}
+		}
+
+		return ret;
+	};
+}
+
+var sortOrder;
+
+if ( document.documentElement.compareDocumentPosition ) {
+	sortOrder = function( a, b ) {
+		if ( !a.compareDocumentPosition || !b.compareDocumentPosition ) {
+			if ( a == b ) {
+				hasDuplicate = true;
+			}
+			return a.compareDocumentPosition ? -1 : 1;
+		}
+
+		var ret = a.compareDocumentPosition(b) & 4 ? -1 : a === b ? 0 : 1;
+		if ( ret === 0 ) {
+			hasDuplicate = true;
+		}
+		return ret;
+	};
+} else if ( "sourceIndex" in document.documentElement ) {
+	sortOrder = function( a, b ) {
+		if ( !a.sourceIndex || !b.sourceIndex ) {
+			if ( a == b ) {
+				hasDuplicate = true;
+			}
+			return a.sourceIndex ? -1 : 1;
+		}
+
+		var ret = a.sourceIndex - b.sourceIndex;
+		if ( ret === 0 ) {
+			hasDuplicate = true;
+		}
+		return ret;
+	};
+} else if ( document.createRange ) {
+	sortOrder = function( a, b ) {
+		if ( !a.ownerDocument || !b.ownerDocument ) {
+			if ( a == b ) {
+				hasDuplicate = true;
+			}
+			return a.ownerDocument ? -1 : 1;
+		}
+
+		var aRange = a.ownerDocument.createRange(), bRange = b.ownerDocument.createRange();
+		aRange.setStart(a, 0);
+		aRange.setEnd(a, 0);
+		bRange.setStart(b, 0);
+		bRange.setEnd(b, 0);
+		var ret = aRange.compareBoundaryPoints(Range.START_TO_END, bRange);
+		if ( ret === 0 ) {
+			hasDuplicate = true;
+		}
+		return ret;
+	};
+}
+
+// Utility function for retreiving the text value of an array of DOM nodes
+function getText( elems ) {
+	var ret = "", elem;
+
+	for ( var i = 0; elems[i]; i++ ) {
+		elem = elems[i];
+
+		// Get the text from text nodes and CDATA nodes
+		if ( elem.nodeType === 3 || elem.nodeType === 4 ) {
+			ret += elem.nodeValue;
+
+		// Traverse everything else, except comment nodes
+		} else if ( elem.nodeType !== 8 ) {
+			ret += getText( elem.childNodes );
+		}
+	}
+
+	return ret;
+}
+
+// Check to see if the browser returns elements by name when
+// querying by getElementById (and provide a workaround)
+(function(){
+	// We're going to inject a fake input element with a specified name
+	var form = document.createElement("div"),
+		id = "script" + (new Date).getTime();
+	form.innerHTML = "<a name='" + id + "'/>";
+
+	// Inject it into the root element, check its status, and remove it quickly
+	var root = document.documentElement;
+	root.insertBefore( form, root.firstChild );
+
+	// The workaround has to do additional checks after a getElementById
+	// Which slows things down for other browsers (hence the branching)
+	if ( document.getElementById( id ) ) {
+		Expr.find.ID = function(match, context, isXML){
+			if ( typeof context.getElementById !== "undefined" && !isXML ) {
+				var m = context.getElementById(match[1]);
+				return m ? m.id === match[1] || typeof m.getAttributeNode !== "undefined" && m.getAttributeNode("id").nodeValue === match[1] ? [m] : undefined : [];
+			}
+		};
+
+		Expr.filter.ID = function(elem, match){
+			var node = typeof elem.getAttributeNode !== "undefined" && elem.getAttributeNode("id");
+			return elem.nodeType === 1 && node && node.nodeValue === match;
+		};
+	}
+
+	root.removeChild( form );
+	root = form = null; // release memory in IE
+})();
+
+(function(){
+	// Check to see if the browser returns only elements
+	// when doing getElementsByTagName("*")
+
+	// Create a fake element
+	var div = document.createElement("div");
+	div.appendChild( document.createComment("") );
+
+	// Make sure no comments are found
+	if ( div.getElementsByTagName("*").length > 0 ) {
+		Expr.find.TAG = function(match, context){
+			var results = context.getElementsByTagName(match[1]);
+
+			// Filter out possible comments
+			if ( match[1] === "*" ) {
+				var tmp = [];
+
+				for ( var i = 0; results[i]; i++ ) {
+					if ( results[i].nodeType === 1 ) {
+						tmp.push( results[i] );
+					}
+				}
+
+				results = tmp;
+			}
+
+			return results;
+		};
+	}
+
+	// Check to see if an attribute returns normalized href attributes
+	div.innerHTML = "<a href='#'></a>";
+	if ( div.firstChild && typeof div.firstChild.getAttribute !== "undefined" &&
+			div.firstChild.getAttribute("href") !== "#" ) {
+		Expr.attrHandle.href = function(elem){
+			return elem.getAttribute("href", 2);
+		};
+	}
+
+	div = null; // release memory in IE
+})();
+
+if ( document.querySelectorAll ) {
+	(function(){
+		var oldSizzle = Sizzle, div = document.createElement("div");
+		div.innerHTML = "<p class='TEST'></p>";
+
+		// Safari can't handle uppercase or unicode characters when
+		// in quirks mode.
+		if ( div.querySelectorAll && div.querySelectorAll(".TEST").length === 0 ) {
+			return;
+		}
+	
+		Sizzle = function(query, context, extra, seed){
+			context = context || document;
+
+			// Only use querySelectorAll on non-XML documents
+			// (ID selectors don't work in non-HTML documents)
+			if ( !seed && context.nodeType === 9 && !isXML(context) ) {
+				try {
+					return makeArray( context.querySelectorAll(query), extra );
+				} catch(e){}
+			}
+		
+			return oldSizzle(query, context, extra, seed);
+		};
+
+		for ( var prop in oldSizzle ) {
+			Sizzle[ prop ] = oldSizzle[ prop ];
+		}
+
+		div = null; // release memory in IE
+	})();
+}
+
+(function(){
+	var div = document.createElement("div");
+
+	div.innerHTML = "<div class='test e'></div><div class='test'></div>";
+
+	// Opera can't find a second classname (in 9.6)
+	// Also, make sure that getElementsByClassName actually exists
+	if ( !div.getElementsByClassName || div.getElementsByClassName("e").length === 0 ) {
+		return;
+	}
+
+	// Safari caches class attributes, doesn't catch changes (in 3.2)
+	div.lastChild.className = "e";
+
+	if ( div.getElementsByClassName("e").length === 1 ) {
+		return;
+	}
+	
+	Expr.order.splice(1, 0, "CLASS");
+	Expr.find.CLASS = function(match, context, isXML) {
+		if ( typeof context.getElementsByClassName !== "undefined" && !isXML ) {
+			return context.getElementsByClassName(match[1]);
+		}
+	};
+
+	div = null; // release memory in IE
+})();
+
+function dirNodeCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {
+	for ( var i = 0, l = checkSet.length; i < l; i++ ) {
+		var elem = checkSet[i];
+		if ( elem ) {
+			elem = elem[dir];
+			var match = false;
+
+			while ( elem ) {
+				if ( elem.sizcache === doneName ) {
+					match = checkSet[elem.sizset];
+					break;
+				}
+
+				if ( elem.nodeType === 1 && !isXML ){
+					elem.sizcache = doneName;
+					elem.sizset = i;
+				}
+
+				if ( elem.nodeName.toLowerCase() === cur ) {
+					match = elem;
+					break;
+				}
+
+				elem = elem[dir];
+			}
+
+			checkSet[i] = match;
+		}
+	}
+}
+
+function dirCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {
+	for ( var i = 0, l = checkSet.length; i < l; i++ ) {
+		var elem = checkSet[i];
+		if ( elem ) {
+			elem = elem[dir];
+			var match = false;
+
+			while ( elem ) {
+				if ( elem.sizcache === doneName ) {
+					match = checkSet[elem.sizset];
+					break;
+				}
+
+				if ( elem.nodeType === 1 ) {
+					if ( !isXML ) {
+						elem.sizcache = doneName;
+						elem.sizset = i;
+					}
+					if ( typeof cur !== "string" ) {
+						if ( elem === cur ) {
+							match = true;
+							break;
+						}
+
+					} else if ( Sizzle.filter( cur, [elem] ).length > 0 ) {
+						match = elem;
+						break;
+					}
+				}
+
+				elem = elem[dir];
+			}
+
+			checkSet[i] = match;
+		}
+	}
+}
+
+var contains = document.compareDocumentPosition ? function(a, b){
+	return !!(a.compareDocumentPosition(b) & 16);
+} : function(a, b){
+	return a !== b && (a.contains ? a.contains(b) : true);
+};
+
+var isXML = function(elem){
+	// documentElement is verified for cases where it doesn't yet exist
+	// (such as loading iframes in IE - #4833) 
+	var documentElement = (elem ? elem.ownerDocument || elem : 0).documentElement;
+	return documentElement ? documentElement.nodeName !== "HTML" : false;
+};
+
+var posProcess = function(selector, context){
+	var tmpSet = [], later = "", match,
+		root = context.nodeType ? [context] : context;
+
+	// Position selectors must be done after the filter
+	// And so must :not(positional) so we move all PSEUDOs to the end
+	while ( (match = Expr.match.PSEUDO.exec( selector )) ) {
+		later += match[0];
+		selector = selector.replace( Expr.match.PSEUDO, "" );
+	}
+
+	selector = Expr.relative[selector] ? selector + "*" : selector;
+
+	for ( var i = 0, l = root.length; i < l; i++ ) {
+		Sizzle( selector, root[i], tmpSet );
+	}
+
+	return Sizzle.filter( later, tmpSet );
+};
+
+// EXPOSE
+jQuery.find = Sizzle;
+jQuery.expr = Sizzle.selectors;
+jQuery.expr[":"] = jQuery.expr.filters;
+jQuery.unique = Sizzle.uniqueSort;
+jQuery.text = getText;
+jQuery.isXMLDoc = isXML;
+jQuery.contains = contains;
+
+return;
+
+window.Sizzle = Sizzle;
+
+})();
+var runtil = /Until$/,
+	rparentsprev = /^(?:parents|prevUntil|prevAll)/,
+	// Note: This RegExp should be improved, or likely pulled from Sizzle
+	rmultiselector = /,/,
+	slice = Array.prototype.slice;
+
+// Implement the identical functionality for filter and not
+var winnow = function( elements, qualifier, keep ) {
+	if ( jQuery.isFunction( qualifier ) ) {
+		return jQuery.grep(elements, function( elem, i ) {
+			return !!qualifier.call( elem, i, elem ) === keep;
+		});
+
+	} else if ( qualifier.nodeType ) {
+		return jQuery.grep(elements, function( elem, i ) {
+			return (elem === qualifier) === keep;
+		});
+
+	} else if ( typeof qualifier === "string" ) {
+		var filtered = jQuery.grep(elements, function( elem ) {
+			return elem.nodeType === 1;
+		});
+
+		if ( isSimple.test( qualifier ) ) {
+			return jQuery.filter(qualifier, filtered, !keep);
+		} else {
+			qualifier = jQuery.filter( qualifier, filtered );
+		}
+	}
+
+	return jQuery.grep(elements, function( elem, i ) {
+		return (jQuery.inArray( elem, qualifier ) >= 0) === keep;
+	});
+};
+
+jQuery.fn.extend({
+	find: function( selector ) {
+		var ret = this.pushStack( "", "find", selector ), length = 0;
+
+		for ( var i = 0, l = this.length; i < l; i++ ) {
+			length = ret.length;
+			jQuery.find( selector, this[i], ret );
+
+			if ( i > 0 ) {
+				// Make sure that the results are unique
+				for ( var n = length; n < ret.length; n++ ) {
+					for ( var r = 0; r < length; r++ ) {
+						if ( ret[r] === ret[n] ) {
+							ret.splice(n--, 1);
+							break;
+						}
+					}
+				}
+			}
+		}
+
+		return ret;
+	},
+
+	has: function( target ) {
+		var targets = jQuery( target );
+		return this.filter(function() {
+			for ( var i = 0, l = targets.length; i < l; i++ ) {
+				if ( jQuery.contains( this, targets[i] ) ) {
+					return true;
+				}
+			}
+		});
+	},
+
+	not: function( selector ) {
+		return this.pushStack( winnow(this, selector, false), "not", selector);
+	},
+
+	filter: function( selector ) {
+		return this.pushStack( winnow(this, selector, true), "filter", selector );
+	},
+	
+	is: function( selector ) {
+		return !!selector && jQuery.filter( selector, this ).length > 0;
+	},
+
+	closest: function( selectors, context ) {
+		if ( jQuery.isArray( selectors ) ) {
+			var ret = [], cur = this[0], match, matches = {}, selector;
+
+			if ( cur && selectors.length ) {
+				for ( var i = 0, l = selectors.length; i < l; i++ ) {
+					selector = selectors[i];
+
+					if ( !matches[selector] ) {
+						matches[selector] = jQuery.expr.match.POS.test( selector ) ? 
+							jQuery( selector, context || this.context ) :
+							selector;
+					}
+				}
+
+				while ( cur && cur.ownerDocument && cur !== context ) {
+					for ( selector in matches ) {
+						match = matches[selector];
+
+						if ( match.jquery ? match.index(cur) > -1 : jQuery(cur).is(match) ) {
+							ret.push({ selector: selector, elem: cur });
+							delete matches[selector];
+						}
+					}
+					cur = cur.parentNode;
+				}
+			}
+
+			return ret;
+		}
+
+		var pos = jQuery.expr.match.POS.test( selectors ) ? 
+			jQuery( selectors, context || this.context ) : null;
+
+		return this.map(function( i, cur ) {
+			while ( cur && cur.ownerDocument && cur !== context ) {
+				if ( pos ? pos.index(cur) > -1 : jQuery(cur).is(selectors) ) {
+					return cur;
+				}
+				cur = cur.parentNode;
+			}
+			return null;
+		});
+	},
+	
+	// Determine the position of an element within
+	// the matched set of elements
+	index: function( elem ) {
+		if ( !elem || typeof elem === "string" ) {
+			return jQuery.inArray( this[0],
+				// If it receives a string, the selector is used
+				// If it receives nothing, the siblings are used
+				elem ? jQuery( elem ) : this.parent().children() );
+		}
+		// Locate the position of the desired element
+		return jQuery.inArray(
+			// If it receives a jQuery object, the first element is used
+			elem.jquery ? elem[0] : elem, this );
+	},
+
+	add: function( selector, context ) {
+		var set = typeof selector === "string" ?
+				jQuery( selector, context || this.context ) :
+				jQuery.makeArray( selector ),
+			all = jQuery.merge( this.get(), set );
+
+		return this.pushStack( isDisconnected( set[0] ) || isDisconnected( all[0] ) ?
+			all :
+			jQuery.unique( all ) );
+	},
+
+	andSelf: function() {
+		return this.add( this.prevObject );
+	}
+});
+
+// A painfully simple check to see if an element is disconnected
+// from a document (should be improved, where feasible).
+function isDisconnected( node ) {
+	return !node || !node.parentNode || node.parentNode.nodeType === 11;
+}
+
+jQuery.each({
+	parent: function( elem ) {
+		var parent = elem.parentNode;
+		return parent && parent.nodeType !== 11 ? parent : null;
+	},
+	parents: function( elem ) {
+		return jQuery.dir( elem, "parentNode" );
+	},
+	parentsUntil: function( elem, i, until ) {
+		return jQuery.dir( elem, "parentNode", until );
+	},
+	next: function( elem ) {
+		return jQuery.nth( elem, 2, "nextSibling" );
+	},
+	prev: function( elem ) {
+		return jQuery.nth( elem, 2, "previousSibling" );
+	},
+	nextAll: function( elem ) {
+		return jQuery.dir( elem, "nextSibling" );
+	},
+	prevAll: function( elem ) {
+		return jQuery.dir( elem, "previousSibling" );
+	},
+	nextUntil: function( elem, i, until ) {
+		return jQuery.dir( elem, "nextSibling", until );
+	},
+	prevUntil: function( elem, i, until ) {
+		return jQuery.dir( elem, "previousSibling", until );
+	},
+	siblings: function( elem ) {
+		return jQuery.sibling( elem.parentNode.firstChild, elem );
+	},
+	children: function( elem ) {
+		return jQuery.sibling( elem.firstChild );
+	},
+	contents: function( elem ) {
+		return jQuery.nodeName( elem, "iframe" ) ?
+			elem.contentDocument || elem.contentWindow.document :
+			jQuery.makeArray( elem.childNodes );
+	}
+}, function( name, fn ) {
+	jQuery.fn[ name ] = function( until, selector ) {
+		var ret = jQuery.map( this, fn, until );
+		
+		if ( !runtil.test( name ) ) {
+			selector = until;
+		}
+
+		if ( selector && typeof selector === "string" ) {
+			ret = jQuery.filter( selector, ret );
+		}
+
+		ret = this.length > 1 ? jQuery.unique( ret ) : ret;
+
+		if ( (this.length > 1 || rmultiselector.test( selector )) && rparentsprev.test( name ) ) {
+			ret = ret.reverse();
+		}
+
+		return this.pushStack( ret, name, slice.call(arguments).join(",") );
+	};
+});
+
+jQuery.extend({
+	filter: function( expr, elems, not ) {
+		if ( not ) {
+			expr = ":not(" + expr + ")";
+		}
+
+		return jQuery.find.matches(expr, elems);
+	},
+	
+	dir: function( elem, dir, until ) {
+		var matched = [], cur = elem[dir];
+		while ( cur && cur.nodeType !== 9 && (until === undefined || cur.nodeType !== 1 || !jQuery( cur ).is( until )) ) {
+			if ( cur.nodeType === 1 ) {
+				matched.push( cur );
+			}
+			cur = cur[dir];
+		}
+		return matched;
+	},
+
+	nth: function( cur, result, dir, elem ) {
+		result = result || 1;
+		var num = 0;
+
+		for ( ; cur; cur = cur[dir] ) {
+			if ( cur.nodeType === 1 && ++num === result ) {
+				break;
+			}
+		}
+
+		return cur;
+	},
+
+	sibling: function( n, elem ) {
+		var r = [];
+
+		for ( ; n; n = n.nextSibling ) {
+			if ( n.nodeType === 1 && n !== elem ) {
+				r.push( n );
+			}
+		}
+
+		return r;
+	}
+});
+var rinlinejQuery = / jQuery\d+="(?:\d+|null)"/g,
+	rleadingWhitespace = /^\s+/,
+	rxhtmlTag = /(<([\w:]+)[^>]*?)\/>/g,
+	rselfClosing = /^(?:area|br|col|embed|hr|img|input|link|meta|param)$/i,
+	rtagName = /<([\w:]+)/,
+	rtbody = /<tbody/i,
+	rhtml = /<|&#?\w+;/,
+	rnocache = /<script|<object|<embed|<option|<style/i,
+	rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i,  // checked="checked" or checked (html5)
+	fcloseTag = function( all, front, tag ) {
+		return rselfClosing.test( tag ) ?
+			all :
+			front + "></" + tag + ">";
+	},
+	wrapMap = {
+		option: [ 1, "<select multiple='multiple'>", "</select>" ],
+		legend: [ 1, "<fieldset>", "</fieldset>" ],
+		thead: [ 1, "<table>", "</table>" ],
+		tr: [ 2, "<table><tbody>", "</tbody></table>" ],
+		td: [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ],
+		col: [ 2, "<table><tbody></tbody><colgroup>", "</colgroup></table>" ],
+		area: [ 1, "<map>", "</map>" ],
+		_default: [ 0, "", "" ]
+	};
+
+wrapMap.optgroup = wrapMap.option;
+wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;
+wrapMap.th = wrapMap.td;
+
+// IE can't serialize <link> and <script> tags normally
+if ( !jQuery.support.htmlSerialize ) {
+	wrapMap._default = [ 1, "div<div>", "</div>" ];
+}
+
+jQuery.fn.extend({
+	text: function( text ) {
+		if ( jQuery.isFunction(text) ) {
+			return this.each(function(i) {
+				var self = jQuery(this);
+				self.text( text.call(this, i, self.text()) );
+			});
+		}
+
+		if ( typeof text !== "object" && text !== undefined ) {
+			return this.empty().append( (this[0] && this[0].ownerDocument || document).createTextNode( text ) );
+		}
+
+		return jQuery.text( this );
+	},
+
+	wrapAll: function( html ) {
+		if ( jQuery.isFunction( html ) ) {
+			return this.each(function(i) {
+				jQuery(this).wrapAll( html.call(this, i) );
+			});
+		}
+
+		if ( this[0] ) {
+			// The elements to wrap the target around
+			var wrap = jQuery( html, this[0].ownerDocument ).eq(0).clone(true);
+
+			if ( this[0].parentNode ) {
+				wrap.insertBefore( this[0] );
+			}
+
+			wrap.map(function() {
+				var elem = this;
+
+				while ( elem.firstChild && elem.firstChild.nodeType === 1 ) {
+					elem = elem.firstChild;
+				}
+
+				return elem;
+			}).append(this);
+		}
+
+		return this;
+	},
+
+	wrapInner: function( html ) {
+		if ( jQuery.isFunction( html ) ) {
+			return this.each(function(i) {
+				jQuery(this).wrapInner( html.call(this, i) );
+			});
+		}
+
+		return this.each(function() {
+			var self = jQuery( this ), contents = self.contents();
+
+			if ( contents.length ) {
+				contents.wrapAll( html );
+
+			} else {
+				self.append( html );
+			}
+		});
+	},
+
+	wrap: function( html ) {
+		return this.each(function() {
+			jQuery( this ).wrapAll( html );
+		});
+	},
+
+	unwrap: function() {
+		return this.parent().each(function() {
+			if ( !jQuery.nodeName( this, "body" ) ) {
+				jQuery( this ).replaceWith( this.childNodes );
+			}
+		}).end();
+	},
+
+	append: function() {
+		return this.domManip(arguments, true, function( elem ) {
+			if ( this.nodeType === 1 ) {
+				this.appendChild( elem );
+			}
+		});
+	},
+
+	prepend: function() {
+		return this.domManip(arguments, true, function( elem ) {
+			if ( this.nodeType === 1 ) {
+				this.insertBefore( elem, this.firstChild );
+			}
+		});
+	},
+
+	before: function() {
+		if ( this[0] && this[0].parentNode ) {
+			return this.domManip(arguments, false, function( elem ) {
+				this.parentNode.insertBefore( elem, this );
+			});
+		} else if ( arguments.length ) {
+			var set = jQuery(arguments[0]);
+			set.push.apply( set, this.toArray() );
+			return this.pushStack( set, "before", arguments );
+		}
+	},
+
+	after: function() {
+		if ( this[0] && this[0].parentNode ) {
+			return this.domManip(arguments, false, function( elem ) {
+				this.parentNode.insertBefore( elem, this.nextSibling );
+			});
+		} else if ( arguments.length ) {
+			var set = this.pushStack( this, "after", arguments );
+			set.push.apply( set, jQuery(arguments[0]).toArray() );
+			return set;
+		}
+	},
+	
+	// keepData is for internal use only--do not document
+	remove: function( selector, keepData ) {
+		for ( var i = 0, elem; (elem = this[i]) != null; i++ ) {
+			if ( !selector || jQuery.filter( selector, [ elem ] ).length ) {
+				if ( !keepData && elem.nodeType === 1 ) {
+					jQuery.cleanData( elem.getElementsByTagName("*") );
+					jQuery.cleanData( [ elem ] );
+				}
+
+				if ( elem.parentNode ) {
+					 elem.parentNode.removeChild( elem );
+				}
+			}
+		}
+		
+		return this;
+	},
+
+	empty: function() {
+		for ( var i = 0, elem; (elem = this[i]) != null; i++ ) {
+			// Remove element nodes and prevent memory leaks
+			if ( elem.nodeType === 1 ) {
+				jQuery.cleanData( elem.getElementsByTagName("*") );
+			}
+
+			// Remove any remaining nodes
+			while ( elem.firstChild ) {
+				elem.removeChild( elem.firstChild );
+			}
+		}
+		
+		return this;
+	},
+
+	clone: function( events ) {
+		// Do the clone
+		var ret = this.map(function() {
+			if ( !jQuery.support.noCloneEvent && !jQuery.isXMLDoc(this) ) {
+				// IE copies events bound via attachEvent when
+				// using cloneNode. Calling detachEvent on the
+				// clone will also remove the events from the orignal
+				// In order to get around this, we use innerHTML.
+				// Unfortunately, this means some modifications to
+				// attributes in IE that are actually only stored
+				// as properties will not be copied (such as the
+				// the name attribute on an input).
+				var html = this.outerHTML, ownerDocument = this.ownerDocument;
+				if ( !html ) {
+					var div = ownerDocument.createElement("div");
+					div.appendChild( this.cloneNode(true) );
+					html = div.innerHTML;
+				}
+
+				return jQuery.clean([html.replace(rinlinejQuery, "")
+					// Handle the case in IE 8 where action=/test/> self-closes a tag
+					.replace(/=([^="'>\s]+\/)>/g, '="$1">')
+					.replace(rleadingWhitespace, "")], ownerDocument)[0];
+			} else {
+				return this.cloneNode(true);
+			}
+		});
+
+		// Copy the events from the original to the clone
+		if ( events === true ) {
+			cloneCopyEvent( this, ret );
+			cloneCopyEvent( this.find("*"), ret.find("*") );
+		}
+
+		// Return the cloned set
+		return ret;
+	},
+
+	html: function( value ) {
+		if ( value === undefined ) {
+			return this[0] && this[0].nodeType === 1 ?
+				this[0].innerHTML.replace(rinlinejQuery, "") :
+				null;
+
+		// See if we can take a shortcut and just use innerHTML
+		} else if ( typeof value === "string" && !rnocache.test( value ) &&
+			(jQuery.support.leadingWhitespace || !rleadingWhitespace.test( value )) &&
+			!wrapMap[ (rtagName.exec( value ) || ["", ""])[1].toLowerCase() ] ) {
+
+			value = value.replace(rxhtmlTag, fcloseTag);
+
+			try {
+				for ( var i = 0, l = this.length; i < l; i++ ) {
+					// Remove element nodes and prevent memory leaks
+					if ( this[i].nodeType === 1 ) {
+						jQuery.cleanData( this[i].getElementsByTagName("*") );
+						this[i].innerHTML = value;
+					}
+				}
+
+			// If using innerHTML throws an exception, use the fallback method
+			} catch(e) {
 				this.empty().append( value );
 			}
-		}, null, value, arguments.length );
-	},
-
-	replaceWith: function() {
-		var ignored = [];
-
-		// Make the changes, replacing each non-ignored context element with the new content
-		return domManip( this, arguments, function( elem ) {
-			var parent = this.parentNode;
-
-			if ( jQuery.inArray( this, ignored ) < 0 ) {
-				jQuery.cleanData( getAll( this ) );
-				if ( parent ) {
-					parent.replaceChild( elem, this );
-				}
-			}
-
-		// Force callback invocation
-		}, ignored );
-	}
-} );
-
-jQuery.each( {
+
+		} else if ( jQuery.isFunction( value ) ) {
+			this.each(function(i){
+				var self = jQuery(this), old = self.html();
+				self.empty().append(function(){
+					return value.call( this, i, old );
+				});
+			});
+
+		} else {
+			this.empty().append( value );
+		}
+
+		return this;
+	},
+
+	replaceWith: function( value ) {
+		if ( this[0] && this[0].parentNode ) {
+			// Make sure that the elements are removed from the DOM before they are inserted
+			// this can help fix replacing a parent with child elements
+			if ( jQuery.isFunction( value ) ) {
+				return this.each(function(i) {
+					var self = jQuery(this), old = self.html();
+					self.replaceWith( value.call( this, i, old ) );
+				});
+			}
+
+			if ( typeof value !== "string" ) {
+				value = jQuery(value).detach();
+			}
+
+			return this.each(function() {
+				var next = this.nextSibling, parent = this.parentNode;
+
+				jQuery(this).remove();
+
+				if ( next ) {
+					jQuery(next).before( value );
+				} else {
+					jQuery(parent).append( value );
+				}
+			});
+		} else {
+			return this.pushStack( jQuery(jQuery.isFunction(value) ? value() : value), "replaceWith", value );
+		}
+	},
+
+	detach: function( selector ) {
+		return this.remove( selector, true );
+	},
+
+	domManip: function( args, table, callback ) {
+		var results, first, value = args[0], scripts = [], fragment, parent;
+
+		// We can't cloneNode fragments that contain checked, in WebKit
+		if ( !jQuery.support.checkClone && arguments.length === 3 && typeof value === "string" && rchecked.test( value ) ) {
+			return this.each(function() {
+				jQuery(this).domManip( args, table, callback, true );
+			});
+		}
+
+		if ( jQuery.isFunction(value) ) {
+			return this.each(function(i) {
+				var self = jQuery(this);
+				args[0] = value.call(this, i, table ? self.html() : undefined);
+				self.domManip( args, table, callback );
+			});
+		}
+
+		if ( this[0] ) {
+			parent = value && value.parentNode;
+
+			// If we're in a fragment, just use that instead of building a new one
+			if ( jQuery.support.parentNode && parent && parent.nodeType === 11 && parent.childNodes.length === this.length ) {
+				results = { fragment: parent };
+
+			} else {
+				results = buildFragment( args, this, scripts );
+			}
+			
+			fragment = results.fragment;
+			
+			if ( fragment.childNodes.length === 1 ) {
+				first = fragment = fragment.firstChild;
+			} else {
+				first = fragment.firstChild;
+			}
+
+			if ( first ) {
+				table = table && jQuery.nodeName( first, "tr" );
+
+				for ( var i = 0, l = this.length; i < l; i++ ) {
+					callback.call(
+						table ?
+							root(this[i], first) :
+							this[i],
+						i > 0 || results.cacheable || this.length > 1  ?
+							fragment.cloneNode(true) :
+							fragment
+					);
+				}
+			}
+
+			if ( scripts.length ) {
+				jQuery.each( scripts, evalScript );
+			}
+		}
+
+		return this;
+
+		function root( elem, cur ) {
+			return jQuery.nodeName(elem, "table") ?
+				(elem.getElementsByTagName("tbody")[0] ||
+				elem.appendChild(elem.ownerDocument.createElement("tbody"))) :
+				elem;
+		}
+	}
+});
+
+function cloneCopyEvent(orig, ret) {
+	var i = 0;
+
+	ret.each(function() {
+		if ( this.nodeName !== (orig[i] && orig[i].nodeName) ) {
+			return;
+		}
+
+		var oldData = jQuery.data( orig[i++] ), curData = jQuery.data( this, oldData ), events = oldData && oldData.events;
+
+		if ( events ) {
+			delete curData.handle;
+			curData.events = {};
+
+			for ( var type in events ) {
+				for ( var handler in events[ type ] ) {
+					jQuery.event.add( this, type, events[ type ][ handler ], events[ type ][ handler ].data );
+				}
+			}
+		}
+	});
+}
+
+function buildFragment( args, nodes, scripts ) {
+	var fragment, cacheable, cacheresults,
+		doc = (nodes && nodes[0] ? nodes[0].ownerDocument || nodes[0] : document);
+
+	// Only cache "small" (1/2 KB) strings that are associated with the main document
+	// Cloning options loses the selected state, so don't cache them
+	// IE 6 doesn't like it when you put <object> or <embed> elements in a fragment
+	// Also, WebKit does not clone 'checked' attributes on cloneNode, so don't cache
+	if ( args.length === 1 && typeof args[0] === "string" && args[0].length < 512 && doc === document &&
+		!rnocache.test( args[0] ) && (jQuery.support.checkClone || !rchecked.test( args[0] )) ) {
+
+		cacheable = true;
+		cacheresults = jQuery.fragments[ args[0] ];
+		if ( cacheresults ) {
+			if ( cacheresults !== 1 ) {
+				fragment = cacheresults;
+			}
+		}
+	}
+
+	if ( !fragment ) {
+		fragment = doc.createDocumentFragment();
+		jQuery.clean( args, doc, fragment, scripts );
+	}
+
+	if ( cacheable ) {
+		jQuery.fragments[ args[0] ] = cacheresults ? fragment : 1;
+	}
+
+	return { fragment: fragment, cacheable: cacheable };
+}
+
+jQuery.fragments = {};
+
+jQuery.each({
 	appendTo: "append",
 	prependTo: "prepend",
@@ -5555,2713 +4392,580 @@
 }, function( name, original ) {
 	jQuery.fn[ name ] = function( selector ) {
-		var elems,
-			ret = [],
-			insert = jQuery( selector ),
-			last = insert.length - 1,
-			i = 0;
-
-		for ( ; i <= last; i++ ) {
-			elems = i === last ? this : this.clone( true );
-			jQuery( insert[ i ] )[ original ]( elems );
-
-			// Support: QtWebKit
-			// .get() because push.apply(_, arraylike) throws
-			push.apply( ret, elems.get() );
-		}
-
-		return this.pushStack( ret );
+		var ret = [], insert = jQuery( selector ),
+			parent = this.length === 1 && this[0].parentNode;
+		
+		if ( parent && parent.nodeType === 11 && parent.childNodes.length === 1 && insert.length === 1 ) {
+			insert[ original ]( this[0] );
+			return this;
+			
+		} else {
+			for ( var i = 0, l = insert.length; i < l; i++ ) {
+				var elems = (i > 0 ? this.clone(true) : this).get();
+				jQuery.fn[ original ].apply( jQuery(insert[i]), elems );
+				ret = ret.concat( elems );
+			}
+		
+			return this.pushStack( ret, name, insert.selector );
+		}
 	};
-} );
-
-
-var iframe,
-	elemdisplay = {
-
-		// Support: Firefox
-		// We have to pre-define these values for FF (#10227)
-		HTML: "block",
-		BODY: "block"
+});
+
+jQuery.extend({
+	clean: function( elems, context, fragment, scripts ) {
+		context = context || document;
+
+		// !context.createElement fails in IE with an error but returns typeof 'object'
+		if ( typeof context.createElement === "undefined" ) {
+			context = context.ownerDocument || context[0] && context[0].ownerDocument || document;
+		}
+
+		var ret = [];
+
+		for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) {
+			if ( typeof elem === "number" ) {
+				elem += "";
+			}
+
+			if ( !elem ) {
+				continue;
+			}
+
+			// Convert html string into DOM nodes
+			if ( typeof elem === "string" && !rhtml.test( elem ) ) {
+				elem = context.createTextNode( elem );
+
+			} else if ( typeof elem === "string" ) {
+				// Fix "XHTML"-style tags in all browsers
+				elem = elem.replace(rxhtmlTag, fcloseTag);
+
+				// Trim whitespace, otherwise indexOf won't work as expected
+				var tag = (rtagName.exec( elem ) || ["", ""])[1].toLowerCase(),
+					wrap = wrapMap[ tag ] || wrapMap._default,
+					depth = wrap[0],
+					div = context.createElement("div");
+
+				// Go to html and back, then peel off extra wrappers
+				div.innerHTML = wrap[1] + elem + wrap[2];
+
+				// Move to the right depth
+				while ( depth-- ) {
+					div = div.lastChild;
+				}
+
+				// Remove IE's autoinserted <tbody> from table fragments
+				if ( !jQuery.support.tbody ) {
+
+					// String was a <table>, *may* have spurious <tbody>
+					var hasBody = rtbody.test(elem),
+						tbody = tag === "table" && !hasBody ?
+							div.firstChild && div.firstChild.childNodes :
+
+							// String was a bare <thead> or <tfoot>
+							wrap[1] === "<table>" && !hasBody ?
+								div.childNodes :
+								[];
+
+					for ( var j = tbody.length - 1; j >= 0 ; --j ) {
+						if ( jQuery.nodeName( tbody[ j ], "tbody" ) && !tbody[ j ].childNodes.length ) {
+							tbody[ j ].parentNode.removeChild( tbody[ j ] );
+						}
+					}
+
+				}
+
+				// IE completely kills leading whitespace when innerHTML is used
+				if ( !jQuery.support.leadingWhitespace && rleadingWhitespace.test( elem ) ) {
+					div.insertBefore( context.createTextNode( rleadingWhitespace.exec(elem)[0] ), div.firstChild );
+				}
+
+				elem = div.childNodes;
+			}
+
+			if ( elem.nodeType ) {
+				ret.push( elem );
+			} else {
+				ret = jQuery.merge( ret, elem );
+			}
+		}
+
+		if ( fragment ) {
+			for ( var i = 0; ret[i]; i++ ) {
+				if ( scripts && jQuery.nodeName( ret[i], "script" ) && (!ret[i].type || ret[i].type.toLowerCase() === "text/javascript") ) {
+					scripts.push( ret[i].parentNode ? ret[i].parentNode.removeChild( ret[i] ) : ret[i] );
+				
+				} else {
+					if ( ret[i].nodeType === 1 ) {
+						ret.splice.apply( ret, [i + 1, 0].concat(jQuery.makeArray(ret[i].getElementsByTagName("script"))) );
+					}
+					fragment.appendChild( ret[i] );
+				}
+			}
+		}
+
+		return ret;
+	},
+	
+	cleanData: function( elems ) {
+		var data, id, cache = jQuery.cache,
+			special = jQuery.event.special,
+			deleteExpando = jQuery.support.deleteExpando;
+		
+		for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) {
+			id = elem[ jQuery.expando ];
+			
+			if ( id ) {
+				data = cache[ id ];
+				
+				if ( data.events ) {
+					for ( var type in data.events ) {
+						if ( special[ type ] ) {
+							jQuery.event.remove( elem, type );
+
+						} else {
+							removeEvent( elem, type, data.handle );
+						}
+					}
+				}
+				
+				if ( deleteExpando ) {
+					delete elem[ jQuery.expando ];
+
+				} else if ( elem.removeAttribute ) {
+					elem.removeAttribute( jQuery.expando );
+				}
+				
+				delete cache[ id ];
+			}
+		}
+	}
+});
+// exclude the following css properties to add px
+var rexclude = /z-?index|font-?weight|opacity|zoom|line-?height/i,
+	ralpha = /alpha\([^)]*\)/,
+	ropacity = /opacity=([^)]*)/,
+	rfloat = /float/i,
+	rdashAlpha = /-([a-z])/ig,
+	rupper = /([A-Z])/g,
+	rnumpx = /^-?\d+(?:px)?$/i,
+	rnum = /^-?\d/,
+
+	cssShow = { position: "absolute", visibility: "hidden", display:"block" },
+	cssWidth = [ "Left", "Right" ],
+	cssHeight = [ "Top", "Bottom" ],
+
+	// cache check for defaultView.getComputedStyle
+	getComputedStyle = document.defaultView && document.defaultView.getComputedStyle,
+	// normalize float css property
+	styleFloat = jQuery.support.cssFloat ? "cssFloat" : "styleFloat",
+	fcamelCase = function( all, letter ) {
+		return letter.toUpperCase();
 	};
 
-/**
- * Retrieve the actual display of a element
- * @param {String} name nodeName of the element
- * @param {Object} doc Document object
- */
-
-// Called only from within defaultDisplay
-function actualDisplay( name, doc ) {
-	var elem = jQuery( doc.createElement( name ) ).appendTo( doc.body ),
-
-		display = jQuery.css( elem[ 0 ], "display" );
-
-	// We don't have any data stored on the element,
-	// so use "detach" method as fast way to get rid of the element
-	elem.detach();
-
-	return display;
-}
-
-/**
- * Try to determine the default display value of an element
- * @param {String} nodeName
- */
-function defaultDisplay( nodeName ) {
-	var doc = document,
-		display = elemdisplay[ nodeName ];
-
-	if ( !display ) {
-		display = actualDisplay( nodeName, doc );
-
-		// If the simple way fails, read from inside an iframe
-		if ( display === "none" || !display ) {
-
-			// Use the already-created iframe if possible
-			iframe = ( iframe || jQuery( "<iframe frameborder='0' width='0' height='0'/>" ) )
-				.appendTo( doc.documentElement );
-
-			// Always write a new HTML skeleton so Webkit and Firefox don't choke on reuse
-			doc = iframe[ 0 ].contentDocument;
-
-			// Support: IE
-			doc.write();
-			doc.close();
-
-			display = actualDisplay( nodeName, doc );
-			iframe.detach();
-		}
-
-		// Store the correct default display
-		elemdisplay[ nodeName ] = display;
-	}
-
-	return display;
-}
-var rmargin = ( /^margin/ );
-
-var rnumnonpx = new RegExp( "^(" + pnum + ")(?!px)[a-z%]+$", "i" );
-
-var getStyles = function( elem ) {
-
-		// Support: IE<=11+, Firefox<=30+ (#15098, #14150)
-		// IE throws on elements created in popups
-		// FF meanwhile throws on frame elements through "defaultView.getComputedStyle"
-		var view = elem.ownerDocument.defaultView;
-
-		if ( !view || !view.opener ) {
-			view = window;
-		}
-
-		return view.getComputedStyle( elem );
+jQuery.fn.css = function( name, value ) {
+	return access( this, name, value, true, function( elem, name, value ) {
+		if ( value === undefined ) {
+			return jQuery.curCSS( elem, name );
+		}
+		
+		if ( typeof value === "number" && !rexclude.test(name) ) {
+			value += "px";
+		}
+
+		jQuery.style( elem, name, value );
+	});
+};
+
+jQuery.extend({
+	style: function( elem, name, value ) {
+		// don't set styles on text and comment nodes
+		if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 ) {
+			return undefined;
+		}
+
+		// ignore negative width and height values #1599
+		if ( (name === "width" || name === "height") && parseFloat(value) < 0 ) {
+			value = undefined;
+		}
+
+		var style = elem.style || elem, set = value !== undefined;
+
+		// IE uses filters for opacity
+		if ( !jQuery.support.opacity && name === "opacity" ) {
+			if ( set ) {
+				// IE has trouble with opacity if it does not have layout
+				// Force it by setting the zoom level
+				style.zoom = 1;
+
+				// Set the alpha filter to set the opacity
+				var opacity = parseInt( value, 10 ) + "" === "NaN" ? "" : "alpha(opacity=" + value * 100 + ")";
+				var filter = style.filter || jQuery.curCSS( elem, "filter" ) || "";
+				style.filter = ralpha.test(filter) ? filter.replace(ralpha, opacity) : opacity;
+			}
+
+			return style.filter && style.filter.indexOf("opacity=") >= 0 ?
+				(parseFloat( ropacity.exec(style.filter)[1] ) / 100) + "":
+				"";
+		}
+
+		// Make sure we're using the right name for getting the float value
+		if ( rfloat.test( name ) ) {
+			name = styleFloat;
+		}
+
+		name = name.replace(rdashAlpha, fcamelCase);
+
+		if ( set ) {
+			style[ name ] = value;
+		}
+
+		return style[ name ];
+	},
+
+	css: function( elem, name, force, extra ) {
+		if ( name === "width" || name === "height" ) {
+			var val, props = cssShow, which = name === "width" ? cssWidth : cssHeight;
+
+			function getWH() {
+				val = name === "width" ? elem.offsetWidth : elem.offsetHeight;
+
+				if ( extra === "border" ) {
+					return;
+				}
+
+				jQuery.each( which, function() {
+					if ( !extra ) {
+						val -= parseFloat(jQuery.curCSS( elem, "padding" + this, true)) || 0;
+					}
+
+					if ( extra === "margin" ) {
+						val += parseFloat(jQuery.curCSS( elem, "margin" + this, true)) || 0;
+					} else {
+						val -= parseFloat(jQuery.curCSS( elem, "border" + this + "Width", true)) || 0;
+					}
+				});
+			}
+
+			if ( elem.offsetWidth !== 0 ) {
+				getWH();
+			} else {
+				jQuery.swap( elem, props, getWH );
+			}
+
+			return Math.max(0, Math.round(val));
+		}
+
+		return jQuery.curCSS( elem, name, force );
+	},
+
+	curCSS: function( elem, name, force ) {
+		var ret, style = elem.style, filter;
+
+		// IE uses filters for opacity
+		if ( !jQuery.support.opacity && name === "opacity" && elem.currentStyle ) {
+			ret = ropacity.test(elem.currentStyle.filter || "") ?
+				(parseFloat(RegExp.$1) / 100) + "" :
+				"";
+
+			return ret === "" ?
+				"1" :
+				ret;
+		}
+
+		// Make sure we're using the right name for getting the float value
+		if ( rfloat.test( name ) ) {
+			name = styleFloat;
+		}
+
+		if ( !force && style && style[ name ] ) {
+			ret = style[ name ];
+
+		} else if ( getComputedStyle ) {
+
+			// Only "float" is needed here
+			if ( rfloat.test( name ) ) {
+				name = "float";
+			}
+
+			name = name.replace( rupper, "-$1" ).toLowerCase();
+
+			var defaultView = elem.ownerDocument.defaultView;
+
+			if ( !defaultView ) {
+				return null;
+			}
+
+			var computedStyle = defaultView.getComputedStyle( elem, null );
+
+			if ( computedStyle ) {
+				ret = computedStyle.getPropertyValue( name );
+			}
+
+			// We should always get a number back from opacity
+			if ( name === "opacity" && ret === "" ) {
+				ret = "1";
+			}
+
+		} else if ( elem.currentStyle ) {
+			var camelCase = name.replace(rdashAlpha, fcamelCase);
+
+			ret = elem.currentStyle[ name ] || elem.currentStyle[ camelCase ];
+
+			// From the awesome hack by Dean Edwards
+			// http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291
+
+			// If we're not dealing with a regular pixel number
+			// but a number that has a weird ending, we need to convert it to pixels
+			if ( !rnumpx.test( ret ) && rnum.test( ret ) ) {
+				// Remember the original values
+				var left = style.left, rsLeft = elem.runtimeStyle.left;
+
+				// Put in the new values to get a computed value out
+				elem.runtimeStyle.left = elem.currentStyle.left;
+				style.left = camelCase === "fontSize" ? "1em" : (ret || 0);
+				ret = style.pixelLeft + "px";
+
+				// Revert the changed values
+				style.left = left;
+				elem.runtimeStyle.left = rsLeft;
+			}
+		}
+
+		return ret;
+	},
+
+	// A method for quickly swapping in/out CSS properties to get correct calculations
+	swap: function( elem, options, callback ) {
+		var old = {};
+
+		// Remember the old values, and insert the new ones
+		for ( var name in options ) {
+			old[ name ] = elem.style[ name ];
+			elem.style[ name ] = options[ name ];
+		}
+
+		callback.call( elem );
+
+		// Revert the old values
+		for ( var name in options ) {
+			elem.style[ name ] = old[ name ];
+		}
+	}
+});
+
+if ( jQuery.expr && jQuery.expr.filters ) {
+	jQuery.expr.filters.hidden = function( elem ) {
+		var width = elem.offsetWidth, height = elem.offsetHeight,
+			skip = elem.nodeName.toLowerCase() === "tr";
+
+		return width === 0 && height === 0 && !skip ?
+			true :
+			width > 0 && height > 0 && !skip ?
+				false :
+				jQuery.curCSS(elem, "display") === "none";
 	};
 
-var swap = function( elem, options, callback, args ) {
-	var ret, name,
-		old = {};
-
-	// Remember the old values, and insert the new ones
-	for ( name in options ) {
-		old[ name ] = elem.style[ name ];
-		elem.style[ name ] = options[ name ];
-	}
-
-	ret = callback.apply( elem, args || [] );
-
-	// Revert the old values
-	for ( name in options ) {
-		elem.style[ name ] = old[ name ];
-	}
-
-	return ret;
-};
-
-
-var documentElement = document.documentElement;
-
-
-
-( function() {
-	var pixelPositionVal, boxSizingReliableVal, pixelMarginRightVal, reliableMarginLeftVal,
-		container = document.createElement( "div" ),
-		div = document.createElement( "div" );
-
-	// Finish early in limited (non-browser) environments
-	if ( !div.style ) {
-		return;
-	}
-
-	// Support: IE9-11+
-	// Style of cloned element affects source element cloned (#8908)
-	div.style.backgroundClip = "content-box";
-	div.cloneNode( true ).style.backgroundClip = "";
-	support.clearCloneStyle = div.style.backgroundClip === "content-box";
-
-	container.style.cssText = "border:0;width:8px;height:0;top:0;left:-9999px;" +
-		"padding:0;margin-top:1px;position:absolute";
-	container.appendChild( div );
-
-	// Executing both pixelPosition & boxSizingReliable tests require only one layout
-	// so they're executed at the same time to save the second computation.
-	function computeStyleTests() {
-		div.style.cssText =
-
-			// Support: Firefox<29, Android 2.3
-			// Vendor-prefix box-sizing
-			"-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;" +
-			"position:relative;display:block;" +
-			"margin:auto;border:1px;padding:1px;" +
-			"top:1%;width:50%";
-		div.innerHTML = "";
-		documentElement.appendChild( container );
-
-		var divStyle = window.getComputedStyle( div );
-		pixelPositionVal = divStyle.top !== "1%";
-		reliableMarginLeftVal = divStyle.marginLeft === "2px";
-		boxSizingReliableVal = divStyle.width === "4px";
-
-		// Support: Android 4.0 - 4.3 only
-		// Some styles come back with percentage values, even though they shouldn't
-		div.style.marginRight = "50%";
-		pixelMarginRightVal = divStyle.marginRight === "4px";
-
-		documentElement.removeChild( container );
-	}
-
-	jQuery.extend( support, {
-		pixelPosition: function() {
-
-			// This test is executed only once but we still do memoizing
-			// since we can use the boxSizingReliable pre-computing.
-			// No need to check if the test was already performed, though.
-			computeStyleTests();
-			return pixelPositionVal;
-		},
-		boxSizingReliable: function() {
-			if ( boxSizingReliableVal == null ) {
-				computeStyleTests();
-			}
-			return boxSizingReliableVal;
-		},
-		pixelMarginRight: function() {
-
-			// Support: Android 4.0-4.3
-			// We're checking for boxSizingReliableVal here instead of pixelMarginRightVal
-			// since that compresses better and they're computed together anyway.
-			if ( boxSizingReliableVal == null ) {
-				computeStyleTests();
-			}
-			return pixelMarginRightVal;
-		},
-		reliableMarginLeft: function() {
-
-			// Support: IE <=8 only, Android 4.0 - 4.3 only, Firefox <=3 - 37
-			if ( boxSizingReliableVal == null ) {
-				computeStyleTests();
-			}
-			return reliableMarginLeftVal;
-		},
-		reliableMarginRight: function() {
-
-			// Support: Android 2.3
-			// Check if div with explicit width and no margin-right incorrectly
-			// gets computed margin-right based on width of container. (#3333)
-			// WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right
-			// This support function is only executed once so no memoizing is needed.
-			var ret,
-				marginDiv = div.appendChild( document.createElement( "div" ) );
-
-			// Reset CSS: box-sizing; display; margin; border; padding
-			marginDiv.style.cssText = div.style.cssText =
-
-				// Support: Android 2.3
-				// Vendor-prefix box-sizing
-				"-webkit-box-sizing:content-box;box-sizing:content-box;" +
-				"display:block;margin:0;border:0;padding:0";
-			marginDiv.style.marginRight = marginDiv.style.width = "0";
-			div.style.width = "1px";
-			documentElement.appendChild( container );
-
-			ret = !parseFloat( window.getComputedStyle( marginDiv ).marginRight );
-
-			documentElement.removeChild( container );
-			div.removeChild( marginDiv );
-
-			return ret;
-		}
-	} );
-} )();
-
-
-function curCSS( elem, name, computed ) {
-	var width, minWidth, maxWidth, ret,
-		style = elem.style;
-
-	computed = computed || getStyles( elem );
-	ret = computed ? computed.getPropertyValue( name ) || computed[ name ] : undefined;
-
-	// Support: Opera 12.1x only
-	// Fall back to style even without computed
-	// computed is undefined for elems on document fragments
-	if ( ( ret === "" || ret === undefined ) && !jQuery.contains( elem.ownerDocument, elem ) ) {
-		ret = jQuery.style( elem, name );
-	}
-
-	// Support: IE9
-	// getPropertyValue is only needed for .css('filter') (#12537)
-	if ( computed ) {
-
-		// A tribute to the "awesome hack by Dean Edwards"
-		// Android Browser returns percentage for some values,
-		// but width seems to be reliably pixels.
-		// This is against the CSSOM draft spec:
-		// http://dev.w3.org/csswg/cssom/#resolved-values
-		if ( !support.pixelMarginRight() && rnumnonpx.test( ret ) && rmargin.test( name ) ) {
-
-			// Remember the original values
-			width = style.width;
-			minWidth = style.minWidth;
-			maxWidth = style.maxWidth;
-
-			// Put in the new values to get a computed value out
-			style.minWidth = style.maxWidth = style.width = ret;
-			ret = computed.width;
-
-			// Revert the changed values
-			style.width = width;
-			style.minWidth = minWidth;
-			style.maxWidth = maxWidth;
-		}
-	}
-
-	return ret !== undefined ?
-
-		// Support: IE9-11+
-		// IE returns zIndex value as an integer.
-		ret + "" :
-		ret;
-}
-
-
-function addGetHookIf( conditionFn, hookFn ) {
-
-	// Define the hook, we'll check on the first run if it's really needed.
-	return {
-		get: function() {
-			if ( conditionFn() ) {
-
-				// Hook not needed (or it's not possible to use it due
-				// to missing dependency), remove it.
-				delete this.get;
-				return;
-			}
-
-			// Hook needed; redefine it so that the support test is not executed again.
-			return ( this.get = hookFn ).apply( this, arguments );
-		}
+	jQuery.expr.filters.visible = function( elem ) {
+		return !jQuery.expr.filters.hidden( elem );
 	};
 }
-
-
-var
-
-	// Swappable if display is none or starts with table
-	// except "table", "table-cell", or "table-caption"
-	// See here for display values: https://developer.mozilla.org/en-US/docs/CSS/display
-	rdisplayswap = /^(none|table(?!-c[ea]).+)/,
-
-	cssShow = { position: "absolute", visibility: "hidden", display: "block" },
-	cssNormalTransform = {
-		letterSpacing: "0",
-		fontWeight: "400"
-	},
-
-	cssPrefixes = [ "Webkit", "O", "Moz", "ms" ],
-	emptyStyle = document.createElement( "div" ).style;
-
-// Return a css property mapped to a potentially vendor prefixed property
-function vendorPropName( name ) {
-
-	// Shortcut for names that are not vendor prefixed
-	if ( name in emptyStyle ) {
-		return name;
-	}
-
-	// Check for vendor prefixed names
-	var capName = name[ 0 ].toUpperCase() + name.slice( 1 ),
-		i = cssPrefixes.length;
-
-	while ( i-- ) {
-		name = cssPrefixes[ i ] + capName;
-		if ( name in emptyStyle ) {
-			return name;
-		}
-	}
-}
-
-function setPositiveNumber( elem, value, subtract ) {
-
-	// Any relative (+/-) values have already been
-	// normalized at this point
-	var matches = rcssNum.exec( value );
-	return matches ?
-
-		// Guard against undefined "subtract", e.g., when used as in cssHooks
-		Math.max( 0, matches[ 2 ] - ( subtract || 0 ) ) + ( matches[ 3 ] || "px" ) :
-		value;
-}
-
-function augmentWidthOrHeight( elem, name, extra, isBorderBox, styles ) {
-	var i = extra === ( isBorderBox ? "border" : "content" ) ?
-
-		// If we already have the right measurement, avoid augmentation
-		4 :
-
-		// Otherwise initialize for horizontal or vertical properties
-		name === "width" ? 1 : 0,
-
-		val = 0;
-
-	for ( ; i < 4; i += 2 ) {
-
-		// Both box models exclude margin, so add it if we want it
-		if ( extra === "margin" ) {
-			val += jQuery.css( elem, extra + cssExpand[ i ], true, styles );
-		}
-
-		if ( isBorderBox ) {
-
-			// border-box includes padding, so remove it if we want content
-			if ( extra === "content" ) {
-				val -= jQuery.css( elem, "padding" + cssExpand[ i ], true, styles );
-			}
-
-			// At this point, extra isn't border nor margin, so remove border
-			if ( extra !== "margin" ) {
-				val -= jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles );
-			}
-		} else {
-
-			// At this point, extra isn't content, so add padding
-			val += jQuery.css( elem, "padding" + cssExpand[ i ], true, styles );
-
-			// At this point, extra isn't content nor padding, so add border
-			if ( extra !== "padding" ) {
-				val += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles );
-			}
-		}
-	}
-
-	return val;
-}
-
-function getWidthOrHeight( elem, name, extra ) {
-
-	// Start with offset property, which is equivalent to the border-box value
-	var valueIsBorderBox = true,
-		val = name === "width" ? elem.offsetWidth : elem.offsetHeight,
-		styles = getStyles( elem ),
-		isBorderBox = jQuery.css( elem, "boxSizing", false, styles ) === "border-box";
-
-	// Some non-html elements return undefined for offsetWidth, so check for null/undefined
-	// svg - https://bugzilla.mozilla.org/show_bug.cgi?id=649285
-	// MathML - https://bugzilla.mozilla.org/show_bug.cgi?id=491668
-	if ( val <= 0 || val == null ) {
-
-		// Fall back to computed then uncomputed css if necessary
-		val = curCSS( elem, name, styles );
-		if ( val < 0 || val == null ) {
-			val = elem.style[ name ];
-		}
-
-		// Computed unit is not pixels. Stop here and return.
-		if ( rnumnonpx.test( val ) ) {
-			return val;
-		}
-
-		// Check for style in case a browser which returns unreliable values
-		// for getComputedStyle silently falls back to the reliable elem.style
-		valueIsBorderBox = isBorderBox &&
-			( support.boxSizingReliable() || val === elem.style[ name ] );
-
-		// Normalize "", auto, and prepare for extra
-		val = parseFloat( val ) || 0;
-	}
-
-	// Use the active box-sizing model to add/subtract irrelevant styles
-	return ( val +
-		augmentWidthOrHeight(
-			elem,
-			name,
-			extra || ( isBorderBox ? "border" : "content" ),
-			valueIsBorderBox,
-			styles
-		)
-	) + "px";
-}
-
-function showHide( elements, show ) {
-	var display, elem, hidden,
-		values = [],
-		index = 0,
-		length = elements.length;
-
-	for ( ; index < length; index++ ) {
-		elem = elements[ index ];
-		if ( !elem.style ) {
-			continue;
-		}
-
-		values[ index ] = dataPriv.get( elem, "olddisplay" );
-		display = elem.style.display;
-		if ( show ) {
-
-			// Reset the inline display of this element to learn if it is
-			// being hidden by cascaded rules or not
-			if ( !values[ index ] && display === "none" ) {
-				elem.style.display = "";
-			}
-
-			// Set elements which have been overridden with display: none
-			// in a stylesheet to whatever the default browser style is
-			// for such an element
-			if ( elem.style.display === "" && isHidden( elem ) ) {
-				values[ index ] = dataPriv.access(
-					elem,
-					"olddisplay",
-					defaultDisplay( elem.nodeName )
-				);
-			}
-		} else {
-			hidden = isHidden( elem );
-
-			if ( display !== "none" || !hidden ) {
-				dataPriv.set(
-					elem,
-					"olddisplay",
-					hidden ? display : jQuery.css( elem, "display" )
-				);
-			}
-		}
-	}
-
-	// Set the display of most of the elements in a second loop
-	// to avoid the constant reflow
-	for ( index = 0; index < length; index++ ) {
-		elem = elements[ index ];
-		if ( !elem.style ) {
-			continue;
-		}
-		if ( !show || elem.style.display === "none" || elem.style.display === "" ) {
-			elem.style.display = show ? values[ index ] || "" : "none";
-		}
-	}
-
-	return elements;
-}
-
-jQuery.extend( {
-
-	// Add in style property hooks for overriding the default
-	// behavior of getting and setting a style property
-	cssHooks: {
-		opacity: {
-			get: function( elem, computed ) {
-				if ( computed ) {
-
-					// We should always get a number back from opacity
-					var ret = curCSS( elem, "opacity" );
-					return ret === "" ? "1" : ret;
-				}
-			}
-		}
-	},
-
-	// Don't automatically add "px" to these possibly-unitless properties
-	cssNumber: {
-		"animationIterationCount": true,
-		"columnCount": true,
-		"fillOpacity": true,
-		"flexGrow": true,
-		"flexShrink": true,
-		"fontWeight": true,
-		"lineHeight": true,
-		"opacity": true,
-		"order": true,
-		"orphans": true,
-		"widows": true,
-		"zIndex": true,
-		"zoom": true
-	},
-
-	// Add in properties whose names you wish to fix before
-	// setting or getting the value
-	cssProps: {
-		"float": "cssFloat"
-	},
-
-	// Get and set the style property on a DOM Node
-	style: function( elem, name, value, extra ) {
-
-		// Don't set styles on text and comment nodes
-		if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) {
-			return;
-		}
-
-		// Make sure that we're working with the right name
-		var ret, type, hooks,
-			origName = jQuery.camelCase( name ),
-			style = elem.style;
-
-		name = jQuery.cssProps[ origName ] ||
-			( jQuery.cssProps[ origName ] = vendorPropName( origName ) || origName );
-
-		// Gets hook for the prefixed version, then unprefixed version
-		hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];
-
-		// Check if we're setting a value
-		if ( value !== undefined ) {
-			type = typeof value;
-
-			// Convert "+=" or "-=" to relative numbers (#7345)
-			if ( type === "string" && ( ret = rcssNum.exec( value ) ) && ret[ 1 ] ) {
-				value = adjustCSS( elem, name, ret );
-
-				// Fixes bug #9237
-				type = "number";
-			}
-
-			// Make sure that null and NaN values aren't set (#7116)
-			if ( value == null || value !== value ) {
-				return;
-			}
-
-			// If a number was passed in, add the unit (except for certain CSS properties)
-			if ( type === "number" ) {
-				value += ret && ret[ 3 ] || ( jQuery.cssNumber[ origName ] ? "" : "px" );
-			}
-
-			// Support: IE9-11+
-			// background-* props affect original clone's values
-			if ( !support.clearCloneStyle && value === "" && name.indexOf( "background" ) === 0 ) {
-				style[ name ] = "inherit";
-			}
-
-			// If a hook was provided, use that value, otherwise just set the specified value
-			if ( !hooks || !( "set" in hooks ) ||
-				( value = hooks.set( elem, value, extra ) ) !== undefined ) {
-
-				style[ name ] = value;
-			}
-
-		} else {
-
-			// If a hook was provided get the non-computed value from there
-			if ( hooks && "get" in hooks &&
-				( ret = hooks.get( elem, false, extra ) ) !== undefined ) {
-
-				return ret;
-			}
-
-			// Otherwise just get the value from the style object
-			return style[ name ];
-		}
-	},
-
-	css: function( elem, name, extra, styles ) {
-		var val, num, hooks,
-			origName = jQuery.camelCase( name );
-
-		// Make sure that we're working with the right name
-		name = jQuery.cssProps[ origName ] ||
-			( jQuery.cssProps[ origName ] = vendorPropName( origName ) || origName );
-
-		// Try prefixed name followed by the unprefixed name
-		hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];
-
-		// If a hook was provided get the computed value from there
-		if ( hooks && "get" in hooks ) {
-			val = hooks.get( elem, true, extra );
-		}
-
-		// Otherwise, if a way to get the computed value exists, use that
-		if ( val === undefined ) {
-			val = curCSS( elem, name, styles );
-		}
-
-		// Convert "normal" to computed value
-		if ( val === "normal" && name in cssNormalTransform ) {
-			val = cssNormalTransform[ name ];
-		}
-
-		// Make numeric if forced or a qualifier was provided and val looks numeric
-		if ( extra === "" || extra ) {
-			num = parseFloat( val );
-			return extra === true || isFinite( num ) ? num || 0 : val;
-		}
-		return val;
-	}
-} );
-
-jQuery.each( [ "height", "width" ], function( i, name ) {
-	jQuery.cssHooks[ name ] = {
-		get: function( elem, computed, extra ) {
-			if ( computed ) {
-
-				// Certain elements can have dimension info if we invisibly show them
-				// but it must have a current display style that would benefit
-				return rdisplayswap.test( jQuery.css( elem, "display" ) ) &&
-					elem.offsetWidth === 0 ?
-						swap( elem, cssShow, function() {
-							return getWidthOrHeight( elem, name, extra );
-						} ) :
-						getWidthOrHeight( elem, name, extra );
-			}
-		},
-
-		set: function( elem, value, extra ) {
-			var matches,
-				styles = extra && getStyles( elem ),
-				subtract = extra && augmentWidthOrHeight(
-					elem,
-					name,
-					extra,
-					jQuery.css( elem, "boxSizing", false, styles ) === "border-box",
-					styles
-				);
-
-			// Convert to pixels if value adjustment is needed
-			if ( subtract && ( matches = rcssNum.exec( value ) ) &&
-				( matches[ 3 ] || "px" ) !== "px" ) {
-
-				elem.style[ name ] = value;
-				value = jQuery.css( elem, name );
-			}
-
-			return setPositiveNumber( elem, value, subtract );
-		}
+var jsc = now(),
+	rscript = /<script(.|\s)*?\/script>/gi,
+	rselectTextarea = /select|textarea/i,
+	rinput = /color|date|datetime|email|hidden|month|number|password|range|search|tel|text|time|url|week/i,
+	jsre = /=\?(&|$)/,
+	rquery = /\?/,
+	rts = /(\?|&)_=.*?(&|$)/,
+	rurl = /^(\w+:)?\/\/([^\/?#]+)/,
+	r20 = /%20/g,
+
+	// Keep a copy of the old load method
+	_load = jQuery.fn.load;
+
+jQuery.fn.extend({
+	load: function( url, params, callback ) {
+		if ( typeof url !== "string" ) {
+			return _load.call( this, url );
+
+		// Don't do a request if no elements are being requested
+		} else if ( !this.length ) {
+			return this;
+		}
+
+		var off = url.indexOf(" ");
+		if ( off >= 0 ) {
+			var selector = url.slice(off, url.length);
+			url = url.slice(0, off);
+		}
+
+		// Default to a GET request
+		var type = "GET";
+
+		// If the second parameter was provided
+		if ( params ) {
+			// If it's a function
+			if ( jQuery.isFunction( params ) ) {
+				// We assume that it's the callback
+				callback = params;
+				params = null;
+
+			// Otherwise, build a param string
+			} else if ( typeof params === "object" ) {
+				params = jQuery.param( params, jQuery.ajaxSettings.traditional );
+				type = "POST";
+			}
+		}
+
+		var self = this;
+
+		// Request the remote document
+		jQuery.ajax({
+			url: url,
+			type: type,
+			dataType: "html",
+			data: params,
+			complete: function( res, status ) {
+				// If successful, inject the HTML into all the matched elements
+				if ( status === "success" || status === "notmodified" ) {
+					// See if a selector was specified
+					self.html( selector ?
+						// Create a dummy div to hold the results
+						jQuery("<div />")
+							// inject the contents of the document in, removing the scripts
+							// to avoid any 'Permission Denied' errors in IE
+							.append(res.responseText.replace(rscript, ""))
+
+							// Locate the specified elements
+							.find(selector) :
+
+						// If not, just inject the full result
+						res.responseText );
+				}
+
+				if ( callback ) {
+					self.each( callback, [res.responseText, status, res] );
+				}
+			}
+		});
+
+		return this;
+	},
+
+	serialize: function() {
+		return jQuery.param(this.serializeArray());
+	},
+	serializeArray: function() {
+		return this.map(function() {
+			return this.elements ? jQuery.makeArray(this.elements) : this;
+		})
+		.filter(function() {
+			return this.name && !this.disabled &&
+				(this.checked || rselectTextarea.test(this.nodeName) ||
+					rinput.test(this.type));
+		})
+		.map(function( i, elem ) {
+			var val = jQuery(this).val();
+
+			return val == null ?
+				null :
+				jQuery.isArray(val) ?
+					jQuery.map( val, function( val, i ) {
+						return { name: elem.name, value: val };
+					}) :
+					{ name: elem.name, value: val };
+		}).get();
+	}
+});
+
+// Attach a bunch of functions for handling common AJAX events
+jQuery.each( "ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "), function( i, o ) {
+	jQuery.fn[o] = function( f ) {
+		return this.bind(o, f);
 	};
-} );
-
-jQuery.cssHooks.marginLeft = addGetHookIf( support.reliableMarginLeft,
-	function( elem, computed ) {
-		if ( computed ) {
-			return ( parseFloat( curCSS( elem, "marginLeft" ) ) ||
-				elem.getBoundingClientRect().left -
-					swap( elem, { marginLeft: 0 }, function() {
-						return elem.getBoundingClientRect().left;
-					} )
-				) + "px";
-		}
-	}
-);
-
-// Support: Android 2.3
-jQuery.cssHooks.marginRight = addGetHookIf( support.reliableMarginRight,
-	function( elem, computed ) {
-		if ( computed ) {
-			return swap( elem, { "display": "inline-block" },
-				curCSS, [ elem, "marginRight" ] );
-		}
-	}
-);
-
-// These hooks are used by animate to expand properties
-jQuery.each( {
-	margin: "",
-	padding: "",
-	border: "Width"
-}, function( prefix, suffix ) {
-	jQuery.cssHooks[ prefix + suffix ] = {
-		expand: function( value ) {
-			var i = 0,
-				expanded = {},
-
-				// Assumes a single number if not a string
-				parts = typeof value === "string" ? value.split( " " ) : [ value ];
-
-			for ( ; i < 4; i++ ) {
-				expanded[ prefix + cssExpand[ i ] + suffix ] =
-					parts[ i ] || parts[ i - 2 ] || parts[ 0 ];
-			}
-
-			return expanded;
-		}
-	};
-
-	if ( !rmargin.test( prefix ) ) {
-		jQuery.cssHooks[ prefix + suffix ].set = setPositiveNumber;
-	}
-} );
-
-jQuery.fn.extend( {
-	css: function( name, value ) {
-		return access( this, function( elem, name, value ) {
-			var styles, len,
-				map = {},
-				i = 0;
-
-			if ( jQuery.isArray( name ) ) {
-				styles = getStyles( elem );
-				len = name.length;
-
-				for ( ; i < len; i++ ) {
-					map[ name[ i ] ] = jQuery.css( elem, name[ i ], false, styles );
-				}
-
-				return map;
-			}
-
-			return value !== undefined ?
-				jQuery.style( elem, name, value ) :
-				jQuery.css( elem, name );
-		}, name, value, arguments.length > 1 );
-	},
-	show: function() {
-		return showHide( this, true );
-	},
-	hide: function() {
-		return showHide( this );
-	},
-	toggle: function( state ) {
-		if ( typeof state === "boolean" ) {
-			return state ? this.show() : this.hide();
-		}
-
-		return this.each( function() {
-			if ( isHidden( this ) ) {
-				jQuery( this ).show();
-			} else {
-				jQuery( this ).hide();
-			}
-		} );
-	}
-} );
-
-
-function Tween( elem, options, prop, end, easing ) {
-	return new Tween.prototype.init( elem, options, prop, end, easing );
-}
-jQuery.Tween = Tween;
-
-Tween.prototype = {
-	constructor: Tween,
-	init: function( elem, options, prop, end, easing, unit ) {
-		this.elem = elem;
-		this.prop = prop;
-		this.easing = easing || jQuery.easing._default;
-		this.options = options;
-		this.start = this.now = this.cur();
-		this.end = end;
-		this.unit = unit || ( jQuery.cssNumber[ prop ] ? "" : "px" );
-	},
-	cur: function() {
-		var hooks = Tween.propHooks[ this.prop ];
-
-		return hooks && hooks.get ?
-			hooks.get( this ) :
-			Tween.propHooks._default.get( this );
-	},
-	run: function( percent ) {
-		var eased,
-			hooks = Tween.propHooks[ this.prop ];
-
-		if ( this.options.duration ) {
-			this.pos = eased = jQuery.easing[ this.easing ](
-				percent, this.options.duration * percent, 0, 1, this.options.duration
-			);
-		} else {
-			this.pos = eased = percent;
-		}
-		this.now = ( this.end - this.start ) * eased + this.start;
-
-		if ( this.options.step ) {
-			this.options.step.call( this.elem, this.now, this );
-		}
-
-		if ( hooks && hooks.set ) {
-			hooks.set( this );
-		} else {
-			Tween.propHooks._default.set( this );
-		}
-		return this;
-	}
-};
-
-Tween.prototype.init.prototype = Tween.prototype;
-
-Tween.propHooks = {
-	_default: {
-		get: function( tween ) {
-			var result;
-
-			// Use a property on the element directly when it is not a DOM element,
-			// or when there is no matching style property that exists.
-			if ( tween.elem.nodeType !== 1 ||
-				tween.elem[ tween.prop ] != null && tween.elem.style[ tween.prop ] == null ) {
-				return tween.elem[ tween.prop ];
-			}
-
-			// Passing an empty string as a 3rd parameter to .css will automatically
-			// attempt a parseFloat and fallback to a string if the parse fails.
-			// Simple values such as "10px" are parsed to Float;
-			// complex values such as "rotate(1rad)" are returned as-is.
-			result = jQuery.css( tween.elem, tween.prop, "" );
-
-			// Empty strings, null, undefined and "auto" are converted to 0.
-			return !result || result === "auto" ? 0 : result;
-		},
-		set: function( tween ) {
-
-			// Use step hook for back compat.
-			// Use cssHook if its there.
-			// Use .style if available and use plain properties where available.
-			if ( jQuery.fx.step[ tween.prop ] ) {
-				jQuery.fx.step[ tween.prop ]( tween );
-			} else if ( tween.elem.nodeType === 1 &&
-				( tween.elem.style[ jQuery.cssProps[ tween.prop ] ] != null ||
-					jQuery.cssHooks[ tween.prop ] ) ) {
-				jQuery.style( tween.elem, tween.prop, tween.now + tween.unit );
-			} else {
-				tween.elem[ tween.prop ] = tween.now;
-			}
-		}
-	}
-};
-
-// Support: IE9
-// Panic based approach to setting things on disconnected nodes
-Tween.propHooks.scrollTop = Tween.propHooks.scrollLeft = {
-	set: function( tween ) {
-		if ( tween.elem.nodeType && tween.elem.parentNode ) {
-			tween.elem[ tween.prop ] = tween.now;
-		}
-	}
-};
-
-jQuery.easing = {
-	linear: function( p ) {
-		return p;
-	},
-	swing: function( p ) {
-		return 0.5 - Math.cos( p * Math.PI ) / 2;
-	},
-	_default: "swing"
-};
-
-jQuery.fx = Tween.prototype.init;
-
-// Back Compat <1.8 extension point
-jQuery.fx.step = {};
-
-
-
-
-var
-	fxNow, timerId,
-	rfxtypes = /^(?:toggle|show|hide)$/,
-	rrun = /queueHooks$/;
-
-// Animations created synchronously will run synchronously
-function createFxNow() {
-	window.setTimeout( function() {
-		fxNow = undefined;
-	} );
-	return ( fxNow = jQuery.now() );
-}
-
-// Generate parameters to create a standard animation
-function genFx( type, includeWidth ) {
-	var which,
-		i = 0,
-		attrs = { height: type };
-
-	// If we include width, step value is 1 to do all cssExpand values,
-	// otherwise step value is 2 to skip over Left and Right
-	includeWidth = includeWidth ? 1 : 0;
-	for ( ; i < 4 ; i += 2 - includeWidth ) {
-		which = cssExpand[ i ];
-		attrs[ "margin" + which ] = attrs[ "padding" + which ] = type;
-	}
-
-	if ( includeWidth ) {
-		attrs.opacity = attrs.width = type;
-	}
-
-	return attrs;
-}
-
-function createTween( value, prop, animation ) {
-	var tween,
-		collection = ( Animation.tweeners[ prop ] || [] ).concat( Animation.tweeners[ "*" ] ),
-		index = 0,
-		length = collection.length;
-	for ( ; index < length; index++ ) {
-		if ( ( tween = collection[ index ].call( animation, prop, value ) ) ) {
-
-			// We're done with this property
-			return tween;
-		}
-	}
-}
-
-function defaultPrefilter( elem, props, opts ) {
-	/* jshint validthis: true */
-	var prop, value, toggle, tween, hooks, oldfire, display, checkDisplay,
-		anim = this,
-		orig = {},
-		style = elem.style,
-		hidden = elem.nodeType && isHidden( elem ),
-		dataShow = dataPriv.get( elem, "fxshow" );
-
-	// Handle queue: false promises
-	if ( !opts.queue ) {
-		hooks = jQuery._queueHooks( elem, "fx" );
-		if ( hooks.unqueued == null ) {
-			hooks.unqueued = 0;
-			oldfire = hooks.empty.fire;
-			hooks.empty.fire = function() {
-				if ( !hooks.unqueued ) {
-					oldfire();
-				}
-			};
-		}
-		hooks.unqueued++;
-
-		anim.always( function() {
-
-			// Ensure the complete handler is called before this completes
-			anim.always( function() {
-				hooks.unqueued--;
-				if ( !jQuery.queue( elem, "fx" ).length ) {
-					hooks.empty.fire();
-				}
-			} );
-		} );
-	}
-
-	// Height/width overflow pass
-	if ( elem.nodeType === 1 && ( "height" in props || "width" in props ) ) {
-
-		// Make sure that nothing sneaks out
-		// Record all 3 overflow attributes because IE9-10 do not
-		// change the overflow attribute when overflowX and
-		// overflowY are set to the same value
-		opts.overflow = [ style.overflow, style.overflowX, style.overflowY ];
-
-		// Set display property to inline-block for height/width
-		// animations on inline elements that are having width/height animated
-		display = jQuery.css( elem, "display" );
-
-		// Test default display if display is currently "none"
-		checkDisplay = display === "none" ?
-			dataPriv.get( elem, "olddisplay" ) || defaultDisplay( elem.nodeName ) : display;
-
-		if ( checkDisplay === "inline" && jQuery.css( elem, "float" ) === "none" ) {
-			style.display = "inline-block";
-		}
-	}
-
-	if ( opts.overflow ) {
-		style.overflow = "hidden";
-		anim.always( function() {
-			style.overflow = opts.overflow[ 0 ];
-			style.overflowX = opts.overflow[ 1 ];
-			style.overflowY = opts.overflow[ 2 ];
-		} );
-	}
-
-	// show/hide pass
-	for ( prop in props ) {
-		value = props[ prop ];
-		if ( rfxtypes.exec( value ) ) {
-			delete props[ prop ];
-			toggle = toggle || value === "toggle";
-			if ( value === ( hidden ? "hide" : "show" ) ) {
-
-				// If there is dataShow left over from a stopped hide or show
-				// and we are going to proceed with show, we should pretend to be hidden
-				if ( value === "show" && dataShow && dataShow[ prop ] !== undefined ) {
-					hidden = true;
-				} else {
-					continue;
-				}
-			}
-			orig[ prop ] = dataShow && dataShow[ prop ] || jQuery.style( elem, prop );
-
-		// Any non-fx value stops us from restoring the original display value
-		} else {
-			display = undefined;
-		}
-	}
-
-	if ( !jQuery.isEmptyObject( orig ) ) {
-		if ( dataShow ) {
-			if ( "hidden" in dataShow ) {
-				hidden = dataShow.hidden;
-			}
-		} else {
-			dataShow = dataPriv.access( elem, "fxshow", {} );
-		}
-
-		// Store state if its toggle - enables .stop().toggle() to "reverse"
-		if ( toggle ) {
-			dataShow.hidden = !hidden;
-		}
-		if ( hidden ) {
-			jQuery( elem ).show();
-		} else {
-			anim.done( function() {
-				jQuery( elem ).hide();
-			} );
-		}
-		anim.done( function() {
-			var prop;
-
-			dataPriv.remove( elem, "fxshow" );
-			for ( prop in orig ) {
-				jQuery.style( elem, prop, orig[ prop ] );
-			}
-		} );
-		for ( prop in orig ) {
-			tween = createTween( hidden ? dataShow[ prop ] : 0, prop, anim );
-
-			if ( !( prop in dataShow ) ) {
-				dataShow[ prop ] = tween.start;
-				if ( hidden ) {
-					tween.end = tween.start;
-					tween.start = prop === "width" || prop === "height" ? 1 : 0;
-				}
-			}
-		}
-
-	// If this is a noop like .hide().hide(), restore an overwritten display value
-	} else if ( ( display === "none" ? defaultDisplay( elem.nodeName ) : display ) === "inline" ) {
-		style.display = display;
-	}
-}
-
-function propFilter( props, specialEasing ) {
-	var index, name, easing, value, hooks;
-
-	// camelCase, specialEasing and expand cssHook pass
-	for ( index in props ) {
-		name = jQuery.camelCase( index );
-		easing = specialEasing[ name ];
-		value = props[ index ];
-		if ( jQuery.isArray( value ) ) {
-			easing = value[ 1 ];
-			value = props[ index ] = value[ 0 ];
-		}
-
-		if ( index !== name ) {
-			props[ name ] = value;
-			delete props[ index ];
-		}
-
-		hooks = jQuery.cssHooks[ name ];
-		if ( hooks && "expand" in hooks ) {
-			value = hooks.expand( value );
-			delete props[ name ];
-
-			// Not quite $.extend, this won't overwrite existing keys.
-			// Reusing 'index' because we have the correct "name"
-			for ( index in value ) {
-				if ( !( index in props ) ) {
-					props[ index ] = value[ index ];
-					specialEasing[ index ] = easing;
-				}
-			}
-		} else {
-			specialEasing[ name ] = easing;
-		}
-	}
-}
-
-function Animation( elem, properties, options ) {
-	var result,
-		stopped,
-		index = 0,
-		length = Animation.prefilters.length,
-		deferred = jQuery.Deferred().always( function() {
-
-			// Don't match elem in the :animated selector
-			delete tick.elem;
-		} ),
-		tick = function() {
-			if ( stopped ) {
-				return false;
-			}
-			var currentTime = fxNow || createFxNow(),
-				remaining = Math.max( 0, animation.startTime + animation.duration - currentTime ),
-
-				// Support: Android 2.3
-				// Archaic crash bug won't allow us to use `1 - ( 0.5 || 0 )` (#12497)
-				temp = remaining / animation.duration || 0,
-				percent = 1 - temp,
-				index = 0,
-				length = animation.tweens.length;
-
-			for ( ; index < length ; index++ ) {
-				animation.tweens[ index ].run( percent );
-			}
-
-			deferred.notifyWith( elem, [ animation, percent, remaining ] );
-
-			if ( percent < 1 && length ) {
-				return remaining;
-			} else {
-				deferred.resolveWith( elem, [ animation ] );
-				return false;
-			}
-		},
-		animation = deferred.promise( {
-			elem: elem,
-			props: jQuery.extend( {}, properties ),
-			opts: jQuery.extend( true, {
-				specialEasing: {},
-				easing: jQuery.easing._default
-			}, options ),
-			originalProperties: properties,
-			originalOptions: options,
-			startTime: fxNow || createFxNow(),
-			duration: options.duration,
-			tweens: [],
-			createTween: function( prop, end ) {
-				var tween = jQuery.Tween( elem, animation.opts, prop, end,
-						animation.opts.specialEasing[ prop ] || animation.opts.easing );
-				animation.tweens.push( tween );
-				return tween;
+});
+
+jQuery.extend({
+
+	get: function( url, data, callback, type ) {
+		// shift arguments if data argument was omited
+		if ( jQuery.isFunction( data ) ) {
+			type = type || callback;
+			callback = data;
+			data = null;
+		}
+
+		return jQuery.ajax({
+			type: "GET",
+			url: url,
+			data: data,
+			success: callback,
+			dataType: type
+		});
+	},
+
+	getScript: function( url, callback ) {
+		return jQuery.get(url, null, callback, "script");
+	},
+
+	getJSON: function( url, data, callback ) {
+		return jQuery.get(url, data, callback, "json");
+	},
+
+	post: function( url, data, callback, type ) {
+		// shift arguments if data argument was omited
+		if ( jQuery.isFunction( data ) ) {
+			type = type || callback;
+			callback = data;
+			data = {};
+		}
+
+		return jQuery.ajax({
+			type: "POST",
+			url: url,
+			data: data,
+			success: callback,
+			dataType: type
+		});
+	},
+
+	ajaxSetup: function( settings ) {
+		jQuery.extend( jQuery.ajaxSettings, settings );
+	},
+
+	ajaxSettings: {
+		url: location.href,
+		global: true,
+		type: "GET",
+		contentType: "application/x-www-form-urlencoded",
+		processData: true,
+		async: true,
+		/*
+		timeout: 0,
+		data: null,
+		username: null,
+		password: null,
+		traditional: false,
+		*/
+		// Create the request object; Microsoft failed to properly
+		// implement the XMLHttpRequest in IE7 (can't request local files),
+		// so we use the ActiveXObject when it is available
+		// This function can be overriden by calling jQuery.ajaxSetup
+		xhr: window.XMLHttpRequest && (window.location.protocol !== "file:" || !window.ActiveXObject) ?
+			function() {
+				return new window.XMLHttpRequest();
+			} :
+			function() {
+				try {
+					return new window.ActiveXObject("Microsoft.XMLHTTP");
+				} catch(e) {}
 			},
-			stop: function( gotoEnd ) {
-				var index = 0,
-
-					// If we are going to the end, we want to run all the tweens
-					// otherwise we skip this part
-					length = gotoEnd ? animation.tweens.length : 0;
-				if ( stopped ) {
-					return this;
-				}
-				stopped = true;
-				for ( ; index < length ; index++ ) {
-					animation.tweens[ index ].run( 1 );
-				}
-
-				// Resolve when we played the last frame; otherwise, reject
-				if ( gotoEnd ) {
-					deferred.notifyWith( elem, [ animation, 1, 0 ] );
-					deferred.resolveWith( elem, [ animation, gotoEnd ] );
-				} else {
-					deferred.rejectWith( elem, [ animation, gotoEnd ] );
-				}
-				return this;
-			}
-		} ),
-		props = animation.props;
-
-	propFilter( props, animation.opts.specialEasing );
-
-	for ( ; index < length ; index++ ) {
-		result = Animation.prefilters[ index ].call( animation, elem, props, animation.opts );
-		if ( result ) {
-			if ( jQuery.isFunction( result.stop ) ) {
-				jQuery._queueHooks( animation.elem, animation.opts.queue ).stop =
-					jQuery.proxy( result.stop, result );
-			}
-			return result;
-		}
-	}
-
-	jQuery.map( props, createTween, animation );
-
-	if ( jQuery.isFunction( animation.opts.start ) ) {
-		animation.opts.start.call( elem, animation );
-	}
-
-	jQuery.fx.timer(
-		jQuery.extend( tick, {
-			elem: elem,
-			anim: animation,
-			queue: animation.opts.queue
-		} )
-	);
-
-	// attach callbacks from options
-	return animation.progress( animation.opts.progress )
-		.done( animation.opts.done, animation.opts.complete )
-		.fail( animation.opts.fail )
-		.always( animation.opts.always );
-}
-
-jQuery.Animation = jQuery.extend( Animation, {
-	tweeners: {
-		"*": [ function( prop, value ) {
-			var tween = this.createTween( prop, value );
-			adjustCSS( tween.elem, prop, rcssNum.exec( value ), tween );
-			return tween;
-		} ]
-	},
-
-	tweener: function( props, callback ) {
-		if ( jQuery.isFunction( props ) ) {
-			callback = props;
-			props = [ "*" ];
-		} else {
-			props = props.match( rnotwhite );
-		}
-
-		var prop,
-			index = 0,
-			length = props.length;
-
-		for ( ; index < length ; index++ ) {
-			prop = props[ index ];
-			Animation.tweeners[ prop ] = Animation.tweeners[ prop ] || [];
-			Animation.tweeners[ prop ].unshift( callback );
-		}
-	},
-
-	prefilters: [ defaultPrefilter ],
-
-	prefilter: function( callback, prepend ) {
-		if ( prepend ) {
-			Animation.prefilters.unshift( callback );
-		} else {
-			Animation.prefilters.push( callback );
-		}
-	}
-} );
-
-jQuery.speed = function( speed, easing, fn ) {
-	var opt = speed && typeof speed === "object" ? jQuery.extend( {}, speed ) : {
-		complete: fn || !fn && easing ||
-			jQuery.isFunction( speed ) && speed,
-		duration: speed,
-		easing: fn && easing || easing && !jQuery.isFunction( easing ) && easing
-	};
-
-	opt.duration = jQuery.fx.off ? 0 : typeof opt.duration === "number" ?
-		opt.duration : opt.duration in jQuery.fx.speeds ?
-			jQuery.fx.speeds[ opt.duration ] : jQuery.fx.speeds._default;
-
-	// Normalize opt.queue - true/undefined/null -> "fx"
-	if ( opt.queue == null || opt.queue === true ) {
-		opt.queue = "fx";
-	}
-
-	// Queueing
-	opt.old = opt.complete;
-
-	opt.complete = function() {
-		if ( jQuery.isFunction( opt.old ) ) {
-			opt.old.call( this );
-		}
-
-		if ( opt.queue ) {
-			jQuery.dequeue( this, opt.queue );
-		}
-	};
-
-	return opt;
-};
-
-jQuery.fn.extend( {
-	fadeTo: function( speed, to, easing, callback ) {
-
-		// Show any hidden elements after setting opacity to 0
-		return this.filter( isHidden ).css( "opacity", 0 ).show()
-
-			// Animate to the value specified
-			.end().animate( { opacity: to }, speed, easing, callback );
-	},
-	animate: function( prop, speed, easing, callback ) {
-		var empty = jQuery.isEmptyObject( prop ),
-			optall = jQuery.speed( speed, easing, callback ),
-			doAnimation = function() {
-
-				// Operate on a copy of prop so per-property easing won't be lost
-				var anim = Animation( this, jQuery.extend( {}, prop ), optall );
-
-				// Empty animations, or finishing resolves immediately
-				if ( empty || dataPriv.get( this, "finish" ) ) {
-					anim.stop( true );
-				}
-			};
-			doAnimation.finish = doAnimation;
-
-		return empty || optall.queue === false ?
-			this.each( doAnimation ) :
-			this.queue( optall.queue, doAnimation );
-	},
-	stop: function( type, clearQueue, gotoEnd ) {
-		var stopQueue = function( hooks ) {
-			var stop = hooks.stop;
-			delete hooks.stop;
-			stop( gotoEnd );
-		};
-
-		if ( typeof type !== "string" ) {
-			gotoEnd = clearQueue;
-			clearQueue = type;
-			type = undefined;
-		}
-		if ( clearQueue && type !== false ) {
-			this.queue( type || "fx", [] );
-		}
-
-		return this.each( function() {
-			var dequeue = true,
-				index = type != null && type + "queueHooks",
-				timers = jQuery.timers,
-				data = dataPriv.get( this );
-
-			if ( index ) {
-				if ( data[ index ] && data[ index ].stop ) {
-					stopQueue( data[ index ] );
-				}
-			} else {
-				for ( index in data ) {
-					if ( data[ index ] && data[ index ].stop && rrun.test( index ) ) {
-						stopQueue( data[ index ] );
-					}
-				}
-			}
-
-			for ( index = timers.length; index--; ) {
-				if ( timers[ index ].elem === this &&
-					( type == null || timers[ index ].queue === type ) ) {
-
-					timers[ index ].anim.stop( gotoEnd );
-					dequeue = false;
-					timers.splice( index, 1 );
-				}
-			}
-
-			// Start the next in the queue if the last step wasn't forced.
-			// Timers currently will call their complete callbacks, which
-			// will dequeue but only if they were gotoEnd.
-			if ( dequeue || !gotoEnd ) {
-				jQuery.dequeue( this, type );
-			}
-		} );
-	},
-	finish: function( type ) {
-		if ( type !== false ) {
-			type = type || "fx";
-		}
-		return this.each( function() {
-			var index,
-				data = dataPriv.get( this ),
-				queue = data[ type + "queue" ],
-				hooks = data[ type + "queueHooks" ],
-				timers = jQuery.timers,
-				length = queue ? queue.length : 0;
-
-			// Enable finishing flag on private data
-			data.finish = true;
-
-			// Empty the queue first
-			jQuery.queue( this, type, [] );
-
-			if ( hooks && hooks.stop ) {
-				hooks.stop.call( this, true );
-			}
-
-			// Look for any active animations, and finish them
-			for ( index = timers.length; index--; ) {
-				if ( timers[ index ].elem === this && timers[ index ].queue === type ) {
-					timers[ index ].anim.stop( true );
-					timers.splice( index, 1 );
-				}
-			}
-
-			// Look for any animations in the old queue and finish them
-			for ( index = 0; index < length; index++ ) {
-				if ( queue[ index ] && queue[ index ].finish ) {
-					queue[ index ].finish.call( this );
-				}
-			}
-
-			// Turn off finishing flag
-			delete data.finish;
-		} );
-	}
-} );
-
-jQuery.each( [ "toggle", "show", "hide" ], function( i, name ) {
-	var cssFn = jQuery.fn[ name ];
-	jQuery.fn[ name ] = function( speed, easing, callback ) {
-		return speed == null || typeof speed === "boolean" ?
-			cssFn.apply( this, arguments ) :
-			this.animate( genFx( name, true ), speed, easing, callback );
-	};
-} );
-
-// Generate shortcuts for custom animations
-jQuery.each( {
-	slideDown: genFx( "show" ),
-	slideUp: genFx( "hide" ),
-	slideToggle: genFx( "toggle" ),
-	fadeIn: { opacity: "show" },
-	fadeOut: { opacity: "hide" },
-	fadeToggle: { opacity: "toggle" }
-}, function( name, props ) {
-	jQuery.fn[ name ] = function( speed, easing, callback ) {
-		return this.animate( props, speed, easing, callback );
-	};
-} );
-
-jQuery.timers = [];
-jQuery.fx.tick = function() {
-	var timer,
-		i = 0,
-		timers = jQuery.timers;
-
-	fxNow = jQuery.now();
-
-	for ( ; i < timers.length; i++ ) {
-		timer = timers[ i ];
-
-		// Checks the timer has not already been removed
-		if ( !timer() && timers[ i ] === timer ) {
-			timers.splice( i--, 1 );
-		}
-	}
-
-	if ( !timers.length ) {
-		jQuery.fx.stop();
-	}
-	fxNow = undefined;
-};
-
-jQuery.fx.timer = function( timer ) {
-	jQuery.timers.push( timer );
-	if ( timer() ) {
-		jQuery.fx.start();
-	} else {
-		jQuery.timers.pop();
-	}
-};
-
-jQuery.fx.interval = 13;
-jQuery.fx.start = function() {
-	if ( !timerId ) {
-		timerId = window.setInterval( jQuery.fx.tick, jQuery.fx.interval );
-	}
-};
-
-jQuery.fx.stop = function() {
-	window.clearInterval( timerId );
-
-	timerId = null;
-};
-
-jQuery.fx.speeds = {
-	slow: 600,
-	fast: 200,
-
-	// Default speed
-	_default: 400
-};
-
-
-// Based off of the plugin by Clint Helfers, with permission.
-// http://web.archive.org/web/20100324014747/http://blindsignals.com/index.php/2009/07/jquery-delay/
-jQuery.fn.delay = function( time, type ) {
-	time = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time;
-	type = type || "fx";
-
-	return this.queue( type, function( next, hooks ) {
-		var timeout = window.setTimeout( next, time );
-		hooks.stop = function() {
-			window.clearTimeout( timeout );
-		};
-	} );
-};
-
-
-( function() {
-	var input = document.createElement( "input" ),
-		select = document.createElement( "select" ),
-		opt = select.appendChild( document.createElement( "option" ) );
-
-	input.type = "checkbox";
-
-	// Support: iOS<=5.1, Android<=4.2+
-	// Default value for a checkbox should be "on"
-	support.checkOn = input.value !== "";
-
-	// Support: IE<=11+
-	// Must access selectedIndex to make default options select
-	support.optSelected = opt.selected;
-
-	// Support: Android<=2.3
-	// Options inside disabled selects are incorrectly marked as disabled
-	select.disabled = true;
-	support.optDisabled = !opt.disabled;
-
-	// Support: IE<=11+
-	// An input loses its value after becoming a radio
-	input = document.createElement( "input" );
-	input.value = "t";
-	input.type = "radio";
-	support.radioValue = input.value === "t";
-} )();
-
-
-var boolHook,
-	attrHandle = jQuery.expr.attrHandle;
-
-jQuery.fn.extend( {
-	attr: function( name, value ) {
-		return access( this, jQuery.attr, name, value, arguments.length > 1 );
-	},
-
-	removeAttr: function( name ) {
-		return this.each( function() {
-			jQuery.removeAttr( this, name );
-		} );
-	}
-} );
-
-jQuery.extend( {
-	attr: function( elem, name, value ) {
-		var ret, hooks,
-			nType = elem.nodeType;
-
-		// Don't get/set attributes on text, comment and attribute nodes
-		if ( nType === 3 || nType === 8 || nType === 2 ) {
-			return;
-		}
-
-		// Fallback to prop when attributes are not supported
-		if ( typeof elem.getAttribute === "undefined" ) {
-			return jQuery.prop( elem, name, value );
-		}
-
-		// All attributes are lowercase
-		// Grab necessary hook if one is defined
-		if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) {
-			name = name.toLowerCase();
-			hooks = jQuery.attrHooks[ name ] ||
-				( jQuery.expr.match.bool.test( name ) ? boolHook : undefined );
-		}
-
-		if ( value !== undefined ) {
-			if ( value === null ) {
-				jQuery.removeAttr( elem, name );
-				return;
-			}
-
-			if ( hooks && "set" in hooks &&
-				( ret = hooks.set( elem, value, name ) ) !== undefined ) {
-				return ret;
-			}
-
-			elem.setAttribute( name, value + "" );
-			return value;
-		}
-
-		if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) {
-			return ret;
-		}
-
-		ret = jQuery.find.attr( elem, name );
-
-		// Non-existent attributes return null, we normalize to undefined
-		return ret == null ? undefined : ret;
-	},
-
-	attrHooks: {
-		type: {
-			set: function( elem, value ) {
-				if ( !support.radioValue && value === "radio" &&
-					jQuery.nodeName( elem, "input" ) ) {
-					var val = elem.value;
-					elem.setAttribute( "type", value );
-					if ( val ) {
-						elem.value = val;
-					}
-					return value;
-				}
-			}
-		}
-	},
-
-	removeAttr: function( elem, value ) {
-		var name, propName,
-			i = 0,
-			attrNames = value && value.match( rnotwhite );
-
-		if ( attrNames && elem.nodeType === 1 ) {
-			while ( ( name = attrNames[ i++ ] ) ) {
-				propName = jQuery.propFix[ name ] || name;
-
-				// Boolean attributes get special treatment (#10870)
-				if ( jQuery.expr.match.bool.test( name ) ) {
-
-					// Set corresponding property to false
-					elem[ propName ] = false;
-				}
-
-				elem.removeAttribute( name );
-			}
-		}
-	}
-} );
-
-// Hooks for boolean attributes
-boolHook = {
-	set: function( elem, value, name ) {
-		if ( value === false ) {
-
-			// Remove boolean attributes when set to false
-			jQuery.removeAttr( elem, name );
-		} else {
-			elem.setAttribute( name, name );
-		}
-		return name;
-	}
-};
-jQuery.each( jQuery.expr.match.bool.source.match( /\w+/g ), function( i, name ) {
-	var getter = attrHandle[ name ] || jQuery.find.attr;
-
-	attrHandle[ name ] = function( elem, name, isXML ) {
-		var ret, handle;
-		if ( !isXML ) {
-
-			// Avoid an infinite loop by temporarily removing this function from the getter
-			handle = attrHandle[ name ];
-			attrHandle[ name ] = ret;
-			ret = getter( elem, name, isXML ) != null ?
-				name.toLowerCase() :
-				null;
-			attrHandle[ name ] = handle;
-		}
-		return ret;
-	};
-} );
-
-
-
-
-var rfocusable = /^(?:input|select|textarea|button)$/i,
-	rclickable = /^(?:a|area)$/i;
-
-jQuery.fn.extend( {
-	prop: function( name, value ) {
-		return access( this, jQuery.prop, name, value, arguments.length > 1 );
-	},
-
-	removeProp: function( name ) {
-		return this.each( function() {
-			delete this[ jQuery.propFix[ name ] || name ];
-		} );
-	}
-} );
-
-jQuery.extend( {
-	prop: function( elem, name, value ) {
-		var ret, hooks,
-			nType = elem.nodeType;
-
-		// Don't get/set properties on text, comment and attribute nodes
-		if ( nType === 3 || nType === 8 || nType === 2 ) {
-			return;
-		}
-
-		if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) {
-
-			// Fix name and attach hooks
-			name = jQuery.propFix[ name ] || name;
-			hooks = jQuery.propHooks[ name ];
-		}
-
-		if ( value !== undefined ) {
-			if ( hooks && "set" in hooks &&
-				( ret = hooks.set( elem, value, name ) ) !== undefined ) {
-				return ret;
-			}
-
-			return ( elem[ name ] = value );
-		}
-
-		if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) {
-			return ret;
-		}
-
-		return elem[ name ];
-	},
-
-	propHooks: {
-		tabIndex: {
-			get: function( elem ) {
-
-				// elem.tabIndex doesn't always return the
-				// correct value when it hasn't been explicitly set
-				// http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/
-				// Use proper attribute retrieval(#12072)
-				var tabindex = jQuery.find.attr( elem, "tabindex" );
-
-				return tabindex ?
-					parseInt( tabindex, 10 ) :
-					rfocusable.test( elem.nodeName ) ||
-						rclickable.test( elem.nodeName ) && elem.href ?
-							0 :
-							-1;
-			}
-		}
-	},
-
-	propFix: {
-		"for": "htmlFor",
-		"class": "className"
-	}
-} );
-
-// Support: IE <=11 only
-// Accessing the selectedIndex property
-// forces the browser to respect setting selected
-// on the option
-// The getter ensures a default option is selected
-// when in an optgroup
-if ( !support.optSelected ) {
-	jQuery.propHooks.selected = {
-		get: function( elem ) {
-			var parent = elem.parentNode;
-			if ( parent && parent.parentNode ) {
-				parent.parentNode.selectedIndex;
-			}
-			return null;
-		},
-		set: function( elem ) {
-			var parent = elem.parentNode;
-			if ( parent ) {
-				parent.selectedIndex;
-
-				if ( parent.parentNode ) {
-					parent.parentNode.selectedIndex;
-				}
-			}
-		}
-	};
-}
-
-jQuery.each( [
-	"tabIndex",
-	"readOnly",
-	"maxLength",
-	"cellSpacing",
-	"cellPadding",
-	"rowSpan",
-	"colSpan",
-	"useMap",
-	"frameBorder",
-	"contentEditable"
-], function() {
-	jQuery.propFix[ this.toLowerCase() ] = this;
-} );
-
-
-
-
-var rclass = /[\t\r\n\f]/g;
-
-function getClass( elem ) {
-	return elem.getAttribute && elem.getAttribute( "class" ) || "";
-}
-
-jQuery.fn.extend( {
-	addClass: function( value ) {
-		var classes, elem, cur, curValue, clazz, j, finalValue,
-			i = 0;
-
-		if ( jQuery.isFunction( value ) ) {
-			return this.each( function( j ) {
-				jQuery( this ).addClass( value.call( this, j, getClass( this ) ) );
-			} );
-		}
-
-		if ( typeof value === "string" && value ) {
-			classes = value.match( rnotwhite ) || [];
-
-			while ( ( elem = this[ i++ ] ) ) {
-				curValue = getClass( elem );
-				cur = elem.nodeType === 1 &&
-					( " " + curValue + " " ).replace( rclass, " " );
-
-				if ( cur ) {
-					j = 0;
-					while ( ( clazz = classes[ j++ ] ) ) {
-						if ( cur.indexOf( " " + clazz + " " ) < 0 ) {
-							cur += clazz + " ";
-						}
-					}
-
-					// Only assign if different to avoid unneeded rendering.
-					finalValue = jQuery.trim( cur );
-					if ( curValue !== finalValue ) {
-						elem.setAttribute( "class", finalValue );
-					}
-				}
-			}
-		}
-
-		return this;
-	},
-
-	removeClass: function( value ) {
-		var classes, elem, cur, curValue, clazz, j, finalValue,
-			i = 0;
-
-		if ( jQuery.isFunction( value ) ) {
-			return this.each( function( j ) {
-				jQuery( this ).removeClass( value.call( this, j, getClass( this ) ) );
-			} );
-		}
-
-		if ( !arguments.length ) {
-			return this.attr( "class", "" );
-		}
-
-		if ( typeof value === "string" && value ) {
-			classes = value.match( rnotwhite ) || [];
-
-			while ( ( elem = this[ i++ ] ) ) {
-				curValue = getClass( elem );
-
-				// This expression is here for better compressibility (see addClass)
-				cur = elem.nodeType === 1 &&
-					( " " + curValue + " " ).replace( rclass, " " );
-
-				if ( cur ) {
-					j = 0;
-					while ( ( clazz = classes[ j++ ] ) ) {
-
-						// Remove *all* instances
-						while ( cur.indexOf( " " + clazz + " " ) > -1 ) {
-							cur = cur.replace( " " + clazz + " ", " " );
-						}
-					}
-
-					// Only assign if different to avoid unneeded rendering.
-					finalValue = jQuery.trim( cur );
-					if ( curValue !== finalValue ) {
-						elem.setAttribute( "class", finalValue );
-					}
-				}
-			}
-		}
-
-		return this;
-	},
-
-	toggleClass: function( value, stateVal ) {
-		var type = typeof value;
-
-		if ( typeof stateVal === "boolean" && type === "string" ) {
-			return stateVal ? this.addClass( value ) : this.removeClass( value );
-		}
-
-		if ( jQuery.isFunction( value ) ) {
-			return this.each( function( i ) {
-				jQuery( this ).toggleClass(
-					value.call( this, i, getClass( this ), stateVal ),
-					stateVal
-				);
-			} );
-		}
-
-		return this.each( function() {
-			var className, i, self, classNames;
-
-			if ( type === "string" ) {
-
-				// Toggle individual class names
-				i = 0;
-				self = jQuery( this );
-				classNames = value.match( rnotwhite ) || [];
-
-				while ( ( className = classNames[ i++ ] ) ) {
-
-					// Check each className given, space separated list
-					if ( self.hasClass( className ) ) {
-						self.removeClass( className );
-					} else {
-						self.addClass( className );
-					}
-				}
-
-			// Toggle whole class name
-			} else if ( value === undefined || type === "boolean" ) {
-				className = getClass( this );
-				if ( className ) {
-
-					// Store className if set
-					dataPriv.set( this, "__className__", className );
-				}
-
-				// If the element has a class name or if we're passed `false`,
-				// then remove the whole classname (if there was one, the above saved it).
-				// Otherwise bring back whatever was previously saved (if anything),
-				// falling back to the empty string if nothing was stored.
-				if ( this.setAttribute ) {
-					this.setAttribute( "class",
-						className || value === false ?
-						"" :
-						dataPriv.get( this, "__className__" ) || ""
-					);
-				}
-			}
-		} );
-	},
-
-	hasClass: function( selector ) {
-		var className, elem,
-			i = 0;
-
-		className = " " + selector + " ";
-		while ( ( elem = this[ i++ ] ) ) {
-			if ( elem.nodeType === 1 &&
-				( " " + getClass( elem ) + " " ).replace( rclass, " " )
-					.indexOf( className ) > -1
-			) {
-				return true;
-			}
-		}
-
-		return false;
-	}
-} );
-
-
-
-
-var rreturn = /\r/g,
-	rspaces = /[\x20\t\r\n\f]+/g;
-
-jQuery.fn.extend( {
-	val: function( value ) {
-		var hooks, ret, isFunction,
-			elem = this[ 0 ];
-
-		if ( !arguments.length ) {
-			if ( elem ) {
-				hooks = jQuery.valHooks[ elem.type ] ||
-					jQuery.valHooks[ elem.nodeName.toLowerCase() ];
-
-				if ( hooks &&
-					"get" in hooks &&
-					( ret = hooks.get( elem, "value" ) ) !== undefined
-				) {
-					return ret;
-				}
-
-				ret = elem.value;
-
-				return typeof ret === "string" ?
-
-					// Handle most common string cases
-					ret.replace( rreturn, "" ) :
-
-					// Handle cases where value is null/undef or number
-					ret == null ? "" : ret;
-			}
-
-			return;
-		}
-
-		isFunction = jQuery.isFunction( value );
-
-		return this.each( function( i ) {
-			var val;
-
-			if ( this.nodeType !== 1 ) {
-				return;
-			}
-
-			if ( isFunction ) {
-				val = value.call( this, i, jQuery( this ).val() );
-			} else {
-				val = value;
-			}
-
-			// Treat null/undefined as ""; convert numbers to string
-			if ( val == null ) {
-				val = "";
-
-			} else if ( typeof val === "number" ) {
-				val += "";
-
-			} else if ( jQuery.isArray( val ) ) {
-				val = jQuery.map( val, function( value ) {
-					return value == null ? "" : value + "";
-				} );
-			}
-
-			hooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ];
-
-			// If set returns undefined, fall back to normal setting
-			if ( !hooks || !( "set" in hooks ) || hooks.set( this, val, "value" ) === undefined ) {
-				this.value = val;
-			}
-		} );
-	}
-} );
-
-jQuery.extend( {
-	valHooks: {
-		option: {
-			get: function( elem ) {
-
-				var val = jQuery.find.attr( elem, "value" );
-				return val != null ?
-					val :
-
-					// Support: IE10-11+
-					// option.text throws exceptions (#14686, #14858)
-					// Strip and collapse whitespace
-					// https://html.spec.whatwg.org/#strip-and-collapse-whitespace
-					jQuery.trim( jQuery.text( elem ) ).replace( rspaces, " " );
-			}
-		},
-		select: {
-			get: function( elem ) {
-				var value, option,
-					options = elem.options,
-					index = elem.selectedIndex,
-					one = elem.type === "select-one" || index < 0,
-					values = one ? null : [],
-					max = one ? index + 1 : options.length,
-					i = index < 0 ?
-						max :
-						one ? index : 0;
-
-				// Loop through all the selected options
-				for ( ; i < max; i++ ) {
-					option = options[ i ];
-
-					// IE8-9 doesn't update selected after form reset (#2551)
-					if ( ( option.selected || i === index ) &&
-
-							// Don't return options that are disabled or in a disabled optgroup
-							( support.optDisabled ?
-								!option.disabled : option.getAttribute( "disabled" ) === null ) &&
-							( !option.parentNode.disabled ||
-								!jQuery.nodeName( option.parentNode, "optgroup" ) ) ) {
-
-						// Get the specific value for the option
-						value = jQuery( option ).val();
-
-						// We don't need an array for one selects
-						if ( one ) {
-							return value;
-						}
-
-						// Multi-Selects return an array
-						values.push( value );
-					}
-				}
-
-				return values;
-			},
-
-			set: function( elem, value ) {
-				var optionSet, option,
-					options = elem.options,
-					values = jQuery.makeArray( value ),
-					i = options.length;
-
-				while ( i-- ) {
-					option = options[ i ];
-					if ( option.selected =
-						jQuery.inArray( jQuery.valHooks.option.get( option ), values ) > -1
-					) {
-						optionSet = true;
-					}
-				}
-
-				// Force browsers to behave consistently when non-matching value is set
-				if ( !optionSet ) {
-					elem.selectedIndex = -1;
-				}
-				return values;
-			}
-		}
-	}
-} );
-
-// Radios and checkboxes getter/setter
-jQuery.each( [ "radio", "checkbox" ], function() {
-	jQuery.valHooks[ this ] = {
-		set: function( elem, value ) {
-			if ( jQuery.isArray( value ) ) {
-				return ( elem.checked = jQuery.inArray( jQuery( elem ).val(), value ) > -1 );
-			}
-		}
-	};
-	if ( !support.checkOn ) {
-		jQuery.valHooks[ this ].get = function( elem ) {
-			return elem.getAttribute( "value" ) === null ? "on" : elem.value;
-		};
-	}
-} );
-
-
-
-
-// Return jQuery for attributes-only inclusion
-
-
-var rfocusMorph = /^(?:focusinfocus|focusoutblur)$/;
-
-jQuery.extend( jQuery.event, {
-
-	trigger: function( event, data, elem, onlyHandlers ) {
-
-		var i, cur, tmp, bubbleType, ontype, handle, special,
-			eventPath = [ elem || document ],
-			type = hasOwn.call( event, "type" ) ? event.type : event,
-			namespaces = hasOwn.call( event, "namespace" ) ? event.namespace.split( "." ) : [];
-
-		cur = tmp = elem = elem || document;
-
-		// Don't do events on text and comment nodes
-		if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
-			return;
-		}
-
-		// focus/blur morphs to focusin/out; ensure we're not firing them right now
-		if ( rfocusMorph.test( type + jQuery.event.triggered ) ) {
-			return;
-		}
-
-		if ( type.indexOf( "." ) > -1 ) {
-
-			// Namespaced trigger; create a regexp to match event type in handle()
-			namespaces = type.split( "." );
-			type = namespaces.shift();
-			namespaces.sort();
-		}
-		ontype = type.indexOf( ":" ) < 0 && "on" + type;
-
-		// Caller can pass in a jQuery.Event object, Object, or just an event type string
-		event = event[ jQuery.expando ] ?
-			event :
-			new jQuery.Event( type, typeof event === "object" && event );
-
-		// Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true)
-		event.isTrigger = onlyHandlers ? 2 : 3;
-		event.namespace = namespaces.join( "." );
-		event.rnamespace = event.namespace ?
-			new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" ) :
-			null;
-
-		// Clean up the event in case it is being reused
-		event.result = undefined;
-		if ( !event.target ) {
-			event.target = elem;
-		}
-
-		// Clone any incoming data and prepend the event, creating the handler arg list
-		data = data == null ?
-			[ event ] :
-			jQuery.makeArray( data, [ event ] );
-
-		// Allow special events to draw outside the lines
-		special = jQuery.event.special[ type ] || {};
-		if ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) {
-			return;
-		}
-
-		// Determine event propagation path in advance, per W3C events spec (#9951)
-		// Bubble up to document, then to window; watch for a global ownerDocument var (#9724)
-		if ( !onlyHandlers && !special.noBubble && !jQuery.isWindow( elem ) ) {
-
-			bubbleType = special.delegateType || type;
-			if ( !rfocusMorph.test( bubbleType + type ) ) {
-				cur = cur.parentNode;
-			}
-			for ( ; cur; cur = cur.parentNode ) {
-				eventPath.push( cur );
-				tmp = cur;
-			}
-
-			// Only add window if we got to document (e.g., not plain obj or detached DOM)
-			if ( tmp === ( elem.ownerDocument || document ) ) {
-				eventPath.push( tmp.defaultView || tmp.parentWindow || window );
-			}
-		}
-
-		// Fire handlers on the event path
-		i = 0;
-		while ( ( cur = eventPath[ i++ ] ) && !event.isPropagationStopped() ) {
-
-			event.type = i > 1 ?
-				bubbleType :
-				special.bindType || type;
-
-			// jQuery handler
-			handle = ( dataPriv.get( cur, "events" ) || {} )[ event.type ] &&
-				dataPriv.get( cur, "handle" );
-			if ( handle ) {
-				handle.apply( cur, data );
-			}
-
-			// Native handler
-			handle = ontype && cur[ ontype ];
-			if ( handle && handle.apply && acceptData( cur ) ) {
-				event.result = handle.apply( cur, data );
-				if ( event.result === false ) {
-					event.preventDefault();
-				}
-			}
-		}
-		event.type = type;
-
-		// If nobody prevented the default action, do it now
-		if ( !onlyHandlers && !event.isDefaultPrevented() ) {
-
-			if ( ( !special._default ||
-				special._default.apply( eventPath.pop(), data ) === false ) &&
-				acceptData( elem ) ) {
-
-				// Call a native DOM method on the target with the same name name as the event.
-				// Don't do default actions on window, that's where global variables be (#6170)
-				if ( ontype && jQuery.isFunction( elem[ type ] ) && !jQuery.isWindow( elem ) ) {
-
-					// Don't re-trigger an onFOO event when we call its FOO() method
-					tmp = elem[ ontype ];
-
-					if ( tmp ) {
-						elem[ ontype ] = null;
-					}
-
-					// Prevent re-triggering of the same event, since we already bubbled it above
-					jQuery.event.triggered = type;
-					elem[ type ]();
-					jQuery.event.triggered = undefined;
-
-					if ( tmp ) {
-						elem[ ontype ] = tmp;
-					}
-				}
-			}
-		}
-
-		return event.result;
-	},
-
-	// Piggyback on a donor event to simulate a different one
-	// Used only for `focus(in | out)` events
-	simulate: function( type, elem, event ) {
-		var e = jQuery.extend(
-			new jQuery.Event(),
-			event,
-			{
-				type: type,
-				isSimulated: true
-			}
-		);
-
-		jQuery.event.trigger( e, null, elem );
-	}
-
-} );
-
-jQuery.fn.extend( {
-
-	trigger: function( type, data ) {
-		return this.each( function() {
-			jQuery.event.trigger( type, data, this );
-		} );
-	},
-	triggerHandler: function( type, data ) {
-		var elem = this[ 0 ];
-		if ( elem ) {
-			return jQuery.event.trigger( type, data, elem, true );
-		}
-	}
-} );
-
-
-jQuery.each( ( "blur focus focusin focusout load resize scroll unload click dblclick " +
-	"mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " +
-	"change select submit keydown keypress keyup error contextmenu" ).split( " " ),
-	function( i, name ) {
-
-	// Handle event binding
-	jQuery.fn[ name ] = function( data, fn ) {
-		return arguments.length > 0 ?
-			this.on( name, null, data, fn ) :
-			this.trigger( name );
-	};
-} );
-
-jQuery.fn.extend( {
-	hover: function( fnOver, fnOut ) {
-		return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver );
-	}
-} );
-
-
-
-
-support.focusin = "onfocusin" in window;
-
-
-// Support: Firefox
-// Firefox doesn't have focus(in | out) events
-// Related ticket - https://bugzilla.mozilla.org/show_bug.cgi?id=687787
-//
-// Support: Chrome, Safari
-// focus(in | out) events fire after focus & blur events,
-// which is spec violation - http://www.w3.org/TR/DOM-Level-3-Events/#events-focusevent-event-order
-// Related ticket - https://code.google.com/p/chromium/issues/detail?id=449857
-if ( !support.focusin ) {
-	jQuery.each( { focus: "focusin", blur: "focusout" }, function( orig, fix ) {
-
-		// Attach a single capturing handler on the document while someone wants focusin/focusout
-		var handler = function( event ) {
-			jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ) );
-		};
-
-		jQuery.event.special[ fix ] = {
-			setup: function() {
-				var doc = this.ownerDocument || this,
-					attaches = dataPriv.access( doc, fix );
-
-				if ( !attaches ) {
-					doc.addEventListener( orig, handler, true );
-				}
-				dataPriv.access( doc, fix, ( attaches || 0 ) + 1 );
-			},
-			teardown: function() {
-				var doc = this.ownerDocument || this,
-					attaches = dataPriv.access( doc, fix ) - 1;
-
-				if ( !attaches ) {
-					doc.removeEventListener( orig, handler, true );
-					dataPriv.remove( doc, fix );
-
-				} else {
-					dataPriv.access( doc, fix, attaches );
-				}
-			}
-		};
-	} );
-}
-var location = window.location;
-
-var nonce = jQuery.now();
-
-var rquery = ( /\?/ );
-
-
-
-// Support: Android 2.3
-// Workaround failure to string-cast null input
-jQuery.parseJSON = function( data ) {
-	return JSON.parse( data + "" );
-};
-
-
-// Cross-browser xml parsing
-jQuery.parseXML = function( data ) {
-	var xml;
-	if ( !data || typeof data !== "string" ) {
-		return null;
-	}
-
-	// Support: IE9
-	try {
-		xml = ( new window.DOMParser() ).parseFromString( data, "text/xml" );
-	} catch ( e ) {
-		xml = undefined;
-	}
-
-	if ( !xml || xml.getElementsByTagName( "parsererror" ).length ) {
-		jQuery.error( "Invalid XML: " + data );
-	}
-	return xml;
-};
-
-
-var
-	rhash = /#.*$/,
-	rts = /([?&])_=[^&]*/,
-	rheaders = /^(.*?):[ \t]*([^\r\n]*)$/mg,
-
-	// #7653, #8125, #8152: local protocol detection
-	rlocalProtocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/,
-	rnoContent = /^(?:GET|HEAD)$/,
-	rprotocol = /^\/\//,
-
-	/* Prefilters
-	 * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example)
-	 * 2) These are called:
-	 *    - BEFORE asking for a transport
-	 *    - AFTER param serialization (s.data is a string if s.processData is true)
-	 * 3) key is the dataType
-	 * 4) the catchall symbol "*" can be used
-	 * 5) execution will start with transport dataType and THEN continue down to "*" if needed
-	 */
-	prefilters = {},
-
-	/* Transports bindings
-	 * 1) key is the dataType
-	 * 2) the catchall symbol "*" can be used
-	 * 3) selection will start with transport dataType and THEN go to "*" if needed
-	 */
-	transports = {},
-
-	// Avoid comment-prolog char sequence (#10098); must appease lint and evade compression
-	allTypes = "*/".concat( "*" ),
-
-	// Anchor tag for parsing the document origin
-	originAnchor = document.createElement( "a" );
-	originAnchor.href = location.href;
-
-// Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport
-function addToPrefiltersOrTransports( structure ) {
-
-	// dataTypeExpression is optional and defaults to "*"
-	return function( dataTypeExpression, func ) {
-
-		if ( typeof dataTypeExpression !== "string" ) {
-			func = dataTypeExpression;
-			dataTypeExpression = "*";
-		}
-
-		var dataType,
-			i = 0,
-			dataTypes = dataTypeExpression.toLowerCase().match( rnotwhite ) || [];
-
-		if ( jQuery.isFunction( func ) ) {
-
-			// For each dataType in the dataTypeExpression
-			while ( ( dataType = dataTypes[ i++ ] ) ) {
-
-				// Prepend if requested
-				if ( dataType[ 0 ] === "+" ) {
-					dataType = dataType.slice( 1 ) || "*";
-					( structure[ dataType ] = structure[ dataType ] || [] ).unshift( func );
-
-				// Otherwise append
-				} else {
-					( structure[ dataType ] = structure[ dataType ] || [] ).push( func );
-				}
-			}
-		}
-	};
-}
-
-// Base inspection function for prefilters and transports
-function inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR ) {
-
-	var inspected = {},
-		seekingTransport = ( structure === transports );
-
-	function inspect( dataType ) {
-		var selected;
-		inspected[ dataType ] = true;
-		jQuery.each( structure[ dataType ] || [], function( _, prefilterOrFactory ) {
-			var dataTypeOrTransport = prefilterOrFactory( options, originalOptions, jqXHR );
-			if ( typeof dataTypeOrTransport === "string" &&
-				!seekingTransport && !inspected[ dataTypeOrTransport ] ) {
-
-				options.dataTypes.unshift( dataTypeOrTransport );
-				inspect( dataTypeOrTransport );
-				return false;
-			} else if ( seekingTransport ) {
-				return !( selected = dataTypeOrTransport );
-			}
-		} );
-		return selected;
-	}
-
-	return inspect( options.dataTypes[ 0 ] ) || !inspected[ "*" ] && inspect( "*" );
-}
-
-// A special extend for ajax options
-// that takes "flat" options (not to be deep extended)
-// Fixes #9887
-function ajaxExtend( target, src ) {
-	var key, deep,
-		flatOptions = jQuery.ajaxSettings.flatOptions || {};
-
-	for ( key in src ) {
-		if ( src[ key ] !== undefined ) {
-			( flatOptions[ key ] ? target : ( deep || ( deep = {} ) ) )[ key ] = src[ key ];
-		}
-	}
-	if ( deep ) {
-		jQuery.extend( true, target, deep );
-	}
-
-	return target;
-}
-
-/* Handles responses to an ajax request:
- * - finds the right dataType (mediates between content-type and expected dataType)
- * - returns the corresponding response
- */
-function ajaxHandleResponses( s, jqXHR, responses ) {
-
-	var ct, type, finalDataType, firstDataType,
-		contents = s.contents,
-		dataTypes = s.dataTypes;
-
-	// Remove auto dataType and get content-type in the process
-	while ( dataTypes[ 0 ] === "*" ) {
-		dataTypes.shift();
-		if ( ct === undefined ) {
-			ct = s.mimeType || jqXHR.getResponseHeader( "Content-Type" );
-		}
-	}
-
-	// Check if we're dealing with a known content-type
-	if ( ct ) {
-		for ( type in contents ) {
-			if ( contents[ type ] && contents[ type ].test( ct ) ) {
-				dataTypes.unshift( type );
-				break;
-			}
-		}
-	}
-
-	// Check to see if we have a response for the expected dataType
-	if ( dataTypes[ 0 ] in responses ) {
-		finalDataType = dataTypes[ 0 ];
-	} else {
-
-		// Try convertible dataTypes
-		for ( type in responses ) {
-			if ( !dataTypes[ 0 ] || s.converters[ type + " " + dataTypes[ 0 ] ] ) {
-				finalDataType = type;
-				break;
-			}
-			if ( !firstDataType ) {
-				firstDataType = type;
-			}
-		}
-
-		// Or just use first one
-		finalDataType = finalDataType || firstDataType;
-	}
-
-	// If we found a dataType
-	// We add the dataType to the list if needed
-	// and return the corresponding response
-	if ( finalDataType ) {
-		if ( finalDataType !== dataTypes[ 0 ] ) {
-			dataTypes.unshift( finalDataType );
-		}
-		return responses[ finalDataType ];
-	}
-}
-
-/* Chain conversions given the request and the original response
- * Also sets the responseXXX fields on the jqXHR instance
- */
-function ajaxConvert( s, response, jqXHR, isSuccess ) {
-	var conv2, current, conv, tmp, prev,
-		converters = {},
-
-		// Work with a copy of dataTypes in case we need to modify it for conversion
-		dataTypes = s.dataTypes.slice();
-
-	// Create converters map with lowercased keys
-	if ( dataTypes[ 1 ] ) {
-		for ( conv in s.converters ) {
-			converters[ conv.toLowerCase() ] = s.converters[ conv ];
-		}
-	}
-
-	current = dataTypes.shift();
-
-	// Convert to each sequential dataType
-	while ( current ) {
-
-		if ( s.responseFields[ current ] ) {
-			jqXHR[ s.responseFields[ current ] ] = response;
-		}
-
-		// Apply the dataFilter if provided
-		if ( !prev && isSuccess && s.dataFilter ) {
-			response = s.dataFilter( response, s.dataType );
-		}
-
-		prev = current;
-		current = dataTypes.shift();
-
-		if ( current ) {
-
-		// There's only work to do if current dataType is non-auto
-			if ( current === "*" ) {
-
-				current = prev;
-
-			// Convert response if prev dataType is non-auto and differs from current
-			} else if ( prev !== "*" && prev !== current ) {
-
-				// Seek a direct converter
-				conv = converters[ prev + " " + current ] || converters[ "* " + current ];
-
-				// If none found, seek a pair
-				if ( !conv ) {
-					for ( conv2 in converters ) {
-
-						// If conv2 outputs current
-						tmp = conv2.split( " " );
-						if ( tmp[ 1 ] === current ) {
-
-							// If prev can be converted to accepted input
-							conv = converters[ prev + " " + tmp[ 0 ] ] ||
-								converters[ "* " + tmp[ 0 ] ];
-							if ( conv ) {
-
-								// Condense equivalence converters
-								if ( conv === true ) {
-									conv = converters[ conv2 ];
-
-								// Otherwise, insert the intermediate dataType
-								} else if ( converters[ conv2 ] !== true ) {
-									current = tmp[ 0 ];
-									dataTypes.unshift( tmp[ 1 ] );
-								}
-								break;
-							}
-						}
-					}
-				}
-
-				// Apply converter (if not an equivalence)
-				if ( conv !== true ) {
-
-					// Unless errors are allowed to bubble, catch and return them
-					if ( conv && s.throws ) {
-						response = conv( response );
-					} else {
-						try {
-							response = conv( response );
-						} catch ( e ) {
-							return {
-								state: "parsererror",
-								error: conv ? e : "No conversion from " + prev + " to " + current
-							};
-						}
-					}
-				}
-			}
-		}
-	}
-
-	return { state: "success", data: response };
-}
-
-jQuery.extend( {
-
-	// Counter for holding the number of active queries
-	active: 0,
+		accepts: {
+			xml: "application/xml, text/xml",
+			html: "text/html",
+			script: "text/javascript, application/javascript",
+			json: "application/json, text/javascript",
+			text: "text/plain",
+			_default: "*/*"
+		}
+	},
 
 	// Last-Modified header cache for next request
@@ -8269,1273 +4973,1113 @@
 	etag: {},
 
-	ajaxSettings: {
-		url: location.href,
-		type: "GET",
-		isLocal: rlocalProtocol.test( location.protocol ),
-		global: true,
-		processData: true,
-		async: true,
-		contentType: "application/x-www-form-urlencoded; charset=UTF-8",
-		/*
-		timeout: 0,
-		data: null,
-		dataType: null,
-		username: null,
-		password: null,
-		cache: null,
-		throws: false,
-		traditional: false,
-		headers: {},
-		*/
-
-		accepts: {
-			"*": allTypes,
-			text: "text/plain",
-			html: "text/html",
-			xml: "application/xml, text/xml",
-			json: "application/json, text/javascript"
-		},
-
-		contents: {
-			xml: /\bxml\b/,
-			html: /\bhtml/,
-			json: /\bjson\b/
-		},
-
-		responseFields: {
-			xml: "responseXML",
-			text: "responseText",
-			json: "responseJSON"
-		},
-
-		// Data converters
-		// Keys separate source (or catchall "*") and destination types with a single space
-		converters: {
-
-			// Convert anything to text
-			"* text": String,
-
-			// Text to html (true = no transformation)
-			"text html": true,
-
-			// Evaluate text as a json expression
-			"text json": jQuery.parseJSON,
-
-			// Parse text as xml
-			"text xml": jQuery.parseXML
-		},
-
-		// For options that shouldn't be deep extended:
-		// you can add your own custom options here if
-		// and when you create one that shouldn't be
-		// deep extended (see ajaxExtend)
-		flatOptions: {
-			url: true,
-			context: true
-		}
-	},
-
-	// Creates a full fledged settings object into target
-	// with both ajaxSettings and settings fields.
-	// If target is omitted, writes into ajaxSettings.
-	ajaxSetup: function( target, settings ) {
-		return settings ?
-
-			// Building a settings object
-			ajaxExtend( ajaxExtend( target, jQuery.ajaxSettings ), settings ) :
-
-			// Extending ajaxSettings
-			ajaxExtend( jQuery.ajaxSettings, target );
-	},
-
-	ajaxPrefilter: addToPrefiltersOrTransports( prefilters ),
-	ajaxTransport: addToPrefiltersOrTransports( transports ),
-
-	// Main method
-	ajax: function( url, options ) {
-
-		// If url is an object, simulate pre-1.5 signature
-		if ( typeof url === "object" ) {
-			options = url;
-			url = undefined;
-		}
-
-		// Force options to be an object
-		options = options || {};
-
-		var transport,
-
-			// URL without anti-cache param
-			cacheURL,
-
-			// Response headers
-			responseHeadersString,
-			responseHeaders,
-
-			// timeout handle
-			timeoutTimer,
-
-			// Url cleanup var
-			urlAnchor,
-
-			// To know if global events are to be dispatched
-			fireGlobals,
-
-			// Loop variable
-			i,
-
-			// Create the final options object
-			s = jQuery.ajaxSetup( {}, options ),
-
-			// Callbacks context
-			callbackContext = s.context || s,
-
-			// Context for global events is callbackContext if it is a DOM node or jQuery collection
-			globalEventContext = s.context &&
-				( callbackContext.nodeType || callbackContext.jquery ) ?
-					jQuery( callbackContext ) :
-					jQuery.event,
-
-			// Deferreds
-			deferred = jQuery.Deferred(),
-			completeDeferred = jQuery.Callbacks( "once memory" ),
-
-			// Status-dependent callbacks
-			statusCode = s.statusCode || {},
-
-			// Headers (they are sent all at once)
-			requestHeaders = {},
-			requestHeadersNames = {},
-
-			// The jqXHR state
-			state = 0,
-
-			// Default abort message
-			strAbort = "canceled",
-
-			// Fake xhr
-			jqXHR = {
-				readyState: 0,
-
-				// Builds headers hashtable if needed
-				getResponseHeader: function( key ) {
-					var match;
-					if ( state === 2 ) {
-						if ( !responseHeaders ) {
-							responseHeaders = {};
-							while ( ( match = rheaders.exec( responseHeadersString ) ) ) {
-								responseHeaders[ match[ 1 ].toLowerCase() ] = match[ 2 ];
-							}
-						}
-						match = responseHeaders[ key.toLowerCase() ];
-					}
-					return match == null ? null : match;
-				},
-
-				// Raw string
-				getAllResponseHeaders: function() {
-					return state === 2 ? responseHeadersString : null;
-				},
-
-				// Caches the header
-				setRequestHeader: function( name, value ) {
-					var lname = name.toLowerCase();
-					if ( !state ) {
-						name = requestHeadersNames[ lname ] = requestHeadersNames[ lname ] || name;
-						requestHeaders[ name ] = value;
-					}
-					return this;
-				},
-
-				// Overrides response content-type header
-				overrideMimeType: function( type ) {
-					if ( !state ) {
-						s.mimeType = type;
-					}
-					return this;
-				},
-
-				// Status-dependent callbacks
-				statusCode: function( map ) {
-					var code;
-					if ( map ) {
-						if ( state < 2 ) {
-							for ( code in map ) {
-
-								// Lazy-add the new callback in a way that preserves old ones
-								statusCode[ code ] = [ statusCode[ code ], map[ code ] ];
-							}
-						} else {
-
-							// Execute the appropriate callbacks
-							jqXHR.always( map[ jqXHR.status ] );
+	ajax: function( origSettings ) {
+		var s = jQuery.extend(true, {}, jQuery.ajaxSettings, origSettings);
+		
+		var jsonp, status, data,
+			callbackContext = origSettings && origSettings.context || s,
+			type = s.type.toUpperCase();
+
+		// convert data if not already a string
+		if ( s.data && s.processData && typeof s.data !== "string" ) {
+			s.data = jQuery.param( s.data, s.traditional );
+		}
+
+		// Handle JSONP Parameter Callbacks
+		if ( s.dataType === "jsonp" ) {
+			if ( type === "GET" ) {
+				if ( !jsre.test( s.url ) ) {
+					s.url += (rquery.test( s.url ) ? "&" : "?") + (s.jsonp || "callback") + "=?";
+				}
+			} else if ( !s.data || !jsre.test(s.data) ) {
+				s.data = (s.data ? s.data + "&" : "") + (s.jsonp || "callback") + "=?";
+			}
+			s.dataType = "json";
+		}
+
+		// Build temporary JSONP function
+		if ( s.dataType === "json" && (s.data && jsre.test(s.data) || jsre.test(s.url)) ) {
+			jsonp = s.jsonpCallback || ("jsonp" + jsc++);
+
+			// Replace the =? sequence both in the query string and the data
+			if ( s.data ) {
+				s.data = (s.data + "").replace(jsre, "=" + jsonp + "$1");
+			}
+
+			s.url = s.url.replace(jsre, "=" + jsonp + "$1");
+
+			// We need to make sure
+			// that a JSONP style response is executed properly
+			s.dataType = "script";
+
+			// Handle JSONP-style loading
+			window[ jsonp ] = window[ jsonp ] || function( tmp ) {
+				data = tmp;
+				success();
+				complete();
+				// Garbage collect
+				window[ jsonp ] = undefined;
+
+				try {
+					delete window[ jsonp ];
+				} catch(e) {}
+
+				if ( head ) {
+					head.removeChild( script );
+				}
+			};
+		}
+
+		if ( s.dataType === "script" && s.cache === null ) {
+			s.cache = false;
+		}
+
+		if ( s.cache === false && type === "GET" ) {
+			var ts = now();
+
+			// try replacing _= if it is there
+			var ret = s.url.replace(rts, "$1_=" + ts + "$2");
+
+			// if nothing was replaced, add timestamp to the end
+			s.url = ret + ((ret === s.url) ? (rquery.test(s.url) ? "&" : "?") + "_=" + ts : "");
+		}
+
+		// If data is available, append data to url for get requests
+		if ( s.data && type === "GET" ) {
+			s.url += (rquery.test(s.url) ? "&" : "?") + s.data;
+		}
+
+		// Watch for a new set of requests
+		if ( s.global && ! jQuery.active++ ) {
+			jQuery.event.trigger( "ajaxStart" );
+		}
+
+		// Matches an absolute URL, and saves the domain
+		var parts = rurl.exec( s.url ),
+			remote = parts && (parts[1] && parts[1] !== location.protocol || parts[2] !== location.host);
+
+		// If we're requesting a remote document
+		// and trying to load JSON or Script with a GET
+		if ( s.dataType === "script" && type === "GET" && remote ) {
+			var head = document.getElementsByTagName("head")[0] || document.documentElement;
+			var script = document.createElement("script");
+			script.src = s.url;
+			if ( s.scriptCharset ) {
+				script.charset = s.scriptCharset;
+			}
+
+			// Handle Script loading
+			if ( !jsonp ) {
+				var done = false;
+
+				// Attach handlers for all browsers
+				script.onload = script.onreadystatechange = function() {
+					if ( !done && (!this.readyState ||
+							this.readyState === "loaded" || this.readyState === "complete") ) {
+						done = true;
+						success();
+						complete();
+
+						// Handle memory leak in IE
+						script.onload = script.onreadystatechange = null;
+						if ( head && script.parentNode ) {
+							head.removeChild( script );
 						}
 					}
-					return this;
-				},
-
-				// Cancel the request
-				abort: function( statusText ) {
-					var finalText = statusText || strAbort;
-					if ( transport ) {
-						transport.abort( finalText );
+				};
+			}
+
+			// Use insertBefore instead of appendChild  to circumvent an IE6 bug.
+			// This arises when a base node is used (#2709 and #4378).
+			head.insertBefore( script, head.firstChild );
+
+			// We handle everything using the script element injection
+			return undefined;
+		}
+
+		var requestDone = false;
+
+		// Create the request object
+		var xhr = s.xhr();
+
+		if ( !xhr ) {
+			return;
+		}
+
+		// Open the socket
+		// Passing null username, generates a login popup on Opera (#2865)
+		if ( s.username ) {
+			xhr.open(type, s.url, s.async, s.username, s.password);
+		} else {
+			xhr.open(type, s.url, s.async);
+		}
+
+		// Need an extra try/catch for cross domain requests in Firefox 3
+		try {
+			// Set the correct header, if data is being sent
+			if ( s.data || origSettings && origSettings.contentType ) {
+				xhr.setRequestHeader("Content-Type", s.contentType);
+			}
+
+			// Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
+			if ( s.ifModified ) {
+				if ( jQuery.lastModified[s.url] ) {
+					xhr.setRequestHeader("If-Modified-Since", jQuery.lastModified[s.url]);
+				}
+
+				if ( jQuery.etag[s.url] ) {
+					xhr.setRequestHeader("If-None-Match", jQuery.etag[s.url]);
+				}
+			}
+
+			// Set header so the called script knows that it's an XMLHttpRequest
+			// Only send the header if it's not a remote XHR
+			if ( !remote ) {
+				xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest");
+			}
+
+			// Set the Accepts header for the server, depending on the dataType
+			xhr.setRequestHeader("Accept", s.dataType && s.accepts[ s.dataType ] ?
+				s.accepts[ s.dataType ] + ", */*" :
+				s.accepts._default );
+		} catch(e) {}
+
+		// Allow custom headers/mimetypes and early abort
+		if ( s.beforeSend && s.beforeSend.call(callbackContext, xhr, s) === false ) {
+			// Handle the global AJAX counter
+			if ( s.global && ! --jQuery.active ) {
+				jQuery.event.trigger( "ajaxStop" );
+			}
+
+			// close opended socket
+			xhr.abort();
+			return false;
+		}
+
+		if ( s.global ) {
+			trigger("ajaxSend", [xhr, s]);
+		}
+
+		// Wait for a response to come back
+		var onreadystatechange = xhr.onreadystatechange = function( isTimeout ) {
+			// The request was aborted
+			if ( !xhr || xhr.readyState === 0 || isTimeout === "abort" ) {
+				// Opera doesn't call onreadystatechange before this point
+				// so we simulate the call
+				if ( !requestDone ) {
+					complete();
+				}
+
+				requestDone = true;
+				if ( xhr ) {
+					xhr.onreadystatechange = jQuery.noop;
+				}
+
+			// The transfer is complete and the data is available, or the request timed out
+			} else if ( !requestDone && xhr && (xhr.readyState === 4 || isTimeout === "timeout") ) {
+				requestDone = true;
+				xhr.onreadystatechange = jQuery.noop;
+
+				status = isTimeout === "timeout" ?
+					"timeout" :
+					!jQuery.httpSuccess( xhr ) ?
+						"error" :
+						s.ifModified && jQuery.httpNotModified( xhr, s.url ) ?
+							"notmodified" :
+							"success";
+
+				var errMsg;
+
+				if ( status === "success" ) {
+					// Watch for, and catch, XML document parse errors
+					try {
+						// process the data (runs the xml through httpData regardless of callback)
+						data = jQuery.httpData( xhr, s.dataType, s );
+					} catch(err) {
+						status = "parsererror";
+						errMsg = err;
 					}
-					done( 0, finalText );
-					return this;
-				}
+				}
+
+				// Make sure that the request was successful or notmodified
+				if ( status === "success" || status === "notmodified" ) {
+					// JSONP handles its own success callback
+					if ( !jsonp ) {
+						success();
+					}
+				} else {
+					jQuery.handleError(s, xhr, status, errMsg);
+				}
+
+				// Fire the complete handlers
+				complete();
+
+				if ( isTimeout === "timeout" ) {
+					xhr.abort();
+				}
+
+				// Stop memory leaks
+				if ( s.async ) {
+					xhr = null;
+				}
+			}
+		};
+
+		// Override the abort handler, if we can (IE doesn't allow it, but that's OK)
+		// Opera doesn't fire onreadystatechange at all on abort
+		try {
+			var oldAbort = xhr.abort;
+			xhr.abort = function() {
+				if ( xhr ) {
+					oldAbort.call( xhr );
+				}
+
+				onreadystatechange( "abort" );
 			};
-
-		// Attach deferreds
-		deferred.promise( jqXHR ).complete = completeDeferred.add;
-		jqXHR.success = jqXHR.done;
-		jqXHR.error = jqXHR.fail;
-
-		// Remove hash character (#7531: and string promotion)
-		// Add protocol if not provided (prefilters might expect it)
-		// Handle falsy url in the settings object (#10093: consistency with old signature)
-		// We also use the url parameter if available
-		s.url = ( ( url || s.url || location.href ) + "" ).replace( rhash, "" )
-			.replace( rprotocol, location.protocol + "//" );
-
-		// Alias method option to type as per ticket #12004
-		s.type = options.method || options.type || s.method || s.type;
-
-		// Extract dataTypes list
-		s.dataTypes = jQuery.trim( s.dataType || "*" ).toLowerCase().match( rnotwhite ) || [ "" ];
-
-		// A cross-domain request is in order when the origin doesn't match the current origin.
-		if ( s.crossDomain == null ) {
-			urlAnchor = document.createElement( "a" );
-
-			// Support: IE8-11+
-			// IE throws exception if url is malformed, e.g. http://example.com:80x/
-			try {
-				urlAnchor.href = s.url;
-
-				// Support: IE8-11+
-				// Anchor's host property isn't correctly set when s.url is relative
-				urlAnchor.href = urlAnchor.href;
-				s.crossDomain = originAnchor.protocol + "//" + originAnchor.host !==
-					urlAnchor.protocol + "//" + urlAnchor.host;
-			} catch ( e ) {
-
-				// If there is an error parsing the URL, assume it is crossDomain,
-				// it can be rejected by the transport if it is invalid
-				s.crossDomain = true;
-			}
-		}
-
-		// Convert data if not already a string
-		if ( s.data && s.processData && typeof s.data !== "string" ) {
-			s.data = jQuery.param( s.data, s.traditional );
-		}
-
-		// Apply prefilters
-		inspectPrefiltersOrTransports( prefilters, s, options, jqXHR );
-
-		// If request was aborted inside a prefilter, stop there
-		if ( state === 2 ) {
-			return jqXHR;
-		}
-
-		// We can fire global events as of now if asked to
-		// Don't fire events if jQuery.event is undefined in an AMD-usage scenario (#15118)
-		fireGlobals = jQuery.event && s.global;
-
-		// Watch for a new set of requests
-		if ( fireGlobals && jQuery.active++ === 0 ) {
-			jQuery.event.trigger( "ajaxStart" );
-		}
-
-		// Uppercase the type
-		s.type = s.type.toUpperCase();
-
-		// Determine if request has content
-		s.hasContent = !rnoContent.test( s.type );
-
-		// Save the URL in case we're toying with the If-Modified-Since
-		// and/or If-None-Match header later on
-		cacheURL = s.url;
-
-		// More options handling for requests with no content
-		if ( !s.hasContent ) {
-
-			// If data is available, append data to url
-			if ( s.data ) {
-				cacheURL = ( s.url += ( rquery.test( cacheURL ) ? "&" : "?" ) + s.data );
-
-				// #9682: remove data so that it's not used in an eventual retry
-				delete s.data;
-			}
-
-			// Add anti-cache in url if needed
-			if ( s.cache === false ) {
-				s.url = rts.test( cacheURL ) ?
-
-					// If there is already a '_' parameter, set its value
-					cacheURL.replace( rts, "$1_=" + nonce++ ) :
-
-					// Otherwise add one to the end
-					cacheURL + ( rquery.test( cacheURL ) ? "&" : "?" ) + "_=" + nonce++;
-			}
-		}
-
-		// Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
-		if ( s.ifModified ) {
-			if ( jQuery.lastModified[ cacheURL ] ) {
-				jqXHR.setRequestHeader( "If-Modified-Since", jQuery.lastModified[ cacheURL ] );
-			}
-			if ( jQuery.etag[ cacheURL ] ) {
-				jqXHR.setRequestHeader( "If-None-Match", jQuery.etag[ cacheURL ] );
-			}
-		}
-
-		// Set the correct header, if data is being sent
-		if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) {
-			jqXHR.setRequestHeader( "Content-Type", s.contentType );
-		}
-
-		// Set the Accepts header for the server, depending on the dataType
-		jqXHR.setRequestHeader(
-			"Accept",
-			s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[ 0 ] ] ?
-				s.accepts[ s.dataTypes[ 0 ] ] +
-					( s.dataTypes[ 0 ] !== "*" ? ", " + allTypes + "; q=0.01" : "" ) :
-				s.accepts[ "*" ]
-		);
-
-		// Check for headers option
-		for ( i in s.headers ) {
-			jqXHR.setRequestHeader( i, s.headers[ i ] );
-		}
-
-		// Allow custom headers/mimetypes and early abort
-		if ( s.beforeSend &&
-			( s.beforeSend.call( callbackContext, jqXHR, s ) === false || state === 2 ) ) {
-
-			// Abort if not done already and return
-			return jqXHR.abort();
-		}
-
-		// Aborting is no longer a cancellation
-		strAbort = "abort";
-
-		// Install callbacks on deferreds
-		for ( i in { success: 1, error: 1, complete: 1 } ) {
-			jqXHR[ i ]( s[ i ] );
-		}
-
-		// Get transport
-		transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR );
-
-		// If no transport, we auto-abort
-		if ( !transport ) {
-			done( -1, "No Transport" );
+		} catch(e) { }
+
+		// Timeout checker
+		if ( s.async && s.timeout > 0 ) {
+			setTimeout(function() {
+				// Check to see if the request is still happening
+				if ( xhr && !requestDone ) {
+					onreadystatechange( "timeout" );
+				}
+			}, s.timeout);
+		}
+
+		// Send the data
+		try {
+			xhr.send( type === "POST" || type === "PUT" || type === "DELETE" ? s.data : null );
+		} catch(e) {
+			jQuery.handleError(s, xhr, null, e);
+			// Fire the complete handlers
+			complete();
+		}
+
+		// firefox 1.5 doesn't fire statechange for sync requests
+		if ( !s.async ) {
+			onreadystatechange();
+		}
+
+		function success() {
+			// If a local callback was specified, fire it and pass it the data
+			if ( s.success ) {
+				s.success.call( callbackContext, data, status, xhr );
+			}
+
+			// Fire the global callback
+			if ( s.global ) {
+				trigger( "ajaxSuccess", [xhr, s] );
+			}
+		}
+
+		function complete() {
+			// Process result
+			if ( s.complete ) {
+				s.complete.call( callbackContext, xhr, status);
+			}
+
+			// The request was completed
+			if ( s.global ) {
+				trigger( "ajaxComplete", [xhr, s] );
+			}
+
+			// Handle the global AJAX counter
+			if ( s.global && ! --jQuery.active ) {
+				jQuery.event.trigger( "ajaxStop" );
+			}
+		}
+		
+		function trigger(type, args) {
+			(s.context ? jQuery(s.context) : jQuery.event).trigger(type, args);
+		}
+
+		// return XMLHttpRequest to allow aborting the request etc.
+		return xhr;
+	},
+
+	handleError: function( s, xhr, status, e ) {
+		// If a local callback was specified, fire it
+		if ( s.error ) {
+			s.error.call( s.context || s, xhr, status, e );
+		}
+
+		// Fire the global callback
+		if ( s.global ) {
+			(s.context ? jQuery(s.context) : jQuery.event).trigger( "ajaxError", [xhr, s, e] );
+		}
+	},
+
+	// Counter for holding the number of active queries
+	active: 0,
+
+	// Determines if an XMLHttpRequest was successful or not
+	httpSuccess: function( xhr ) {
+		try {
+			// IE error sometimes returns 1223 when it should be 204 so treat it as success, see #1450
+			return !xhr.status && location.protocol === "file:" ||
+				// Opera returns 0 when status is 304
+				( xhr.status >= 200 && xhr.status < 300 ) ||
+				xhr.status === 304 || xhr.status === 1223 || xhr.status === 0;
+		} catch(e) {}
+
+		return false;
+	},
+
+	// Determines if an XMLHttpRequest returns NotModified
+	httpNotModified: function( xhr, url ) {
+		var lastModified = xhr.getResponseHeader("Last-Modified"),
+			etag = xhr.getResponseHeader("Etag");
+
+		if ( lastModified ) {
+			jQuery.lastModified[url] = lastModified;
+		}
+
+		if ( etag ) {
+			jQuery.etag[url] = etag;
+		}
+
+		// Opera returns 0 when status is 304
+		return xhr.status === 304 || xhr.status === 0;
+	},
+
+	httpData: function( xhr, type, s ) {
+		var ct = xhr.getResponseHeader("content-type") || "",
+			xml = type === "xml" || !type && ct.indexOf("xml") >= 0,
+			data = xml ? xhr.responseXML : xhr.responseText;
+
+		if ( xml && data.documentElement.nodeName === "parsererror" ) {
+			jQuery.error( "parsererror" );
+		}
+
+		// Allow a pre-filtering function to sanitize the response
+		// s is checked to keep backwards compatibility
+		if ( s && s.dataFilter ) {
+			data = s.dataFilter( data, type );
+		}
+
+		// The filter can actually parse the response
+		if ( typeof data === "string" ) {
+			// Get the JavaScript object, if JSON is used.
+			if ( type === "json" || !type && ct.indexOf("json") >= 0 ) {
+				data = jQuery.parseJSON( data );
+
+			// If the type is "script", eval it in global context
+			} else if ( type === "script" || !type && ct.indexOf("javascript") >= 0 ) {
+				jQuery.globalEval( data );
+			}
+		}
+
+		return data;
+	},
+
+	// Serialize an array of form elements or a set of
+	// key/values into a query string
+	param: function( a, traditional ) {
+		var s = [];
+		
+		// Set traditional to true for jQuery <= 1.3.2 behavior.
+		if ( traditional === undefined ) {
+			traditional = jQuery.ajaxSettings.traditional;
+		}
+		
+		// If an array was passed in, assume that it is an array of form elements.
+		if ( jQuery.isArray(a) || a.jquery ) {
+			// Serialize the form elements
+			jQuery.each( a, function() {
+				add( this.name, this.value );
+			});
+			
 		} else {
-			jqXHR.readyState = 1;
-
-			// Send global event
-			if ( fireGlobals ) {
-				globalEventContext.trigger( "ajaxSend", [ jqXHR, s ] );
-			}
-
-			// If request was aborted inside ajaxSend, stop there
-			if ( state === 2 ) {
-				return jqXHR;
-			}
-
-			// Timeout
-			if ( s.async && s.timeout > 0 ) {
-				timeoutTimer = window.setTimeout( function() {
-					jqXHR.abort( "timeout" );
-				}, s.timeout );
-			}
-
-			try {
-				state = 1;
-				transport.send( requestHeaders, done );
-			} catch ( e ) {
-
-				// Propagate exception as error if not done
-				if ( state < 2 ) {
-					done( -1, e );
-
-				// Simply rethrow otherwise
+			// If traditional, encode the "old" way (the way 1.3.2 or older
+			// did it), otherwise encode params recursively.
+			for ( var prefix in a ) {
+				buildParams( prefix, a[prefix] );
+			}
+		}
+
+		// Return the resulting serialization
+		return s.join("&").replace(r20, "+");
+
+		function buildParams( prefix, obj ) {
+			if ( jQuery.isArray(obj) ) {
+				// Serialize array item.
+				jQuery.each( obj, function( i, v ) {
+					if ( traditional || /\[\]$/.test( prefix ) ) {
+						// Treat each array item as a scalar.
+						add( prefix, v );
+					} else {
+						// If array item is non-scalar (array or object), encode its
+						// numeric index to resolve deserialization ambiguity issues.
+						// Note that rack (as of 1.0.0) can't currently deserialize
+						// nested arrays properly, and attempting to do so may cause
+						// a server error. Possible fixes are to modify rack's
+						// deserialization algorithm or to provide an option or flag
+						// to force array serialization to be shallow.
+						buildParams( prefix + "[" + ( typeof v === "object" || jQuery.isArray(v) ? i : "" ) + "]", v );
+					}
+				});
+					
+			} else if ( !traditional && obj != null && typeof obj === "object" ) {
+				// Serialize object item.
+				jQuery.each( obj, function( k, v ) {
+					buildParams( prefix + "[" + k + "]", v );
+				});
+					
+			} else {
+				// Serialize scalar item.
+				add( prefix, obj );
+			}
+		}
+
+		function add( key, value ) {
+			// If value is a function, invoke it and return its value
+			value = jQuery.isFunction(value) ? value() : value;
+			s[ s.length ] = encodeURIComponent(key) + "=" + encodeURIComponent(value);
+		}
+	}
+});
+var elemdisplay = {},
+	rfxtypes = /toggle|show|hide/,
+	rfxnum = /^([+-]=)?([\d+-.]+)(.*)$/,
+	timerId,
+	fxAttrs = [
+		// height animations
+		[ "height", "marginTop", "marginBottom", "paddingTop", "paddingBottom" ],
+		// width animations
+		[ "width", "marginLeft", "marginRight", "paddingLeft", "paddingRight" ],
+		// opacity animations
+		[ "opacity" ]
+	];
+
+jQuery.fn.extend({
+	show: function( speed, callback ) {
+		if ( speed || speed === 0) {
+			return this.animate( genFx("show", 3), speed, callback);
+
+		} else {
+			for ( var i = 0, l = this.length; i < l; i++ ) {
+				var old = jQuery.data(this[i], "olddisplay");
+
+				this[i].style.display = old || "";
+
+				if ( jQuery.css(this[i], "display") === "none" ) {
+					var nodeName = this[i].nodeName, display;
+
+					if ( elemdisplay[ nodeName ] ) {
+						display = elemdisplay[ nodeName ];
+
+					} else {
+						var elem = jQuery("<" + nodeName + " />").appendTo("body");
+
+						display = elem.css("display");
+
+						if ( display === "none" ) {
+							display = "block";
+						}
+
+						elem.remove();
+
+						elemdisplay[ nodeName ] = display;
+					}
+
+					jQuery.data(this[i], "olddisplay", display);
+				}
+			}
+
+			// Set the display of the elements in a second loop
+			// to avoid the constant reflow
+			for ( var j = 0, k = this.length; j < k; j++ ) {
+				this[j].style.display = jQuery.data(this[j], "olddisplay") || "";
+			}
+
+			return this;
+		}
+	},
+
+	hide: function( speed, callback ) {
+		if ( speed || speed === 0 ) {
+			return this.animate( genFx("hide", 3), speed, callback);
+
+		} else {
+			for ( var i = 0, l = this.length; i < l; i++ ) {
+				var old = jQuery.data(this[i], "olddisplay");
+				if ( !old && old !== "none" ) {
+					jQuery.data(this[i], "olddisplay", jQuery.css(this[i], "display"));
+				}
+			}
+
+			// Set the display of the elements in a second loop
+			// to avoid the constant reflow
+			for ( var j = 0, k = this.length; j < k; j++ ) {
+				this[j].style.display = "none";
+			}
+
+			return this;
+		}
+	},
+
+	// Save the old toggle function
+	_toggle: jQuery.fn.toggle,
+
+	toggle: function( fn, fn2 ) {
+		var bool = typeof fn === "boolean";
+
+		if ( jQuery.isFunction(fn) && jQuery.isFunction(fn2) ) {
+			this._toggle.apply( this, arguments );
+
+		} else if ( fn == null || bool ) {
+			this.each(function() {
+				var state = bool ? fn : jQuery(this).is(":hidden");
+				jQuery(this)[ state ? "show" : "hide" ]();
+			});
+
+		} else {
+			this.animate(genFx("toggle", 3), fn, fn2);
+		}
+
+		return this;
+	},
+
+	fadeTo: function( speed, to, callback ) {
+		return this.filter(":hidden").css("opacity", 0).show().end()
+					.animate({opacity: to}, speed, callback);
+	},
+
+	animate: function( prop, speed, easing, callback ) {
+		var optall = jQuery.speed(speed, easing, callback);
+
+		if ( jQuery.isEmptyObject( prop ) ) {
+			return this.each( optall.complete );
+		}
+
+		return this[ optall.queue === false ? "each" : "queue" ](function() {
+			var opt = jQuery.extend({}, optall), p,
+				hidden = this.nodeType === 1 && jQuery(this).is(":hidden"),
+				self = this;
+
+			for ( p in prop ) {
+				var name = p.replace(rdashAlpha, fcamelCase);
+
+				if ( p !== name ) {
+					prop[ name ] = prop[ p ];
+					delete prop[ p ];
+					p = name;
+				}
+
+				if ( prop[p] === "hide" && hidden || prop[p] === "show" && !hidden ) {
+					return opt.complete.call(this);
+				}
+
+				if ( ( p === "height" || p === "width" ) && this.style ) {
+					// Store display property
+					opt.display = jQuery.css(this, "display");
+
+					// Make sure that nothing sneaks out
+					opt.overflow = this.style.overflow;
+				}
+
+				if ( jQuery.isArray( prop[p] ) ) {
+					// Create (if needed) and add to specialEasing
+					(opt.specialEasing = opt.specialEasing || {})[p] = prop[p][1];
+					prop[p] = prop[p][0];
+				}
+			}
+
+			if ( opt.overflow != null ) {
+				this.style.overflow = "hidden";
+			}
+
+			opt.curAnim = jQuery.extend({}, prop);
+
+			jQuery.each( prop, function( name, val ) {
+				var e = new jQuery.fx( self, opt, name );
+
+				if ( rfxtypes.test(val) ) {
+					e[ val === "toggle" ? hidden ? "show" : "hide" : val ]( prop );
+
 				} else {
-					throw e;
-				}
-			}
-		}
-
-		// Callback for when everything is done
-		function done( status, nativeStatusText, responses, headers ) {
-			var isSuccess, success, error, response, modified,
-				statusText = nativeStatusText;
-
-			// Called once
-			if ( state === 2 ) {
-				return;
-			}
-
-			// State is "done" now
-			state = 2;
-
-			// Clear timeout if it exists
-			if ( timeoutTimer ) {
-				window.clearTimeout( timeoutTimer );
-			}
-
-			// Dereference transport for early garbage collection
-			// (no matter how long the jqXHR object will be used)
-			transport = undefined;
-
-			// Cache response headers
-			responseHeadersString = headers || "";
-
-			// Set readyState
-			jqXHR.readyState = status > 0 ? 4 : 0;
-
-			// Determine if successful
-			isSuccess = status >= 200 && status < 300 || status === 304;
-
-			// Get response data
-			if ( responses ) {
-				response = ajaxHandleResponses( s, jqXHR, responses );
-			}
-
-			// Convert no matter what (that way responseXXX fields are always set)
-			response = ajaxConvert( s, response, jqXHR, isSuccess );
-
-			// If successful, handle type chaining
-			if ( isSuccess ) {
-
-				// Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
-				if ( s.ifModified ) {
-					modified = jqXHR.getResponseHeader( "Last-Modified" );
-					if ( modified ) {
-						jQuery.lastModified[ cacheURL ] = modified;
+					var parts = rfxnum.exec(val),
+						start = e.cur(true) || 0;
+
+					if ( parts ) {
+						var end = parseFloat( parts[2] ),
+							unit = parts[3] || "px";
+
+						// We need to compute starting value
+						if ( unit !== "px" ) {
+							self.style[ name ] = (end || 1) + unit;
+							start = ((end || 1) / e.cur(true)) * start;
+							self.style[ name ] = start + unit;
+						}
+
+						// If a +=/-= token was provided, we're doing a relative animation
+						if ( parts[1] ) {
+							end = ((parts[1] === "-=" ? -1 : 1) * end) + start;
+						}
+
+						e.custom( start, end, unit );
+
+					} else {
+						e.custom( start, val, "" );
 					}
-					modified = jqXHR.getResponseHeader( "etag" );
-					if ( modified ) {
-						jQuery.etag[ cacheURL ] = modified;
+				}
+			});
+
+			// For JS strict compliance
+			return true;
+		});
+	},
+
+	stop: function( clearQueue, gotoEnd ) {
+		var timers = jQuery.timers;
+
+		if ( clearQueue ) {
+			this.queue([]);
+		}
+
+		this.each(function() {
+			// go in reverse order so anything added to the queue during the loop is ignored
+			for ( var i = timers.length - 1; i >= 0; i-- ) {
+				if ( timers[i].elem === this ) {
+					if (gotoEnd) {
+						// force the next step to be the last
+						timers[i](true);
 					}
-				}
-
-				// if no content
-				if ( status === 204 || s.type === "HEAD" ) {
-					statusText = "nocontent";
-
-				// if not modified
-				} else if ( status === 304 ) {
-					statusText = "notmodified";
-
-				// If we have data, let's convert it
-				} else {
-					statusText = response.state;
-					success = response.data;
-					error = response.error;
-					isSuccess = !error;
-				}
+
+					timers.splice(i, 1);
+				}
+			}
+		});
+
+		// start the next in the queue if the last step wasn't forced
+		if ( !gotoEnd ) {
+			this.dequeue();
+		}
+
+		return this;
+	}
+
+});
+
+// Generate shortcuts for custom animations
+jQuery.each({
+	slideDown: genFx("show", 1),
+	slideUp: genFx("hide", 1),
+	slideToggle: genFx("toggle", 1),
+	fadeIn: { opacity: "show" },
+	fadeOut: { opacity: "hide" }
+}, function( name, props ) {
+	jQuery.fn[ name ] = function( speed, callback ) {
+		return this.animate( props, speed, callback );
+	};
+});
+
+jQuery.extend({
+	speed: function( speed, easing, fn ) {
+		var opt = speed && typeof speed === "object" ? speed : {
+			complete: fn || !fn && easing ||
+				jQuery.isFunction( speed ) && speed,
+			duration: speed,
+			easing: fn && easing || easing && !jQuery.isFunction(easing) && easing
+		};
+
+		opt.duration = jQuery.fx.off ? 0 : typeof opt.duration === "number" ? opt.duration :
+			jQuery.fx.speeds[opt.duration] || jQuery.fx.speeds._default;
+
+		// Queueing
+		opt.old = opt.complete;
+		opt.complete = function() {
+			if ( opt.queue !== false ) {
+				jQuery(this).dequeue();
+			}
+			if ( jQuery.isFunction( opt.old ) ) {
+				opt.old.call( this );
+			}
+		};
+
+		return opt;
+	},
+
+	easing: {
+		linear: function( p, n, firstNum, diff ) {
+			return firstNum + diff * p;
+		},
+		swing: function( p, n, firstNum, diff ) {
+			return ((-Math.cos(p*Math.PI)/2) + 0.5) * diff + firstNum;
+		}
+	},
+
+	timers: [],
+
+	fx: function( elem, options, prop ) {
+		this.options = options;
+		this.elem = elem;
+		this.prop = prop;
+
+		if ( !options.orig ) {
+			options.orig = {};
+		}
+	}
+
+});
+
+jQuery.fx.prototype = {
+	// Simple function for setting a style value
+	update: function() {
+		if ( this.options.step ) {
+			this.options.step.call( this.elem, this.now, this );
+		}
+
+		(jQuery.fx.step[this.prop] || jQuery.fx.step._default)( this );
+
+		// Set display property to block for height/width animations
+		if ( ( this.prop === "height" || this.prop === "width" ) && this.elem.style ) {
+			this.elem.style.display = "block";
+		}
+	},
+
+	// Get the current size
+	cur: function( force ) {
+		if ( this.elem[this.prop] != null && (!this.elem.style || this.elem.style[this.prop] == null) ) {
+			return this.elem[ this.prop ];
+		}
+
+		var r = parseFloat(jQuery.css(this.elem, this.prop, force));
+		return r && r > -10000 ? r : parseFloat(jQuery.curCSS(this.elem, this.prop)) || 0;
+	},
+
+	// Start an animation from one number to another
+	custom: function( from, to, unit ) {
+		this.startTime = now();
+		this.start = from;
+		this.end = to;
+		this.unit = unit || this.unit || "px";
+		this.now = this.start;
+		this.pos = this.state = 0;
+
+		var self = this;
+		function t( gotoEnd ) {
+			return self.step(gotoEnd);
+		}
+
+		t.elem = this.elem;
+
+		if ( t() && jQuery.timers.push(t) && !timerId ) {
+			timerId = setInterval(jQuery.fx.tick, 13);
+		}
+	},
+
+	// Simple 'show' function
+	show: function() {
+		// Remember where we started, so that we can go back to it later
+		this.options.orig[this.prop] = jQuery.style( this.elem, this.prop );
+		this.options.show = true;
+
+		// Begin the animation
+		// Make sure that we start at a small width/height to avoid any
+		// flash of content
+		this.custom(this.prop === "width" || this.prop === "height" ? 1 : 0, this.cur());
+
+		// Start by showing the element
+		jQuery( this.elem ).show();
+	},
+
+	// Simple 'hide' function
+	hide: function() {
+		// Remember where we started, so that we can go back to it later
+		this.options.orig[this.prop] = jQuery.style( this.elem, this.prop );
+		this.options.hide = true;
+
+		// Begin the animation
+		this.custom(this.cur(), 0);
+	},
+
+	// Each step of an animation
+	step: function( gotoEnd ) {
+		var t = now(), done = true;
+
+		if ( gotoEnd || t >= this.options.duration + this.startTime ) {
+			this.now = this.end;
+			this.pos = this.state = 1;
+			this.update();
+
+			this.options.curAnim[ this.prop ] = true;
+
+			for ( var i in this.options.curAnim ) {
+				if ( this.options.curAnim[i] !== true ) {
+					done = false;
+				}
+			}
+
+			if ( done ) {
+				if ( this.options.display != null ) {
+					// Reset the overflow
+					this.elem.style.overflow = this.options.overflow;
+
+					// Reset the display
+					var old = jQuery.data(this.elem, "olddisplay");
+					this.elem.style.display = old ? old : this.options.display;
+
+					if ( jQuery.css(this.elem, "display") === "none" ) {
+						this.elem.style.display = "block";
+					}
+				}
+
+				// Hide the element if the "hide" operation was done
+				if ( this.options.hide ) {
+					jQuery(this.elem).hide();
+				}
+
+				// Reset the properties, if the item has been hidden or shown
+				if ( this.options.hide || this.options.show ) {
+					for ( var p in this.options.curAnim ) {
+						jQuery.style(this.elem, p, this.options.orig[p]);
+					}
+				}
+
+				// Execute the complete function
+				this.options.complete.call( this.elem );
+			}
+
+			return false;
+
+		} else {
+			var n = t - this.startTime;
+			this.state = n / this.options.duration;
+
+			// Perform the easing function, defaults to swing
+			var specialEasing = this.options.specialEasing && this.options.specialEasing[this.prop];
+			var defaultEasing = this.options.easing || (jQuery.easing.swing ? "swing" : "linear");
+			this.pos = jQuery.easing[specialEasing || defaultEasing](this.state, n, 0, 1, this.options.duration);
+			this.now = this.start + ((this.end - this.start) * this.pos);
+
+			// Perform the next step of the animation
+			this.update();
+		}
+
+		return true;
+	}
+};
+
+jQuery.extend( jQuery.fx, {
+	tick: function() {
+		var timers = jQuery.timers;
+
+		for ( var i = 0; i < timers.length; i++ ) {
+			if ( !timers[i]() ) {
+				timers.splice(i--, 1);
+			}
+		}
+
+		if ( !timers.length ) {
+			jQuery.fx.stop();
+		}
+	},
+		
+	stop: function() {
+		clearInterval( timerId );
+		timerId = null;
+	},
+	
+	speeds: {
+		slow: 600,
+ 		fast: 200,
+ 		// Default speed
+ 		_default: 400
+	},
+
+	step: {
+		opacity: function( fx ) {
+			jQuery.style(fx.elem, "opacity", fx.now);
+		},
+
+		_default: function( fx ) {
+			if ( fx.elem.style && fx.elem.style[ fx.prop ] != null ) {
+				fx.elem.style[ fx.prop ] = (fx.prop === "width" || fx.prop === "height" ? Math.max(0, fx.now) : fx.now) + fx.unit;
 			} else {
-
-				// Extract error from statusText and normalize for non-aborts
-				error = statusText;
-				if ( status || !statusText ) {
-					statusText = "error";
-					if ( status < 0 ) {
-						status = 0;
-					}
-				}
-			}
-
-			// Set data for the fake xhr object
-			jqXHR.status = status;
-			jqXHR.statusText = ( nativeStatusText || statusText ) + "";
-
-			// Success/Error
-			if ( isSuccess ) {
-				deferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] );
-			} else {
-				deferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] );
-			}
-
-			// Status-dependent callbacks
-			jqXHR.statusCode( statusCode );
-			statusCode = undefined;
-
-			if ( fireGlobals ) {
-				globalEventContext.trigger( isSuccess ? "ajaxSuccess" : "ajaxError",
-					[ jqXHR, s, isSuccess ? success : error ] );
-			}
-
-			// Complete
-			completeDeferred.fireWith( callbackContext, [ jqXHR, statusText ] );
-
-			if ( fireGlobals ) {
-				globalEventContext.trigger( "ajaxComplete", [ jqXHR, s ] );
-
-				// Handle the global AJAX counter
-				if ( !( --jQuery.active ) ) {
-					jQuery.event.trigger( "ajaxStop" );
-				}
-			}
-		}
-
-		return jqXHR;
-	},
-
-	getJSON: function( url, data, callback ) {
-		return jQuery.get( url, data, callback, "json" );
-	},
-
-	getScript: function( url, callback ) {
-		return jQuery.get( url, undefined, callback, "script" );
-	}
-} );
-
-jQuery.each( [ "get", "post" ], function( i, method ) {
-	jQuery[ method ] = function( url, data, callback, type ) {
-
-		// Shift arguments if data argument was omitted
-		if ( jQuery.isFunction( data ) ) {
-			type = type || callback;
-			callback = data;
-			data = undefined;
-		}
-
-		// The url can be an options object (which then must have .url)
-		return jQuery.ajax( jQuery.extend( {
-			url: url,
-			type: method,
-			dataType: type,
-			data: data,
-			success: callback
-		}, jQuery.isPlainObject( url ) && url ) );
+				fx.elem[ fx.prop ] = fx.now;
+			}
+		}
+	}
+});
+
+if ( jQuery.expr && jQuery.expr.filters ) {
+	jQuery.expr.filters.animated = function( elem ) {
+		return jQuery.grep(jQuery.timers, function( fn ) {
+			return elem === fn.elem;
+		}).length;
 	};
-} );
-
-
-jQuery._evalUrl = function( url ) {
-	return jQuery.ajax( {
-		url: url,
-
-		// Make this explicit, since user can override this through ajaxSetup (#11264)
-		type: "GET",
-		dataType: "script",
-		async: false,
-		global: false,
-		"throws": true
-	} );
-};
-
-
-jQuery.fn.extend( {
-	wrapAll: function( html ) {
-		var wrap;
-
-		if ( jQuery.isFunction( html ) ) {
-			return this.each( function( i ) {
-				jQuery( this ).wrapAll( html.call( this, i ) );
-			} );
-		}
-
-		if ( this[ 0 ] ) {
-
-			// The elements to wrap the target around
-			wrap = jQuery( html, this[ 0 ].ownerDocument ).eq( 0 ).clone( true );
-
-			if ( this[ 0 ].parentNode ) {
-				wrap.insertBefore( this[ 0 ] );
-			}
-
-			wrap.map( function() {
-				var elem = this;
-
-				while ( elem.firstElementChild ) {
-					elem = elem.firstElementChild;
-				}
-
-				return elem;
-			} ).append( this );
-		}
-
-		return this;
-	},
-
-	wrapInner: function( html ) {
-		if ( jQuery.isFunction( html ) ) {
-			return this.each( function( i ) {
-				jQuery( this ).wrapInner( html.call( this, i ) );
-			} );
-		}
-
-		return this.each( function() {
-			var self = jQuery( this ),
-				contents = self.contents();
-
-			if ( contents.length ) {
-				contents.wrapAll( html );
-
-			} else {
-				self.append( html );
-			}
-		} );
-	},
-
-	wrap: function( html ) {
-		var isFunction = jQuery.isFunction( html );
-
-		return this.each( function( i ) {
-			jQuery( this ).wrapAll( isFunction ? html.call( this, i ) : html );
-		} );
-	},
-
-	unwrap: function() {
-		return this.parent().each( function() {
-			if ( !jQuery.nodeName( this, "body" ) ) {
-				jQuery( this ).replaceWith( this.childNodes );
-			}
-		} ).end();
-	}
-} );
-
-
-jQuery.expr.filters.hidden = function( elem ) {
-	return !jQuery.expr.filters.visible( elem );
-};
-jQuery.expr.filters.visible = function( elem ) {
-
-	// Support: Opera <= 12.12
-	// Opera reports offsetWidths and offsetHeights less than zero on some elements
-	// Use OR instead of AND as the element is not visible if either is true
-	// See tickets #10406 and #13132
-	return elem.offsetWidth > 0 || elem.offsetHeight > 0 || elem.getClientRects().length > 0;
-};
-
-
-
-
-var r20 = /%20/g,
-	rbracket = /\[\]$/,
-	rCRLF = /\r?\n/g,
-	rsubmitterTypes = /^(?:submit|button|image|reset|file)$/i,
-	rsubmittable = /^(?:input|select|textarea|keygen)/i;
-
-function buildParams( prefix, obj, traditional, add ) {
-	var name;
-
-	if ( jQuery.isArray( obj ) ) {
-
-		// Serialize array item.
-		jQuery.each( obj, function( i, v ) {
-			if ( traditional || rbracket.test( prefix ) ) {
-
-				// Treat each array item as a scalar.
-				add( prefix, v );
-
-			} else {
-
-				// Item is non-scalar (array or object), encode its numeric index.
-				buildParams(
-					prefix + "[" + ( typeof v === "object" && v != null ? i : "" ) + "]",
-					v,
-					traditional,
-					add
-				);
-			}
-		} );
-
-	} else if ( !traditional && jQuery.type( obj ) === "object" ) {
-
-		// Serialize object item.
-		for ( name in obj ) {
-			buildParams( prefix + "[" + name + "]", obj[ name ], traditional, add );
-		}
-
-	} else {
-
-		// Serialize scalar item.
-		add( prefix, obj );
-	}
 }
 
-// Serialize an array of form elements or a set of
-// key/values into a query string
-jQuery.param = function( a, traditional ) {
-	var prefix,
-		s = [],
-		add = function( key, value ) {
-
-			// If value is a function, invoke it and return its value
-			value = jQuery.isFunction( value ) ? value() : ( value == null ? "" : value );
-			s[ s.length ] = encodeURIComponent( key ) + "=" + encodeURIComponent( value );
+function genFx( type, num ) {
+	var obj = {};
+
+	jQuery.each( fxAttrs.concat.apply([], fxAttrs.slice(0,num)), function() {
+		obj[ this ] = type;
+	});
+
+	return obj;
+}
+if ( "getBoundingClientRect" in document.documentElement ) {
+	jQuery.fn.offset = function( options ) {
+		var elem = this[0];
+
+		if ( options ) { 
+			return this.each(function( i ) {
+				jQuery.offset.setOffset( this, options, i );
+			});
+		}
+
+		if ( !elem || !elem.ownerDocument ) {
+			return null;
+		}
+
+		if ( elem === elem.ownerDocument.body ) {
+			return jQuery.offset.bodyOffset( elem );
+		}
+
+		var box = elem.getBoundingClientRect(), doc = elem.ownerDocument, body = doc.body, docElem = doc.documentElement,
+			clientTop = docElem.clientTop || body.clientTop || 0, clientLeft = docElem.clientLeft || body.clientLeft || 0,
+			top  = box.top  + (self.pageYOffset || jQuery.support.boxModel && docElem.scrollTop  || body.scrollTop ) - clientTop,
+			left = box.left + (self.pageXOffset || jQuery.support.boxModel && docElem.scrollLeft || body.scrollLeft) - clientLeft;
+
+		return { top: top, left: left };
+	};
+
+} else {
+	jQuery.fn.offset = function( options ) {
+		var elem = this[0];
+
+		if ( options ) { 
+			return this.each(function( i ) {
+				jQuery.offset.setOffset( this, options, i );
+			});
+		}
+
+		if ( !elem || !elem.ownerDocument ) {
+			return null;
+		}
+
+		if ( elem === elem.ownerDocument.body ) {
+			return jQuery.offset.bodyOffset( elem );
+		}
+
+		jQuery.offset.initialize();
+
+		var offsetParent = elem.offsetParent, prevOffsetParent = elem,
+			doc = elem.ownerDocument, computedStyle, docElem = doc.documentElement,
+			body = doc.body, defaultView = doc.defaultView,
+			prevComputedStyle = defaultView ? defaultView.getComputedStyle( elem, null ) : elem.currentStyle,
+			top = elem.offsetTop, left = elem.offsetLeft;
+
+		while ( (elem = elem.parentNode) && elem !== body && elem !== docElem ) {
+			if ( jQuery.offset.supportsFixedPosition && prevComputedStyle.position === "fixed" ) {
+				break;
+			}
+
+			computedStyle = defaultView ? defaultView.getComputedStyle(elem, null) : elem.currentStyle;
+			top  -= elem.scrollTop;
+			left -= elem.scrollLeft;
+
+			if ( elem === offsetParent ) {
+				top  += elem.offsetTop;
+				left += elem.offsetLeft;
+
+				if ( jQuery.offset.doesNotAddBorder && !(jQuery.offset.doesAddBorderForTableAndCells && /^t(able|d|h)$/i.test(elem.nodeName)) ) {
+					top  += parseFloat( computedStyle.borderTopWidth  ) || 0;
+					left += parseFloat( computedStyle.borderLeftWidth ) || 0;
+				}
+
+				prevOffsetParent = offsetParent, offsetParent = elem.offsetParent;
+			}
+
+			if ( jQuery.offset.subtractsBorderForOverflowNotVisible && computedStyle.overflow !== "visible" ) {
+				top  += parseFloat( computedStyle.borderTopWidth  ) || 0;
+				left += parseFloat( computedStyle.borderLeftWidth ) || 0;
+			}
+
+			prevComputedStyle = computedStyle;
+		}
+
+		if ( prevComputedStyle.position === "relative" || prevComputedStyle.position === "static" ) {
+			top  += body.offsetTop;
+			left += body.offsetLeft;
+		}
+
+		if ( jQuery.offset.supportsFixedPosition && prevComputedStyle.position === "fixed" ) {
+			top  += Math.max( docElem.scrollTop, body.scrollTop );
+			left += Math.max( docElem.scrollLeft, body.scrollLeft );
+		}
+
+		return { top: top, left: left };
+	};
+}
+
+jQuery.offset = {
+	initialize: function() {
+		var body = document.body, container = document.createElement("div"), innerDiv, checkDiv, table, td, bodyMarginTop = parseFloat( jQuery.curCSS(body, "marginTop", true) ) || 0,
+			html = "<div style='position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;'><div></div></div><table style='position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;' cellpadding='0' cellspacing='0'><tr><td></td></tr></table>";
+
+		jQuery.extend( container.style, { position: "absolute", top: 0, left: 0, margin: 0, border: 0, width: "1px", height: "1px", visibility: "hidden" } );
+
+		container.innerHTML = html;
+		body.insertBefore( container, body.firstChild );
+		innerDiv = container.firstChild;
+		checkDiv = innerDiv.firstChild;
+		td = innerDiv.nextSibling.firstChild.firstChild;
+
+		this.doesNotAddBorder = (checkDiv.offsetTop !== 5);
+		this.doesAddBorderForTableAndCells = (td.offsetTop === 5);
+
+		checkDiv.style.position = "fixed", checkDiv.style.top = "20px";
+		// safari subtracts parent border width here which is 5px
+		this.supportsFixedPosition = (checkDiv.offsetTop === 20 || checkDiv.offsetTop === 15);
+		checkDiv.style.position = checkDiv.style.top = "";
+
+		innerDiv.style.overflow = "hidden", innerDiv.style.position = "relative";
+		this.subtractsBorderForOverflowNotVisible = (checkDiv.offsetTop === -5);
+
+		this.doesNotIncludeMarginInBodyOffset = (body.offsetTop !== bodyMarginTop);
+
+		body.removeChild( container );
+		body = container = innerDiv = checkDiv = table = td = null;
+		jQuery.offset.initialize = jQuery.noop;
+	},
+
+	bodyOffset: function( body ) {
+		var top = body.offsetTop, left = body.offsetLeft;
+
+		jQuery.offset.initialize();
+
+		if ( jQuery.offset.doesNotIncludeMarginInBodyOffset ) {
+			top  += parseFloat( jQuery.curCSS(body, "marginTop",  true) ) || 0;
+			left += parseFloat( jQuery.curCSS(body, "marginLeft", true) ) || 0;
+		}
+
+		return { top: top, left: left };
+	},
+	
+	setOffset: function( elem, options, i ) {
+		// set position first, in-case top/left are set even on static elem
+		if ( /static/.test( jQuery.curCSS( elem, "position" ) ) ) {
+			elem.style.position = "relative";
+		}
+		var curElem   = jQuery( elem ),
+			curOffset = curElem.offset(),
+			curTop    = parseInt( jQuery.curCSS( elem, "top",  true ), 10 ) || 0,
+			curLeft   = parseInt( jQuery.curCSS( elem, "left", true ), 10 ) || 0;
+
+		if ( jQuery.isFunction( options ) ) {
+			options = options.call( elem, i, curOffset );
+		}
+
+		var props = {
+			top:  (options.top  - curOffset.top)  + curTop,
+			left: (options.left - curOffset.left) + curLeft
 		};
-
-	// Set traditional to true for jQuery <= 1.3.2 behavior.
-	if ( traditional === undefined ) {
-		traditional = jQuery.ajaxSettings && jQuery.ajaxSettings.traditional;
-	}
-
-	// If an array was passed in, assume that it is an array of form elements.
-	if ( jQuery.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) {
-
-		// Serialize the form elements
-		jQuery.each( a, function() {
-			add( this.name, this.value );
-		} );
-
-	} else {
-
-		// If traditional, encode the "old" way (the way 1.3.2 or older
-		// did it), otherwise encode params recursively.
-		for ( prefix in a ) {
-			buildParams( prefix, a[ prefix ], traditional, add );
-		}
-	}
-
-	// Return the resulting serialization
-	return s.join( "&" ).replace( r20, "+" );
-};
-
-jQuery.fn.extend( {
-	serialize: function() {
-		return jQuery.param( this.serializeArray() );
-	},
-	serializeArray: function() {
-		return this.map( function() {
-
-			// Can add propHook for "elements" to filter or add form elements
-			var elements = jQuery.prop( this, "elements" );
-			return elements ? jQuery.makeArray( elements ) : this;
-		} )
-		.filter( function() {
-			var type = this.type;
-
-			// Use .is( ":disabled" ) so that fieldset[disabled] works
-			return this.name && !jQuery( this ).is( ":disabled" ) &&
-				rsubmittable.test( this.nodeName ) && !rsubmitterTypes.test( type ) &&
-				( this.checked || !rcheckableType.test( type ) );
-		} )
-		.map( function( i, elem ) {
-			var val = jQuery( this ).val();
-
-			return val == null ?
-				null :
-				jQuery.isArray( val ) ?
-					jQuery.map( val, function( val ) {
-						return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
-					} ) :
-					{ name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
-		} ).get();
-	}
-} );
-
-
-jQuery.ajaxSettings.xhr = function() {
-	try {
-		return new window.XMLHttpRequest();
-	} catch ( e ) {}
-};
-
-var xhrSuccessStatus = {
-
-		// File protocol always yields status code 0, assume 200
-		0: 200,
-
-		// Support: IE9
-		// #1450: sometimes IE returns 1223 when it should be 204
-		1223: 204
-	},
-	xhrSupported = jQuery.ajaxSettings.xhr();
-
-support.cors = !!xhrSupported && ( "withCredentials" in xhrSupported );
-support.ajax = xhrSupported = !!xhrSupported;
-
-jQuery.ajaxTransport( function( options ) {
-	var callback, errorCallback;
-
-	// Cross domain only allowed if supported through XMLHttpRequest
-	if ( support.cors || xhrSupported && !options.crossDomain ) {
-		return {
-			send: function( headers, complete ) {
-				var i,
-					xhr = options.xhr();
-
-				xhr.open(
-					options.type,
-					options.url,
-					options.async,
-					options.username,
-					options.password
-				);
-
-				// Apply custom fields if provided
-				if ( options.xhrFields ) {
-					for ( i in options.xhrFields ) {
-						xhr[ i ] = options.xhrFields[ i ];
-					}
-				}
-
-				// Override mime type if needed
-				if ( options.mimeType && xhr.overrideMimeType ) {
-					xhr.overrideMimeType( options.mimeType );
-				}
-
-				// X-Requested-With header
-				// For cross-domain requests, seeing as conditions for a preflight are
-				// akin to a jigsaw puzzle, we simply never set it to be sure.
-				// (it can always be set on a per-request basis or even using ajaxSetup)
-				// For same-domain requests, won't change header if already provided.
-				if ( !options.crossDomain && !headers[ "X-Requested-With" ] ) {
-					headers[ "X-Requested-With" ] = "XMLHttpRequest";
-				}
-
-				// Set headers
-				for ( i in headers ) {
-					xhr.setRequestHeader( i, headers[ i ] );
-				}
-
-				// Callback
-				callback = function( type ) {
-					return function() {
-						if ( callback ) {
-							callback = errorCallback = xhr.onload =
-								xhr.onerror = xhr.onabort = xhr.onreadystatechange = null;
-
-							if ( type === "abort" ) {
-								xhr.abort();
-							} else if ( type === "error" ) {
-
-								// Support: IE9
-								// On a manual native abort, IE9 throws
-								// errors on any property access that is not readyState
-								if ( typeof xhr.status !== "number" ) {
-									complete( 0, "error" );
-								} else {
-									complete(
-
-										// File: protocol always yields status 0; see #8605, #14207
-										xhr.status,
-										xhr.statusText
-									);
-								}
-							} else {
-								complete(
-									xhrSuccessStatus[ xhr.status ] || xhr.status,
-									xhr.statusText,
-
-									// Support: IE9 only
-									// IE9 has no XHR2 but throws on binary (trac-11426)
-									// For XHR2 non-text, let the caller handle it (gh-2498)
-									( xhr.responseType || "text" ) !== "text"  ||
-									typeof xhr.responseText !== "string" ?
-										{ binary: xhr.response } :
-										{ text: xhr.responseText },
-									xhr.getAllResponseHeaders()
-								);
-							}
-						}
-					};
-				};
-
-				// Listen to events
-				xhr.onload = callback();
-				errorCallback = xhr.onerror = callback( "error" );
-
-				// Support: IE9
-				// Use onreadystatechange to replace onabort
-				// to handle uncaught aborts
-				if ( xhr.onabort !== undefined ) {
-					xhr.onabort = errorCallback;
-				} else {
-					xhr.onreadystatechange = function() {
-
-						// Check readyState before timeout as it changes
-						if ( xhr.readyState === 4 ) {
-
-							// Allow onerror to be called first,
-							// but that will not handle a native abort
-							// Also, save errorCallback to a variable
-							// as xhr.onerror cannot be accessed
-							window.setTimeout( function() {
-								if ( callback ) {
-									errorCallback();
-								}
-							} );
-						}
-					};
-				}
-
-				// Create the abort callback
-				callback = callback( "abort" );
-
-				try {
-
-					// Do send the request (this may raise an exception)
-					xhr.send( options.hasContent && options.data || null );
-				} catch ( e ) {
-
-					// #14683: Only rethrow if this hasn't been notified as an error yet
-					if ( callback ) {
-						throw e;
-					}
-				}
-			},
-
-			abort: function() {
-				if ( callback ) {
-					callback();
-				}
-			}
-		};
-	}
-} );
-
-
-
-
-// Install script dataType
-jQuery.ajaxSetup( {
-	accepts: {
-		script: "text/javascript, application/javascript, " +
-			"application/ecmascript, application/x-ecmascript"
-	},
-	contents: {
-		script: /\b(?:java|ecma)script\b/
-	},
-	converters: {
-		"text script": function( text ) {
-			jQuery.globalEval( text );
-			return text;
-		}
-	}
-} );
-
-// Handle cache's special case and crossDomain
-jQuery.ajaxPrefilter( "script", function( s ) {
-	if ( s.cache === undefined ) {
-		s.cache = false;
-	}
-	if ( s.crossDomain ) {
-		s.type = "GET";
-	}
-} );
-
-// Bind script tag hack transport
-jQuery.ajaxTransport( "script", function( s ) {
-
-	// This transport only deals with cross domain requests
-	if ( s.crossDomain ) {
-		var script, callback;
-		return {
-			send: function( _, complete ) {
-				script = jQuery( "<script>" ).prop( {
-					charset: s.scriptCharset,
-					src: s.url
-				} ).on(
-					"load error",
-					callback = function( evt ) {
-						script.remove();
-						callback = null;
-						if ( evt ) {
-							complete( evt.type === "error" ? 404 : 200, evt.type );
-						}
-					}
-				);
-
-				// Use native DOM manipulation to avoid our domManip AJAX trickery
-				document.head.appendChild( script[ 0 ] );
-			},
-			abort: function() {
-				if ( callback ) {
-					callback();
-				}
-			}
-		};
-	}
-} );
-
-
-
-
-var oldCallbacks = [],
-	rjsonp = /(=)\?(?=&|$)|\?\?/;
-
-// Default jsonp settings
-jQuery.ajaxSetup( {
-	jsonp: "callback",
-	jsonpCallback: function() {
-		var callback = oldCallbacks.pop() || ( jQuery.expando + "_" + ( nonce++ ) );
-		this[ callback ] = true;
-		return callback;
-	}
-} );
-
-// Detect, normalize options and install callbacks for jsonp requests
-jQuery.ajaxPrefilter( "json jsonp", function( s, originalSettings, jqXHR ) {
-
-	var callbackName, overwritten, responseContainer,
-		jsonProp = s.jsonp !== false && ( rjsonp.test( s.url ) ?
-			"url" :
-			typeof s.data === "string" &&
-				( s.contentType || "" )
-					.indexOf( "application/x-www-form-urlencoded" ) === 0 &&
-				rjsonp.test( s.data ) && "data"
-		);
-
-	// Handle iff the expected data type is "jsonp" or we have a parameter to set
-	if ( jsonProp || s.dataTypes[ 0 ] === "jsonp" ) {
-
-		// Get callback name, remembering preexisting value associated with it
-		callbackName = s.jsonpCallback = jQuery.isFunction( s.jsonpCallback ) ?
-			s.jsonpCallback() :
-			s.jsonpCallback;
-
-		// Insert callback into url or form data
-		if ( jsonProp ) {
-			s[ jsonProp ] = s[ jsonProp ].replace( rjsonp, "$1" + callbackName );
-		} else if ( s.jsonp !== false ) {
-			s.url += ( rquery.test( s.url ) ? "&" : "?" ) + s.jsonp + "=" + callbackName;
-		}
-
-		// Use data converter to retrieve json after script execution
-		s.converters[ "script json" ] = function() {
-			if ( !responseContainer ) {
-				jQuery.error( callbackName + " was not called" );
-			}
-			return responseContainer[ 0 ];
-		};
-
-		// Force json dataType
-		s.dataTypes[ 0 ] = "json";
-
-		// Install callback
-		overwritten = window[ callbackName ];
-		window[ callbackName ] = function() {
-			responseContainer = arguments;
-		};
-
-		// Clean-up function (fires after converters)
-		jqXHR.always( function() {
-
-			// If previous value didn't exist - remove it
-			if ( overwritten === undefined ) {
-				jQuery( window ).removeProp( callbackName );
-
-			// Otherwise restore preexisting value
-			} else {
-				window[ callbackName ] = overwritten;
-			}
-
-			// Save back as free
-			if ( s[ callbackName ] ) {
-
-				// Make sure that re-using the options doesn't screw things around
-				s.jsonpCallback = originalSettings.jsonpCallback;
-
-				// Save the callback name for future use
-				oldCallbacks.push( callbackName );
-			}
-
-			// Call if it was a function and we have a response
-			if ( responseContainer && jQuery.isFunction( overwritten ) ) {
-				overwritten( responseContainer[ 0 ] );
-			}
-
-			responseContainer = overwritten = undefined;
-		} );
-
-		// Delegate to script
-		return "script";
-	}
-} );
-
-
-
-
-// Argument "data" should be string of html
-// context (optional): If specified, the fragment will be created in this context,
-// defaults to document
-// keepScripts (optional): If true, will include scripts passed in the html string
-jQuery.parseHTML = function( data, context, keepScripts ) {
-	if ( !data || typeof data !== "string" ) {
-		return null;
-	}
-	if ( typeof context === "boolean" ) {
-		keepScripts = context;
-		context = false;
-	}
-	context = context || document;
-
-	var parsed = rsingleTag.exec( data ),
-		scripts = !keepScripts && [];
-
-	// Single tag
-	if ( parsed ) {
-		return [ context.createElement( parsed[ 1 ] ) ];
-	}
-
-	parsed = buildFragment( [ data ], context, scripts );
-
-	if ( scripts && scripts.length ) {
-		jQuery( scripts ).remove();
-	}
-
-	return jQuery.merge( [], parsed.childNodes );
-};
-
-
-// Keep a copy of the old load method
-var _load = jQuery.fn.load;
-
-/**
- * Load a url into a page
- */
-jQuery.fn.load = function( url, params, callback ) {
-	if ( typeof url !== "string" && _load ) {
-		return _load.apply( this, arguments );
-	}
-
-	var selector, type, response,
-		self = this,
-		off = url.indexOf( " " );
-
-	if ( off > -1 ) {
-		selector = jQuery.trim( url.slice( off ) );
-		url = url.slice( 0, off );
-	}
-
-	// If it's a function
-	if ( jQuery.isFunction( params ) ) {
-
-		// We assume that it's the callback
-		callback = params;
-		params = undefined;
-
-	// Otherwise, build a param string
-	} else if ( params && typeof params === "object" ) {
-		type = "POST";
-	}
-
-	// If we have elements to modify, make the request
-	if ( self.length > 0 ) {
-		jQuery.ajax( {
-			url: url,
-
-			// If "type" variable is undefined, then "GET" method will be used.
-			// Make value of this field explicit since
-			// user can override it through ajaxSetup method
-			type: type || "GET",
-			dataType: "html",
-			data: params
-		} ).done( function( responseText ) {
-
-			// Save response for use in complete callback
-			response = arguments;
-
-			self.html( selector ?
-
-				// If a selector was specified, locate the right elements in a dummy div
-				// Exclude scripts to avoid IE 'Permission Denied' errors
-				jQuery( "<div>" ).append( jQuery.parseHTML( responseText ) ).find( selector ) :
-
-				// Otherwise use the full result
-				responseText );
-
-		// If the request succeeds, this function gets "data", "status", "jqXHR"
-		// but they are ignored because response was set above.
-		// If it fails, this function gets "jqXHR", "status", "error"
-		} ).always( callback && function( jqXHR, status ) {
-			self.each( function() {
-				callback.apply( this, response || [ jqXHR.responseText, status, jqXHR ] );
-			} );
-		} );
-	}
-
-	return this;
-};
-
-
-
-
-// Attach a bunch of functions for handling common AJAX events
-jQuery.each( [
-	"ajaxStart",
-	"ajaxStop",
-	"ajaxComplete",
-	"ajaxError",
-	"ajaxSuccess",
-	"ajaxSend"
-], function( i, type ) {
-	jQuery.fn[ type ] = function( fn ) {
-		return this.on( type, fn );
-	};
-} );
-
-
-
-
-jQuery.expr.filters.animated = function( elem ) {
-	return jQuery.grep( jQuery.timers, function( fn ) {
-		return elem === fn.elem;
-	} ).length;
-};
-
-
-
-
-/**
- * Gets a window from an element
- */
-function getWindow( elem ) {
-	return jQuery.isWindow( elem ) ? elem : elem.nodeType === 9 && elem.defaultView;
-}
-
-jQuery.offset = {
-	setOffset: function( elem, options, i ) {
-		var curPosition, curLeft, curCSSTop, curTop, curOffset, curCSSLeft, calculatePosition,
-			position = jQuery.css( elem, "position" ),
-			curElem = jQuery( elem ),
-			props = {};
-
-		// Set position first, in-case top/left are set even on static elem
-		if ( position === "static" ) {
-			elem.style.position = "relative";
-		}
-
-		curOffset = curElem.offset();
-		curCSSTop = jQuery.css( elem, "top" );
-		curCSSLeft = jQuery.css( elem, "left" );
-		calculatePosition = ( position === "absolute" || position === "fixed" ) &&
-			( curCSSTop + curCSSLeft ).indexOf( "auto" ) > -1;
-
-		// Need to be able to calculate position if either
-		// top or left is auto and position is either absolute or fixed
-		if ( calculatePosition ) {
-			curPosition = curElem.position();
-			curTop = curPosition.top;
-			curLeft = curPosition.left;
-
-		} else {
-			curTop = parseFloat( curCSSTop ) || 0;
-			curLeft = parseFloat( curCSSLeft ) || 0;
-		}
-
-		if ( jQuery.isFunction( options ) ) {
-
-			// Use jQuery.extend here to allow modification of coordinates argument (gh-1848)
-			options = options.call( elem, i, jQuery.extend( {}, curOffset ) );
-		}
-
-		if ( options.top != null ) {
-			props.top = ( options.top - curOffset.top ) + curTop;
-		}
-		if ( options.left != null ) {
-			props.left = ( options.left - curOffset.left ) + curLeft;
-		}
-
+		
 		if ( "using" in options ) {
 			options.using.call( elem, props );
-
 		} else {
 			curElem.css( props );
@@ -9544,271 +6088,153 @@
 };
 
-jQuery.fn.extend( {
-	offset: function( options ) {
-		if ( arguments.length ) {
-			return options === undefined ?
-				this :
-				this.each( function( i ) {
-					jQuery.offset.setOffset( this, options, i );
-				} );
-		}
-
-		var docElem, win,
-			elem = this[ 0 ],
-			box = { top: 0, left: 0 },
-			doc = elem && elem.ownerDocument;
-
-		if ( !doc ) {
-			return;
-		}
-
-		docElem = doc.documentElement;
-
-		// Make sure it's not a disconnected DOM node
-		if ( !jQuery.contains( docElem, elem ) ) {
-			return box;
-		}
-
-		box = elem.getBoundingClientRect();
-		win = getWindow( doc );
+
+jQuery.fn.extend({
+	position: function() {
+		if ( !this[0] ) {
+			return null;
+		}
+
+		var elem = this[0],
+
+		// Get *real* offsetParent
+		offsetParent = this.offsetParent(),
+
+		// Get correct offsets
+		offset       = this.offset(),
+		parentOffset = /^body|html$/i.test(offsetParent[0].nodeName) ? { top: 0, left: 0 } : offsetParent.offset();
+
+		// Subtract element margins
+		// note: when an element has margin: auto the offsetLeft and marginLeft
+		// are the same in Safari causing offset.left to incorrectly be 0
+		offset.top  -= parseFloat( jQuery.curCSS(elem, "marginTop",  true) ) || 0;
+		offset.left -= parseFloat( jQuery.curCSS(elem, "marginLeft", true) ) || 0;
+
+		// Add offsetParent borders
+		parentOffset.top  += parseFloat( jQuery.curCSS(offsetParent[0], "borderTopWidth",  true) ) || 0;
+		parentOffset.left += parseFloat( jQuery.curCSS(offsetParent[0], "borderLeftWidth", true) ) || 0;
+
+		// Subtract the two offsets
 		return {
-			top: box.top + win.pageYOffset - docElem.clientTop,
-			left: box.left + win.pageXOffset - docElem.clientLeft
+			top:  offset.top  - parentOffset.top,
+			left: offset.left - parentOffset.left
 		};
 	},
 
-	position: function() {
-		if ( !this[ 0 ] ) {
-			return;
-		}
-
-		var offsetParent, offset,
-			elem = this[ 0 ],
-			parentOffset = { top: 0, left: 0 };
-
-		// Fixed elements are offset from window (parentOffset = {top:0, left: 0},
-		// because it is its only offset parent
-		if ( jQuery.css( elem, "position" ) === "fixed" ) {
-
-			// Assume getBoundingClientRect is there when computed position is fixed
-			offset = elem.getBoundingClientRect();
-
+	offsetParent: function() {
+		return this.map(function() {
+			var offsetParent = this.offsetParent || document.body;
+			while ( offsetParent && (!/^body|html$/i.test(offsetParent.nodeName) && jQuery.css(offsetParent, "position") === "static") ) {
+				offsetParent = offsetParent.offsetParent;
+			}
+			return offsetParent;
+		});
+	}
+});
+
+
+// Create scrollLeft and scrollTop methods
+jQuery.each( ["Left", "Top"], function( i, name ) {
+	var method = "scroll" + name;
+
+	jQuery.fn[ method ] = function(val) {
+		var elem = this[0], win;
+		
+		if ( !elem ) {
+			return null;
+		}
+
+		if ( val !== undefined ) {
+			// Set the scroll offset
+			return this.each(function() {
+				win = getWindow( this );
+
+				if ( win ) {
+					win.scrollTo(
+						!i ? val : jQuery(win).scrollLeft(),
+						 i ? val : jQuery(win).scrollTop()
+					);
+
+				} else {
+					this[ method ] = val;
+				}
+			});
 		} else {
-
-			// Get *real* offsetParent
-			offsetParent = this.offsetParent();
-
-			// Get correct offsets
-			offset = this.offset();
-			if ( !jQuery.nodeName( offsetParent[ 0 ], "html" ) ) {
-				parentOffset = offsetParent.offset();
-			}
-
-			// Add offsetParent borders
-			parentOffset.top += jQuery.css( offsetParent[ 0 ], "borderTopWidth", true );
-			parentOffset.left += jQuery.css( offsetParent[ 0 ], "borderLeftWidth", true );
-		}
-
-		// Subtract parent offsets and element margins
-		return {
-			top: offset.top - parentOffset.top - jQuery.css( elem, "marginTop", true ),
-			left: offset.left - parentOffset.left - jQuery.css( elem, "marginLeft", true )
-		};
-	},
-
-	// This method will return documentElement in the following cases:
-	// 1) For the element inside the iframe without offsetParent, this method will return
-	//    documentElement of the parent window
-	// 2) For the hidden or detached element
-	// 3) For body or html element, i.e. in case of the html node - it will return itself
-	//
-	// but those exceptions were never presented as a real life use-cases
-	// and might be considered as more preferable results.
-	//
-	// This logic, however, is not guaranteed and can change at any point in the future
-	offsetParent: function() {
-		return this.map( function() {
-			var offsetParent = this.offsetParent;
-
-			while ( offsetParent && jQuery.css( offsetParent, "position" ) === "static" ) {
-				offsetParent = offsetParent.offsetParent;
-			}
-
-			return offsetParent || documentElement;
-		} );
-	}
-} );
-
-// Create scrollLeft and scrollTop methods
-jQuery.each( { scrollLeft: "pageXOffset", scrollTop: "pageYOffset" }, function( method, prop ) {
-	var top = "pageYOffset" === prop;
-
-	jQuery.fn[ method ] = function( val ) {
-		return access( this, function( elem, method, val ) {
-			var win = getWindow( elem );
-
-			if ( val === undefined ) {
-				return win ? win[ prop ] : elem[ method ];
-			}
-
-			if ( win ) {
-				win.scrollTo(
-					!top ? val : win.pageXOffset,
-					top ? val : win.pageYOffset
-				);
-
-			} else {
-				elem[ method ] = val;
-			}
-		}, method, val, arguments.length );
+			win = getWindow( elem );
+
+			// Return the scroll offset
+			return win ? ("pageXOffset" in win) ? win[ i ? "pageYOffset" : "pageXOffset" ] :
+				jQuery.support.boxModel && win.document.documentElement[ method ] ||
+					win.document.body[ method ] :
+				elem[ method ];
+		}
 	};
-} );
-
-// Support: Safari<7-8+, Chrome<37-44+
-// Add the top/left cssHooks using jQuery.fn.position
-// Webkit bug: https://bugs.webkit.org/show_bug.cgi?id=29084
-// Blink bug: https://code.google.com/p/chromium/issues/detail?id=229280
-// getComputedStyle returns percent when specified for top/left/bottom/right;
-// rather than make the css module depend on the offset module, just check for it here
-jQuery.each( [ "top", "left" ], function( i, prop ) {
-	jQuery.cssHooks[ prop ] = addGetHookIf( support.pixelPosition,
-		function( elem, computed ) {
-			if ( computed ) {
-				computed = curCSS( elem, prop );
-
-				// If curCSS returns percentage, fallback to offset
-				return rnumnonpx.test( computed ) ?
-					jQuery( elem ).position()[ prop ] + "px" :
-					computed;
-			}
-		}
-	);
-} );
-
-
-// Create innerHeight, innerWidth, height, width, outerHeight and outerWidth methods
-jQuery.each( { Height: "height", Width: "width" }, function( name, type ) {
-	jQuery.each( { padding: "inner" + name, content: type, "": "outer" + name },
-		function( defaultExtra, funcName ) {
-
-		// Margin is only for outerHeight, outerWidth
-		jQuery.fn[ funcName ] = function( margin, value ) {
-			var chainable = arguments.length && ( defaultExtra || typeof margin !== "boolean" ),
-				extra = defaultExtra || ( margin === true || value === true ? "margin" : "border" );
-
-			return access( this, function( elem, type, value ) {
-				var doc;
-
-				if ( jQuery.isWindow( elem ) ) {
-
-					// As of 5/8/2012 this will yield incorrect results for Mobile Safari, but there
-					// isn't a whole lot we can do. See pull request at this URL for discussion:
-					// https://github.com/jquery/jquery/pull/764
-					return elem.document.documentElement[ "client" + name ];
-				}
-
-				// Get document width or height
-				if ( elem.nodeType === 9 ) {
-					doc = elem.documentElement;
-
-					// Either scroll[Width/Height] or offset[Width/Height] or client[Width/Height],
-					// whichever is greatest
-					return Math.max(
-						elem.body[ "scroll" + name ], doc[ "scroll" + name ],
-						elem.body[ "offset" + name ], doc[ "offset" + name ],
-						doc[ "client" + name ]
-					);
-				}
-
-				return value === undefined ?
-
-					// Get width or height on the element, requesting but not forcing parseFloat
-					jQuery.css( elem, type, extra ) :
-
-					// Set width or height on the element
-					jQuery.style( elem, type, value, extra );
-			}, type, chainable ? margin : undefined, chainable, null );
-		};
-	} );
-} );
-
-
-jQuery.fn.extend( {
-
-	bind: function( types, data, fn ) {
-		return this.on( types, null, data, fn );
-	},
-	unbind: function( types, fn ) {
-		return this.off( types, null, fn );
-	},
-
-	delegate: function( selector, types, data, fn ) {
-		return this.on( types, selector, data, fn );
-	},
-	undelegate: function( selector, types, fn ) {
-
-		// ( namespace ) or ( selector, types [, fn] )
-		return arguments.length === 1 ?
-			this.off( selector, "**" ) :
-			this.off( types, selector || "**", fn );
-	},
-	size: function() {
-		return this.length;
-	}
-} );
-
-jQuery.fn.andSelf = jQuery.fn.addBack;
-
-
-
-
-// Register as a named AMD module, since jQuery can be concatenated with other
-// files that may use define, but not via a proper concatenation script that
-// understands anonymous AMD modules. A named AMD is safest and most robust
-// way to register. Lowercase jquery is used because AMD module names are
-// derived from file names, and jQuery is normally delivered in a lowercase
-// file name. Do this after creating the global so that if an AMD module wants
-// to call noConflict to hide this version of jQuery, it will work.
-
-// Note that for maximum portability, libraries that are not jQuery should
-// declare themselves as anonymous modules, and avoid setting a global if an
-// AMD loader is present. jQuery is a special case. For more information, see
-// https://github.com/jrburke/requirejs/wiki/Updating-existing-libraries#wiki-anon
-
-if ( typeof define === "function" && define.amd ) {
-	define( "jquery", [], function() {
-		return jQuery;
-	} );
+});
+
+function getWindow( elem ) {
+	return ("scrollTo" in elem && elem.document) ?
+		elem :
+		elem.nodeType === 9 ?
+			elem.defaultView || elem.parentWindow :
+			false;
 }
-
-
-
-var
-
-	// Map over jQuery in case of overwrite
-	_jQuery = window.jQuery,
-
-	// Map over the $ in case of overwrite
-	_$ = window.$;
-
-jQuery.noConflict = function( deep ) {
-	if ( window.$ === jQuery ) {
-		window.$ = _$;
-	}
-
-	if ( deep && window.jQuery === jQuery ) {
-		window.jQuery = _jQuery;
-	}
-
-	return jQuery;
-};
-
-// Expose jQuery and $ identifiers, even in AMD
-// (#7102#comment:10, https://github.com/jquery/jquery/pull/557)
-// and CommonJS for browser emulators (#13566)
-if ( !noGlobal ) {
-	window.jQuery = window.$ = jQuery;
-}
-
-return jQuery;
-}));
+// Create innerHeight, innerWidth, outerHeight and outerWidth methods
+jQuery.each([ "Height", "Width" ], function( i, name ) {
+
+	var type = name.toLowerCase();
+
+	// innerHeight and innerWidth
+	jQuery.fn["inner" + name] = function() {
+		return this[0] ?
+			jQuery.css( this[0], type, false, "padding" ) :
+			null;
+	};
+
+	// outerHeight and outerWidth
+	jQuery.fn["outer" + name] = function( margin ) {
+		return this[0] ?
+			jQuery.css( this[0], type, false, margin ? "margin" : "border" ) :
+			null;
+	};
+
+	jQuery.fn[ type ] = function( size ) {
+		// Get window width or height
+		var elem = this[0];
+		if ( !elem ) {
+			return size == null ? null : this;
+		}
+		
+		if ( jQuery.isFunction( size ) ) {
+			return this.each(function( i ) {
+				var self = jQuery( this );
+				self[ type ]( size.call( this, i, self[ type ]() ) );
+			});
+		}
+
+		return ("scrollTo" in elem && elem.document) ? // does it walk and quack like a window?
+			// Everyone else use document.documentElement or document.body depending on Quirks vs Standards mode
+			elem.document.compatMode === "CSS1Compat" && elem.document.documentElement[ "client" + name ] ||
+			elem.document.body[ "client" + name ] :
+
+			// Get document width or height
+			(elem.nodeType === 9) ? // is it a document
+				// Either scroll[Width/Height] or offset[Width/Height], whichever is greater
+				Math.max(
+					elem.documentElement["client" + name],
+					elem.body["scroll" + name], elem.documentElement["scroll" + name],
+					elem.body["offset" + name], elem.documentElement["offset" + name]
+				) :
+
+				// Get or set width or height on the element
+				size === undefined ?
+					// Get width or height on the element
+					jQuery.css( elem, type ) :
+
+					// Set the width or height on the element (default to pixels if value is unitless)
+					this.css( type, typeof size === "string" ? size : size + "px" );
+	};
+
+});
+// Expose jQuery to the global object
+window.jQuery = window.$ = jQuery;
+
+})(window);
Index: admin/js/jquery/jquery.magnific-popup.js
===================================================================
--- admin/js/jquery/jquery.magnific-popup.js	(revision 3368)
+++ 	(revision )
@@ -1,1860 +1,0 @@
-/*! Magnific Popup - v1.1.0 - 2016-02-20
-* http://dimsemenov.com/plugins/magnific-popup/
-* Copyright (c) 2016 Dmitry Semenov; */
-;(function (factory) {
-if (typeof define === 'function' && define.amd) {
- // AMD. Register as an anonymous module.
- define(['jquery'], factory);
- } else if (typeof exports === 'object') {
- // Node/CommonJS
- factory(require('jquery'));
- } else {
- // Browser globals
- factory(window.jQuery || window.Zepto);
- }
- }(function($) {
-
-/*>>core*/
-/**
- *
- * Magnific Popup Core JS file
- *
- */
-
-
-/**
- * Private static constants
- */
-var CLOSE_EVENT = 'Close',
-	BEFORE_CLOSE_EVENT = 'BeforeClose',
-	AFTER_CLOSE_EVENT = 'AfterClose',
-	BEFORE_APPEND_EVENT = 'BeforeAppend',
-	MARKUP_PARSE_EVENT = 'MarkupParse',
-	OPEN_EVENT = 'Open',
-	CHANGE_EVENT = 'Change',
-	NS = 'mfp',
-	EVENT_NS = '.' + NS,
-	READY_CLASS = 'mfp-ready',
-	REMOVING_CLASS = 'mfp-removing',
-	PREVENT_CLOSE_CLASS = 'mfp-prevent-close';
-
-
-/**
- * Private vars
- */
-/*jshint -W079 */
-var mfp, // As we have only one instance of MagnificPopup object, we define it locally to not to use 'this'
-	MagnificPopup = function(){},
-	_isJQ = !!(window.jQuery),
-	_prevStatus,
-	_window = $(window),
-	_document,
-	_prevContentType,
-	_wrapClasses,
-	_currPopupType;
-
-
-/**
- * Private functions
- */
-var _mfpOn = function(name, f) {
-		mfp.ev.on(NS + name + EVENT_NS, f);
-	},
-	_getEl = function(className, appendTo, html, raw) {
-		var el = document.createElement('div');
-		el.className = 'mfp-'+className;
-		if(html) {
-			el.innerHTML = html;
-		}
-		if(!raw) {
-			el = $(el);
-			if(appendTo) {
-				el.appendTo(appendTo);
-			}
-		} else if(appendTo) {
-			appendTo.appendChild(el);
-		}
-		return el;
-	},
-	_mfpTrigger = function(e, data) {
-		mfp.ev.triggerHandler(NS + e, data);
-
-		if(mfp.st.callbacks) {
-			// converts "mfpEventName" to "eventName" callback and triggers it if it's present
-			e = e.charAt(0).toLowerCase() + e.slice(1);
-			if(mfp.st.callbacks[e]) {
-				mfp.st.callbacks[e].apply(mfp, $.isArray(data) ? data : [data]);
-			}
-		}
-	},
-	_getCloseBtn = function(type) {
-		if(type !== _currPopupType || !mfp.currTemplate.closeBtn) {
-			mfp.currTemplate.closeBtn = $( mfp.st.closeMarkup.replace('%title%', mfp.st.tClose ) );
-			_currPopupType = type;
-		}
-		return mfp.currTemplate.closeBtn;
-	},
-	// Initialize Magnific Popup only when called at least once
-	_checkInstance = function() {
-		if(!$.magnificPopup.instance) {
-			/*jshint -W020 */
-			mfp = new MagnificPopup();
-			mfp.init();
-			$.magnificPopup.instance = mfp;
-		}
-	},
-	// CSS transition detection, http://stackoverflow.com/questions/7264899/detect-css-transitions-using-javascript-and-without-modernizr
-	supportsTransitions = function() {
-		var s = document.createElement('p').style, // 's' for style. better to create an element if body yet to exist
-			v = ['ms','O','Moz','Webkit']; // 'v' for vendor
-
-		if( s['transition'] !== undefined ) {
-			return true;
-		}
-
-		while( v.length ) {
-			if( v.pop() + 'Transition' in s ) {
-				return true;
-			}
-		}
-
-		return false;
-	};
-
-
-
-/**
- * Public functions
- */
-MagnificPopup.prototype = {
-
-	constructor: MagnificPopup,
-
-	/**
-	 * Initializes Magnific Popup plugin.
-	 * This function is triggered only once when $.fn.magnificPopup or $.magnificPopup is executed
-	 */
-	init: function() {
-		var appVersion = navigator.appVersion;
-		mfp.isLowIE = mfp.isIE8 = document.all && !document.addEventListener;
-		mfp.isAndroid = (/android/gi).test(appVersion);
-		mfp.isIOS = (/iphone|ipad|ipod/gi).test(appVersion);
-		mfp.supportsTransition = supportsTransitions();
-
-		// We disable fixed positioned lightbox on devices that don't handle it nicely.
-		// If you know a better way of detecting this - let me know.
-		mfp.probablyMobile = (mfp.isAndroid || mfp.isIOS || /(Opera Mini)|Kindle|webOS|BlackBerry|(Opera Mobi)|(Windows Phone)|IEMobile/i.test(navigator.userAgent) );
-		_document = $(document);
-
-		mfp.popupsCache = {};
-	},
-
-	/**
-	 * Opens popup
-	 * @param  data [description]
-	 */
-	open: function(data) {
-
-		var i;
-
-		if(data.isObj === false) {
-			// convert jQuery collection to array to avoid conflicts later
-			mfp.items = data.items.toArray();
-
-			mfp.index = 0;
-			var items = data.items,
-				item;
-			for(i = 0; i < items.length; i++) {
-				item = items[i];
-				if(item.parsed) {
-					item = item.el[0];
-				}
-				if(item === data.el[0]) {
-					mfp.index = i;
-					break;
-				}
-			}
-		} else {
-			mfp.items = $.isArray(data.items) ? data.items : [data.items];
-			mfp.index = data.index || 0;
-		}
-
-		// if popup is already opened - we just update the content
-		if(mfp.isOpen) {
-			mfp.updateItemHTML();
-			return;
-		}
-
-		mfp.types = [];
-		_wrapClasses = '';
-		if(data.mainEl && data.mainEl.length) {
-			mfp.ev = data.mainEl.eq(0);
-		} else {
-			mfp.ev = _document;
-		}
-
-		if(data.key) {
-			if(!mfp.popupsCache[data.key]) {
-				mfp.popupsCache[data.key] = {};
-			}
-			mfp.currTemplate = mfp.popupsCache[data.key];
-		} else {
-			mfp.currTemplate = {};
-		}
-
-
-
-		mfp.st = $.extend(true, {}, $.magnificPopup.defaults, data );
-		mfp.fixedContentPos = mfp.st.fixedContentPos === 'auto' ? !mfp.probablyMobile : mfp.st.fixedContentPos;
-
-		if(mfp.st.modal) {
-			mfp.st.closeOnContentClick = false;
-			mfp.st.closeOnBgClick = false;
-			mfp.st.showCloseBtn = false;
-			mfp.st.enableEscapeKey = false;
-		}
-
-
-		// Building markup
-		// main containers are created only once
-		if(!mfp.bgOverlay) {
-
-			// Dark overlay
-			mfp.bgOverlay = _getEl('bg').on('click'+EVENT_NS, function() {
-				mfp.close();
-			});
-
-			mfp.wrap = _getEl('wrap').attr('tabindex', -1).on('click'+EVENT_NS, function(e) {
-				if(mfp._checkIfClose(e.target)) {
-					mfp.close();
-				}
-			});
-
-			mfp.container = _getEl('container', mfp.wrap);
-		}
-
-		mfp.contentContainer = _getEl('content');
-		if(mfp.st.preloader) {
-			mfp.preloader = _getEl('preloader', mfp.container, mfp.st.tLoading);
-		}
-
-
-		// Initializing modules
-		var modules = $.magnificPopup.modules;
-		for(i = 0; i < modules.length; i++) {
-			var n = modules[i];
-			n = n.charAt(0).toUpperCase() + n.slice(1);
-			mfp['init'+n].call(mfp);
-		}
-		_mfpTrigger('BeforeOpen');
-
-
-		if(mfp.st.showCloseBtn) {
-			// Close button
-			if(!mfp.st.closeBtnInside) {
-				mfp.wrap.append( _getCloseBtn() );
-			} else {
-				_mfpOn(MARKUP_PARSE_EVENT, function(e, template, values, item) {
-					values.close_replaceWith = _getCloseBtn(item.type);
-				});
-				_wrapClasses += ' mfp-close-btn-in';
-			}
-		}
-
-		if(mfp.st.alignTop) {
-			_wrapClasses += ' mfp-align-top';
-		}
-
-
-
-		if(mfp.fixedContentPos) {
-			mfp.wrap.css({
-				overflow: mfp.st.overflowY,
-				overflowX: 'hidden',
-				overflowY: mfp.st.overflowY
-			});
-		} else {
-			mfp.wrap.css({
-				top: _window.scrollTop(),
-				position: 'absolute'
-			});
-		}
-		if( mfp.st.fixedBgPos === false || (mfp.st.fixedBgPos === 'auto' && !mfp.fixedContentPos) ) {
-			mfp.bgOverlay.css({
-				height: _document.height(),
-				position: 'absolute'
-			});
-		}
-
-
-
-		if(mfp.st.enableEscapeKey) {
-			// Close on ESC key
-			_document.on('keyup' + EVENT_NS, function(e) {
-				if(e.keyCode === 27) {
-					mfp.close();
-				}
-			});
-		}
-
-		_window.on('resize' + EVENT_NS, function() {
-			mfp.updateSize();
-		});
-
-
-		if(!mfp.st.closeOnContentClick) {
-			_wrapClasses += ' mfp-auto-cursor';
-		}
-
-		if(_wrapClasses)
-			mfp.wrap.addClass(_wrapClasses);
-
-
-		// this triggers recalculation of layout, so we get it once to not to trigger twice
-		var windowHeight = mfp.wH = _window.height();
-
-
-		var windowStyles = {};
-
-		if( mfp.fixedContentPos ) {
-            if(mfp._hasScrollBar(windowHeight)){
-                var s = mfp._getScrollbarSize();
-                if(s) {
-                    windowStyles.marginRight = s;
-                }
-            }
-        }
-
-		if(mfp.fixedContentPos) {
-			if(!mfp.isIE7) {
-				windowStyles.overflow = 'hidden';
-			} else {
-				// ie7 double-scroll bug
-				$('body, html').css('overflow', 'hidden');
-			}
-		}
-
-
-
-		var classesToadd = mfp.st.mainClass;
-		if(mfp.isIE7) {
-			classesToadd += ' mfp-ie7';
-		}
-		if(classesToadd) {
-			mfp._addClassToMFP( classesToadd );
-		}
-
-		// add content
-		mfp.updateItemHTML();
-
-		_mfpTrigger('BuildControls');
-
-		// remove scrollbar, add margin e.t.c
-		$('html').css(windowStyles);
-
-		// add everything to DOM
-		mfp.bgOverlay.add(mfp.wrap).prependTo( mfp.st.prependTo || $(document.body) );
-
-		// Save last focused element
-		mfp._lastFocusedEl = document.activeElement;
-
-		// Wait for next cycle to allow CSS transition
-		setTimeout(function() {
-
-			if(mfp.content) {
-				mfp._addClassToMFP(READY_CLASS);
-				mfp._setFocus();
-			} else {
-				// if content is not defined (not loaded e.t.c) we add class only for BG
-				mfp.bgOverlay.addClass(READY_CLASS);
-			}
-
-			// Trap the focus in popup
-			_document.on('focusin' + EVENT_NS, mfp._onFocusIn);
-
-		}, 16);
-
-		mfp.isOpen = true;
-		mfp.updateSize(windowHeight);
-		_mfpTrigger(OPEN_EVENT);
-
-		return data;
-	},
-
-	/**
-	 * Closes the popup
-	 */
-	close: function() {
-		if(!mfp.isOpen) return;
-		_mfpTrigger(BEFORE_CLOSE_EVENT);
-
-		mfp.isOpen = false;
-		// for CSS3 animation
-		if(mfp.st.removalDelay && !mfp.isLowIE && mfp.supportsTransition )  {
-			mfp._addClassToMFP(REMOVING_CLASS);
-			setTimeout(function() {
-				mfp._close();
-			}, mfp.st.removalDelay);
-		} else {
-			mfp._close();
-		}
-	},
-
-	/**
-	 * Helper for close() function
-	 */
-	_close: function() {
-		_mfpTrigger(CLOSE_EVENT);
-
-		var classesToRemove = REMOVING_CLASS + ' ' + READY_CLASS + ' ';
-
-		mfp.bgOverlay.detach();
-		mfp.wrap.detach();
-		mfp.container.empty();
-
-		if(mfp.st.mainClass) {
-			classesToRemove += mfp.st.mainClass + ' ';
-		}
-
-		mfp._removeClassFromMFP(classesToRemove);
-
-		if(mfp.fixedContentPos) {
-			var windowStyles = {marginRight: ''};
-			if(mfp.isIE7) {
-				$('body, html').css('overflow', '');
-			} else {
-				windowStyles.overflow = '';
-			}
-			$('html').css(windowStyles);
-		}
-
-		_document.off('keyup' + EVENT_NS + ' focusin' + EVENT_NS);
-		mfp.ev.off(EVENT_NS);
-
-		// clean up DOM elements that aren't removed
-		mfp.wrap.attr('class', 'mfp-wrap').removeAttr('style');
-		mfp.bgOverlay.attr('class', 'mfp-bg');
-		mfp.container.attr('class', 'mfp-container');
-
-		// remove close button from target element
-		if(mfp.st.showCloseBtn &&
-		(!mfp.st.closeBtnInside || mfp.currTemplate[mfp.currItem.type] === true)) {
-			if(mfp.currTemplate.closeBtn)
-				mfp.currTemplate.closeBtn.detach();
-		}
-
-
-		if(mfp.st.autoFocusLast && mfp._lastFocusedEl) {
-			$(mfp._lastFocusedEl).focus(); // put tab focus back
-		}
-		mfp.currItem = null;
-		mfp.content = null;
-		mfp.currTemplate = null;
-		mfp.prevHeight = 0;
-
-		_mfpTrigger(AFTER_CLOSE_EVENT);
-	},
-
-	updateSize: function(winHeight) {
-
-		if(mfp.isIOS) {
-			// fixes iOS nav bars https://github.com/dimsemenov/Magnific-Popup/issues/2
-			var zoomLevel = document.documentElement.clientWidth / window.innerWidth;
-			var height = window.innerHeight * zoomLevel;
-			mfp.wrap.css('height', height);
-			mfp.wH = height;
-		} else {
-			mfp.wH = winHeight || _window.height();
-		}
-		// Fixes #84: popup incorrectly positioned with position:relative on body
-		if(!mfp.fixedContentPos) {
-			mfp.wrap.css('height', mfp.wH);
-		}
-
-		_mfpTrigger('Resize');
-
-	},
-
-	/**
-	 * Set content of popup based on current index
-	 */
-	updateItemHTML: function() {
-		var item = mfp.items[mfp.index];
-
-		// Detach and perform modifications
-		mfp.contentContainer.detach();
-
-		if(mfp.content)
-			mfp.content.detach();
-
-		if(!item.parsed) {
-			item = mfp.parseEl( mfp.index );
-		}
-
-		var type = item.type;
-
-		_mfpTrigger('BeforeChange', [mfp.currItem ? mfp.currItem.type : '', type]);
-		// BeforeChange event works like so:
-		// _mfpOn('BeforeChange', function(e, prevType, newType) { });
-
-		mfp.currItem = item;
-
-		if(!mfp.currTemplate[type]) {
-			var markup = mfp.st[type] ? mfp.st[type].markup : false;
-
-			// allows to modify markup
-			_mfpTrigger('FirstMarkupParse', markup);
-
-			if(markup) {
-				mfp.currTemplate[type] = $(markup);
-			} else {
-				// if there is no markup found we just define that template is parsed
-				mfp.currTemplate[type] = true;
-			}
-		}
-
-		if(_prevContentType && _prevContentType !== item.type) {
-			mfp.container.removeClass('mfp-'+_prevContentType+'-holder');
-		}
-
-		var newContent = mfp['get' + type.charAt(0).toUpperCase() + type.slice(1)](item, mfp.currTemplate[type]);
-		mfp.appendContent(newContent, type);
-
-		item.preloaded = true;
-
-		_mfpTrigger(CHANGE_EVENT, item);
-		_prevContentType = item.type;
-
-		// Append container back after its content changed
-		mfp.container.prepend(mfp.contentContainer);
-
-		_mfpTrigger('AfterChange');
-	},
-
-
-	/**
-	 * Set HTML content of popup
-	 */
-	appendContent: function(newContent, type) {
-		mfp.content = newContent;
-
-		if(newContent) {
-			if(mfp.st.showCloseBtn && mfp.st.closeBtnInside &&
-				mfp.currTemplate[type] === true) {
-				// if there is no markup, we just append close button element inside
-				if(!mfp.content.find('.mfp-close').length) {
-					mfp.content.append(_getCloseBtn());
-				}
-			} else {
-				mfp.content = newContent;
-			}
-		} else {
-			mfp.content = '';
-		}
-
-		_mfpTrigger(BEFORE_APPEND_EVENT);
-		mfp.container.addClass('mfp-'+type+'-holder');
-
-		mfp.contentContainer.append(mfp.content);
-	},
-
-
-	/**
-	 * Creates Magnific Popup data object based on given data
-	 * @param  {int} index Index of item to parse
-	 */
-	parseEl: function(index) {
-		var item = mfp.items[index],
-			type;
-
-		if(item.tagName) {
-			item = { el: $(item) };
-		} else {
-			type = item.type;
-			item = { data: item, src: item.src };
-		}
-
-		if(item.el) {
-			var types = mfp.types;
-
-			// check for 'mfp-TYPE' class
-			for(var i = 0; i < types.length; i++) {
-				if( item.el.hasClass('mfp-'+types[i]) ) {
-					type = types[i];
-					break;
-				}
-			}
-
-			item.src = item.el.attr('data-mfp-src');
-			if(!item.src) {
-				item.src = item.el.attr('href');
-			}
-		}
-
-		item.type = type || mfp.st.type || 'inline';
-		item.index = index;
-		item.parsed = true;
-		mfp.items[index] = item;
-		_mfpTrigger('ElementParse', item);
-
-		return mfp.items[index];
-	},
-
-
-	/**
-	 * Initializes single popup or a group of popups
-	 */
-	addGroup: function(el, options) {
-		var eHandler = function(e) {
-			e.mfpEl = this;
-			mfp._openClick(e, el, options);
-		};
-
-		if(!options) {
-			options = {};
-		}
-
-		var eName = 'click.magnificPopup';
-		options.mainEl = el;
-
-		if(options.items) {
-			options.isObj = true;
-			el.off(eName).on(eName, eHandler);
-		} else {
-			options.isObj = false;
-			if(options.delegate) {
-				el.off(eName).on(eName, options.delegate , eHandler);
-			} else {
-				options.items = el;
-				el.off(eName).on(eName, eHandler);
-			}
-		}
-	},
-	_openClick: function(e, el, options) {
-		var midClick = options.midClick !== undefined ? options.midClick : $.magnificPopup.defaults.midClick;
-
-
-		if(!midClick && ( e.which === 2 || e.ctrlKey || e.metaKey || e.altKey || e.shiftKey ) ) {
-			return;
-		}
-
-		var disableOn = options.disableOn !== undefined ? options.disableOn : $.magnificPopup.defaults.disableOn;
-
-		if(disableOn) {
-			if($.isFunction(disableOn)) {
-				if( !disableOn.call(mfp) ) {
-					return true;
-				}
-			} else { // else it's number
-				if( _window.width() < disableOn ) {
-					return true;
-				}
-			}
-		}
-
-		if(e.type) {
-			e.preventDefault();
-
-			// This will prevent popup from closing if element is inside and popup is already opened
-			if(mfp.isOpen) {
-				e.stopPropagation();
-			}
-		}
-
-		options.el = $(e.mfpEl);
-		if(options.delegate) {
-			options.items = el.find(options.delegate);
-		}
-		mfp.open(options);
-	},
-
-
-	/**
-	 * Updates text on preloader
-	 */
-	updateStatus: function(status, text) {
-
-		if(mfp.preloader) {
-			if(_prevStatus !== status) {
-				mfp.container.removeClass('mfp-s-'+_prevStatus);
-			}
-
-			if(!text && status === 'loading') {
-				text = mfp.st.tLoading;
-			}
-
-			var data = {
-				status: status,
-				text: text
-			};
-			// allows to modify status
-			_mfpTrigger('UpdateStatus', data);
-
-			status = data.status;
-			text = data.text;
-
-			mfp.preloader.html(text);
-
-			mfp.preloader.find('a').on('click', function(e) {
-				e.stopImmediatePropagation();
-			});
-
-			mfp.container.addClass('mfp-s-'+status);
-			_prevStatus = status;
-		}
-	},
-
-
-	/*
-		"Private" helpers that aren't private at all
-	 */
-	// Check to close popup or not
-	// "target" is an element that was clicked
-	_checkIfClose: function(target) {
-
-		if($(target).hasClass(PREVENT_CLOSE_CLASS)) {
-			return;
-		}
-
-		var closeOnContent = mfp.st.closeOnContentClick;
-		var closeOnBg = mfp.st.closeOnBgClick;
-
-		if(closeOnContent && closeOnBg) {
-			return true;
-		} else {
-
-			// We close the popup if click is on close button or on preloader. Or if there is no content.
-			if(!mfp.content || $(target).hasClass('mfp-close') || (mfp.preloader && target === mfp.preloader[0]) ) {
-				return true;
-			}
-
-			// if click is outside the content
-			if(  (target !== mfp.content[0] && !$.contains(mfp.content[0], target))  ) {
-				if(closeOnBg) {
-					// last check, if the clicked element is in DOM, (in case it's removed onclick)
-					if( $.contains(document, target) ) {
-						return true;
-					}
-				}
-			} else if(closeOnContent) {
-				return true;
-			}
-
-		}
-		return false;
-	},
-	_addClassToMFP: function(cName) {
-		mfp.bgOverlay.addClass(cName);
-		mfp.wrap.addClass(cName);
-	},
-	_removeClassFromMFP: function(cName) {
-		this.bgOverlay.removeClass(cName);
-		mfp.wrap.removeClass(cName);
-	},
-	_hasScrollBar: function(winHeight) {
-		return (  (mfp.isIE7 ? _document.height() : document.body.scrollHeight) > (winHeight || _window.height()) );
-	},
-	_setFocus: function() {
-		(mfp.st.focus ? mfp.content.find(mfp.st.focus).eq(0) : mfp.wrap).focus();
-	},
-	_onFocusIn: function(e) {
-		if( e.target !== mfp.wrap[0] && !$.contains(mfp.wrap[0], e.target) ) {
-			mfp._setFocus();
-			return false;
-		}
-	},
-	_parseMarkup: function(template, values, item) {
-		var arr;
-		if(item.data) {
-			values = $.extend(item.data, values);
-		}
-		_mfpTrigger(MARKUP_PARSE_EVENT, [template, values, item] );
-
-		$.each(values, function(key, value) {
-			if(value === undefined || value === false) {
-				return true;
-			}
-			arr = key.split('_');
-			if(arr.length > 1) {
-				var el = template.find(EVENT_NS + '-'+arr[0]);
-
-				if(el.length > 0) {
-					var attr = arr[1];
-					if(attr === 'replaceWith') {
-						if(el[0] !== value[0]) {
-							el.replaceWith(value);
-						}
-					} else if(attr === 'img') {
-						if(el.is('img')) {
-							el.attr('src', value);
-						} else {
-							el.replaceWith( $('<img>').attr('src', value).attr('class', el.attr('class')) );
-						}
-					} else {
-						el.attr(arr[1], value);
-					}
-				}
-
-			} else {
-				template.find(EVENT_NS + '-'+key).html(value);
-			}
-		});
-	},
-
-	_getScrollbarSize: function() {
-		// thx David
-		if(mfp.scrollbarSize === undefined) {
-			var scrollDiv = document.createElement("div");
-			scrollDiv.style.cssText = 'width: 99px; height: 99px; overflow: scroll; position: absolute; top: -9999px;';
-			document.body.appendChild(scrollDiv);
-			mfp.scrollbarSize = scrollDiv.offsetWidth - scrollDiv.clientWidth;
-			document.body.removeChild(scrollDiv);
-		}
-		return mfp.scrollbarSize;
-	}
-
-}; /* MagnificPopup core prototype end */
-
-
-
-
-/**
- * Public static functions
- */
-$.magnificPopup = {
-	instance: null,
-	proto: MagnificPopup.prototype,
-	modules: [],
-
-	open: function(options, index) {
-		_checkInstance();
-
-		if(!options) {
-			options = {};
-		} else {
-			options = $.extend(true, {}, options);
-		}
-
-		options.isObj = true;
-		options.index = index || 0;
-		return this.instance.open(options);
-	},
-
-	close: function() {
-		return $.magnificPopup.instance && $.magnificPopup.instance.close();
-	},
-
-	registerModule: function(name, module) {
-		if(module.options) {
-			$.magnificPopup.defaults[name] = module.options;
-		}
-		$.extend(this.proto, module.proto);
-		this.modules.push(name);
-	},
-
-	defaults: {
-
-		// Info about options is in docs:
-		// http://dimsemenov.com/plugins/magnific-popup/documentation.html#options
-
-		disableOn: 0,
-
-		key: null,
-
-		midClick: false,
-
-		mainClass: '',
-
-		preloader: true,
-
-		focus: '', // CSS selector of input to focus after popup is opened
-
-		closeOnContentClick: false,
-
-		closeOnBgClick: true,
-
-		closeBtnInside: true,
-
-		showCloseBtn: true,
-
-		enableEscapeKey: true,
-
-		modal: false,
-
-		alignTop: false,
-
-		removalDelay: 0,
-
-		prependTo: null,
-
-		fixedContentPos: 'auto',
-
-		fixedBgPos: 'auto',
-
-		overflowY: 'auto',
-
-		closeMarkup: '<button title="%title%" type="button" class="mfp-close">&#215;</button>',
-
-		tClose: 'Close (Esc)',
-
-		tLoading: 'Loading...',
-
-		autoFocusLast: true
-
-	}
-};
-
-
-
-$.fn.magnificPopup = function(options) {
-	_checkInstance();
-
-	var jqEl = $(this);
-
-	// We call some API method of first param is a string
-	if (typeof options === "string" ) {
-
-		if(options === 'open') {
-			var items,
-				itemOpts = _isJQ ? jqEl.data('magnificPopup') : jqEl[0].magnificPopup,
-				index = parseInt(arguments[1], 10) || 0;
-
-			if(itemOpts.items) {
-				items = itemOpts.items[index];
-			} else {
-				items = jqEl;
-				if(itemOpts.delegate) {
-					items = items.find(itemOpts.delegate);
-				}
-				items = items.eq( index );
-			}
-			mfp._openClick({mfpEl:items}, jqEl, itemOpts);
-		} else {
-			if(mfp.isOpen)
-				mfp[options].apply(mfp, Array.prototype.slice.call(arguments, 1));
-		}
-
-	} else {
-		// clone options obj
-		options = $.extend(true, {}, options);
-
-		/*
-		 * As Zepto doesn't support .data() method for objects
-		 * and it works only in normal browsers
-		 * we assign "options" object directly to the DOM element. FTW!
-		 */
-		if(_isJQ) {
-			jqEl.data('magnificPopup', options);
-		} else {
-			jqEl[0].magnificPopup = options;
-		}
-
-		mfp.addGroup(jqEl, options);
-
-	}
-	return jqEl;
-};
-
-/*>>core*/
-
-/*>>inline*/
-
-var INLINE_NS = 'inline',
-	_hiddenClass,
-	_inlinePlaceholder,
-	_lastInlineElement,
-	_putInlineElementsBack = function() {
-		if(_lastInlineElement) {
-			_inlinePlaceholder.after( _lastInlineElement.addClass(_hiddenClass) ).detach();
-			_lastInlineElement = null;
-		}
-	};
-
-$.magnificPopup.registerModule(INLINE_NS, {
-	options: {
-		hiddenClass: 'hide', // will be appended with `mfp-` prefix
-		markup: '',
-		tNotFound: 'Content not found'
-	},
-	proto: {
-
-		initInline: function() {
-			mfp.types.push(INLINE_NS);
-
-			_mfpOn(CLOSE_EVENT+'.'+INLINE_NS, function() {
-				_putInlineElementsBack();
-			});
-		},
-
-		getInline: function(item, template) {
-
-			_putInlineElementsBack();
-
-			if(item.src) {
-				var inlineSt = mfp.st.inline,
-					el = $(item.src);
-
-				if(el.length) {
-
-					// If target element has parent - we replace it with placeholder and put it back after popup is closed
-					var parent = el[0].parentNode;
-					if(parent && parent.tagName) {
-						if(!_inlinePlaceholder) {
-							_hiddenClass = inlineSt.hiddenClass;
-							_inlinePlaceholder = _getEl(_hiddenClass);
-							_hiddenClass = 'mfp-'+_hiddenClass;
-						}
-						// replace target inline element with placeholder
-						_lastInlineElement = el.after(_inlinePlaceholder).detach().removeClass(_hiddenClass);
-					}
-
-					mfp.updateStatus('ready');
-				} else {
-					mfp.updateStatus('error', inlineSt.tNotFound);
-					el = $('<div>');
-				}
-
-				item.inlineElement = el;
-				return el;
-			}
-
-			mfp.updateStatus('ready');
-			mfp._parseMarkup(template, {}, item);
-			return template;
-		}
-	}
-});
-
-/*>>inline*/
-
-/*>>ajax*/
-var AJAX_NS = 'ajax',
-	_ajaxCur,
-	_removeAjaxCursor = function() {
-		if(_ajaxCur) {
-			$(document.body).removeClass(_ajaxCur);
-		}
-	},
-	_destroyAjaxRequest = function() {
-		_removeAjaxCursor();
-		if(mfp.req) {
-			mfp.req.abort();
-		}
-	};
-
-$.magnificPopup.registerModule(AJAX_NS, {
-
-	options: {
-		settings: null,
-		cursor: 'mfp-ajax-cur',
-		tError: '<a href="%url%">The content</a> could not be loaded.'
-	},
-
-	proto: {
-		initAjax: function() {
-			mfp.types.push(AJAX_NS);
-			_ajaxCur = mfp.st.ajax.cursor;
-
-			_mfpOn(CLOSE_EVENT+'.'+AJAX_NS, _destroyAjaxRequest);
-			_mfpOn('BeforeChange.' + AJAX_NS, _destroyAjaxRequest);
-		},
-		getAjax: function(item) {
-
-			if(_ajaxCur) {
-				$(document.body).addClass(_ajaxCur);
-			}
-
-			mfp.updateStatus('loading');
-
-			var opts = $.extend({
-				url: item.src,
-				success: function(data, textStatus, jqXHR) {
-					var temp = {
-						data:data,
-						xhr:jqXHR
-					};
-
-					_mfpTrigger('ParseAjax', temp);
-
-					mfp.appendContent( $(temp.data), AJAX_NS );
-
-					item.finished = true;
-
-					_removeAjaxCursor();
-
-					mfp._setFocus();
-
-					setTimeout(function() {
-						mfp.wrap.addClass(READY_CLASS);
-					}, 16);
-
-					mfp.updateStatus('ready');
-
-					_mfpTrigger('AjaxContentAdded');
-				},
-				error: function() {
-					_removeAjaxCursor();
-					item.finished = item.loadError = true;
-					mfp.updateStatus('error', mfp.st.ajax.tError.replace('%url%', item.src));
-				}
-			}, mfp.st.ajax.settings);
-
-			mfp.req = $.ajax(opts);
-
-			return '';
-		}
-	}
-});
-
-/*>>ajax*/
-
-/*>>image*/
-var _imgInterval,
-	_getTitle = function(item) {
-		if(item.data && item.data.title !== undefined)
-			return item.data.title;
-
-		var src = mfp.st.image.titleSrc;
-
-		if(src) {
-			if($.isFunction(src)) {
-				return src.call(mfp, item);
-			} else if(item.el) {
-				return item.el.attr(src) || '';
-			}
-		}
-		return '';
-	};
-
-$.magnificPopup.registerModule('image', {
-
-	options: {
-		markup: '<div class="mfp-figure">'+
-					'<div class="mfp-close"></div>'+
-					'<figure>'+
-						'<div class="mfp-img"></div>'+
-						'<figcaption>'+
-							'<div class="mfp-bottom-bar">'+
-								'<div class="mfp-title"></div>'+
-								'<div class="mfp-counter"></div>'+
-							'</div>'+
-						'</figcaption>'+
-					'</figure>'+
-				'</div>',
-		cursor: 'mfp-zoom-out-cur',
-		titleSrc: 'title',
-		verticalFit: true,
-		tError: '<a href="%url%">The image</a> could not be loaded.'
-	},
-
-	proto: {
-		initImage: function() {
-			var imgSt = mfp.st.image,
-				ns = '.image';
-
-			mfp.types.push('image');
-
-			_mfpOn(OPEN_EVENT+ns, function() {
-				if(mfp.currItem.type === 'image' && imgSt.cursor) {
-					$(document.body).addClass(imgSt.cursor);
-				}
-			});
-
-			_mfpOn(CLOSE_EVENT+ns, function() {
-				if(imgSt.cursor) {
-					$(document.body).removeClass(imgSt.cursor);
-				}
-				_window.off('resize' + EVENT_NS);
-			});
-
-			_mfpOn('Resize'+ns, mfp.resizeImage);
-			if(mfp.isLowIE) {
-				_mfpOn('AfterChange', mfp.resizeImage);
-			}
-		},
-		resizeImage: function() {
-			var item = mfp.currItem;
-			if(!item || !item.img) return;
-
-			if(mfp.st.image.verticalFit) {
-				var decr = 0;
-				// fix box-sizing in ie7/8
-				if(mfp.isLowIE) {
-					decr = parseInt(item.img.css('padding-top'), 10) + parseInt(item.img.css('padding-bottom'),10);
-				}
-				item.img.css('max-height', mfp.wH-decr);
-			}
-		},
-		_onImageHasSize: function(item) {
-			if(item.img) {
-
-				item.hasSize = true;
-
-				if(_imgInterval) {
-					clearInterval(_imgInterval);
-				}
-
-				item.isCheckingImgSize = false;
-
-				_mfpTrigger('ImageHasSize', item);
-
-				if(item.imgHidden) {
-					if(mfp.content)
-						mfp.content.removeClass('mfp-loading');
-
-					item.imgHidden = false;
-				}
-
-			}
-		},
-
-		/**
-		 * Function that loops until the image has size to display elements that rely on it asap
-		 */
-		findImageSize: function(item) {
-
-			var counter = 0,
-				img = item.img[0],
-				mfpSetInterval = function(delay) {
-
-					if(_imgInterval) {
-						clearInterval(_imgInterval);
-					}
-					// decelerating interval that checks for size of an image
-					_imgInterval = setInterval(function() {
-						if(img.naturalWidth > 0) {
-							mfp._onImageHasSize(item);
-							return;
-						}
-
-						if(counter > 200) {
-							clearInterval(_imgInterval);
-						}
-
-						counter++;
-						if(counter === 3) {
-							mfpSetInterval(10);
-						} else if(counter === 40) {
-							mfpSetInterval(50);
-						} else if(counter === 100) {
-							mfpSetInterval(500);
-						}
-					}, delay);
-				};
-
-			mfpSetInterval(1);
-		},
-
-		getImage: function(item, template) {
-
-			var guard = 0,
-
-				// image load complete handler
-				onLoadComplete = function() {
-					if(item) {
-						if (item.img[0].complete) {
-							item.img.off('.mfploader');
-
-							if(item === mfp.currItem){
-								mfp._onImageHasSize(item);
-
-								mfp.updateStatus('ready');
-							}
-
-							item.hasSize = true;
-							item.loaded = true;
-
-							_mfpTrigger('ImageLoadComplete');
-
-						}
-						else {
-							// if image complete check fails 200 times (20 sec), we assume that there was an error.
-							guard++;
-							if(guard < 200) {
-								setTimeout(onLoadComplete,100);
-							} else {
-								onLoadError();
-							}
-						}
-					}
-				},
-
-				// image error handler
-				onLoadError = function() {
-					if(item) {
-						item.img.off('.mfploader');
-						if(item === mfp.currItem){
-							mfp._onImageHasSize(item);
-							mfp.updateStatus('error', imgSt.tError.replace('%url%', item.src) );
-						}
-
-						item.hasSize = true;
-						item.loaded = true;
-						item.loadError = true;
-					}
-				},
-				imgSt = mfp.st.image;
-
-
-			var el = template.find('.mfp-img');
-			if(el.length) {
-				var img = document.createElement('img');
-				img.className = 'mfp-img';
-				if(item.el && item.el.find('img').length) {
-					img.alt = item.el.find('img').attr('alt');
-				}
-				item.img = $(img).on('load.mfploader', onLoadComplete).on('error.mfploader', onLoadError);
-				img.src = item.src;
-
-				// without clone() "error" event is not firing when IMG is replaced by new IMG
-				// TODO: find a way to avoid such cloning
-				if(el.is('img')) {
-					item.img = item.img.clone();
-				}
-
-				img = item.img[0];
-				if(img.naturalWidth > 0) {
-					item.hasSize = true;
-				} else if(!img.width) {
-					item.hasSize = false;
-				}
-			}
-
-			mfp._parseMarkup(template, {
-				title: _getTitle(item),
-				img_replaceWith: item.img
-			}, item);
-
-			mfp.resizeImage();
-
-			if(item.hasSize) {
-				if(_imgInterval) clearInterval(_imgInterval);
-
-				if(item.loadError) {
-					template.addClass('mfp-loading');
-					mfp.updateStatus('error', imgSt.tError.replace('%url%', item.src) );
-				} else {
-					template.removeClass('mfp-loading');
-					mfp.updateStatus('ready');
-				}
-				return template;
-			}
-
-			mfp.updateStatus('loading');
-			item.loading = true;
-
-			if(!item.hasSize) {
-				item.imgHidden = true;
-				template.addClass('mfp-loading');
-				mfp.findImageSize(item);
-			}
-
-			return template;
-		}
-	}
-});
-
-/*>>image*/
-
-/*>>zoom*/
-var hasMozTransform,
-	getHasMozTransform = function() {
-		if(hasMozTransform === undefined) {
-			hasMozTransform = document.createElement('p').style.MozTransform !== undefined;
-		}
-		return hasMozTransform;
-	};
-
-$.magnificPopup.registerModule('zoom', {
-
-	options: {
-		enabled: false,
-		easing: 'ease-in-out',
-		duration: 300,
-		opener: function(element) {
-			return element.is('img') ? element : element.find('img');
-		}
-	},
-
-	proto: {
-
-		initZoom: function() {
-			var zoomSt = mfp.st.zoom,
-				ns = '.zoom',
-				image;
-
-			if(!zoomSt.enabled || !mfp.supportsTransition) {
-				return;
-			}
-
-			var duration = zoomSt.duration,
-				getElToAnimate = function(image) {
-					var newImg = image.clone().removeAttr('style').removeAttr('class').addClass('mfp-animated-image'),
-						transition = 'all '+(zoomSt.duration/1000)+'s ' + zoomSt.easing,
-						cssObj = {
-							position: 'fixed',
-							zIndex: 9999,
-							left: 0,
-							top: 0,
-							'-webkit-backface-visibility': 'hidden'
-						},
-						t = 'transition';
-
-					cssObj['-webkit-'+t] = cssObj['-moz-'+t] = cssObj['-o-'+t] = cssObj[t] = transition;
-
-					newImg.css(cssObj);
-					return newImg;
-				},
-				showMainContent = function() {
-					mfp.content.css('visibility', 'visible');
-				},
-				openTimeout,
-				animatedImg;
-
-			_mfpOn('BuildControls'+ns, function() {
-				if(mfp._allowZoom()) {
-
-					clearTimeout(openTimeout);
-					mfp.content.css('visibility', 'hidden');
-
-					// Basically, all code below does is clones existing image, puts in on top of the current one and animated it
-
-					image = mfp._getItemToZoom();
-
-					if(!image) {
-						showMainContent();
-						return;
-					}
-
-					animatedImg = getElToAnimate(image);
-
-					animatedImg.css( mfp._getOffset() );
-
-					mfp.wrap.append(animatedImg);
-
-					openTimeout = setTimeout(function() {
-						animatedImg.css( mfp._getOffset( true ) );
-						openTimeout = setTimeout(function() {
-
-							showMainContent();
-
-							setTimeout(function() {
-								animatedImg.remove();
-								image = animatedImg = null;
-								_mfpTrigger('ZoomAnimationEnded');
-							}, 16); // avoid blink when switching images
-
-						}, duration); // this timeout equals animation duration
-
-					}, 16); // by adding this timeout we avoid short glitch at the beginning of animation
-
-
-					// Lots of timeouts...
-				}
-			});
-			_mfpOn(BEFORE_CLOSE_EVENT+ns, function() {
-				if(mfp._allowZoom()) {
-
-					clearTimeout(openTimeout);
-
-					mfp.st.removalDelay = duration;
-
-					if(!image) {
-						image = mfp._getItemToZoom();
-						if(!image) {
-							return;
-						}
-						animatedImg = getElToAnimate(image);
-					}
-
-					animatedImg.css( mfp._getOffset(true) );
-					mfp.wrap.append(animatedImg);
-					mfp.content.css('visibility', 'hidden');
-
-					setTimeout(function() {
-						animatedImg.css( mfp._getOffset() );
-					}, 16);
-				}
-
-			});
-
-			_mfpOn(CLOSE_EVENT+ns, function() {
-				if(mfp._allowZoom()) {
-					showMainContent();
-					if(animatedImg) {
-						animatedImg.remove();
-					}
-					image = null;
-				}
-			});
-		},
-
-		_allowZoom: function() {
-			return mfp.currItem.type === 'image';
-		},
-
-		_getItemToZoom: function() {
-			if(mfp.currItem.hasSize) {
-				return mfp.currItem.img;
-			} else {
-				return false;
-			}
-		},
-
-		// Get element postion relative to viewport
-		_getOffset: function(isLarge) {
-			var el;
-			if(isLarge) {
-				el = mfp.currItem.img;
-			} else {
-				el = mfp.st.zoom.opener(mfp.currItem.el || mfp.currItem);
-			}
-
-			var offset = el.offset();
-			var paddingTop = parseInt(el.css('padding-top'),10);
-			var paddingBottom = parseInt(el.css('padding-bottom'),10);
-			offset.top -= ( $(window).scrollTop() - paddingTop );
-
-
-			/*
-
-			Animating left + top + width/height looks glitchy in Firefox, but perfect in Chrome. And vice-versa.
-
-			 */
-			var obj = {
-				width: el.width(),
-				// fix Zepto height+padding issue
-				height: (_isJQ ? el.innerHeight() : el[0].offsetHeight) - paddingBottom - paddingTop
-			};
-
-			// I hate to do this, but there is no another option
-			if( getHasMozTransform() ) {
-				obj['-moz-transform'] = obj['transform'] = 'translate(' + offset.left + 'px,' + offset.top + 'px)';
-			} else {
-				obj.left = offset.left;
-				obj.top = offset.top;
-			}
-			return obj;
-		}
-
-	}
-});
-
-
-
-/*>>zoom*/
-
-/*>>iframe*/
-
-var IFRAME_NS = 'iframe',
-	_emptyPage = '//about:blank',
-
-	_fixIframeBugs = function(isShowing) {
-		if(mfp.currTemplate[IFRAME_NS]) {
-			var el = mfp.currTemplate[IFRAME_NS].find('iframe');
-			if(el.length) {
-				// reset src after the popup is closed to avoid "video keeps playing after popup is closed" bug
-				if(!isShowing) {
-					el[0].src = _emptyPage;
-				}
-
-				// IE8 black screen bug fix
-				if(mfp.isIE8) {
-					el.css('display', isShowing ? 'block' : 'none');
-				}
-			}
-		}
-	};
-
-$.magnificPopup.registerModule(IFRAME_NS, {
-
-	options: {
-		markup: '<div class="mfp-iframe-scaler">'+
-					'<div class="mfp-close"></div>'+
-					'<iframe class="mfp-iframe" src="//about:blank" frameborder="0" allowfullscreen></iframe>'+
-				'</div>',
-
-		srcAction: 'iframe_src',
-
-		// we don't care and support only one default type of URL by default
-		patterns: {
-			youtube: {
-				index: 'youtube.com',
-				id: 'v=',
-				src: '//www.youtube.com/embed/%id%?autoplay=1'
-			},
-			vimeo: {
-				index: 'vimeo.com/',
-				id: '/',
-				src: '//player.vimeo.com/video/%id%?autoplay=1'
-			},
-			gmaps: {
-				index: '//maps.google.',
-				src: '%id%&output=embed'
-			}
-		}
-	},
-
-	proto: {
-		initIframe: function() {
-			mfp.types.push(IFRAME_NS);
-
-			_mfpOn('BeforeChange', function(e, prevType, newType) {
-				if(prevType !== newType) {
-					if(prevType === IFRAME_NS) {
-						_fixIframeBugs(); // iframe if removed
-					} else if(newType === IFRAME_NS) {
-						_fixIframeBugs(true); // iframe is showing
-					}
-				}// else {
-					// iframe source is switched, don't do anything
-				//}
-			});
-
-			_mfpOn(CLOSE_EVENT + '.' + IFRAME_NS, function() {
-				_fixIframeBugs();
-			});
-		},
-
-		getIframe: function(item, template) {
-			var embedSrc = item.src;
-			var iframeSt = mfp.st.iframe;
-
-			$.each(iframeSt.patterns, function() {
-				if(embedSrc.indexOf( this.index ) > -1) {
-					if(this.id) {
-						if(typeof this.id === 'string') {
-							embedSrc = embedSrc.substr(embedSrc.lastIndexOf(this.id)+this.id.length, embedSrc.length);
-						} else {
-							embedSrc = this.id.call( this, embedSrc );
-						}
-					}
-					embedSrc = this.src.replace('%id%', embedSrc );
-					return false; // break;
-				}
-			});
-
-			var dataObj = {};
-			if(iframeSt.srcAction) {
-				dataObj[iframeSt.srcAction] = embedSrc;
-			}
-			mfp._parseMarkup(template, dataObj, item);
-
-			mfp.updateStatus('ready');
-
-			return template;
-		}
-	}
-});
-
-
-
-/*>>iframe*/
-
-/*>>gallery*/
-/**
- * Get looped index depending on number of slides
- */
-var _getLoopedId = function(index) {
-		var numSlides = mfp.items.length;
-		if(index > numSlides - 1) {
-			return index - numSlides;
-		} else  if(index < 0) {
-			return numSlides + index;
-		}
-		return index;
-	},
-	_replaceCurrTotal = function(text, curr, total) {
-		return text.replace(/%curr%/gi, curr + 1).replace(/%total%/gi, total);
-	};
-
-$.magnificPopup.registerModule('gallery', {
-
-	options: {
-		enabled: false,
-		arrowMarkup: '<button title="%title%" type="button" class="mfp-arrow mfp-arrow-%dir%"></button>',
-		preload: [0,2],
-		navigateByImgClick: true,
-		arrows: true,
-
-		tPrev: 'Previous (Left arrow key)',
-		tNext: 'Next (Right arrow key)',
-		tCounter: '%curr% of %total%'
-	},
-
-	proto: {
-		initGallery: function() {
-
-			var gSt = mfp.st.gallery,
-				ns = '.mfp-gallery';
-
-			mfp.direction = true; // true - next, false - prev
-
-			if(!gSt || !gSt.enabled ) return false;
-
-			_wrapClasses += ' mfp-gallery';
-
-			_mfpOn(OPEN_EVENT+ns, function() {
-
-				if(gSt.navigateByImgClick) {
-					mfp.wrap.on('click'+ns, '.mfp-img', function() {
-						if(mfp.items.length > 1) {
-							mfp.next();
-							return false;
-						}
-					});
-				}
-
-				_document.on('keydown'+ns, function(e) {
-					if (e.keyCode === 37) {
-						mfp.prev();
-					} else if (e.keyCode === 39) {
-						mfp.next();
-					}
-				});
-			});
-
-			_mfpOn('UpdateStatus'+ns, function(e, data) {
-				if(data.text) {
-					data.text = _replaceCurrTotal(data.text, mfp.currItem.index, mfp.items.length);
-				}
-			});
-
-			_mfpOn(MARKUP_PARSE_EVENT+ns, function(e, element, values, item) {
-				var l = mfp.items.length;
-				values.counter = l > 1 ? _replaceCurrTotal(gSt.tCounter, item.index, l) : '';
-			});
-
-			_mfpOn('BuildControls' + ns, function() {
-				if(mfp.items.length > 1 && gSt.arrows && !mfp.arrowLeft) {
-					var markup = gSt.arrowMarkup,
-						arrowLeft = mfp.arrowLeft = $( markup.replace(/%title%/gi, gSt.tPrev).replace(/%dir%/gi, 'left') ).addClass(PREVENT_CLOSE_CLASS),
-						arrowRight = mfp.arrowRight = $( markup.replace(/%title%/gi, gSt.tNext).replace(/%dir%/gi, 'right') ).addClass(PREVENT_CLOSE_CLASS);
-
-					arrowLeft.click(function() {
-						mfp.prev();
-					});
-					arrowRight.click(function() {
-						mfp.next();
-					});
-
-					mfp.container.append(arrowLeft.add(arrowRight));
-				}
-			});
-
-			_mfpOn(CHANGE_EVENT+ns, function() {
-				if(mfp._preloadTimeout) clearTimeout(mfp._preloadTimeout);
-
-				mfp._preloadTimeout = setTimeout(function() {
-					mfp.preloadNearbyImages();
-					mfp._preloadTimeout = null;
-				}, 16);
-			});
-
-
-			_mfpOn(CLOSE_EVENT+ns, function() {
-				_document.off(ns);
-				mfp.wrap.off('click'+ns);
-				mfp.arrowRight = mfp.arrowLeft = null;
-			});
-
-		},
-		next: function() {
-			mfp.direction = true;
-			mfp.index = _getLoopedId(mfp.index + 1);
-			mfp.updateItemHTML();
-		},
-		prev: function() {
-			mfp.direction = false;
-			mfp.index = _getLoopedId(mfp.index - 1);
-			mfp.updateItemHTML();
-		},
-		goTo: function(newIndex) {
-			mfp.direction = (newIndex >= mfp.index);
-			mfp.index = newIndex;
-			mfp.updateItemHTML();
-		},
-		preloadNearbyImages: function() {
-			var p = mfp.st.gallery.preload,
-				preloadBefore = Math.min(p[0], mfp.items.length),
-				preloadAfter = Math.min(p[1], mfp.items.length),
-				i;
-
-			for(i = 1; i <= (mfp.direction ? preloadAfter : preloadBefore); i++) {
-				mfp._preloadItem(mfp.index+i);
-			}
-			for(i = 1; i <= (mfp.direction ? preloadBefore : preloadAfter); i++) {
-				mfp._preloadItem(mfp.index-i);
-			}
-		},
-		_preloadItem: function(index) {
-			index = _getLoopedId(index);
-
-			if(mfp.items[index].preloaded) {
-				return;
-			}
-
-			var item = mfp.items[index];
-			if(!item.parsed) {
-				item = mfp.parseEl( index );
-			}
-
-			_mfpTrigger('LazyLoad', item);
-
-			if(item.type === 'image') {
-				item.img = $('<img class="mfp-img" />').on('load.mfploader', function() {
-					item.hasSize = true;
-				}).on('error.mfploader', function() {
-					item.hasSize = true;
-					item.loadError = true;
-					_mfpTrigger('LazyLoadError', item);
-				}).attr('src', item.src);
-			}
-
-
-			item.preloaded = true;
-		}
-	}
-});
-
-/*>>gallery*/
-
-/*>>retina*/
-
-var RETINA_NS = 'retina';
-
-$.magnificPopup.registerModule(RETINA_NS, {
-	options: {
-		replaceSrc: function(item) {
-			return item.src.replace(/\.\w+$/, function(m) { return '@2x' + m; });
-		},
-		ratio: 1 // Function or number.  Set to 1 to disable.
-	},
-	proto: {
-		initRetina: function() {
-			if(window.devicePixelRatio > 1) {
-
-				var st = mfp.st.retina,
-					ratio = st.ratio;
-
-				ratio = !isNaN(ratio) ? ratio : ratio();
-
-				if(ratio > 1) {
-					_mfpOn('ImageHasSize' + '.' + RETINA_NS, function(e, item) {
-						item.img.css({
-							'max-width': item.img[0].naturalWidth / ratio,
-							'width': '100%'
-						});
-					});
-					_mfpOn('ElementParse' + '.' + RETINA_NS, function(e, item) {
-						item.src = st.replaceSrc(item, ratio);
-					});
-				}
-			}
-
-		}
-	}
-});
-
-/*>>retina*/
- _checkInstance(); }));
Index: admin/js/jquery/jquery.mjs.nestedSortable.js
===================================================================
--- admin/js/jquery/jquery.mjs.nestedSortable.js	(revision 1532)
+++ 	(revision )
@@ -1,429 +1,0 @@
-/*
- * jQuery UI Nested Sortable
- * v 1.3.5 / 21 jun 2012
- * http://mjsarfatti.com/code/nestedSortable
- *
- * Depends on:
- *	 jquery.ui.sortable.js 1.8+
- *
- * Copyright (c) 2010-2012 Manuele J Sarfatti
- * Licensed under the MIT License
- * http://www.opensource.org/licenses/mit-license.php
- */
-
-(function($) {
-
-	$.widget("mjs.nestedSortable", $.extend({}, $.ui.sortable.prototype, {
-
-		options: {
-			tabSize: 20,
-			disableNesting: 'mjs-nestedSortable-no-nesting',
-			errorClass: 'mjs-nestedSortable-error',
-			doNotClear: false,
-			listType: 'ol',
-			maxLevels: 0,
-			protectRoot: false,
-			rootID: null,
-			rtl: false,
-			isAllowed: function(item, parent) { return true; }
-		},
-
-		_create: function() {
-			this.element.data('sortable', this.element.data('nestedSortable'));
-
-			if (!this.element.is(this.options.listType))
-				throw new Error('nestedSortable: Please check the listType option is set to your actual list type');
-
-			return $.ui.sortable.prototype._create.apply(this, arguments);
-		},
-
-		destroy: function() {
-			this.element
-				.removeData("nestedSortable")
-				.unbind(".nestedSortable");
-			return $.ui.sortable.prototype.destroy.apply(this, arguments);
-		},
-
-		_mouseDrag: function(event) {
-
-			//Compute the helpers position
-			this.position = this._generatePosition(event);
-			this.positionAbs = this._convertPositionTo("absolute");
-
-			if (!this.lastPositionAbs) {
-				this.lastPositionAbs = this.positionAbs;
-			}
-
-			var o = this.options;
-
-			//Do scrolling
-			if(this.options.scroll) {
-				var scrolled = false;
-				if(this.scrollParent[0] != document && this.scrollParent[0].tagName != 'HTML') {
-
-					if((this.overflowOffset.top + this.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity)
-						this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop + o.scrollSpeed;
-					else if(event.pageY - this.overflowOffset.top < o.scrollSensitivity)
-						this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop - o.scrollSpeed;
-
-					if((this.overflowOffset.left + this.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity)
-						this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft + o.scrollSpeed;
-					else if(event.pageX - this.overflowOffset.left < o.scrollSensitivity)
-						this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft - o.scrollSpeed;
-
-				} else {
-
-					if(event.pageY - $(document).scrollTop() < o.scrollSensitivity)
-						scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed);
-					else if($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity)
-						scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed);
-
-					if(event.pageX - $(document).scrollLeft() < o.scrollSensitivity)
-						scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed);
-					else if($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity)
-						scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed);
-
-				}
-
-				if(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour)
-					$.ui.ddmanager.prepareOffsets(this, event);
-			}
-
-			//Regenerate the absolute position used for position checks
-			this.positionAbs = this._convertPositionTo("absolute");
-
-      // Find the top offset before rearrangement,
-      var previousTopOffset = this.placeholder.offset().top;
-
-			//Set the helper position
-			if(!this.options.axis || this.options.axis != "y") this.helper[0].style.left = this.position.left+'px';
-			if(!this.options.axis || this.options.axis != "x") this.helper[0].style.top = this.position.top+'px';
-
-			//Rearrange
-			for (var i = this.items.length - 1; i >= 0; i--) {
-
-				//Cache variables and intersection, continue if no intersection
-				var item = this.items[i], itemElement = item.item[0], intersection = this._intersectsWithPointer(item);
-				if (!intersection) continue;
-
-				if(itemElement != this.currentItem[0] //cannot intersect with itself
-					&&	this.placeholder[intersection == 1 ? "next" : "prev"]()[0] != itemElement //no useless actions that have been done before
-					&&	!$.contains(this.placeholder[0], itemElement) //no action if the item moved is the parent of the item checked
-					&& (this.options.type == 'semi-dynamic' ? !$.contains(this.element[0], itemElement) : true)
-					//&& itemElement.parentNode == this.placeholder[0].parentNode // only rearrange items within the same container
-				) {
-
-					$(itemElement).mouseenter();
-
-					this.direction = intersection == 1 ? "down" : "up";
-
-					if (this.options.tolerance == "pointer" || this._intersectsWithSides(item)) {
-						$(itemElement).mouseleave();
-						this._rearrange(event, item);
-					} else {
-						break;
-					}
-
-					// Clear emtpy ul's/ol's
-					this._clearEmpty(itemElement);
-
-					this._trigger("change", event, this._uiHash());
-					break;
-				}
-			}
-
-			var parentItem = (this.placeholder[0].parentNode.parentNode &&
-							 $(this.placeholder[0].parentNode.parentNode).closest('.ui-sortable').length)
-				       			? $(this.placeholder[0].parentNode.parentNode)
-				       			: null,
-			    level = this._getLevel(this.placeholder),
-			    childLevels = this._getChildLevels(this.helper);
-
-      // To find the previous sibling in the list, keep backtracking until we hit a valid list item.
-			var previousItem = this.placeholder[0].previousSibling ? $(this.placeholder[0].previousSibling) : null;
-			if (previousItem != null) {
-				while (previousItem[0].nodeName.toLowerCase() != 'li' || previousItem[0] == this.currentItem[0] || previousItem[0] == this.helper[0]) {
-					if (previousItem[0].previousSibling) {
-						previousItem = $(previousItem[0].previousSibling);
-					} else {
-						previousItem = null;
-						break;
-					}
-				}
-			}
-
-      // To find the next sibling in the list, keep stepping forward until we hit a valid list item.
-      var nextItem = this.placeholder[0].nextSibling ? $(this.placeholder[0].nextSibling) : null;
-      if (nextItem != null) {
-        while (nextItem[0].nodeName.toLowerCase() != 'li' || nextItem[0] == this.currentItem[0] || nextItem[0] == this.helper[0]) {
-          if (nextItem[0].nextSibling) {
-            nextItem = $(nextItem[0].nextSibling);
-          } else {
-            nextItem = null;
-            break;
-          }
-        }
-      }
-
-			var newList = document.createElement(o.listType);
-
-			this.beyondMaxLevels = 0;
-			
-			// If the item is moved to the left, send it to its parent's level unless there are siblings below it.
-			if (parentItem != null && nextItem == null &&
-					(o.rtl && (this.positionAbs.left + this.helper.outerWidth() > parentItem.offset().left + parentItem.outerWidth()) ||
-					!o.rtl && (this.positionAbs.left < parentItem.offset().left))) {
-				parentItem.after(this.placeholder[0]);
-				this._clearEmpty(parentItem[0]);
-				this._trigger("change", event, this._uiHash());
-			}
-			// If the item is below a sibling and is moved to the right, make it a child of that sibling.
-			else if (previousItem != null &&
-						(o.rtl && (this.positionAbs.left + this.helper.outerWidth() < previousItem.offset().left + previousItem.outerWidth() - o.tabSize) ||
-						!o.rtl && (this.positionAbs.left > previousItem.offset().left + o.tabSize))) {
-				this._isAllowed(previousItem, level, level+childLevels+1);
-				if (!previousItem.children(o.listType).length) {
-					previousItem[0].appendChild(newList);
-				}
-        // If this item is being moved from the top, add it to the top of the list.
-        if (previousTopOffset && (previousTopOffset <= previousItem.offset().top)) {
-          previousItem.children(o.listType).prepend(this.placeholder);
-        }
-        // Otherwise, add it to the bottom of the list.
-        else {
-				  previousItem.children(o.listType)[0].appendChild(this.placeholder[0]);
-        }
-				this._trigger("change", event, this._uiHash());
-			}
-			else {
-				this._isAllowed(parentItem, level, level+childLevels);
-			}
-
-			//Post events to containers
-			this._contactContainers(event);
-
-			//Interconnect with droppables
-			if($.ui.ddmanager) $.ui.ddmanager.drag(this, event);
-
-			//Call callbacks
-			this._trigger('sort', event, this._uiHash());
-
-			this.lastPositionAbs = this.positionAbs;
-			return false;
-
-		},
-
-		_mouseStop: function(event, noPropagation) {
-
-			// If the item is in a position not allowed, send it back
-			if (this.beyondMaxLevels) {
-
-				this.placeholder.removeClass(this.options.errorClass);
-
-				if (this.domPosition.prev) {
-					$(this.domPosition.prev).after(this.placeholder);
-				} else {
-					$(this.domPosition.parent).prepend(this.placeholder);
-				}
-
-				this._trigger("revert", event, this._uiHash());
-
-			}
-
-			// Clean last empty ul/ol
-			for (var i = this.items.length - 1; i >= 0; i--) {
-				var item = this.items[i].item[0];
-				this._clearEmpty(item);
-			}
-
-			$.ui.sortable.prototype._mouseStop.apply(this, arguments);
-
-		},
-
-		serialize: function(options) {
-
-			var o = $.extend({}, this.options, options),
-				items = this._getItemsAsjQuery(o && o.connected),
-			    str = [];
-
-			$(items).each(function() {
-				var res = ($(o.item || this).attr(o.attribute || 'id') || '')
-						.match(o.expression || (/(.+)[-=_](.+)/)),
-				    pid = ($(o.item || this).parent(o.listType)
-						.parent(o.items)
-						.attr(o.attribute || 'id') || '')
-						.match(o.expression || (/(.+)[-=_](.+)/));
-
-				if (res) {
-					str.push(((o.key || res[1]) + '[' + (o.key && o.expression ? res[1] : res[2]) + ']')
-						+ '='
-						+ (pid ? (o.key && o.expression ? pid[1] : pid[2]) : o.rootID));
-				}
-			});
-
-			if(!str.length && o.key) {
-				str.push(o.key + '=');
-			}
-
-			return str.join('&');
-
-		},
-
-		toHierarchy: function(options) {
-
-			var o = $.extend({}, this.options, options),
-				sDepth = o.startDepthCount || 0,
-			    ret = [];
-
-			$(this.element).children(o.items).each(function () {
-				var level = _recursiveItems(this);
-				ret.push(level);
-			});
-
-			return ret;
-
-			function _recursiveItems(item) {
-				var id = ($(item).attr(o.attribute || 'id') || '').match(o.expression || (/(.+)[-=_](.+)/));
-				if (id) {
-					var currentItem = {"id" : id[2]};
-					if ($(item).children(o.listType).children(o.items).length > 0) {
-						currentItem.children = [];
-						$(item).children(o.listType).children(o.items).each(function() {
-							var level = _recursiveItems(this);
-							currentItem.children.push(level);
-						});
-					}
-					return currentItem;
-				}
-			}
-		},
-
-		toArray: function(options) {
-
-			var o = $.extend({}, this.options, options),
-				sDepth = o.startDepthCount || 0,
-			    ret = [],
-			    left = 2;
-
-			ret.push({
-				"item_id": o.rootID,
-				"parent_id": 'none',
-				"depth": sDepth,
-				"left": '1',
-				"right": ($(o.items, this.element).length + 1) * 2
-			});
-
-			$(this.element).children(o.items).each(function () {
-				left = _recursiveArray(this, sDepth + 1, left);
-			});
-
-			ret = ret.sort(function(a,b){ return (a.left - b.left); });
-
-			return ret;
-
-			function _recursiveArray(item, depth, left) {
-
-				var right = left + 1,
-				    id,
-				    pid;
-
-				if ($(item).children(o.listType).children(o.items).length > 0) {
-					depth ++;
-					$(item).children(o.listType).children(o.items).each(function () {
-						right = _recursiveArray($(this), depth, right);
-					});
-					depth --;
-				}
-
-				id = ($(item).attr(o.attribute || 'id')).match(o.expression || (/(.+)[-=_](.+)/));
-
-				if (depth === sDepth + 1) {
-					pid = o.rootID;
-				} else {
-					var parentItem = ($(item).parent(o.listType)
-											 .parent(o.items)
-											 .attr(o.attribute || 'id'))
-											 .match(o.expression || (/(.+)[-=_](.+)/));
-					pid = parentItem[2];
-				}
-
-				if (id) {
-						ret.push({"item_id": id[2], "parent_id": pid, "depth": depth, "left": left, "right": right});
-				}
-
-				left = right + 1;
-				return left;
-			}
-
-		},
-
-		_clearEmpty: function(item) {
-
-			var emptyList = $(item).children(this.options.listType);
-			if (emptyList.length && !emptyList.children().length && !this.options.doNotClear) {
-				emptyList.remove();
-			}
-
-		},
-
-		_getLevel: function(item) {
-
-			var level = 1;
-
-			if (this.options.listType) {
-				var list = item.closest(this.options.listType);
-				while (list && list.length > 0 && 
-                    	!list.is('.ui-sortable')) {
-					level++;
-					list = list.parent().closest(this.options.listType);
-				}
-			}
-
-			return level;
-		},
-
-		_getChildLevels: function(parent, depth) {
-			var self = this,
-			    o = this.options,
-			    result = 0;
-			depth = depth || 0;
-
-			$(parent).children(o.listType).children(o.items).each(function (index, child) {
-					result = Math.max(self._getChildLevels(child, depth + 1), result);
-			});
-
-			return depth ? result + 1 : result;
-		},
-
-		_isAllowed: function(parentItem, level, levels) {
-			var o = this.options,
-				isRoot = $(this.domPosition.parent).hasClass('ui-sortable') ? true : false,
-				maxLevels = this.placeholder.closest('.ui-sortable').nestedSortable('option', 'maxLevels'); // this takes into account the maxLevels set to the recipient list
-
-			// Is the root protected?
-			// Are we trying to nest under a no-nest?
-			// Are we nesting too deep?
-			if (!o.isAllowed(this.currentItem, parentItem) ||
-				parentItem && parentItem.hasClass(o.disableNesting) ||
-				o.protectRoot && (parentItem == null && !isRoot || isRoot && level > 1)) {
-					this.placeholder.addClass(o.errorClass);
-					if (maxLevels < levels && maxLevels != 0) {
-						this.beyondMaxLevels = levels - maxLevels;
-					} else {
-						this.beyondMaxLevels = 1;
-					}
-			} else {
-				if (maxLevels < levels && maxLevels != 0) {
-					this.placeholder.addClass(o.errorClass);
-					this.beyondMaxLevels = levels - maxLevels;
-				} else {
-					this.placeholder.removeClass(o.errorClass);
-					this.beyondMaxLevels = 0;
-				}
-			}
-		}
-
-	}));
-
-	$.mjs.nestedSortable.prototype.options = $.extend({}, $.ui.sortable.prototype.options, $.mjs.nestedSortable.prototype.options);
-})(jQuery);
Index: admin/js/jquery/jquery.modal.js
===================================================================
--- admin/js/jquery/jquery.modal.js	(revision 0)
+++ admin/js/jquery/jquery.modal.js	(revision 0)
@@ -0,0 +1,324 @@
+(function($) {
+	if (/^1\.(0|1)\./.test($.fn.jquery) || /^1\.2\.(0|1|2|3|4|5)/.test($.fn.jquery)) {
+		throw('Modal requieres jQuery v1.2.6 or later. You are using v'+$.fn.jquery);
+		return;
+	}
+	
+	$.modal = function(data,params) {
+		this.params = $.extend(this.params,params);
+		return this.build(data);
+	};
+	$.modal.version = '1.0';
+	
+	$.modal.prototype = {
+		params: {
+			width: null,
+			height: null,
+			speed: 300,
+			opacity: 0.9,
+			loader_img: 'loader.gif',
+			loader_txt: 'loading...',
+			close_img: 'close.png',
+			close_txt: 'close',
+			on_close: function() {}
+		},
+		ctrl: {
+			box: $(),
+			loader: $(),
+			overlay: $('<div id="jq-modal-overlay"></div>'),
+			hidden: $()
+		},
+		
+		build: function(data) {
+			this.ctrl.loader = $('<div class="jq-modal-load"><img src="' + this.params.loader_img + '" alt="' + this.params.loader_txt + '" /></div>');
+			this.addOverlay();
+			var size = this.getBoxSize(this.ctrl.loading);
+			
+			this.ctrl.box = this.getBox(this.ctrl.loading,{
+				top: Math.round($(window).height()/2 + $(window).scrollTop() - size.h/2),
+				left: Math.round($(window).width()/2 + $(window).scrollLeft() - size.w/2),
+				visibility: 'hidden'
+			});
+			this.ctrl.overlay.after(this.ctrl.box);
+			if (data != undefined) {
+				this.updateBox(data);
+				this.data = data;
+			}
+			return this;
+		},
+		updateBox: function(data,fn) {
+			var This = this;
+			this.hideCloser();
+			fn = $.isFunction(fn) ? fn : function() {};
+			var content = $('div.jq-modal-content',this.ctrl.box);
+			content.empty().append(this.ctrl.loader);
+			var size = this.getBoxSize(data,this.params.width,this.params.height);
+			
+			var top = Math.round($(window).height()/2 + $(window).scrollTop() - size.h/2);
+			var left = Math.round($(window).width()/2 + $(window).scrollLeft() - size.w/2);
+			
+			this.ctrl.box.css('visibility','visible').animate({
+				top: top < 0 ? 0 : top,
+				left: left < 0 ? 0 : left,
+				width: size.w,
+				height: size.h
+			},this.params.speed,function() {
+				This.setContentSize(content,This.params.width,This.params.height);
+				content.empty().append(data).css('opacity',0)
+				.fadeTo(This.params.speed,1,function() {
+					fn.call(This,content);
+				});
+				This.showCloser();
+			});
+		},
+		getBox: function(data,css,content_w,content_h) {
+			var box = $(
+				'<div class="jq-modal">'+
+				'<div class="jq-modal-container"><div class="jq-modal-content">'+
+				'</div></div></div>'
+				).css($.extend({
+					position: 'absolute',
+					top: 0,
+					left: 0,
+					zIndex: 100
+				},css));
+			
+			if (data != undefined) {
+				$('div.jq-modal-content',box).append(data);
+			}
+			
+			this.setContentSize($('div.jq-modal-content',box),content_w,content_h);
+			return box;
+		},
+		getBoxSize: function(data,content_w,content_h) {
+			var box = this.getBox(data,{ visibility: 'hidden' },content_w,content_h);
+			this.ctrl.overlay.after(box);
+			var size = { w: box.width(), h: box.height() };
+			box.remove();
+			box = null;
+			return size;
+		},
+		setContentSize: function(content,w,h) {
+			content.css({
+				width: w > 0 ? w : 'auto',
+				height: h > 0 ? h : 'auto'
+			});
+		},
+		showCloser: function() {
+			if ($('div.jq-modal-closer',this.ctrl.box).length > 0) {
+				$('div.jq-modal-closer',this.ctrl.box).show();
+				return;
+			}
+			
+			$('div.jq-modal-container',this.ctrl.box).append(
+				'<div class="jq-modal-closer"><a href="#">' + this.params.close_txt + '</a></div>'
+			);
+			var This = this;
+			var close = $('div.jq-modal-closer a',this.ctrl.box)
+			close.css({
+				background: 'transparent url(' + this.params.close_img + ') no-repeat'
+			})
+			.click(function() {
+				This.removeOverlay();
+				return false;
+			});
+			
+			if (document.all) {
+				close[0].runtimeStyle.filter = 'progid:DXImageTransform.Microsoft.AlphaImageLoader(src="' + this.params.close_img + '", sizingMethod="crop")';
+				close[0].runtimeStyle.backgroundImage = "none"
+			}
+		},
+		hideCloser: function() {
+			$('div.jq-modal-closer',this.ctrl.box).hide();
+		},
+		
+		addOverlay: function() {
+			var This = this;
+			if (document.all) {
+				this.ctrl.hidden = $('select:visible, object:visible, embed:visible').
+				css('visibility','hidden');
+			}
+			this.ctrl.overlay.css({
+				backgroundColor: '#000',
+				position: 'absolute',
+				top: 0,
+				left: 0,
+				zIndex: 90,
+				opacity: this.params.opacity
+			})
+			.appendTo('body')
+			.dblclick(function() { This.removeOverlay(); });
+			
+			this.resizeOverlay({data:this.ctrl});
+			
+			$(window).bind('resize.modal',this.ctrl,this.resizeOverlay);
+			$(document).bind('keypress.modal',this,this.keyRemove);
+		},
+		resizeOverlay: function(e) {
+			e.data.overlay.css({
+				width: $(window).width(),
+				height: $(document).height()
+			});
+			if (e.data.box.parents('body').length > 0) {
+				var top = Math.round($(window).height()/2 + $(window).scrollTop() - e.data.box.height()/2);
+				var left = Math.round($(window).width()/2 + $(window).scrollLeft() - e.data.box.width()/2);
+				e.data.box.css({
+					top: top < 0 ? 0 : top,
+					left: left < 0 ? 0 : left
+				});
+			}
+		},
+		keyRemove: function(e) {
+			if (e.keyCode == 27) {
+				e.data.removeOverlay();
+			}
+			return true;
+		},
+		removeOverlay: function() {
+			$(window).unbind('resize.modal');
+			$(document).unbind('keypress');
+			this.params.on_close.apply(this);
+			this.ctrl.overlay.remove();
+			this.ctrl.hidden.css('visibility','visible');
+			this.ctrl.box.remove();
+			this.ctrl.box = $();
+		}
+	};
+})(jQuery);
+
+(function($) {
+	$.fn.modalImages = function(params) {
+		params = $.extend(this.params,params);
+		var links = new Array();
+		this.each(function() {
+			if ($(this).attr('href') == '' || $(this).attr('href') == undefined || $(this).attr('href') == '#') {
+				return false;
+			}
+			var index = links.length;
+			links.push($(this));
+			$(this).click(function() {
+				new $.modalImages(index,links,params);
+				return false;
+			});
+			return true;
+		});
+		
+		return this;
+	};
+	
+	$.modalImages = function(index,links,params) {
+		this.links = links;
+		this.modal = new $.modal(null,params);
+		this.showImage(index);
+	};
+	
+	$.modalImages.prototype = {
+		params: {
+			prev_txt: 'previous',
+			next_txt: 'next',
+			prev_img: 'prev.png',
+			next_img: 'next.png',
+			blank_img: 'blank.gif'
+		},
+		showImage: function(index) {
+			var This = this;
+			$(document).unbind('keypress.modalImage');
+			if (this.links[index] == undefined) {
+				this.modal.removeOverlay();
+			}
+			var link = this.links[index];
+			var modal = this.modal;
+			
+			var res = $('<div></div>');
+			res.append('<img src="' + link.attr('href') + '" alt="" />');
+			
+			var thumb = $('img:first',link);
+			if (thumb.length > 0 && thumb.attr('title')) {
+				res.append('<span class="jq-modal-legend">' + thumb.attr('title') + '</span>');
+			} else if (link.attr('title')) {
+				res.append('<span class="jq-modal-legend">' + link.attr('title') + '</span>');
+			}
+			
+			// Add prev/next buttons
+			if (index != 0) {
+				$('<a class="jq-modal-prev" href="#">prev</a>').appendTo(res);
+			}
+			if (index+1 < this.links.length) {
+				$('<a class="jq-modal-next" href="#">next</a>').appendTo(res);
+			}
+			
+			var img = new Image();
+			
+			// Display loader while loading image
+			if (this.modal.ctrl.box.css('visibility') == 'visible') {
+				$('div.jq-modal-content',this.modal.ctrl.box)
+				.empty().append(this.modal.ctrl.loader);
+			} else {
+				this.modal.updateBox(this.modal.ctrl.loader);
+			}
+			
+			img.onload = function() {
+				modal.updateBox(res,function() {
+					var Img = $('div.jq-modal-content img',this.ctrl.box);
+					This.navBtnStyle($('a.jq-modal-next',this.ctrl.box),true).css('height',Img.height()).bind('click',index+1,navClick);
+					This.navBtnStyle($('a.jq-modal-prev',this.ctrl.box),false).css('height',Img.height()).bind('click',index-1,navClick);
+					Img.click(function() {
+						This.modal.removeOverlay();
+					});
+					$(document).bind('keypress.modalImage',navKey);
+				});
+				this.onload = function() {};
+			};
+			img.src = link.attr('href');
+			
+			var navClick = function(e) {
+				This.showImage(e.data);
+				return false;
+			};
+			var navKey = function(e) {
+				var key = String.fromCharCode(e.which).toLowerCase();
+				if ((key == 'n' || e.keyCode == 39) && index+1 < This.links.length) { // Press "n"
+					This.showImage(index+1);
+				}
+				if ((key == 'p' || e.keyCode == 37) && index != 0) { // Press "p"
+					This.showImage(index-1);
+				}
+			};
+		},
+		navBtnStyle: function(btn,next) {
+			var default_bg = 'transparent url(' + this.modal.params.blank_img + ') repeat';
+			var over_bg_i = next ? this.modal.params.next_img : this.modal.params.prev_img;
+			var over_bg_p = next ? 'right' : 'left';
+			
+			btn.css('background',default_bg)
+			.bind('mouseenter',function() {
+				$(this).css('background','transparent url(' + over_bg_i + ') no-repeat center ' + over_bg_p).css('z-index',110);
+			})
+			.bind('mouseleave',function() {
+				$(this).css('background',default_bg);
+			});
+			
+			return btn;
+		}
+	};
+})(jQuery);
+
+(function($) {
+	$.modalWeb = function(url,w,h) {
+		iframe = $('<iframe src="' + url + '" frameborder="0">').css({
+			border: 'none',
+			width: w,
+			height: h
+		});
+		return new $.modal(iframe);
+	};
+	
+	$.fn.modalWeb = function(w,h) {
+		this.click(function() {
+			if (this.href != undefined) {
+				$.modalWeb(this.href,w,h);
+			}
+			return false;
+		});
+	};
+})(jQuery);
Index: admin/js/jquery/jquery.pageTabs.js
===================================================================
--- admin/js/jquery/jquery.pageTabs.js	(revision 3884)
+++ admin/js/jquery/jquery.pageTabs.js	(revision 0)
@@ -1,150 +1,116 @@
-/*global jQuery, chainHandler */
-'use strict';
+jQuery.pageTabs = function(start_tab,settings) {
+	return new jQuery._pageTabs(start_tab,settings);
+};
 
-(function($) {
+jQuery._pageTabs = function(start_tab,settings) {
+	var defaults = {
+		className: 'multi-part',
+		listClassName: 'part-tabs',
+		breakerClassName: 'clear'
+	};
+	
+	var index = start_tab ? start_tab : 0;
+	
+	this.params = jQuery.extend(defaults,settings);
+	this.divs = jQuery('div.'+this.params.className);
+	this.createList();
+	this.showDiv(index);
+};
 
-  $.pageTabs = function(start_tab, opts) {
-    const defaults = {
-      containerClass: 'part-tabs',
-      partPrefix: 'part-',
-      contentClass: 'multi-part',
-      activeClass: 'part-tabs-active',
-      idTabPrefix: 'part-tabs-'
-    };
-
-    $.pageTabs.options = $.extend({}, defaults, opts);
-    let active_tab = start_tab || '';
-    const hash = $.pageTabs.getLocationHash();
-    const subhash = $.pageTabs.getLocationSubhash();
-
-    if (hash !== undefined && hash) {
-      window.scrollTo(0, 0);
-      active_tab = hash;
-    } else if (active_tab == '') { // open first part
-      active_tab = $('.' + $.pageTabs.options.contentClass + ':eq(0)').attr('id');
-    }
-
-    createTabs();
-
-    $('ul li', '.' + $.pageTabs.options.containerClass).click(function() {
-      if ($(this).hasClass($.pageTabs.options.activeClass)) {
-        return;
-      }
-
-      $(this).parent().find('li.' + $.pageTabs.options.activeClass).removeClass($.pageTabs.options.activeClass);
-      $(this).addClass($.pageTabs.options.activeClass);
-      $('.' + $.pageTabs.options.contentClass + '.active').removeClass('active').hide();
-
-      const part_to_activate = $('#' + $.pageTabs.options.partPrefix + getHash($(this).find('a').attr('href')));
-
-      part_to_activate.addClass('active').show();
-      if (!part_to_activate.hasClass('loaded')) {
-        part_to_activate.onetabload();
-        part_to_activate.addClass('loaded');
-      }
-
-      part_to_activate.tabload();
-    });
-
-    $(window).bind('hashchange onhashchange', function() {
-      $.pageTabs.clickTab($.pageTabs.getLocationHash());
-    });
-
-    $.pageTabs.clickTab(active_tab);
-
-    if (subhash !== undefined) {
-      const elt = document.getElementById(subhash);
-      // Tab displayed, now scroll to the sub-part if defined in original document.location (#tab.sub-part)
-      elt.scrollIntoView();
-      // Give focus to the sub-part if possible
-      $('#' + subhash).addClass('focus').focusout(function() {
-        $(this).removeClass('focus');
-      });
-      elt.focus();
-    }
-
-    return this;
-  };
-
-  const createTabs = function createTabs() {
-    let lis = [];
-
-    $('.' + $.pageTabs.options.contentClass).each(function() {
-      $(this).hide();
-      lis.push('<li id="' + $.pageTabs.options.idTabPrefix + $(this).attr('id') + '">' +
-        '<a href="#' + $(this).attr('id') + '">' + $(this).attr('title') + '</a></li>');
-      $(this).attr('id', $.pageTabs.options.partPrefix + $(this).attr('id')).prop('title', '');
-    });
-
-    $('<div class="' + $.pageTabs.options.containerClass + '"><ul>' + lis.join('') + '</ul></div>')
-      .insertBefore($('.' + $.pageTabs.options.contentClass).get(0));
-  };
-
-  const getHash = function getHash(href) {
-    href = href || '';
-
-    return href.replace(/.*#/, '');
-  };
-
-  $.pageTabs.clickTab = function(tab) {
-    if (tab == '') {
-      tab = getHash($('ul li a', '.' + $.pageTabs.options.containerClass + ':eq(0)').attr('href'));
-    } else if ($('#' + $.pageTabs.options.idTabPrefix + tab, '.' + $.pageTabs.options.containerClass).length == 0) {
-      // try to find anchor in a .multi-part div
-      if ($('#' + tab).length == 1) {
-        const div_content = $('#' + tab).parents('.' + $.pageTabs.options.contentClass);
-        if (div_content.length == 1) {
-          tab = div_content.attr('id').replace($.pageTabs.options.partPrefix, '');
-        } else {
-          tab = getHash($('ul li a', '.' + $.pageTabs.options.containerClass + ':eq(0)').attr('href'));
-        }
-      } else {
-        tab = getHash($('ul li a', '.' + $.pageTabs.options.containerClass + ':eq(0)').attr('href'));
-      }
-    }
-
-    $('ul li a', '.' + $.pageTabs.options.containerClass).filter(function() {
-      return getHash($(this).attr('href')) == tab;
-    }).parent().click();
-  };
-
-  $.pageTabs.getLocationHash = function() {
-    // Return the URL hash (without subhash — #hash[.subhash])
-    const h = getHash(document.location.hash).split('.');
-    return h[0];
-  };
-  $.pageTabs.getLocationSubhash = function() {
-    // Return the URL subhash if present (without hash — #hash[.subhash])
-    const sh = getHash(document.location.hash).split('.');
-    return sh[1];
-  };
-})(jQuery);
+jQuery._pageTabs.prototype = {
+	items: new Array(),
+	
+	createList: function() {
+		if (this.divs.length <= 0) {
+			return;
+		}
+		
+		this.block = document.createElement('div');
+		this.block.className = this.params.listClassName;
+		this.list = document.createElement('ul');
+		//this.list.className = this.params.listClassName;
+		this.block.appendChild(this.list);
+		var li, a;
+		
+		var This = this;
+		var i=0;
+		jQuery('.'+this.params.className).each(function() {
+			if (this.tagName == "DIV") {
+				li = document.createElement('li');
+				a = document.createElement('a');
+				a.appendChild(document.createTextNode(this.title));
+				this.title = '';
+				a.href = '#';
+				a.fn = This.showDiv;
+				a.index = this.id || i;
+				a.obj = This;
+				jQuery(a).click(function() { this.fn.call(this.obj,this.index); return false; });
+				li.appendChild(a);
+				This.list.appendChild(li);
+				This.items[i] = li;
+				i++;
+			} else {
+				li = document.createElement('li');
+				li.className = This.params.listClassName+'-link';
+				li.appendChild(this);
+				This.list.appendChild(li);
+			}
+		});
+		
+		this.breaker = document.createElement('br');
+		this.breaker.className = this.params.breakerClassName;
+		
+		jQuery(this.divs.get(0)).before(this.block);
+		jQuery(this.block).after(this.breaker);
+	},
+	
+	showDiv: function(index) {
+		var This = this;
+		var i = 0;
+		var to_trigger = null;
+		
+		this.divs.each(function() {
+			if ((this.id != '' && this.id == index) || i == index) {
+				jQuery(this).show();
+				This.items[i].className = This.params.listClassName+'-active';
+				to_trigger = i;
+			} else {
+				jQuery(this).hide();
+				This.items[i].className = '';
+			}
+			
+			i++;
+		});
+		
+		if (to_trigger != null) {
+			jQuery(this.divs[to_trigger]).onetabload();
+			jQuery(this.divs[to_trigger]).tabload();
+		}
+	}
+};
 
 jQuery.fn.tabload = function(f) {
-  this.each(function() {
-    if (f) {
-      chainHandler(this, 'tabload', f);
-    } else {
-      const h = this.tabload;
-      if (h) {
-        h.apply(this);
-      }
-    }
-  });
-  return this;
+	this.each(function() {
+		if (f) {
+			chainHandler(this,'tabload',f)
+		} else {
+			var h = this.tabload;
+			if (h) { h.apply(this); }
+		}
+	});
+	return this;
 };
-
 jQuery.fn.onetabload = function(f) {
-  this.each(function() {
-    if (f) {
-      chainHandler(this, 'onetabload', f);
-    } else {
-      const h = this.onetabload;
-      if (h != null) {
-        h.apply(this);
-        this.onetabload = null;
-      }
-    }
-  });
-  return this;
+	this.each(function() {
+		if (f) {
+			chainHandler(this,'onetabload',f);
+		} else {
+			var h = this.onetabload;
+			if (h != null) {
+				h.apply(this);
+				this.onetabload = null;
+			}
+		}
+	});
+	return this;
 };
Index: admin/js/jquery/jquery.pwstrength.js
===================================================================
--- admin/js/jquery/jquery.pwstrength.js	(revision 3689)
+++ 	(revision )
@@ -1,85 +1,0 @@
-(function($) {
-  $.pwstrength = function(password) {
-    var score = 0;
-    var symbols = '[!,@,#,$,%,^,&,*,?,_,~]';
-    // Regexp
-    var check = new RegExp('(' + symbols + ')');
-    var doublecheck = new RegExp('(' + '.*' + symbols + '.*' + symbols + ')');
-    // password length
-    score += password.length * 4;
-    score += checkRepetition(1, password).length - password.length;
-    score += checkRepetition(2, password).length - password.length;
-    score += checkRepetition(3, password).length - password.length;
-    score += checkRepetition(4, password).length - password.length;
-    // password has 3 numbers
-    if (password.match(/(.*[0-9].*[0-9].*[0-9])/)) {
-      score += 5;
-    }
-    // password has at least 2 symbols
-    if (password.match(doublecheck)) {
-      score += 5;
-    }
-    // password has Upper and Lower chars
-    if (password.match(/([a-z].*[A-Z])|([A-Z].*[a-z])/)) {
-      score += 10;
-    }
-    // password has number and chars
-    if (password.match(/([a-zA-Z])/) && password.match(/([0-9])/)) {
-      score += 15;
-    }
-    // password has number and symbol
-    if (password.match(check) && password.match(/([0-9])/)) {
-      score += 15;
-    }
-    // password has char and symbol
-    if (password.match(check) && password.match(/([a-zA-Z])/)) {
-      score += 15;
-    }
-    // password is just numbers or chars
-    if (password.match(/^\w+$/) || password.match(/^\d+$/)) {
-      score -= 10;
-    }
-    return Math.floor(Math.max(Math.min(score, 99), 0) / 20);
-  };
-
-  function checkRepetition(rLen, str) {
-    var res = "",
-      repeated = false;
-    for (var i = 0; i < str.length; i++) {
-      repeated = true;
-      for (var j = 0; j < rLen && (j + i + rLen) < str.length; j++) {
-        repeated = repeated && (str.charAt(j + i) === str.charAt(j + i + rLen));
-      }
-      if (j < rLen) {
-        repeated = false;
-      }
-      if (repeated) {
-        i += rLen - 1;
-        repeated = false;
-      } else {
-        res += str.charAt(i);
-      }
-    }
-    return res;
-  }
-
-  function updateIndicator(event) {
-    var strength = $.pwstrength($(this).val()),
-      options = event.data,
-      klass;
-    klass = options.classes[strength];
-    options.indicator.removeClass(options.indicator.data('pwclass'));
-    options.indicator.data('pwclass', klass);
-    options.indicator.addClass(klass);
-    options.indicator.find(options.label).html(options.texts[strength]);
-  }
-  $.fn.pwstrength = function(options) {
-    var options = $.extend({
-      label: '.label',
-      classes: ['pw-very-weak', 'pw-weak', 'pw-mediocre', 'pw-strong', 'pw-very-strong'],
-      texts: ['very weak', 'weak', 'mediocre', 'strong', 'very strong']
-    }, options || {});
-    options.indicator = $('#' + this.data('indicator'));
-    return this.keyup(options, updateIndicator);
-  };
-})(jQuery);
Index: admin/js/jquery/jquery.ui.touch-punch.js
===================================================================
--- admin/js/jquery/jquery.ui.touch-punch.js	(revision 3904)
+++ 	(revision )
@@ -1,187 +1,0 @@
-/*!
- * jQuery UI Touch Punch 0.2.3
- *
- * Copyright 2011–2014, Dave Furfero
- * Dual licensed under the MIT or GPL Version 2 licenses.
- *
- * Depends:
- *  jquery.ui.widget.js
- *  jquery.ui.mouse.js
- */
-(function($) {
-
-  // Detect touch support
-  $.support.touch = 'ontouchend' in document;
-
-  // Ignore browsers without touch support
-  if (!$.support.touch) {
-    return;
-  }
-
-  var mouseProto = $.ui.mouse.prototype,
-    _mouseInit = mouseProto._mouseInit,
-    _mouseDestroy = mouseProto._mouseDestroy,
-    touchHandled;
-
-  /**
-   * Simulate a mouse event based on a corresponding touch event
-   * @param {Object} event A touch event
-   * @param {String} simulatedType The corresponding mouse event
-   */
-  function simulateMouseEvent(event, simulatedType) {
-
-    // Ignore multi-touch events
-    if (event.originalEvent.touches.length > 1) {
-      return;
-    }
-
-//    event.preventDefault();
-
-    var touch = event.originalEvent.changedTouches[0],
-      simulatedEvent = document.createEvent('MouseEvents');
-
-    // Check if element is an input or a textarea
-    if ($(touch.target).is("input") || $(touch.target).is("textarea")) {
-      event.stopPropagation();
-    } else {
-      event.preventDefault();
-    }
-
-    // Initialize the simulated mouse event using the touch event's coordinates
-    simulatedEvent.initMouseEvent(
-      simulatedType, // type
-      true, // bubbles
-      true, // cancelable
-      window, // view
-      1, // detail
-      touch.screenX, // screenX
-      touch.screenY, // screenY
-      touch.clientX, // clientX
-      touch.clientY, // clientY
-      false, // ctrlKey
-      false, // altKey
-      false, // shiftKey
-      false, // metaKey
-      0, // button
-      null // relatedTarget
-    );
-
-    // Dispatch the simulated event to the target element
-    event.target.dispatchEvent(simulatedEvent);
-  }
-
-  /**
-   * Handle the jQuery UI widget's touchstart events
-   * @param {Object} event The widget element's touchstart event
-   */
-  mouseProto._touchStart = function(event) {
-
-    var self = this;
-
-    // Ignore the event if another widget is already being handled
-    if (touchHandled || !self._mouseCapture(event.originalEvent.changedTouches[0])) {
-      return;
-    }
-
-    // Set the flag to prevent other widgets from inheriting the touch event
-    touchHandled = true;
-
-    // Track movement to determine if interaction was a click
-    self._touchMoved = false;
-
-    // Simulate the mouseover event
-    simulateMouseEvent(event, 'mouseover');
-
-    // Simulate the mousemove event
-    simulateMouseEvent(event, 'mousemove');
-
-    // Simulate the mousedown event
-    simulateMouseEvent(event, 'mousedown');
-  };
-
-  /**
-   * Handle the jQuery UI widget's touchmove events
-   * @param {Object} event The document's touchmove event
-   */
-  mouseProto._touchMove = function(event) {
-
-    // Ignore event if not handled
-    if (!touchHandled) {
-      return;
-    }
-
-    // Interaction was not a click
-    this._touchMoved = true;
-
-    // Simulate the mousemove event
-    simulateMouseEvent(event, 'mousemove');
-  };
-
-  /**
-   * Handle the jQuery UI widget's touchend events
-   * @param {Object} event The document's touchend event
-   */
-  mouseProto._touchEnd = function(event) {
-
-    // Ignore event if not handled
-    if (!touchHandled) {
-      return;
-    }
-
-    // Simulate the mouseup event
-    simulateMouseEvent(event, 'mouseup');
-
-    // Simulate the mouseout event
-    simulateMouseEvent(event, 'mouseout');
-
-    // If the touch interaction did not move, it should trigger a click
-    if (!this._touchMoved) {
-
-      // Simulate the click event
-      simulateMouseEvent(event, 'click');
-    }
-
-    // Unset the flag to allow other widgets to inherit the touch event
-    touchHandled = false;
-  };
-
-  /**
-   * A duck punch of the $.ui.mouse _mouseInit method to support touch events.
-   * This method extends the widget with bound touch event handlers that
-   * translate touch events to mouse events and pass them to the widget's
-   * original mouse event handling methods.
-   */
-  mouseProto._mouseInit = function() {
-
-    var self = this;
-
-    // Delegate the touch handlers to the widget's element
-    self.element.bind({
-      touchstart: $.proxy(self, '_touchStart'),
-      touchmove: $.proxy(self, '_touchMove'),
-      touchend: $.proxy(self, '_touchEnd')
-    });
-
-    // Call the original $.ui.mouse init method
-    _mouseInit.call(self);
-  };
-
-  /**
-   * Remove the touch event handlers
-   */
-  mouseProto._mouseDestroy = function() {
-
-    var self = this;
-
-    // Delegate the touch handlers to the widget's element
-    self.element.unbind({
-      touchstart: $.proxy(self, '_touchStart'),
-      touchmove: $.proxy(self, '_touchMove'),
-      touchend: $.proxy(self, '_touchEnd')
-    });
-
-    // Call the original $.ui.mouse destroy method
-    _mouseDestroy.call(self);
-  };
-
-})(jQuery);
Index: admin/js/jsToolBar/jsToolBar.dotclear.js
===================================================================
--- admin/js/jsToolBar/jsToolBar.dotclear.js	(revision 0)
+++ admin/js/jsToolBar/jsToolBar.dotclear.js	(revision 0)
@@ -0,0 +1,378 @@
+/* Change link button actions
+-------------------------------------------------------- */
+jsToolBar.prototype.elements.link.data = {};
+jsToolBar.prototype.elements.link.fncall = {};
+jsToolBar.prototype.elements.link.open_url = 'popup_link.php';
+
+jsToolBar.prototype.elements.link.popup = function (args) {
+	window.the_toolbar = this;
+	args = args || '';
+	
+	this.elements.link.data = {};
+	var url = this.elements.link.open_url+args;
+	
+	var p_win = window.open(url,'dc_popup',
+	'alwaysRaised=yes,dependent=yes,toolbar=yes,height=420,width=380,'+
+	'menubar=no,resizable=yes,scrollbars=yes,status=no');
+};
+
+jsToolBar.prototype.elements.link.fn.wiki = function() {
+	this.elements.link.popup.call(this,'?hreflang='+this.elements.link.default_hreflang);
+};
+jsToolBar.prototype.elements.link.fncall.wiki = function() {
+	var data = this.elements.link.data;
+	
+	if (data.href == '') { return; }
+	
+	var etag = '|'+data.href;
+	if (data.hreflang) { etag += '|'+data.hreflang; }
+	
+	if (data.title) {
+		if (!data.hreflang) { etag += '|'; }
+		etag += '|'+data.title;
+	}
+	
+	if (data.content) {
+		this.encloseSelection('['+data.content,etag+']');
+	} else {
+		this.encloseSelection('[',etag+']');
+	}
+};
+
+jsToolBar.prototype.elements.link.fn.xhtml = function() {
+	this.elements.link.popup.call(this,'?hreflang='+this.elements.link.default_hreflang);
+};
+jsToolBar.prototype.elements.link.fncall.xhtml = function() {
+	var data = this.elements.link.data;
+	
+	if (data.href == '') { return; }
+	
+	var stag = '<a href="'+data.href+'"';
+	
+	if (data.hreflang) { stag += ' hreflang="'+data.hreflang+'"'; }
+	if (data.title) { stag += ' title="'+data.title+'"'; }
+	stag += '>';
+	var etag = '</a>';
+	
+	if (data.content) {
+		this.encloseSelection('','',function() {
+			return stag + data.content + etag;
+		});
+	} else {
+		this.encloseSelection(stag,etag);
+	}
+};
+
+jsToolBar.prototype.elements.link.fn.wysiwyg = function() {
+	var href, title, hreflang;
+	href = title = hreflang = '';
+	hreflang = this.elements.link.default_hreflang;
+	
+	var a = this.getAncestor();
+	
+	if (a.tagName == 'a') {
+		href= a.tag.href || '';
+		title = a.tag.title || '';
+		hreflang = a.tag.hreflang || '';
+	}
+	
+	this.elements.link.popup.call(this,'?href='+href+'&hreflang='+hreflang+'&title='+title);
+};
+jsToolBar.prototype.elements.link.fncall.wysiwyg = function() {
+	var data = this.elements.link.data;
+	
+	var a = this.getAncestor();
+	
+	if (a.tagName == 'a') {
+		if (data.href == '') {
+			// Remove link
+			this.replaceNodeByContent(a.tag);
+			this.iwin.focus();
+			return;
+		} else {
+			// Update link
+			a.tag.href = data.href;
+			if (data.hreflang) {
+				a.tag.setAttribute('hreflang',data.hreflang);
+			} else {
+				a.tag.removeAttribute('hreflang');
+			}
+			if (data.title) {
+				a.tag.setAttribute('title',data.title);
+			} else {
+				a.tag.removeAttribute('title');
+			}
+			return;
+		}
+	}
+	
+	// Create link
+	if (data.content) {
+		var n = document.createTextNode(data.content);
+	} else {
+		var n = this.getSelectedNode();
+	}
+	var a = this.iwin.document.createElement('a');
+	a.href = data.href;
+	if (data.hreflang) a.setAttribute('hreflang',data.hreflang);
+	a.appendChild(n);
+	this.insertNode(a);
+};
+jsToolBar.prototype.getAncestor = function() {
+	var res = {};
+	var range, commonAncestorContainer;
+	
+	if (this.iwin.getSelection) { //gecko
+		var selection = this.iwin.getSelection();
+		range = selection.getRangeAt(0);
+		commonAncestorContainer = range.commonAncestorContainer;
+		while (commonAncestorContainer.nodeType != 1) {
+			commonAncestorContainer = commonAncestorContainer.parentNode;
+		}
+	} else { //ie
+		range = this.iwin.document.selection.createRange();
+		commonAncestorContainer = range.parentElement();
+	}
+	
+	var ancestorTagName = commonAncestorContainer.tagName.toLowerCase();
+	while (ancestorTagName!='a' && ancestorTagName!='body') {
+		commonAncestorContainer = commonAncestorContainer.parentNode;
+		ancestorTagName = commonAncestorContainer.tagName.toLowerCase();
+	}
+	
+	res.tag = commonAncestorContainer;
+	res.tagName = ancestorTagName;
+	
+	return res;
+};
+
+/* Image selector
+-------------------------------------------------------- */
+jsToolBar.prototype.elements.img_select = {
+	type: 'button',
+	title: 'Image chooser',
+	fn: {},
+	fncall: {},
+	open_url: 'media.php?popup=1',
+	data: {},
+	popup: function() {
+		window.the_toolbar = this;
+		this.elements.img_select.data = {};
+		
+		var p_win = window.open(this.elements.img_select.open_url,'dc_popup',
+		'alwaysRaised=yes,dependent=yes,toolbar=yes,height=500,width=760,'+
+		'menubar=no,resizable=yes,scrollbars=yes,status=no');
+	}
+};
+jsToolBar.prototype.elements.img_select.fn.wiki = function() {
+	this.elements.img_select.popup.call(this);
+};
+jsToolBar.prototype.elements.img_select.fncall.wiki = function() {
+	var d = this.elements.img_select.data;
+	if (d.src == undefined) { return; }
+	
+	this.encloseSelection('','',function(str) {
+		var alt = (str) ? str : d.title;
+		var res = '(('+d.src+'|'+alt;
+		
+		if (d.alignment == 'left') {
+			res += '|L';
+		} else if (d.alignment == 'right') {
+			res += '|R';
+		} else if (d.alignment == 'center') {
+			res += '|C';
+		} else if (d.description) {
+			res += '|';
+		}
+		
+		if (d.description) {
+			res += '|'+d.description;
+		}
+		
+		res += '))';
+		
+		if (d.link) {
+			var ltitle = (alt) ? '||'+alt : '';
+			res = '['+res+'|'+d.url+ltitle+']';
+		}
+		
+		return res;
+	});
+};
+jsToolBar.prototype.elements.img_select.fn.xhtml = function() {
+	this.elements.img_select.popup.call(this);
+};
+jsToolBar.prototype.elements.img_select.fncall.xhtml = function() {
+	var d = this.elements.img_select.data;
+	if (d.src == undefined) { return; }
+	
+	this.encloseSelection('','',function(str) {
+		var alt = (str) ? str : d.title;
+		var res = '<img src="'+d.src+'" alt="'+alt.replace('&','&amp;').replace('>','&gt;').replace('<','&lt;').replace('"','&quot;')+'"';
+		
+		if (d.alignment == 'left') {
+			res += ' style="float: left; margin: 0 1em 1em 0;"';
+		} else if (d.alignment == 'right') {
+			res += ' style="float: right; margin: 0 0 1em 1em;"';
+		} else if (d.alignment == 'center') {
+			res += ' style="margin: 0 auto; display: block;"';
+		}
+		
+		if (d.description) {
+			res += ' title="'+d.description.replace('&','&amp;').replace('>','&gt;').replace('<','&lt;').replace('"','&quot;')+'"';
+		}
+		
+		res += ' />';
+		
+		if (d.link) {
+			var ltitle = (alt) ? ' title="'+alt.replace('&','&amp;').replace('>','&gt;').replace('<','&lt;').replace('"','&quot;')+'"' : '';
+			res = '<a href="'+d.url+'"'+ltitle+'>'+res+'</a>';
+		}
+		
+		return res;
+	});
+};
+
+jsToolBar.prototype.elements.img.fn.wysiwyg = function() {
+	var src = this.elements.img.prompt.call(this);
+	if (!src) { return; }
+	
+	var img = this.iwin.document.createElement('img');
+	img.src = src;
+	img.setAttribute('alt',this.getSelectedText());
+	
+	this.insertNode(img);
+};
+
+jsToolBar.prototype.elements.img_select.fn.wysiwyg = function() {
+	this.elements.img_select.popup.call(this);
+};
+jsToolBar.prototype.elements.img_select.fncall.wysiwyg = function() {
+	var d = this.elements.img_select.data;
+	var alt = (this.getSelectedText()) ? this.getSelectedText() : d.title;
+	if (d.src == undefined) { return; }
+	
+	var img = this.iwin.document.createElement('img');
+	img.src = d.src;
+	img.setAttribute('alt',alt);
+	
+	
+	if (d.alignment == 'left') {
+		if (img.style.styleFloat != undefined) {
+			img.style.styleFloat = 'left';
+		} else {
+			img.style.cssFloat = 'left';
+		}
+		img.style.marginTop = 0;
+		img.style.marginRight = '1em';
+		img.style.marginBottom = '1em';
+		img.style.marginLeft = 0;
+	} else if (d.alignment == 'right') {
+		if (img.style.styleFloat != undefined) {
+			img.style.styleFloat = 'right';
+		} else {
+			img.style.cssFloat = 'right';
+		}
+		img.style.marginTop = 0;
+		img.style.marginRight = 0;
+		img.style.marginBottom = '1em';
+		img.style.marginLeft = '1em';
+	} else if (d.alignment == 'center') {
+		img.style.marginTop = 0;
+		img.style.marginRight = 'auto';
+		img.style.marginBottom = 0;
+		img.style.marginLeft = 'auto';
+		img.style.display = 'block';
+	}
+	
+	if (d.description) {
+		img.setAttribute('title',d.description);
+	}
+	
+	if (d.link) {
+		var a = this.iwin.document.createElement('a');
+		a.href = d.url;
+		if (alt) {
+			a.setAttribute('title',alt);
+		}
+		a.appendChild(img);
+		this.insertNode(a);
+	} else {
+		this.insertNode(img);
+	}
+};
+
+// MP3 helpers
+jsToolBar.prototype.elements.mp3_insert = { fncall: {}, data: {} };
+jsToolBar.prototype.elements.mp3_insert.fncall.wiki = function() {
+	var d = this.elements.mp3_insert.data;
+	if (d.player == undefined) { return; }
+	
+	this.encloseSelection('','',function(str) {
+		return '\n///html\n' + d.player + '///\n';
+	});
+};
+jsToolBar.prototype.elements.mp3_insert.fncall.xhtml = function() {
+	var d = this.elements.mp3_insert.data;
+	if (d.player == undefined) { return; }
+	
+	this.encloseSelection('','',function(str) {
+		return '\n' + d.player + '\n';
+	});
+};
+jsToolBar.prototype.elements.mp3_insert.fncall.wysiwyg = function() {
+	return;
+};
+
+// FLV helpers
+jsToolBar.prototype.elements.flv_insert = { fncall: {}, data: {} };
+jsToolBar.prototype.elements.flv_insert.fncall.wiki = function() {
+	var d = this.elements.flv_insert.data;
+	if (d.player == undefined) { return; }
+	
+	this.encloseSelection('','',function(str) {
+		return '\n///html\n' + d.player + '///\n';
+	});
+};
+jsToolBar.prototype.elements.flv_insert.fncall.xhtml = function() {
+	var d = this.elements.flv_insert.data;
+	if (d.player == undefined) { return; }
+	
+	this.encloseSelection('','',function(str) {
+		return '\n' + d.player + '\n';
+	});
+};
+jsToolBar.prototype.elements.flv_insert.fncall.wysiwyg = function() {
+	return;
+};
+
+
+/* Posts selector
+-------------------------------------------------------- */
+jsToolBar.prototype.elements.post_link = {
+	type: 'button',
+	title: 'Link to an entry',
+	fn: {},
+	open_url: 'popup_posts.php',
+	data: {},
+	popup: function() {
+		window.the_toolbar = this;
+		this.elements.img_select.data = {};
+		
+		var p_win = window.open(this.elements.post_link.open_url,'dc_popup',
+		'alwaysRaised=yes,dependent=yes,toolbar=yes,height=500,width=760,'+
+		'menubar=no,resizable=yes,scrollbars=yes,status=no');
+	}
+};
+jsToolBar.prototype.elements.post_link.fn.wiki = function() {
+	this.elements.post_link.popup.call(this);
+};
+jsToolBar.prototype.elements.post_link.fn.xhtml = function() {
+	this.elements.post_link.popup.call(this);
+};
+jsToolBar.prototype.elements.post_link.fn.wysiwyg = function() {
+	this.elements.post_link.popup.call(this);
+};
+
+// Last space element
+jsToolBar.prototype.elements.space3 = {type: 'space'};
Index: admin/js/jsToolBar/jsToolBar.js
===================================================================
--- admin/js/jsToolBar/jsToolBar.js	(revision 0)
+++ admin/js/jsToolBar/jsToolBar.js	(revision 0)
@@ -0,0 +1,581 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * This file is part of DotClear.
+ * Copyright (c) 2005 Nicolas Martin & Olivier Meunier and contributors. All
+ * rights reserved.
+ *
+ * DotClear is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ * 
+ * DotClear is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with DotClear; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * ***** END LICENSE BLOCK *****
+*/
+
+function jsToolBar(textarea) {
+	if (!document.createElement) { return; }
+	
+	if (!textarea) { return; }
+	
+	if ((typeof(document["selection"]) == "undefined")
+	&& (typeof(textarea["setSelectionRange"]) == "undefined")) {
+		return;
+	}
+	
+	this.textarea = textarea;
+	
+	this.editor = document.createElement('div');
+	this.editor.className = 'jstEditor';
+	
+	this.textarea.parentNode.insertBefore(this.editor,this.textarea);
+	this.editor.appendChild(this.textarea);
+	
+	this.toolbar = document.createElement("div");
+	this.toolbar.className = 'jstElements';
+	this.editor.parentNode.insertBefore(this.toolbar,this.editor);
+	
+	// Dragable resizing (only for gecko)
+	if (this.editor.addEventListener)
+	{
+		this.handle = document.createElement('div');
+		this.handle.className = 'jstHandle';
+		var dragStart = this.resizeDragStart;
+		var This = this;
+		this.handle.addEventListener('mousedown',function(event) { dragStart.call(This,event); },false);
+		// fix memory leak in Firefox (bug #241518)
+		window.addEventListener('unload',function() {
+				var del = This.handle.parentNode.removeChild(This.handle);
+				delete(This.handle);
+		},false);
+		
+		this.editor.parentNode.insertBefore(this.handle,this.editor.nextSibling);
+	}
+	
+	this.context = null;
+	this.toolNodes = {}; // lorsque la toolbar est dessinée , cet objet est garni 
+					// de raccourcis vers les éléments DOM correspondants aux outils.
+};
+
+function jsButton(title, fn, scope, className) {
+	this.title = title || null;
+	this.fn = fn || function(){};
+	this.scope = scope || null;
+	this.className = className || null;
+};
+jsButton.prototype.draw = function() {
+	if (!this.scope) return null;
+	
+	var button = document.createElement('button');
+	button.setAttribute('type','button');
+	if (this.className) button.className = this.className;
+	button.title = this.title;
+	var span = document.createElement('span');
+	span.appendChild(document.createTextNode(this.title));
+	button.appendChild(span);
+	
+	if (this.icon != undefined) {
+		button.style.backgroundImage = 'url('+this.icon+')';
+	}
+	if (typeof(this.fn) == 'function') {
+		var This = this;
+		button.onclick = function() { try { This.fn.apply(This.scope, arguments) } catch (e) {} return false; };
+	}
+	return button;
+};
+
+function jsSpace(id) {
+	this.id = id || null;
+	this.width = null;
+};
+jsSpace.prototype.draw = function() {
+	var span = document.createElement('span');
+	if (this.id) span.id = this.id;
+	span.appendChild(document.createTextNode(String.fromCharCode(160)));
+	span.className = 'jstSpacer';
+	if (this.width) span.style.marginRight = this.width+'px';
+	
+	return span;
+};
+
+function jsCombo(title, options, scope, fn, className) {
+	this.title = title || null;
+	this.options = options || null;
+	this.scope = scope || null;
+	this.fn = fn || function(){};
+	this.className = className || null;
+};
+jsCombo.prototype.draw = function() {
+	if (!this.scope || !this.options) return null;
+	
+	var select = document.createElement('select');
+	if (this.className) select.className = className;
+	select.title = this.title;
+	
+	for (var o in this.options) {
+		//var opt = this.options[o];
+		var option = document.createElement('option');
+		option.value = o;
+		option.appendChild(document.createTextNode(this.options[o]));
+		select.appendChild(option);
+	}
+	
+	var This = this;
+	select.onchange = function() {
+		try { 
+			This.fn.call(This.scope, this.value);
+		} catch (e) { alert(e); }
+		
+		return false;
+	};
+	
+	return select;
+};
+
+
+jsToolBar.prototype = {
+	base_url: '',
+	mode: 'xhtml',
+	elements: {},
+	
+	getMode: function() {
+		return this.mode;
+	},
+	
+	setMode: function(mode) {
+		this.mode = mode || 'xhtml';
+	},
+	
+	switchMode: function(mode) {
+		mode = mode || 'xhtml';
+		this.draw(mode);
+	},
+	
+	button: function(toolName) {
+		var tool = this.elements[toolName];
+		if (typeof tool.fn[this.mode] != 'function') return null;
+		var b = new jsButton(tool.title, tool.fn[this.mode], this, 'jstb_'+toolName);
+		if (tool.icon != undefined) {
+			b.icon = tool.icon;
+		}
+		return b;
+	},
+	space: function(toolName) {
+		var tool = new jsSpace(toolName);
+		if (this.elements[toolName].width !== undefined) {
+			tool.width = this.elements[toolName].width;
+		}
+		return tool;
+	},
+	combo: function(toolName) {
+		var tool = this.elements[toolName];
+		var length = tool[this.mode].list.length;
+		
+		if (typeof tool[this.mode].fn != 'function' || length == 0) {
+			return null;
+		} else {
+			var options = {};
+			for (var i=0; i < length; i++) {
+				var opt = tool[this.mode].list[i];
+				options[opt] = tool.options[opt];
+			}
+			return new jsCombo(tool.title, options, this, tool[this.mode].fn);
+		}
+	},
+	draw: function(mode) {
+		this.setMode(mode);
+		
+		// Empty toolbar
+		while (this.toolbar.hasChildNodes()) {
+			this.toolbar.removeChild(this.toolbar.firstChild)
+		}
+		this.toolNodes = {}; // vide les raccourcis DOM/**/
+		
+		// Draw toolbar elements
+		var b, tool, newTool;
+		
+		for (var i in this.elements) {
+			b = this.elements[i];
+			
+			var disabled =
+			b.type == undefined || b.type == ''
+			|| (b.disabled != undefined && b.disabled)
+			|| (b.context != undefined && b.context != null && b.context != this.context);
+			
+			if (!disabled && typeof this[b.type] == 'function') {
+				tool = this[b.type](i);
+				if (tool) newTool = tool.draw();
+				if (newTool) {
+					this.toolNodes[i] = newTool; //mémorise l'accès DOM pour usage éventuel ultérieur
+					this.toolbar.appendChild(newTool);
+				}
+			}
+		}
+	},
+	
+	singleTag: function(stag,etag) {
+		stag = stag || null;
+		etag = etag || stag;
+		
+		if (!stag || !etag) { return; }
+		
+		this.encloseSelection(stag,etag);
+	},
+	
+	encloseSelection: function(prefix, suffix, fn) {
+		this.textarea.focus();
+		
+		prefix = prefix || '';
+		suffix = suffix || '';
+		
+		var start, end, sel, scrollPos, subst, res;
+		
+		if (typeof(document["selection"]) != "undefined") {
+			sel = document.selection.createRange().text;
+		} else if (typeof(this.textarea["setSelectionRange"]) != "undefined") {
+			start = this.textarea.selectionStart;
+			end = this.textarea.selectionEnd;
+			scrollPos = this.textarea.scrollTop;
+			sel = this.textarea.value.substring(start, end);
+		}
+		
+		if (sel.match(/ $/)) { // exclude ending space char, if any
+			sel = sel.substring(0, sel.length - 1);
+			suffix = suffix + " ";
+		}
+		
+		if (typeof(fn) == 'function') {
+			res = (sel) ? fn.call(this,sel) : fn('');
+		} else {
+			res = (sel) ? sel : '';
+		}
+		
+		subst = prefix + res + suffix;
+		
+		if (typeof(document["selection"]) != "undefined") {
+			var range = document.selection.createRange().text = subst;
+			this.textarea.caretPos -= suffix.length;
+		} else if (typeof(this.textarea["setSelectionRange"]) != "undefined") {
+			this.textarea.value = this.textarea.value.substring(0, start) + subst +
+			this.textarea.value.substring(end);
+			if (sel) {
+				this.textarea.setSelectionRange(start + subst.length, start + subst.length);
+			} else {
+				this.textarea.setSelectionRange(start + prefix.length, start + prefix.length);
+			}
+			this.textarea.scrollTop = scrollPos;
+		}
+	},
+	
+	stripBaseURL: function(url) {
+		if (this.base_url != '') {
+			var pos = url.indexOf(this.base_url);
+			if (pos == 0) {
+				url = url.substr(this.base_url.length);
+			}
+		}
+		
+		return url;
+	}
+};
+
+/** Resizer
+-------------------------------------------------------- */
+jsToolBar.prototype.resizeSetStartH = function() {
+	this.dragStartH = this.textarea.offsetHeight + 0;
+};
+jsToolBar.prototype.resizeDragStart = function(event) {
+	var This = this;
+	this.dragStartY = event.clientY;
+	this.resizeSetStartH();
+	document.addEventListener('mousemove', this.dragMoveHdlr=function(event){This.resizeDragMove(event);}, false);
+	document.addEventListener('mouseup', this.dragStopHdlr=function(event){This.resizeDragStop(event);}, false);
+};
+
+jsToolBar.prototype.resizeDragMove = function(event) {
+	this.textarea.style.height = (this.dragStartH+event.clientY-this.dragStartY)+'px';
+};
+
+jsToolBar.prototype.resizeDragStop = function(event) {
+	document.removeEventListener('mousemove', this.dragMoveHdlr, false);
+	document.removeEventListener('mouseup', this.dragStopHdlr, false);
+};
+
+// Elements definition ------------------------------------
+// block format (paragraph, headers)
+jsToolBar.prototype.elements.blocks = {
+	type: 'combo',
+	title: 'block format',
+	options: {
+		none: '-- none --', // only for wysiwyg mode
+		nonebis: '- block format -', // only for xhtml mode
+		p: 'Paragraph',
+		h1: 'Header 1',
+		h2: 'Header 2',
+		h3: 'Header 3',
+		h4: 'Header 4',
+		h5: 'Header 5',
+		h6: 'Header 6'
+	},
+	xhtml: {
+		list: ['nonebis','p','h1','h2','h3','h4','h5','h6'],
+		fn: function(opt) {
+			if (opt=='nonebis')
+				this.textarea.focus();
+			else
+				try {this.singleTag('<'+opt+'>','</'+opt+'>');} catch(e){};
+			this.toolNodes.blocks.value = 'nonebis';
+		}
+	},
+	wiki: {
+		list: ['nonebis','h2','h3','h4','h5'],
+		fn: function(opt) {
+			switch (opt) {
+				case 'nonebis': this.textarea.focus(); break;
+				case 'h2': this.encloseSelection('!!!!'); break;
+				case 'h3': this.encloseSelection('!!!'); break;
+				case 'h4': this.encloseSelection('!!'); break;
+				case 'h5': this.encloseSelection('!'); break;
+			}
+			this.toolNodes.blocks.value = 'nonebis';
+		}
+	}
+};
+
+// spacer
+jsToolBar.prototype.elements.space0 = {type: 'space'};
+
+// strong
+jsToolBar.prototype.elements.strong = {
+	type: 'button',
+	title: 'Strong emphasis',
+	fn: {
+		wiki: function() { this.singleTag('__') },
+		xhtml: function() { this.singleTag('<strong>','</strong>') }
+	}
+};
+
+// em
+jsToolBar.prototype.elements.em = {
+	type: 'button',
+	title: 'Emphasis',
+	fn: {
+		wiki: function() { this.singleTag("''") },
+		xhtml: function() { this.singleTag('<em>','</em>') }
+	}
+};
+
+// ins
+jsToolBar.prototype.elements.ins = {
+	type: 'button',
+	title: 'Inserted',
+	fn: {
+		wiki: function() { this.singleTag('++') },
+		xhtml: function() { this.singleTag('<ins>','</ins>') }
+	}
+};
+
+// del
+jsToolBar.prototype.elements.del = {
+	type: 'button',
+	title: 'Deleted',
+	fn: {
+		wiki: function() { this.singleTag('--') },
+		xhtml: function() { this.singleTag('<del>','</del>') }
+	}
+};
+
+// quote
+jsToolBar.prototype.elements.quote = {
+	type: 'button',
+	title: 'Inline quote',
+	fn: {
+		wiki: function() { this.singleTag('{{','}}') },
+		xhtml: function() { this.singleTag('<q>','</q>') }
+	}
+};
+
+// code
+jsToolBar.prototype.elements.code = {
+	type: 'button',
+	title: 'Code',
+	fn: {
+		wiki: function() { this.singleTag('@@') },
+		xhtml: function() { this.singleTag('<code>','</code>')}
+	}
+};
+
+// spacer
+jsToolBar.prototype.elements.space1 = {type: 'space'};
+
+// br
+jsToolBar.prototype.elements.br = {
+	type: 'button',
+	title: 'Line break',
+	fn: {
+		wiki: function() { this.encloseSelection("%%%\n",'') },
+		xhtml: function() { this.encloseSelection("<br />\n",'')}
+	}
+};
+
+// spacer
+jsToolBar.prototype.elements.space2 = {type: 'space'};
+
+// blockquote
+jsToolBar.prototype.elements.blockquote = {
+	type: 'button',
+	title: 'Blockquote',
+	fn: {
+		xhtml: function() { this.singleTag('<blockquote>','</blockquote>') },
+		wiki: function() {
+			this.encloseSelection("\n",'',
+			function(str) {
+				str = str.replace(/\r/g,'');
+				return '> '+str.replace(/\n/g,"\n> ");
+			});
+		}
+	}
+};
+
+// pre
+jsToolBar.prototype.elements.pre = {
+	type: 'button',
+	title: 'Preformated text',
+	fn: {
+		wiki: function() { this.singleTag("///\n","\n///") },
+		xhtml: function() { this.singleTag('<pre>','</pre>') }
+	}
+};
+
+// ul
+jsToolBar.prototype.elements.ul = {
+	type: 'button',
+	title: 'Unordered list',
+	fn: {
+		wiki: function() {
+			this.encloseSelection('','',function(str) {
+				str = str.replace(/\r/g,'');
+				return '* '+str.replace(/\n/g,"\n* ");
+			});
+		},
+		xhtml: function() {
+			this.encloseSelection('','',function(str) {
+				str = str.replace(/\r/g,'');
+				str = str.replace(/\n/g,"</li>\n <li>");
+				return "<ul>\n <li>"+str+"</li>\n</ul>";
+			});
+		}
+	}
+};
+
+// ol
+jsToolBar.prototype.elements.ol = {
+	type: 'button',
+	title: 'Ordered list',
+	fn: {
+		wiki: function() {
+			this.encloseSelection('','',function(str) {
+				str = str.replace(/\r/g,'');
+				return '# '+str.replace(/\n/g,"\n# ");
+			});
+		},
+		xhtml: function() {
+			this.encloseSelection('','',function(str) {
+				str = str.replace(/\r/g,'');
+				str = str.replace(/\n/g,"</li>\n <li>");
+				return "<ol>\n <li>"+str+"</li>\n</ol>";
+			});
+		}
+	}
+};
+
+// spacer
+jsToolBar.prototype.elements.space3 = {type: 'space'};
+
+// link
+jsToolBar.prototype.elements.link = {
+	type: 'button',
+	title: 'Link',
+	fn: {},
+	href_prompt: 'Please give page URL:',
+	hreflang_prompt: 'Language of this page:',
+	default_hreflang: '',
+	prompt: function(href,hreflang) {
+		href = href || '';
+		hreflang = hreflang || this.elements.link.default_hreflang;
+		
+		href = window.prompt(this.elements.link.href_prompt,href);
+		if (!href) { return false; }
+		
+		hreflang = window.prompt(this.elements.link.hreflang_prompt,
+		hreflang);
+		
+		return { href: this.stripBaseURL(href), hreflang: hreflang };
+	}
+};
+
+jsToolBar.prototype.elements.link.fn.xhtml = function() {
+	var link = this.elements.link.prompt.call(this);
+	if (link) {
+		var stag = '<a href="'+link.href+'"';
+		if (link.hreflang) { stag = stag+' hreflang="'+link.hreflang+'"'; }
+		stag = stag+'>';
+		var etag = '</a>';
+		
+		this.encloseSelection(stag,etag);
+	}
+};
+jsToolBar.prototype.elements.link.fn.wiki = function() {
+	var link = this.elements.link.prompt.call(this);
+	if (link) {
+		var stag = '[';
+		var etag = '|'+link.href;
+		if (link.hreflang) { etag = etag+'|'+link.hreflang; }
+		etag = etag+']';
+		
+		this.encloseSelection(stag,etag);
+	}
+};
+
+// img
+jsToolBar.prototype.elements.img = {
+		type: 'button',
+		title: 'External image',
+		src_prompt: 'Please give image URL:',
+		fn: {},
+		prompt: function(src) {
+			src = src || '';
+			return this.stripBaseURL(window.prompt(this.elements.img.src_prompt,src));
+		}
+};
+jsToolBar.prototype.elements.img.fn.xhtml = function() {
+	var src = this.elements.img.prompt.call(this);
+	if (src) {
+		this.encloseSelection('','',function(str) {
+			if (str) {
+				return '<img src="'+src+'" alt="'+str+'" />';
+			} else {
+				return '<img src="'+src+'" alt="" />';
+			}
+		});
+	}
+};
+jsToolBar.prototype.elements.img.fn.wiki = function() {
+	var src = this.elements.img.prompt.call(this);
+	if (src) {
+		this.encloseSelection('','',function(str) {
+			if (str) {
+				return '(('+src+'|'+str+'))';
+			} else {
+				return '(('+src+'))';
+			}
+		});
+	}
+};
Index: admin/js/jsToolBar/jsToolBar.wysiwyg.js
===================================================================
--- admin/js/jsToolBar/jsToolBar.wysiwyg.js	(revision 0)
+++ admin/js/jsToolBar/jsToolBar.wysiwyg.js	(revision 0)
@@ -0,0 +1,798 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * This file is part of DotClear.
+ * Copyright (c) 2005 Nicolas Martin & Olivier Meunier and contributors. All
+ * rights reserved.
+ *
+ * DotClear is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ * 
+ * DotClear is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with DotClear; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * ***** END LICENSE BLOCK *****
+*/
+
+jsToolBar.prototype.can_wwg = (document.designMode != undefined);
+jsToolBar.prototype.iframe = null;
+jsToolBar.prototype.iwin = null;
+jsToolBar.prototype.ibody = null;
+jsToolBar.prototype.iframe_css = null;
+
+/* Editor methods
+-------------------------------------------------------- */
+jsToolBar.prototype.drawToolBar = jsToolBar.prototype.draw;
+jsToolBar.prototype.draw = function(mode) {
+	mode = mode || 'xhtml';
+	
+	if (this.can_wwg) {
+		this.mode = 'wysiwyg';
+		this.drawToolBar('wysiwyg');
+		this.initWindow();
+	} else {
+		this.drawToolBar(mode);
+	}
+};
+
+jsToolBar.prototype.switchMode = function(mode) {
+	mode = mode || 'xhtml';
+	
+	if (mode == 'xhtml') {
+		this.draw(mode);
+	} else {
+		if (this.wwg_mode) {
+			this.syncContents('iframe');
+		}
+		this.removeEditor();
+		this.textarea.style.display = '';
+		this.drawToolBar(mode);
+	}
+};
+
+jsToolBar.prototype.syncContents = function(from) {
+	from = from || 'textarea';
+	var This = this;
+	if (from == 'textarea') {
+		initContent();
+	} else {
+		this.validBlockquote();
+		var html = this.applyHtmlFilters(this.ibody.innerHTML);
+		if (html == '<br />') { html = '<p></p>'; }
+		this.textarea.value = html;
+	}
+	
+	function initContent() {
+		if (!This.iframe.contentWindow.document || !This.iframe.contentWindow.document.body) {
+			setTimeout(initContent, 1);
+			return;
+		}
+		This.ibody = This.iframe.contentWindow.document.body;
+		
+		if (This.textarea.value != '' && This.textarea.value != '<p></p>') {
+			This.ibody.innerHTML = This.applyWysiwygFilters(This.textarea.value);
+			if (This.ibody.createTextRange) { //cursor at the begin for IE
+				var IErange = This.ibody.createTextRange();
+				IErange.execCommand("SelectAll");
+				IErange.collapse();
+				IErange.select();
+			}
+		} else if (window.navigator.product != undefined && 
+							 window.navigator.product == 'Gecko') {
+			This.ibody.innerHTML = '<p><br _moz_editor_blogus_node="TRUE" _moz_dirty=""></p>';
+		} else {
+			var idoc = This.iwin.document;
+			var para = idoc.createElement('p');
+			para.appendChild(idoc.createTextNode(''));
+			while (idoc.body.hasChildNodes()) {
+				idoc.body.removeChild(idoc.body.lastChild);
+			}
+			idoc.body.appendChild(para);
+		}
+	}
+};
+jsToolBar.prototype.htmlFilters = {
+	tagsoup: function(str){
+		return this.tagsoup2xhtml(str);
+	}
+};
+jsToolBar.prototype.applyHtmlFilters = function(str) {
+	for (var fn in this.htmlFilters) {
+		 str = this.htmlFilters[fn].call(this, str);
+	}
+	return str;
+};
+jsToolBar.prototype.wysiwygFilters = {};
+jsToolBar.prototype.applyWysiwygFilters = function( str) {
+	for (var fn in this.wysiwygFilters) {
+		 str = this.wysiwygFilters[fn].call(this, str);
+	}
+	return str;
+};
+
+jsToolBar.prototype.switchEdit = function() {
+	if (this.wwg_mode) {
+		this.textarea.style.display = '';
+		this.iframe.style.display = 'none';
+		this.syncContents('iframe');
+		this.drawToolBar('xhtml');
+		this.wwg_mode = false;
+		this.focusEditor();
+	} else {
+		this.iframe.style.display = '';
+		this.textarea.style.display = 'none';
+		this.syncContents('textarea');
+		this.drawToolBar('wysiwyg');
+		this.wwg_mode = true;
+		this.focusEditor();
+	}
+	this.setSwitcher();
+};
+
+/** Creates iframe for editor, inits a blank document
+*/
+jsToolBar.prototype.initWindow = function() {
+	var This = this;
+	
+	this.iframe = document.createElement('iframe');
+	this.textarea.parentNode.insertBefore(this.iframe,this.textarea.nextSibling);
+	
+	this.switcher = document.createElement('ul');
+	this.switcher.className = 'jstSwitcher';
+	this.editor.appendChild(this.switcher);
+	
+	this.iframe.height = this.textarea.offsetHeight + 0;
+	this.iframe.width = this.textarea.offsetWidth + 0;
+	
+	if (this.textarea.tabIndex != undefined) {
+		this.iframe.tabIndex = this.textarea.tabIndex;
+	}
+	
+	function initIframe() {
+		var doc = This.iframe.contentWindow.document;
+		if (!doc) {
+			setTimeout(initIframe,1);
+			return false;
+		}
+		
+		doc.open();
+		var html =
+		'<html>\n'+
+		'<head>\n'+
+		'<style type="text/css">'+This.iframe_css+'</style>\n'+
+		(This.base_url != '' ? '<base href="'+This.base_url+'" />' : '')+
+		'</head>\n'+
+		'<body>\n'+
+		'</body>\n'+
+		'</html>';
+		
+		doc.write(html);
+		doc.close();
+		if (document.all) { // for IE
+			doc.designMode = 'on';
+			// warning : doc is now inaccessible for IE6 sp1
+		}
+		
+		This.iwin = This.iframe.contentWindow;
+		
+		This.syncContents('textarea');
+		
+		if (This.wwg_mode == undefined) {
+			This.wwg_mode = true;
+		}
+		
+		if (This.wwg_mode) {
+			This.textarea.style.display = 'none';
+		} else {
+			This.iframe.style.display = 'none';
+		}
+		
+		// update textarea on submit
+		if (This.textarea.form) {
+			chainHandler(This.textarea.form,'onsubmit', function() {
+				if (This.wwg_mode) {
+					This.syncContents('iframe');
+				}
+			});
+		}
+		
+		for (var evt in This.iwinEvents) {
+			var event = This.iwinEvents[evt];
+			This.addIwinEvent(This.iframe.contentWindow.document, event.type, event.fn, This);
+		}
+		
+		This.setSwitcher();
+		setTimeout(function(){This.focusEditor();},1);
+		
+		return true;
+	}
+	initIframe();
+};
+jsToolBar.prototype.addIwinEvent = function(target, type, fn, scope) {
+	var myFn = function(e){fn.call(scope, e)};
+	addEvent(target, type, myFn, true);
+	// fix memory leak
+	addEvent(scope.iwin, 'unload', function(){
+		removeEvent(target, type, myFn, true);
+	}, true);
+};
+jsToolBar.prototype.iwinEvents = {
+	block1: {
+		type: 'mouseup',
+		fn: function(){ this.adjustBlockLevelCombo() }
+	},
+	block2: {
+		type: 'keyup',
+		fn: function(){ this.adjustBlockLevelCombo() }
+	}
+};
+
+/** Insert a mode switcher after editor area
+*/
+jsToolBar.prototype.switcher_visual_title = 'visual';
+jsToolBar.prototype.switcher_source_title = 'source';
+jsToolBar.prototype.setSwitcher = function() {
+	while (this.switcher.hasChildNodes()) {
+		this.switcher.removeChild(this.switcher.firstChild);
+	}
+	
+	var This = this;
+	function setLink(title,link) {
+		var li = document.createElement('li');
+		if (link) {
+			var a = document.createElement('a');
+			a.href = '#';
+			a.editor = This;
+			a.onclick = function() { this.editor.switchEdit(); return false; };
+			a.appendChild(document.createTextNode(title));
+		} else {
+			li.className = 'jstSwitcherCurrent';
+			a = document.createTextNode(title);
+		}
+		
+		li.appendChild(a);
+		This.switcher.appendChild(li);
+	}
+	
+	setLink(this.switcher_visual_title,!this.wwg_mode);
+	setLink(this.switcher_source_title,this.wwg_mode);
+};
+
+/** Removes editor area and mode switcher
+*/
+jsToolBar.prototype.removeEditor = function() {
+	if (this.iframe != null) {
+		this.iframe.parentNode.removeChild(this.iframe);
+		this.iframe = null;
+	}
+	
+	if (this.switcher != undefined && this.switcher.parentNode != undefined) {
+		this.switcher.parentNode.removeChild(this.switcher);
+	}
+};
+
+/** Focus on the editor area
+*/
+jsToolBar.prototype.focusEditor = function() {
+	if (this.wwg_mode) {
+		try { this.iwin.document.designMode = 'on'; } catch (e) {}; // Firefox needs this
+		var This = this;
+		setTimeout(function() {This.iframe.contentWindow.focus()},1);
+	} else {
+		this.textarea.focus();
+	}
+};
+
+/** Resizer
+*/
+jsToolBar.prototype.resizeSetStartH = function() {
+	if (this.wwg_mode && this.iframe != undefined) {
+		this.dragStartH = this.iframe.offsetHeight;
+		return;
+	}
+	this.dragStartH = this.textarea.offsetHeight + 0;
+};
+jsToolBar.prototype.resizeDragMove = function(event) {
+	var new_height = (this.dragStartH+event.clientY-this.dragStartY)+'px';
+	if (this.iframe != undefined) {
+		this.iframe.style.height = new_height;
+	}
+	this.textarea.style.height = new_height;
+};
+
+/* Editing methods
+-------------------------------------------------------- */
+/** Replaces current selection by given node
+*/
+jsToolBar.prototype.insertNode = function(node) {
+	var range;
+	
+	if (this.iwin.getSelection) { // Gecko
+		var sel = this.iwin.getSelection();
+		range = sel.getRangeAt(0);
+		
+		// deselect all ranges
+		sel.removeAllRanges();
+		
+		// empty range
+		range.deleteContents();
+		
+		// Insert node
+		range.insertNode(node);
+		
+		range.selectNodeContents(node);
+		range.setEndAfter(node);
+		if (range.endContainer.childNodes.length > range.endOffset &&
+		range.endContainer.nodeType != Node.TEXT_NODE) {
+			range.setEnd(range.endContainer.childNodes[range.endOffset], 0);
+		} else {
+			range.setEnd(range.endContainer.childNodes[0]);
+		}
+		sel.addRange(range);
+		
+		sel.collapseToEnd();
+	} else { // IE
+		// lambda element
+		var p = this.iwin.document.createElement('div');
+		p.appendChild(node);
+		range = this.iwin.document.selection.createRange();
+		range.execCommand('delete');
+		// insert innerHTML from element
+		range.pasteHTML(p.innerHTML);
+		range.collapse(false);
+		range.select();
+	}
+	this.iwin.focus();
+};
+
+/** Returns a document fragment with selected nodes
+*/
+jsToolBar.prototype.getSelectedNode = function() {
+	if (this.iwin.getSelection) { // Gecko
+		var sel = this.iwin.getSelection();
+		var range = sel.getRangeAt(0);
+		var content = range.cloneContents();
+	} else { // IE
+		var sel = this.iwin.document.selection;
+		var d = this.iwin.document.createElement('div');
+		d.innerHTML = sel.createRange().htmlText;
+		var content = this.iwin.document.createDocumentFragment();
+		for (var i=0; i < d.childNodes.length; i++) {
+			content.appendChild(d.childNodes[i].cloneNode(true));
+		}
+	}
+	return content;
+};
+
+/** Returns string representation for selected node
+*/
+jsToolBar.prototype.getSelectedText = function() {
+	if (this.iwin.getSelection) { // Gecko
+		return this.iwin.getSelection().toString();
+	} else { // IE
+		var range = this.iwin.document.selection.createRange();
+		return range.text;
+	}
+};
+
+jsToolBar.prototype.replaceNodeByContent = function(node) {
+	var content = this.iwin.document.createDocumentFragment();
+	for (var i=0; i < node.childNodes.length; i++) {
+		content.appendChild(node.childNodes[i].cloneNode(true));
+	}
+	node.parentNode.replaceChild(content, node);
+};
+
+jsToolBar.prototype.getBlockLevel = function() {
+	var blockElts = ['p','h1','h2','h3','h4','h5','h6'];
+	
+	var range, commonAncestorContainer;
+	if (this.iwin.getSelection) { //gecko
+		var selection = this.iwin.getSelection();
+		range = selection.getRangeAt(0);
+		commonAncestorContainer = range.commonAncestorContainer;
+		while (commonAncestorContainer.nodeType != 1) {
+			commonAncestorContainer = commonAncestorContainer.parentNode;
+		}
+	} else { //ie
+		range = this.iwin.document.selection.createRange();
+		commonAncestorContainer = range.parentElement();
+	}
+	
+	var ancestorTagName = commonAncestorContainer.tagName.toLowerCase();
+	while (arrayIndexOf(blockElts, ancestorTagName)==-1 && ancestorTagName!='body') {
+		commonAncestorContainer = commonAncestorContainer.parentNode;
+		ancestorTagName = commonAncestorContainer.tagName.toLowerCase();
+	}
+	if (ancestorTagName == 'body') return null;
+	else return commonAncestorContainer;
+};
+jsToolBar.prototype.adjustBlockLevelCombo = function() {
+	var blockLevel = this.getBlockLevel();
+	if (blockLevel !== null)
+		this.toolNodes.blocks.value = blockLevel.tagName.toLowerCase();
+	else {
+		if (this.mode == 'wysiwyg') this.toolNodes.blocks.value = 'none';
+		if (this.mode == 'xhtml') this.toolNodes.blocks.value = 'nonebis';
+	}
+};
+
+/** HTML code cleanup
+-------------------------------------------------------- */
+jsToolBar.prototype.simpleCleanRegex = new Array(
+	/* Remove every tags we don't need */
+	[/<meta[\w\W]*?>/gim,''],
+	[/<style[\w\W]*?>[\w\W]*?<\/style>/gim, ''],
+	[/<\/?font[\w\W]*?>/gim, ''],
+	
+	
+	/* Replacements */
+	[/<(\/?)(B|b|STRONG)([\s>\/])/g, "<$1strong$3"],
+	[/<(\/?)(I|i|EM)([\s>\/])/g, "<$1em$3"],
+	[/<IMG ([^>]*?[^\/])>/gi, "<img $1 />"],
+	[/<INPUT ([^>]*?[^\/])>/gi, "<input $1 />"],
+	[/<COL ([^>]*?[^\/])>/gi, "<col $1 />"],
+	[/<AREA ([^>]*?[^\/])>/gi, "<area $1 />"],
+	[/<PARAM ([^>]*?[^\/])>/gi, "<param $1 />"],
+	[/<HR ([^>]*?[^\/])>/gi, "<hr $1/>"],
+	[/<BR ([^>]*?[^\/])>/gi, "<br $1/>"],
+	[/<(\/?)U([\s>\/])/gi, "<$1ins$2"],
+	[/<(\/?)STRIKE([\s>\/])/gi, "<$1del$2"],
+	[/<span style="font-weight: normal;">([\w\W]*?)<\/span>/gm, "$1"],
+	[/<span style="font-weight: bold;">([\w\W]*?)<\/span>/gm, "<strong>$1</strong>"],
+	[/<span style="font-style: italic;">([\w\W]*?)<\/span>/gm, "<em>$1</em>"],
+	[/<span style="text-decoration: underline;">([\w\W]*?)<\/span>/gm, "<ins>$1</ins>"],
+	[/<span style="text-decoration: line-through;">([\w\W]*?)<\/span>/gm, "<del>$1</del>"],
+	[/<span style="text-decoration: underline line-through;">([\w\W]*?)<\/span>/gm, "<del><ins>$1</ins></del>"],
+	[/<span style="(font-weight: bold; ?|font-style: italic; ?){2}">([\w\W]*?)<\/span>/gm, "<strong><em>$2</em></strong>"],
+	[/<span style="(font-weight: bold; ?|text-decoration: underline; ?){2}">([\w\W]*?)<\/span>/gm, "<ins><strong>$2</strong></ins>"],
+	[/<span style="(font-weight: italic; ?|text-decoration: underline; ?){2}">([\w\W]*?)<\/span>/gm, "<ins><em>$2</em></ins>"],
+	[/<span style="(font-weight: bold; ?|text-decoration: line-through; ?){2}">([\w\W]*?)<\/span>/gm, "<del><strong>$2</strong></del>"],
+	[/<span style="(font-weight: italic; ?|text-decoration: line-through; ?){2}">([\w\W]*?)<\/span>/gm, "<del><em>$2</em></del>"],
+	[/<span style="(font-weight: bold; ?|font-style: italic; ?|text-decoration: underline; ?){3}">([\w\W]*?)<\/span>/gm, "<ins><strong><em>$2</em></strong></ins>"],
+	[/<span style="(font-weight: bold; ?|font-style: italic; ?|text-decoration: line-through; ?){3}">([\w\W]*?)<\/span>/gm, "<del><strong><em>$2</em></strong></del>"],
+	[/<span style="(font-weight: bold; ?|font-style: italic; ?|text-decoration: underline line-through; ?){3}">([\w\W]*?)<\/span>/gm, "<del><ins><strong><em>$2</em></strong></ins></del>"],
+	[/<strong style="font-weight: normal;">([\w\W]*?)<\/strong>/gm, "$1"],
+	[/<([a-z]+) style="font-weight: normal;">([\w\W]*?)<\/\1>/gm, "<$1>$2</$1>"],
+	[/<([a-z]+) style="font-weight: bold;">([\w\W]*?)<\/\1>/gm, "<$1><strong>$2</strong></$1>"],
+	[/<([a-z]+) style="font-style: italic;">([\w\W]*?)<\/\1>/gm, "<$1><em>$2</em></$1>"],
+	[/<([a-z]+) style="text-decoration: underline;">([\w\W]*?)<\/\1>/gm, "<ins><$1>$2</$1></ins>"],
+	[/<([a-z]+) style="text-decoration: line-through;">([\w\W]*?)<\/\1>/gm, "<del><$1>$2</$1></del>"],
+	[/<([a-z]+) style="text-decoration: underline line-through;">([\w\W]*?)<\/\1>/gm, "<del><ins><$1>$2</$1></ins></del>"],
+	[/<([a-z]+) style="(font-weight: bold; ?|font-style: italic; ?){2}">([\w\W]*?)<\/\1>/gm, "<$1><strong><em>$3</em></strong></$1>"],
+	[/<([a-z]+) style="(font-weight: bold; ?|text-decoration: underline; ?){2}">([\w\W]*?)<\/\1>/gm, "<ins><$1><strong>$3</strong></$1></ins>"],
+	[/<([a-z]+) style="(font-weight: italic; ?|text-decoration: underline; ?){2}">([\w\W]*?)<\/\1>/gm, "<ins><$1><em>$3</em></$1></ins>"],
+	[/<([a-z]+) style="(font-weight: bold; ?|text-decoration: line-through; ?){2}">([\w\W]*?)<\/\1>/gm, "<del><$1><strong>$3</strong></$1></del>"],
+	[/<([a-z]+) style="(font-weight: italic; ?|text-decoration: line-through; ?){2}">([\w\W]*?)<\/\1>/gm, "<del><$1><em>$3</em></$1></del>"],
+	[/<([a-z]+) style="(font-weight: bold; ?|font-style: italic; ?|text-decoration: underline; ?){3}">([\w\W]*?)<\/\1>/gm, "<ins><$1><strong><em>$3</em></strong></$1></ins>"],
+	[/<([a-z]+) style="(font-weight: bold; ?|font-style: italic; ?|text-decoration: line-through; ?){3}">([\w\W]*?)<\/\1>/gm, "<del><$1><strong><em>$3</em></strong></$1></del>"],
+	[/<([a-z]+) style="(font-weight: bold; ?|font-style: italic; ?|text-decoration: underline line-through; ?){3}">([\w\W]*?)<\/\1>/gm, "<del><ins><$1><strong><em>$3</em></strong></$1></ins></del>"],
+	[/<p><blockquote>(.*)(\n)+<\/blockquote><\/p>/i,"<blockquote>$1</blockquote>\n"],
+	/* mise en forme identique contigue */
+	[/<\/(strong|em|ins|del|q|code)>(\s*?)<\1>/gim, "$2"],
+	[/<(br|BR)>/g, "<br />"],
+	/* opera est trop strict ;)) */
+	[/([^\s])\/>/g, "$1 />"],
+	/* br intempestifs de fin de block */
+	[/<br \/>\s*<\/(h1|h2|h3|h4|h5|h6|ul|ol|li|p|blockquote|div)/gi, "</$1"],
+	[/<\/(h1|h2|h3|h4|h5|h6|ul|ol|li|p|blockquote)>([^\n\u000B\r\f])/gi, "</$1>\n$2"],
+	[/<hr style="width: 100%; height: 2px;" \/>/g, "<hr />"]
+);
+
+/** Cleanup HTML code
+*/
+jsToolBar.prototype.tagsoup2xhtml = function(html) {
+	for (var reg in this.simpleCleanRegex) {
+		html = html.replace(this.simpleCleanRegex[reg][0], this.simpleCleanRegex[reg][1]);
+	}
+	/* tags vides */
+	/* note : on tente de ne pas tenir compte des commentaires html, ceux-ci
+	   permettent entre autre d'inserer des commentaires conditionnels pour ie */
+	while ( /(<[^\/!]>|<[^\/!][^>]*[^\/]>)\s*<\/[^>]*[^-]>/.test(html) ) {
+		html = html.replace(/(<[^\/!]>|<[^\/!][^>]*[^\/]>)\s*<\/[^>]*[^-]>/g, "");
+	}
+	
+	/* tous les tags en minuscule */
+	html = html.replace(/<(\/?)([A-Z0-9]+)/g,
+			function(match0, match1, match2) {
+				return "<" + match1 + match2.toLowerCase();
+			});
+	
+	/* IE laisse souvent des attributs sans guillemets */
+	var myRegexp = /<[^>]+((\s+\w+\s*=\s*)([^"'][\w~@+$,%\/:.#?=&;!*()-]*))[^>]*?>/;
+	while ( myRegexp.test(html)) {
+		html = html.replace(
+			myRegexp,
+			function (str, val1, val2, val3){
+				var tamponRegex = new RegExp(regexpEscape(val1));
+				return str.replace(tamponRegex, val2+'"'+val3+'"');
+			}
+		)
+	}
+	
+	/* les navigateurs rajoutent une unite aux longueurs css nulles */
+	/* note: a ameliorer ! */
+	while ( /(<[^>]+style=(["'])[^>]+[\s:]+)0(pt|px)(\2|\s|;)/.test(html)) {
+		html = html.replace(/(<[^>]+style=(["'])[^>]+[\s:]+)0(pt|px)(\2|\s|;)/gi, "$1"+"0$4");
+	}
+	
+	/* correction des fins de lignes : le textarea edite contient des \n
+	* le wysiwyg des \r\n , et le textarea mis a jour SANS etre affiche des \r\n ! */
+	html = html.replace(/\r\n/g,"\n");
+	
+	/* Trim */
+	html = html.replace(/^\s+/gm,'');
+	html = html.replace(/\s+$/gm,'');
+	
+	return html;
+};
+jsToolBar.prototype.validBlockquote = function() {
+	var blockElts = ['address','blockquote','dl','div','fieldset','form','h1',
+	                 'h2','h3','h4','h5','h6','hr','ol','p','pre','table','ul'];
+	var BQs = this.iwin.document.getElementsByTagName('blockquote');
+	var bqChilds;
+	
+	for (var bq = 0; bq < BQs.length; bq++) {
+		bqChilds = BQs[bq].childNodes;
+		var frag = this.iwin.document.createDocumentFragment();
+		for (var i = (bqChilds.length-1); i >= 0; i--) {
+			if (bqChilds[i].nodeType == 1 && // Node.ELEMENT_NODE
+			    arrayIndexOf(blockElts, bqChilds[i].tagName.toLowerCase()) >= 0)
+			{
+				if (frag.childNodes.length > 0) {
+					var p = this.iwin.document.createElement('p');
+					p.appendChild(frag);
+					BQs[bq].replaceChild(p, bqChilds[i+1]);
+					frag = this.iwin.document.createDocumentFragment();
+				}
+			} else {
+				if (frag.childNodes.length > 0) BQs[bq].removeChild(bqChilds[i+1]);
+				frag.insertBefore(bqChilds[i].cloneNode(true), frag.firstChild);
+			}
+		}
+		if (frag.childNodes.length > 0) {
+			var p = this.iwin.document.createElement('p');
+			p.appendChild(frag);
+			BQs[bq].replaceChild(p, bqChilds[0]);
+		}
+	}
+};
+
+/* Removing text formating */
+jsToolBar.prototype.removeFormatRegexp = new Array(
+	[/(<[a-z][^>]*)margin\s*:[^;]*;/mg, "$1"],
+	[/(<[a-z][^>]*)margin-bottom\s*:[^;]*;/mg, "$1"],
+	[/(<[a-z][^>]*)margin-left\s*:[^;]*;/mg, "$1"],
+	[/(<[a-z][^>]*)margin-right\s*:[^;]*;/mg, "$1"],
+	[/(<[a-z][^>]*)margin-top\s*:[^;]*;/mg, "$1"],
+	
+	[/(<[a-z][^>]*)padding\s*:[^;]*;/mg, "$1"],
+	[/(<[a-z][^>]*)padding-bottom\s*:[^;]*;/mg, "$1"],
+	[/(<[a-z][^>]*)padding-left\s*:[^;]*;/mg, "$1"],
+	[/(<[a-z][^>]*)padding-right\s*:[^;]*;/mg, "$1"],
+	[/(<[a-z][^>]*)padding-top\s*:[^;]*;/mg, "$1"],
+	
+	[/(<[a-z][^>]*)font\s*:[^;]*;/mg, "$1"],
+	[/(<[a-z][^>]*)font-family\s*:[^;]*;/mg, "$1"],
+	[/(<[a-z][^>]*)font-size\s*:[^;]*;/mg, "$1"],
+	[/(<[a-z][^>]*)font-style\s*:[^;]*;/mg, "$1"],
+	[/(<[a-z][^>]*)font-variant\s*:[^;]*;/mg, "$1"],
+	[/(<[a-z][^>]*)font-weight\s*:[^;]*;/mg, "$1"],
+	
+	[/(<[a-z][^>]*)color\s*:[^;]*;/mg, "$1"]
+);
+
+jsToolBar.prototype.removeTextFormating = function(html) {
+	for (var reg in this.removeFormatRegexp) {
+		html = html.replace(this.removeFormatRegexp[reg][0], this.removeFormatRegexp[reg][1]);
+	}
+	
+	html = this.tagsoup2xhtml(html);
+	html = html.replace(/style="\s*?"/mgi,'');
+	return html;
+};
+
+/** Toolbar elements
+-------------------------------------------------------- */
+jsToolBar.prototype.elements.blocks.wysiwyg = {
+	list: ['none','p','h1','h2','h3','h4','h5','h6'],
+	fn: function(opt) {
+		if (opt=='none') {
+			var blockLevel = this.getBlockLevel();
+			if (blockLevel !== null) {
+				this.replaceNodeByContent(blockLevel);
+			}
+			this.iwin.focus();
+		} else {
+			try { this.iwin.document.execCommand('formatblock',false,'<'+opt+'>');
+			} catch(e){};
+			this.iwin.focus();
+		}
+	}
+};
+
+jsToolBar.prototype.elements.strong.fn.wysiwyg = function() {
+	this.iwin.document.execCommand('bold', false, null);
+	this.iwin.focus();
+};
+
+jsToolBar.prototype.elements.em.fn.wysiwyg = function() {
+	this.iwin.document.execCommand('italic', false, null);
+	this.iwin.focus();
+};
+
+jsToolBar.prototype.elements.ins.fn.wysiwyg = function() {
+	this.iwin.document.execCommand('underline', false, null);
+	this.iwin.focus();
+};
+
+jsToolBar.prototype.elements.del.fn.wysiwyg = function() {
+	this.iwin.document.execCommand('strikethrough', false, null);
+	this.iwin.focus();
+};
+
+jsToolBar.prototype.elements.quote.fn.wysiwyg = function() {
+	var n = this.getSelectedNode();
+	var q = this.iwin.document.createElement('q');
+	q.appendChild(n);
+	this.insertNode(q);
+};
+
+jsToolBar.prototype.elements.code.fn.wysiwyg = function() {
+	var n = this.getSelectedNode();
+	var code = this.iwin.document.createElement('code');
+	code.appendChild(n);
+	this.insertNode(code);
+};
+
+jsToolBar.prototype.elements.br.fn.wysiwyg = function() {
+	var n = this.iwin.document.createElement('br');
+	this.insertNode(n);
+};
+
+jsToolBar.prototype.elements.blockquote.fn.wysiwyg = function() {
+	var n = this.getSelectedNode();
+	var q = this.iwin.document.createElement('blockquote');
+	q.appendChild(n);
+	this.insertNode(q);
+};
+
+jsToolBar.prototype.elements.pre.fn.wysiwyg = function() {
+	this.iwin.document.execCommand('formatblock',false,'<pre>');
+	this.iwin.focus();
+};
+
+jsToolBar.prototype.elements.ul.fn.wysiwyg = function() {
+	this.iwin.document.execCommand('insertunorderedlist',false,null);
+	this.iwin.focus();
+};
+
+jsToolBar.prototype.elements.ol.fn.wysiwyg = function() {
+	this.iwin.document.execCommand('insertorderedlist',false,null);
+	this.iwin.focus();
+};
+
+jsToolBar.prototype.elements.link.fn.wysiwyg = function() {
+	var href, hreflang;
+	var range, commonAncestorContainer;
+	if (this.iwin.getSelection) { //gecko
+		var selection = this.iwin.getSelection();
+		range = selection.getRangeAt(0);
+		commonAncestorContainer = range.commonAncestorContainer;
+		while (commonAncestorContainer.nodeType != 1) {
+			commonAncestorContainer = commonAncestorContainer.parentNode;
+		}
+	} else { //ie
+		range = this.iwin.document.selection.createRange();
+		commonAncestorContainer = range.parentElement();
+	}
+	
+	var ancestorTagName = commonAncestorContainer.tagName.toLowerCase();
+	while (ancestorTagName!='a' && ancestorTagName!='body') {
+		commonAncestorContainer = commonAncestorContainer.parentNode;
+		ancestorTagName = commonAncestorContainer.tagName.toLowerCase();
+	}
+	
+	// Update or remove link?
+	if (ancestorTagName == 'a') {
+		href = commonAncestorContainer.href || '';
+		hreflang = commonAncestorContainer.hreflang || '';
+	}
+	
+	href = window.prompt(this.elements.link.href_prompt,href);
+	
+	// Remove link
+	if (ancestorTagName == 'a' && href=='') {
+		this.replaceNodeByContent(commonAncestorContainer);
+	}
+	if (!href) return; // user cancel
+	
+	hreflang = window.prompt(this.elements.link.hreflang_prompt, hreflang);
+	
+	// Update link
+	if (ancestorTagName == 'a' && href) {
+		commonAncestorContainer.setAttribute('href', href);
+		if (hreflang) {
+			commonAncestorContainer.setAttribute('hreflang', hreflang);
+		} else {
+			commonAncestorContainer.removeAttribute('hreflang');
+		}
+		return;
+	}
+	
+	// Create link
+	var n = this.getSelectedNode();
+	var a = this.iwin.document.createElement('a');
+	a.href = href;
+	if (hreflang) a.setAttribute('hreflang',hreflang);
+	a.appendChild(n);
+	this.insertNode(a);
+};
+
+
+
+// Remove format and Toggle
+jsToolBar.prototype.elements.removeFormat = {
+	type: 'button',
+	title: 'Remove text formating',
+	fn: {}
+};
+jsToolBar.prototype.elements.removeFormat.disabled = !jsToolBar.prototype.can_wwg;
+jsToolBar.prototype.elements.removeFormat.fn.xhtml = function() {
+	var html = this.textarea.value;
+	html = this.removeTextFormating(html);
+	this.textarea.value = html;
+};
+jsToolBar.prototype.elements.removeFormat.fn.wysiwyg = function() {
+	var html = this.iwin.document.body.innerHTML;
+	html = this.removeTextFormating(html);
+	this.iwin.document.body.innerHTML = html;
+};
+/** Utilities
+-------------------------------------------------------- */
+function arrayIndexOf(aArray, aValue){
+	if (typeof Array.indexOf == 'function') {
+		return aArray.indexOf(aValue);
+	} else {
+		var index = -1;
+		var l = aArray.length;
+		for (var i = 0; i < l ; i++) {
+			if (aArray[i] === aValue) {
+				index = i;
+				break;
+			}
+		}
+		return index;
+	}
+};
+function addEvent(obj, evType, fn, useCapture) {
+	if (obj.addEventListener){
+		obj.addEventListener(evType, fn, useCapture);
+		return true;
+	} else if (obj.attachEvent){
+		var r = obj.attachEvent("on"+evType, fn);
+		return r;
+	} else {
+		return false;
+	}
+};
+function removeEvent(obj, evType, fn, useCapture) {
+	if (obj.removeEventListener){
+		obj.removeEventListener(evType, fn, useCapture);
+		return true;
+	} else if (obj.detachEvent){
+		var r = obj.detachEvent("on"+evType, fn);
+		return r;
+	} else {
+		return false;
+  }
+};
+function regexpEscape(s) {
+	return s.replace(/([\\\^\$*+[\]?{}.=!:(|)])/g,"\\$1")
+};
Index: admin/js/jsToolBar/popup_link.js
===================================================================
--- admin/js/jsToolBar/popup_link.js	(revision 0)
+++ admin/js/jsToolBar/popup_link.js	(revision 0)
@@ -0,0 +1,23 @@
+$(function() {
+	$('#link-insert-cancel').click(function() {
+		window.close();
+	});
+	
+	$('#link-insert-ok').click(function() {
+		sendClose();
+		window.close();
+	});
+	
+	function sendClose() {
+		var insert_form = $('#link-insert-form').get(0);
+		if (insert_form == undefined) { return; }
+		
+		var tb = window.opener.the_toolbar;
+		var data = tb.elements.link.data;
+		
+		data.href = tb.stripBaseURL(insert_form.elements.href.value);
+		data.title = insert_form.elements.title.value;
+		data.hreflang = insert_form.elements.hreflang.value;
+		tb.elements.link.fncall[tb.mode].call(tb);
+	};
+});
Index: admin/js/jsToolBar/popup_media.js
===================================================================
--- admin/js/jsToolBar/popup_media.js	(revision 0)
+++ admin/js/jsToolBar/popup_media.js	(revision 0)
@@ -0,0 +1,92 @@
+$(function() {
+	var toolBar = window.opener.the_toolbar.textarea;
+	
+	$('#media-insert').onetabload(function() {
+		$('#media-insert-cancel').click(function() {
+			window.close();
+		});
+		
+		$('#media-insert-ok').click(function() {
+			sendClose();
+			window.close();
+		});
+	});
+	
+	function sendClose() {
+		var insert_form = $('#media-insert-form').get(0);
+		if (insert_form == undefined) { return; }
+		
+		var tb = window.opener.the_toolbar;
+		var type = insert_form.elements.type.value;
+		
+		var media_align_grid = {
+			left: 'float: left; margin: 0 1em 1em 0;',
+			right: 'float: right; margin: 0 0 1em 1em;',
+			center: 'text-align: center;'
+		};
+		
+		if (type == 'image')
+		{
+			tb.elements.img_select.data.src = tb.stripBaseURL($('input[name="src"]:checked',insert_form).val());
+			tb.elements.img_select.data.alignment = $('input[name="alignment"]:checked',insert_form).val();
+			tb.elements.img_select.data.link = $('input[name="insertion"]:checked',insert_form).val() == 'link';
+			
+			tb.elements.img_select.data.title = insert_form.elements.title.value;
+			tb.elements.img_select.data.description = $('input[name="description"]',insert_form).val();
+			tb.elements.img_select.data.url = tb.stripBaseURL(insert_form.elements.url.value);
+			tb.elements.img_select.fncall[tb.mode].call(tb);
+		}
+		else if (type == 'mp3')
+		{
+			var player = $('#public_player').val();
+			var align = $('input[name="alignment"]:checked',insert_form).val();
+			
+			if (align != undefined && align != 'none') {
+				player = '<div style="' + media_align_grid[align] + '">' + player + '</div>';
+			}
+			
+			tb.elements.mp3_insert.data.player = player.replace(/>/g,'>\n');
+			tb.elements.mp3_insert.fncall[tb.mode].call(tb);
+		}
+		else if (type == 'flv')
+		{
+			var oplayer = $('<div>'+$('#public_player').val()+'</div>');
+			var flashvars = $("[name=FlashVars]",oplayer).val();
+			
+			var align = $('input[name="alignment"]:checked',insert_form).val();
+			var title = insert_form.elements.title.value;
+			
+			if (title) {
+				flashvars = 'title='+encodeURI(title)+'&amp;'+flashvars;
+			}
+			$('object',oplayer).attr('width',$('#video_w').val());
+			$('object',oplayer).attr('height',$('#video_h').val());
+			flashvars = flashvars.replace(/(width=\d*)/,'width='+$('#video_w').val());
+			flashvars = flashvars.replace(/(height=\d*)/,'height='+$('#video_h').val());
+			
+			$("[name=FlashVars]",oplayer).val(flashvars);
+			var player = oplayer.html();	
+			
+			if (align != undefined && align != 'none') {
+				player = '<div style="' + media_align_grid[align] + '">' + player + '</div>';
+			}
+			
+			tb.elements.flv_insert.data.player = player.replace(/>/g,'>\n');
+			tb.elements.flv_insert.fncall[tb.mode].call(tb);
+		}
+		else
+		{
+			tb.elements.link.data.href = tb.stripBaseURL(insert_form.elements.url.value);
+			tb.elements.link.data.content = insert_form.elements.title.value;
+			tb.elements.link.fncall[tb.mode].call(tb);
+		}
+	};
+	
+	function playerFormat(s) {
+		s = s.replace(/&lt;/g,'<');
+		s = s.replace(/&gt;/g,'>\n');
+		s = s.replace(/&amp;/g,'&');
+		
+		return s;
+	};
+});
Index: admin/js/jsToolBar/popup_posts.js
===================================================================
--- admin/js/jsToolBar/popup_posts.js	(revision 0)
+++ admin/js/jsToolBar/popup_posts.js	(revision 0)
@@ -0,0 +1,16 @@
+$(function() {
+	$('#link-insert-cancel').click(function() {
+		window.close();
+	});
+	
+	$('#form-entries tr>td.maximal>a').click(function() {
+		// Get post_id
+		var tb = window.opener.the_toolbar;
+		var data = tb.elements.link.data;
+		
+		data.href = tb.stripBaseURL($(this).attr('title'));
+		
+		tb.elements.link.fncall[tb.mode].call(tb);
+		window.close();
+	});
+});
Index: admin/js/jsUpload/jquery.fileupload-process.js
===================================================================
--- admin/js/jsUpload/jquery.fileupload-process.js	(revision 1320)
+++ 	(revision )
@@ -1,164 +1,0 @@
-/*
- * jQuery File Upload Processing Plugin 1.2.2
- * https://github.com/blueimp/jQuery-File-Upload
- *
- * Copyright 2012, Sebastian Tschan
- * https://blueimp.net
- *
- * Licensed under the MIT license:
- * http://www.opensource.org/licenses/MIT
- */
-
-/*jslint nomen: true, unparam: true */
-/*global define, window */
-
-(function (factory) {
-    'use strict';
-    if (typeof define === 'function' && define.amd) {
-        // Register as an anonymous AMD module:
-        define([
-            'jquery',
-            './jquery.fileupload'
-        ], factory);
-    } else {
-        // Browser globals:
-        factory(
-            window.jQuery
-        );
-    }
-}(function ($) {
-    'use strict';
-
-    var originalAdd = $.blueimp.fileupload.prototype.options.add;
-
-    // The File Upload Processing plugin extends the fileupload widget
-    // with file processing functionality:
-    $.widget('blueimp.fileupload', $.blueimp.fileupload, {
-
-        options: {
-            // The list of processing actions:
-            processQueue: [
-                /*
-                {
-                    action: 'log',
-                    type: 'debug'
-                }
-                */
-            ],
-            add: function (e, data) {
-                var $this = $(this);
-                data.process(function () {
-                    return $this.fileupload('process', data);
-                });
-                originalAdd.call(this, e, data);
-            }
-        },
-
-        processActions: {
-            /*
-            log: function (data, options) {
-                console[options.type](
-                    'Processing "' + data.files[data.index].name + '"'
-                );
-            }
-            */
-        },
-
-        _processFile: function (data) {
-            var that = this,
-                dfd = $.Deferred().resolveWith(that, [data]),
-                chain = dfd.promise();
-            this._trigger('process', null, data);
-            $.each(data.processQueue, function (i, settings) {
-                var func = function (data) {
-                    return that.processActions[settings.action].call(
-                        that,
-                        data,
-                        settings
-                    );
-                };
-                chain = chain.pipe(func, settings.always && func);
-            });
-            chain
-                .done(function () {
-                    that._trigger('processdone', null, data);
-                    that._trigger('processalways', null, data);
-                })
-                .fail(function () {
-                    that._trigger('processfail', null, data);
-                    that._trigger('processalways', null, data);
-                });
-            return chain;
-        },
-
-        // Replaces the settings of each processQueue item that
-        // are strings starting with an "@", using the remaining
-        // substring as key for the option map,
-        // e.g. "@autoUpload" is replaced with options.autoUpload:
-        _transformProcessQueue: function (options) {
-            var processQueue = [];
-            $.each(options.processQueue, function () {
-                var settings = {},
-                    action = this.action,
-                    prefix = this.prefix === true ? action : this.prefix;
-                $.each(this, function (key, value) {
-                    if ($.type(value) === 'string' &&
-                            value.charAt(0) === '@') {
-                        settings[key] = options[
-                            value.slice(1) || (prefix ? prefix +
-                                key.charAt(0).toUpperCase() + key.slice(1) : key)
-                        ];
-                    } else {
-                        settings[key] = value;
-                    }
-
-                });
-                processQueue.push(settings);
-            });
-            options.processQueue = processQueue;
-        },
-
-        // Returns the number of files currently in the processsing queue:
-        processing: function () {
-            return this._processing;
-        },
-
-        // Processes the files given as files property of the data parameter,
-        // returns a Promise object that allows to bind callbacks:
-        process: function (data) {
-            var that = this,
-                options = $.extend({}, this.options, data);
-            if (options.processQueue && options.processQueue.length) {
-                this._transformProcessQueue(options);
-                if (this._processing === 0) {
-                    this._trigger('processstart');
-                }
-                $.each(data.files, function (index) {
-                    var opts = index ? $.extend({}, options) : options,
-                        func = function () {
-                            return that._processFile(opts);
-                        };
-                    opts.index = index;
-                    that._processing += 1;
-                    that._processingQueue = that._processingQueue.pipe(func, func)
-                        .always(function () {
-                            that._processing -= 1;
-                            if (that._processing === 0) {
-                                that._trigger('processstop');
-                            }
-                        });
-                });
-            }
-            return this._processingQueue;
-        },
-
-        _create: function () {
-            this._super();
-            this._processing = 0;
-            this._processingQueue = $.Deferred().resolveWith(this)
-                .promise();
-        }
-
-    });
-
-}));
Index: admin/js/jsUpload/jquery.fileupload-resize.js
===================================================================
--- admin/js/jsUpload/jquery.fileupload-resize.js	(revision 1144)
+++ 	(revision )
@@ -1,212 +1,0 @@
-/*
- * jQuery File Upload Image Resize Plugin 1.1.2
- * https://github.com/blueimp/jQuery-File-Upload
- *
- * Copyright 2013, Sebastian Tschan
- * https://blueimp.net
- *
- * Licensed under the MIT license:
- * http://www.opensource.org/licenses/MIT
- */
-
-/*jslint nomen: true, unparam: true, regexp: true */
-/*global define, window */
-
-(function (factory) {
-    'use strict';
-    if (typeof define === 'function' && define.amd) {
-        // Register as an anonymous AMD module:
-        define([
-            'jquery',
-            'load-image',
-            'canvas-to-blob',
-            './jquery.fileupload-process'
-        ], factory);
-    } else {
-        // Browser globals:
-        factory(
-            window.jQuery,
-            window.loadImage
-        );
-    }
-}(function ($, loadImage) {
-    'use strict';
-
-    // Prepend to the default processQueue:
-    $.blueimp.fileupload.prototype.options.processQueue.unshift(
-        {
-            action: 'loadImage',
-            fileTypes: '@loadImageFileTypes',
-            maxFileSize: '@loadImageMaxFileSize',
-            noRevoke: '@loadImageNoRevoke',
-            disabled: '@disableImageLoad'
-        },
-        {
-            action: 'resizeImage',
-            maxWidth: '@imageMaxWidth',
-            maxHeight: '@imageMaxHeight',
-            minWidth: '@imageMinWidth',
-            minHeight: '@imageMinHeight',
-            crop: '@imageCrop',
-            disabled: '@disableImageResize'
-        },
-        {
-            action: 'saveImage',
-            disabled: '@disableImageResize'
-        },
-        {
-            action: 'resizeImage',
-            maxWidth: '@previewMaxWidth',
-            maxHeight: '@previewMaxHeight',
-            minWidth: '@previewMinWidth',
-            minHeight: '@previewMinHeight',
-            crop: '@previewCrop',
-            canvas: '@previewAsCanvas',
-            disabled: '@disableImagePreview'
-        },
-        {
-            action: 'setImage',
-            // The name of the property the resized image
-            // is saved as on the associated file object:
-            name: 'preview',
-            disabled: '@disableImagePreview'
-        }
-    );
-
-    // The File Upload Resize plugin extends the fileupload widget
-    // with image resize functionality:
-    $.widget('blueimp.fileupload', $.blueimp.fileupload, {
-
-        options: {
-            // The regular expression for the types of images to load:
-            // matched against the file type:
-            loadImageFileTypes: /^image\/(gif|jpeg|png)$/,
-            // The maximum file size of images to load:
-            loadImageMaxFileSize: 5000000, // 5MB
-            // The maximum width of resized images:
-            imageMaxWidth: 1920,
-            // The maximum height of resized images:
-            imageMaxHeight: 1080,
-            // Define if resized images should be cropped or only scaled:
-            imageCrop: false,
-            // Disable the resize image functionality by default:
-            disableImageResize: true,
-            // The maximum width of the preview images:
-            previewMaxWidth: 80,
-            // The maximum height of the preview images:
-            previewMaxHeight: 80,
-            // Define if preview images should be cropped or only scaled:
-            previewCrop: false,
-            // Define if preview images should be resized as canvas elements:
-            previewAsCanvas: true
-        },
-
-        processActions: {
-
-            // Loads the image given via data.files and data.index
-            // as img element if the browser supports canvas.
-            // Accepts the options fileTypes (regular expression)
-            // and maxFileSize (integer) to limit the files to load:
-            loadImage: function (data, options) {
-                if (options.disabled) {
-                    return data;
-                }
-                var that = this,
-                    file = data.files[data.index],
-                    dfd = $.Deferred();
-                if (($.type(options.maxFileSize) === 'number' &&
-                            file.size > options.maxFileSize) ||
-                        (options.fileTypes &&
-                            !options.fileTypes.test(file.type)) ||
-                        !loadImage(
-                            file,
-                            function (img) {
-                                if (!img.src) {
-                                    return dfd.rejectWith(that, [data]);
-                                }
-                                data.img = img;
-                                dfd.resolveWith(that, [data]);
-                            },
-                            options
-                        )) {
-                    dfd.rejectWith(that, [data]);
-                }
-                return dfd.promise();
-            },
-
-            // Resizes the image given as data.canvas or data.img
-            // and updates data.canvas or data.img with the resized image.
-            // Accepts the options maxWidth, maxHeight, minWidth,
-            // minHeight, canvas and crop:
-            resizeImage: function (data, options) {
-                options = $.extend({canvas: true}, options);
-                var img = (options.canvas && data.canvas) || data.img,
-                    canvas;
-                if (img && !options.disabled) {
-                    canvas = loadImage.scale(img, options);
-                    if (canvas && (canvas.width !== img.width ||
-                            canvas.height !== img.height)) {
-                        data[canvas.getContext ? 'canvas' : 'img'] = canvas;
-                    }
-                }
-                return data;
-            },
-
-            // Saves the processed image given as data.canvas
-            // inplace at data.index of data.files:
-            saveImage: function (data, options) {
-                if (!data.canvas || options.disabled) {
-                    return data;
-                }
-                var that = this,
-                    file = data.files[data.index],
-                    name = file.name,
-                    dfd = $.Deferred(),
-                    callback = function (blob) {
-                        if (!blob.name) {
-                            if (file.type === blob.type) {
-                                blob.name = file.name;
-                            } else if (file.name) {
-                                blob.name = file.name.replace(
-                                    /\..+$/,
-                                    '.' + blob.type.substr(6)
-                                );
-                            }
-                        }
-                        // Store the created blob at the position
-                        // of the original file in the files list:
-                        data.files[data.index] = blob;
-                        dfd.resolveWith(that, [data]);
-                    };
-                // Use canvas.mozGetAsFile directly, to retain the filename, as
-                // Gecko doesn't support the filename option for FormData.append:
-                if (data.canvas.mozGetAsFile) {
-                    callback(data.canvas.mozGetAsFile(
-                        (/^image\/(jpeg|png)$/.test(file.type) && name) ||
-                            ((name && name.replace(/\..+$/, '')) ||
-                                'blob') + '.png',
-                        file.type
-                    ));
-                } else if (data.canvas.toBlob) {
-                    data.canvas.toBlob(callback, file.type);
-                } else {
-                    return data;
-                }
-                return dfd.promise();
-            },
-
-            // Sets the resized version of the image as a property of the
-            // file object, must be called after "saveImage":
-            setImage: function (data, options) {
-                var img = data.canvas || data.img;
-                if (img && !options.disabled) {
-                    data.files[data.index][options.name] = img;
-                }
-                return data;
-            }
-
-        }
-
-    });
-
-}));
Index: admin/js/jsUpload/jquery.fileupload-ui.js
===================================================================
--- admin/js/jsUpload/jquery.fileupload-ui.js	(revision 1320)
+++ 	(revision )
@@ -1,643 +1,0 @@
-/*
- * jQuery File Upload User Interface Plugin 8.7.1
- * https://github.com/blueimp/jQuery-File-Upload
- *
- * Copyright 2010, Sebastian Tschan
- * https://blueimp.net
- *
- * Licensed under the MIT license:
- * http://www.opensource.org/licenses/MIT
- */
-
-/*jslint nomen: true, unparam: true, regexp: true */
-/*global define, window, URL, webkitURL, FileReader */
-
-(function (factory) {
-    'use strict';
-    if (typeof define === 'function' && define.amd) {
-        // Register as an anonymous AMD module:
-        define([
-            'jquery',
-            'tmpl',
-            './jquery.fileupload-image',
-            './jquery.fileupload-audio',
-            './jquery.fileupload-video',
-            './jquery.fileupload-validate'
-        ], factory);
-    } else {
-        // Browser globals:
-        factory(
-            window.jQuery,
-            window.tmpl
-        );
-    }
-}(function ($, tmpl, loadImage) {
-    'use strict';
-
-    $.blueimp.fileupload.prototype._specialOptions.push(
-        'filesContainer',
-        'uploadTemplateId',
-        'downloadTemplateId'
-    );
-
-    // The UI version extends the file upload widget
-    // and adds complete user interface interaction:
-    $.widget('blueimp.fileupload', $.blueimp.fileupload, {
-
-        options: {
-            // By default, files added to the widget are uploaded as soon
-            // as the user clicks on the start buttons. To enable automatic
-            // uploads, set the following option to true:
-            autoUpload: false,
-            // The ID of the upload template:
-            uploadTemplateId: 'template-upload',
-            // The ID of the download template:
-            downloadTemplateId: 'template-download',
-            // The container for the list of files. If undefined, it is set to
-            // an element with class "files" inside of the widget element:
-            filesContainer: undefined,
-            // By default, files are appended to the files container.
-            // Set the following option to true, to prepend files instead:
-            prependFiles: false,
-            // The expected data type of the upload response, sets the dataType
-            // option of the $.ajax upload requests:
-            dataType: 'json',
-
-            // Function returning the current number of files,
-            // used by the maxNumberOfFiles validation:
-            getNumberOfFiles: function () {
-                return this.filesContainer.children().length;
-            },
-
-            // Callback to retrieve the list of files from the server response:
-            getFilesFromResponse: function (data) {
-                if (data.result && $.isArray(data.result.files)) {
-                    return data.result.files;
-                }
-                return [];
-            },
-
-            // The add callback is invoked as soon as files are added to the fileupload
-            // widget (via file input selection, drag & drop or add API call).
-            // See the basic file upload widget for more information:
-            add: function (e, data) {
-                var $this = $(this),
-                    that = $this.data('blueimp-fileupload') ||
-                        $this.data('fileupload'),
-                    options = that.options,
-                    files = data.files;
-                data.process(function () {
-                    return $this.fileupload('process', data);
-                }).always(function () {
-                    data.context = that._renderUpload(files).data('data', data);
-                    that._renderPreviews(data);
-                    options.filesContainer[
-                        options.prependFiles ? 'prepend' : 'append'
-                    ](data.context);
-                    that._forceReflow(data.context);
-                    that._transition(data.context).done(
-                        function () {
-                            if ((that._trigger('added', e, data) !== false) &&
-                                    (options.autoUpload || data.autoUpload) &&
-                                    data.autoUpload !== false && !data.files.error) {
-                                data.submit();
-                            }
-                        }
-                    );
-                });
-            },
-            // Callback for the start of each file upload request:
-            send: function (e, data) {
-                var that = $(this).data('blueimp-fileupload') ||
-                        $(this).data('fileupload');
-                if (data.context && data.dataType &&
-                        data.dataType.substr(0, 6) === 'iframe') {
-                    // Iframe Transport does not support progress events.
-                    // In lack of an indeterminate progress bar, we set
-                    // the progress to 100%, showing the full animated bar:
-                    data.context
-                        .find('.progress').addClass(
-                            !$.support.transition && 'progress-animated'
-                        )
-                        .attr('aria-valuenow', 100)
-                        .find('.bar').css(
-                            'width',
-                            '100%'
-                        );
-                }
-                return that._trigger('sent', e, data);
-            },
-            // Callback for successful uploads:
-            done: function (e, data) {
-                var that = $(this).data('blueimp-fileupload') ||
-                        $(this).data('fileupload'),
-                    getFilesFromResponse = data.getFilesFromResponse ||
-                        that.options.getFilesFromResponse,
-                    files = getFilesFromResponse(data),
-                    template,
-                    deferred;
-                if (data.context) {
-                    data.context.each(function (index) {
-                        var file = files[index] ||
-                                {error: 'Empty file upload result'};
-                        deferred = that._addFinishedDeferreds();
-                        that._transition($(this)).done(
-                            function () {
-                                var node = $(this);
-                                template = that._renderDownload([file])
-                                    .replaceAll(node);
-                                that._forceReflow(template);
-                                that._transition(template).done(
-                                    function () {
-                                        data.context = $(this);
-                                        that._trigger('completed', e, data);
-                                        that._trigger('finished', e, data);
-                                        deferred.resolve();
-                                    }
-                                );
-                            }
-                        );
-                    });
-                } else {
-                    template = that._renderDownload(files)[
-                        that.options.prependFiles ? 'prependTo' : 'appendTo'
-                    ](that.options.filesContainer);
-                    that._forceReflow(template);
-                    deferred = that._addFinishedDeferreds();
-                    that._transition(template).done(
-                        function () {
-                            data.context = $(this);
-                            that._trigger('completed', e, data);
-                            that._trigger('finished', e, data);
-                            deferred.resolve();
-                        }
-                    );
-                }
-            },
-            // Callback for failed (abort or error) uploads:
-            fail: function (e, data) {
-                var that = $(this).data('blueimp-fileupload') ||
-                        $(this).data('fileupload'),
-                    template,
-                    deferred;
-                if (data.context) {
-                    data.context.each(function (index) {
-                        if (data.errorThrown !== 'abort') {
-                            var file = data.files[index];
-                            file.error = file.error || data.errorThrown ||
-                                true;
-                            deferred = that._addFinishedDeferreds();
-                            that._transition($(this)).done(
-                                function () {
-                                    var node = $(this);
-                                    template = that._renderDownload([file])
-                                        .replaceAll(node);
-                                    that._forceReflow(template);
-                                    that._transition(template).done(
-                                        function () {
-                                            data.context = $(this);
-                                            that._trigger('failed', e, data);
-                                            that._trigger('finished', e, data);
-                                            deferred.resolve();
-                                        }
-                                    );
-                                }
-                            );
-                        } else {
-                            deferred = that._addFinishedDeferreds();
-                            that._transition($(this)).done(
-                                function () {
-                                    $(this).remove();
-                                    that._trigger('failed', e, data);
-                                    that._trigger('finished', e, data);
-                                    deferred.resolve();
-                                }
-                            );
-                        }
-                    });
-                } else if (data.errorThrown !== 'abort') {
-                    data.context = that._renderUpload(data.files)[
-                        that.options.prependFiles ? 'prependTo' : 'appendTo'
-                    ](that.options.filesContainer)
-                        .data('data', data);
-                    that._forceReflow(data.context);
-                    deferred = that._addFinishedDeferreds();
-                    that._transition(data.context).done(
-                        function () {
-                            data.context = $(this);
-                            that._trigger('failed', e, data);
-                            that._trigger('finished', e, data);
-                            deferred.resolve();
-                        }
-                    );
-                } else {
-                    that._trigger('failed', e, data);
-                    that._trigger('finished', e, data);
-                    that._addFinishedDeferreds().resolve();
-                }
-            },
-            // Callback for upload progress events:
-            progress: function (e, data) {
-                if (data.context) {
-                    var progress = Math.floor(data.loaded / data.total * 100);
-                    data.context.find('.progress')
-                        .attr('aria-valuenow', progress)
-                        .find('.bar').css(
-                            'width',
-                            progress + '%'
-                        );
-                }
-            },
-            // Callback for global upload progress events:
-            progressall: function (e, data) {
-                var $this = $(this),
-                    progress = Math.floor(data.loaded / data.total * 100),
-                    globalProgressNode = $this.find('.fileupload-progress'),
-                    extendedProgressNode = globalProgressNode
-                        .find('.progress-extended');
-                if (extendedProgressNode.length) {
-                    extendedProgressNode.html(
-                        ($this.data('blueimp-fileupload') || $this.data('fileupload'))
-                            ._renderExtendedProgress(data)
-                    );
-                }
-                globalProgressNode
-                    .find('.progress')
-                    .attr('aria-valuenow', progress)
-                    .find('.bar').css(
-                        'width',
-                        progress + '%'
-                    );
-            },
-            // Callback for uploads start, equivalent to the global ajaxStart event:
-            start: function (e) {
-                var that = $(this).data('blueimp-fileupload') ||
-                        $(this).data('fileupload');
-                that._resetFinishedDeferreds();
-                that._transition($(this).find('.fileupload-progress')).done(
-                    function () {
-                        that._trigger('started', e);
-                    }
-                );
-            },
-            // Callback for uploads stop, equivalent to the global ajaxStop event:
-            stop: function (e) {
-                var that = $(this).data('blueimp-fileupload') ||
-                        $(this).data('fileupload'),
-                    deferred = that._addFinishedDeferreds();
-                $.when.apply($, that._getFinishedDeferreds())
-                    .done(function () {
-                        that._trigger('stopped', e);
-                    });
-                that._transition($(this).find('.fileupload-progress')).done(
-                    function () {
-                        $(this).find('.progress')
-                            .attr('aria-valuenow', '0')
-                            .find('.bar').css('width', '0%');
-                        $(this).find('.progress-extended').html('&nbsp;');
-                        deferred.resolve();
-                    }
-                );
-            },
-            processstart: function () {
-                $(this).addClass('fileupload-processing');
-            },
-            processstop: function () {
-                $(this).removeClass('fileupload-processing');
-            },
-            // Callback for file deletion:
-            destroy: function (e, data) {
-                var that = $(this).data('blueimp-fileupload') ||
-                        $(this).data('fileupload'),
-                    removeNode = function () {
-                        that._transition(data.context).done(
-                            function () {
-                                $(this).remove();
-                                that._trigger('destroyed', e, data);
-                            }
-                        );
-                    };
-                if (data.url) {
-                    $.ajax(data).done(removeNode);
-                } else {
-                    removeNode();
-                }
-            }
-        },
-
-        _resetFinishedDeferreds: function () {
-            this._finishedUploads = [];
-        },
-
-        _addFinishedDeferreds: function (deferred) {
-            if (!deferred) {
-                deferred = $.Deferred();
-            }
-            this._finishedUploads.push(deferred);
-            return deferred;
-        },
-
-        _getFinishedDeferreds: function () {
-            return this._finishedUploads;
-        },
-
-        // Link handler, that allows to download files
-        // by drag & drop of the links to the desktop:
-        _enableDragToDesktop: function () {
-            var link = $(this),
-                url = link.prop('href'),
-                name = link.prop('download'),
-                type = 'application/octet-stream';
-            link.bind('dragstart', function (e) {
-                try {
-                    e.originalEvent.dataTransfer.setData(
-                        'DownloadURL',
-                        [type, name, url].join(':')
-                    );
-                } catch (ignore) {}
-            });
-        },
-
-        _formatFileSize: function (bytes) {
-            if (typeof bytes !== 'number') {
-                return '';
-            }
-            if (bytes >= 1000000000) {
-                return (bytes / 1000000000).toFixed(2) + ' GB';
-            }
-            if (bytes >= 1000000) {
-                return (bytes / 1000000).toFixed(2) + ' MB';
-            }
-            return (bytes / 1000).toFixed(2) + ' KB';
-        },
-
-        _formatBitrate: function (bits) {
-            if (typeof bits !== 'number') {
-                return '';
-            }
-            if (bits >= 1000000000) {
-                return (bits / 1000000000).toFixed(2) + ' Gbit/s';
-            }
-            if (bits >= 1000000) {
-                return (bits / 1000000).toFixed(2) + ' Mbit/s';
-            }
-            if (bits >= 1000) {
-                return (bits / 1000).toFixed(2) + ' kbit/s';
-            }
-            return bits.toFixed(2) + ' bit/s';
-        },
-
-        _formatTime: function (seconds) {
-            var date = new Date(seconds * 1000),
-                days = Math.floor(seconds / 86400);
-            days = days ? days + 'd ' : '';
-            return days +
-                ('0' + date.getUTCHours()).slice(-2) + ':' +
-                ('0' + date.getUTCMinutes()).slice(-2) + ':' +
-                ('0' + date.getUTCSeconds()).slice(-2);
-        },
-
-        _formatPercentage: function (floatValue) {
-            return (floatValue * 100).toFixed(2) + ' %';
-        },
-
-        _renderExtendedProgress: function (data) {
-            return this._formatBitrate(data.bitrate) + ' | ' +
-                this._formatTime(
-                    (data.total - data.loaded) * 8 / data.bitrate
-                ) + ' | ' +
-                this._formatPercentage(
-                    data.loaded / data.total
-                ) + ' | ' +
-                this._formatFileSize(data.loaded) + ' / ' +
-                this._formatFileSize(data.total);
-        },
-
-        _renderTemplate: function (func, files) {
-            if (!func) {
-                return $();
-            }
-            var result = func({
-                files: files,
-                formatFileSize: this._formatFileSize,
-                options: this.options
-            });
-            if (result instanceof $) {
-                return result;
-            }
-            return $(this.options.templatesContainer).html(result).children();
-        },
-
-        _renderPreviews: function (data) {
-            data.context.find('.preview').each(function (index, elm) {
-                $(elm).append(data.files[index].preview);
-            });
-        },
-
-        _renderUpload: function (files) {
-            return this._renderTemplate(
-                this.options.uploadTemplate,
-                files
-            );
-        },
-
-        _renderDownload: function (files) {
-            return this._renderTemplate(
-                this.options.downloadTemplate,
-                files
-            ).find('a[download]').each(this._enableDragToDesktop).end();
-        },
-
-        _startHandler: function (e) {
-            e.preventDefault();
-            var button = $(e.currentTarget),
-                template = button.closest('.template-upload'),
-                data = template.data('data');
-            if (data && data.submit && !data.jqXHR && data.submit()) {
-                button.prop('disabled', true);
-            }
-        },
-
-        _cancelHandler: function (e) {
-            e.preventDefault();
-            var template = $(e.currentTarget).closest('.template-upload'),
-                data = template.data('data') || {};
-            if (!data.jqXHR) {
-                data.errorThrown = 'abort';
-                this._trigger('fail', e, data);
-            } else {
-                data.jqXHR.abort();
-            }
-        },
-
-        _deleteHandler: function (e) {
-            e.preventDefault();
-            var button = $(e.currentTarget);
-            this._trigger('destroy', e, $.extend({
-                context: button.closest('.template-download'),
-                type: 'DELETE'
-            }, button.data()));
-        },
-
-        _forceReflow: function (node) {
-            return $.support.transition && node.length &&
-                node[0].offsetWidth;
-        },
-
-        _transition: function (node) {
-            var dfd = $.Deferred();
-            if ($.support.transition && node.hasClass('fade') && node.is(':visible')) {
-                node.bind(
-                    $.support.transition.end,
-                    function (e) {
-                        // Make sure we don't respond to other transitions events
-                        // in the container element, e.g. from button elements:
-                        if (e.target === node[0]) {
-                            node.unbind($.support.transition.end);
-                            dfd.resolveWith(node);
-                        }
-                    }
-                ).toggleClass('in');
-            } else {
-                node.toggleClass('in');
-                dfd.resolveWith(node);
-            }
-            return dfd;
-        },
-
-        _initButtonBarEventHandlers: function () {
-            var fileUploadButtonBar = this.element.find('.fileupload-buttonbar'),
-                filesList = this.options.filesContainer;
-            this._on(fileUploadButtonBar.find('.start'), {
-                click: function (e) {
-                    e.preventDefault();
-                    filesList.find('.start').click();
-                }
-            });
-            this._on(fileUploadButtonBar.find('.cancel'), {
-                click: function (e) {
-                    e.preventDefault();
-                    filesList.find('.cancel').click();
-                }
-            });
-            this._on(fileUploadButtonBar.find('.delete'), {
-                click: function (e) {
-                    e.preventDefault();
-                    filesList.find('.toggle:checked')
-                        .closest('.template-download')
-                        .find('.delete').click();
-                    fileUploadButtonBar.find('.toggle')
-                        .prop('checked', false);
-                }
-            });
-            this._on(fileUploadButtonBar.find('.toggle'), {
-                change: function (e) {
-                    filesList.find('.toggle').prop(
-                        'checked',
-                        $(e.currentTarget).is(':checked')
-                    );
-                }
-            });
-        },
-
-        _destroyButtonBarEventHandlers: function () {
-            this._off(
-                this.element.find('.fileupload-buttonbar')
-                    .find('.start, .cancel, .delete'),
-                'click'
-            );
-            this._off(
-                this.element.find('.fileupload-buttonbar .toggle'),
-                'change.'
-            );
-        },
-
-        _initEventHandlers: function () {
-            this._super();
-            this._on(this.options.filesContainer, {
-                'click .start': this._startHandler,
-                'click .cancel': this._cancelHandler,
-                'click .delete': this._deleteHandler
-            });
-            this._initButtonBarEventHandlers();
-        },
-
-        _destroyEventHandlers: function () {
-            this._destroyButtonBarEventHandlers();
-            this._off(this.options.filesContainer, 'click');
-            this._super();
-        },
-
-        _enableFileInputButton: function () {
-            this.element.find('.fileinput-button input')
-                .prop('disabled', false)
-                .parent().removeClass('disabled');
-        },
-
-        _disableFileInputButton: function () {
-            this.element.find('.fileinput-button input')
-                .prop('disabled', true)
-                .parent().addClass('disabled');
-        },
-
-        _initTemplates: function () {
-            var options = this.options;
-            options.templatesContainer = this.document[0].createElement(
-                options.filesContainer.prop('nodeName')
-            );
-            if (tmpl) {
-                if (options.uploadTemplateId) {
-                    options.uploadTemplate = tmpl(options.uploadTemplateId);
-                }
-                if (options.downloadTemplateId) {
-                    options.downloadTemplate = tmpl(options.downloadTemplateId);
-                }
-            }
-        },
-
-        _initFilesContainer: function () {
-            var options = this.options;
-            if (options.filesContainer === undefined) {
-                options.filesContainer = this.element.find('.files');
-            } else if (!(options.filesContainer instanceof $)) {
-                options.filesContainer = $(options.filesContainer);
-            }
-        },
-
-        _initSpecialOptions: function () {
-            this._super();
-            this._initFilesContainer();
-            this._initTemplates();
-        },
-
-        _create: function () {
-            this._super();
-            this._resetFinishedDeferreds();
-            if (!$.support.fileInput) {
-                this._disableFileInputButton();
-            }
-        },
-
-        enable: function () {
-            var wasDisabled = false;
-            if (this.options.disabled) {
-                wasDisabled = true;
-            }
-            this._super();
-            if (wasDisabled) {
-                this.element.find('input, button').prop('disabled', false);
-                this._enableFileInputButton();
-            }
-        },
-
-        disable: function () {
-            if (!this.options.disabled) {
-                this.element.find('input, button').prop('disabled', true);
-                this._disableFileInputButton();
-            }
-            this._super();
-        }
-
-    });
-
-}));
Index: admin/js/jsUpload/jquery.fileupload.js
===================================================================
--- admin/js/jsUpload/jquery.fileupload.js	(revision 1320)
+++ 	(revision )
@@ -1,1333 +1,0 @@
-/*
- * jQuery File Upload Plugin 5.32.2
- * https://github.com/blueimp/jQuery-File-Upload
- *
- * Copyright 2010, Sebastian Tschan
- * https://blueimp.net
- *
- * Licensed under the MIT license:
- * http://www.opensource.org/licenses/MIT
- */
-
-/*jslint nomen: true, unparam: true, regexp: true */
-/*global define, window, document, location, File, Blob, FormData */
-
-(function (factory) {
-    'use strict';
-    if (typeof define === 'function' && define.amd) {
-        // Register as an anonymous AMD module:
-        define([
-            'jquery',
-            'jquery.ui.widget'
-        ], factory);
-    } else {
-        // Browser globals:
-        factory(window.jQuery);
-    }
-}(function ($) {
-    'use strict';
-
-    // Detect file input support, based on
-    // http://viljamis.com/blog/2012/file-upload-support-on-mobile/
-    $.support.fileInput = !(new RegExp(
-        // Handle devices which give false positives for the feature detection:
-        '(Android (1\\.[0156]|2\\.[01]))' +
-            '|(Windows Phone (OS 7|8\\.0))|(XBLWP)|(ZuneWP)|(WPDesktop)' +
-            '|(w(eb)?OSBrowser)|(webOS)' +
-            '|(Kindle/(1\\.0|2\\.[05]|3\\.0))'
-    ).test(window.navigator.userAgent) ||
-        // Feature detection for all other devices:
-        $('<input type="file">').prop('disabled'));
-
-    // The FileReader API is not actually used, but works as feature detection,
-    // as e.g. Safari supports XHR file uploads via the FormData API,
-    // but not non-multipart XHR file uploads:
-    $.support.xhrFileUpload = !!(window.XMLHttpRequestUpload && window.FileReader);
-    $.support.xhrFormDataFileUpload = !!window.FormData;
-
-    // Detect support for Blob slicing (required for chunked uploads):
-    $.support.blobSlice = window.Blob && (Blob.prototype.slice ||
-        Blob.prototype.webkitSlice || Blob.prototype.mozSlice);
-
-    // The fileupload widget listens for change events on file input fields defined
-    // via fileInput setting and paste or drop events of the given dropZone.
-    // In addition to the default jQuery Widget methods, the fileupload widget
-    // exposes the "add" and "send" methods, to add or directly send files using
-    // the fileupload API.
-    // By default, files added via file input selection, paste, drag & drop or
-    // "add" method are uploaded immediately, but it is possible to override
-    // the "add" callback option to queue file uploads.
-    $.widget('blueimp.fileupload', {
-
-        options: {
-            // The drop target element(s), by the default the complete document.
-            // Set to null to disable drag & drop support:
-            dropZone: $(document),
-            // The paste target element(s), by the default the complete document.
-            // Set to null to disable paste support:
-            pasteZone: $(document),
-            // The file input field(s), that are listened to for change events.
-            // If undefined, it is set to the file input fields inside
-            // of the widget element on plugin initialization.
-            // Set to null to disable the change listener.
-            fileInput: undefined,
-            // By default, the file input field is replaced with a clone after
-            // each input field change event. This is required for iframe transport
-            // queues and allows change events to be fired for the same file
-            // selection, but can be disabled by setting the following option to false:
-            replaceFileInput: true,
-            // The parameter name for the file form data (the request argument name).
-            // If undefined or empty, the name property of the file input field is
-            // used, or "files[]" if the file input name property is also empty,
-            // can be a string or an array of strings:
-            paramName: undefined,
-            // By default, each file of a selection is uploaded using an individual
-            // request for XHR type uploads. Set to false to upload file
-            // selections in one request each:
-            singleFileUploads: true,
-            // To limit the number of files uploaded with one XHR request,
-            // set the following option to an integer greater than 0:
-            limitMultiFileUploads: undefined,
-            // Set the following option to true to issue all file upload requests
-            // in a sequential order:
-            sequentialUploads: false,
-            // To limit the number of concurrent uploads,
-            // set the following option to an integer greater than 0:
-            limitConcurrentUploads: undefined,
-            // Set the following option to true to force iframe transport uploads:
-            forceIframeTransport: false,
-            // Set the following option to the location of a redirect url on the
-            // origin server, for cross-domain iframe transport uploads:
-            redirect: undefined,
-            // The parameter name for the redirect url, sent as part of the form
-            // data and set to 'redirect' if this option is empty:
-            redirectParamName: undefined,
-            // Set the following option to the location of a postMessage window,
-            // to enable postMessage transport uploads:
-            postMessage: undefined,
-            // By default, XHR file uploads are sent as multipart/form-data.
-            // The iframe transport is always using multipart/form-data.
-            // Set to false to enable non-multipart XHR uploads:
-            multipart: true,
-            // To upload large files in smaller chunks, set the following option
-            // to a preferred maximum chunk size. If set to 0, null or undefined,
-            // or the browser does not support the required Blob API, files will
-            // be uploaded as a whole.
-            maxChunkSize: undefined,
-            // When a non-multipart upload or a chunked multipart upload has been
-            // aborted, this option can be used to resume the upload by setting
-            // it to the size of the already uploaded bytes. This option is most
-            // useful when modifying the options object inside of the "add" or
-            // "send" callbacks, as the options are cloned for each file upload.
-            uploadedBytes: undefined,
-            // By default, failed (abort or error) file uploads are removed from the
-            // global progress calculation. Set the following option to false to
-            // prevent recalculating the global progress data:
-            recalculateProgress: true,
-            // Interval in milliseconds to calculate and trigger progress events:
-            progressInterval: 100,
-            // Interval in milliseconds to calculate progress bitrate:
-            bitrateInterval: 500,
-            // By default, uploads are started automatically when adding files:
-            autoUpload: true,
-
-            // Error and info messages:
-            messages: {
-                uploadedBytes: 'Uploaded bytes exceed file size'
-            },
-
-            // Translation function, gets the message key to be translated
-            // and an object with context specific data as arguments:
-            i18n: function (message, context) {
-                message = this.messages[message] || message.toString();
-                if (context) {
-                    $.each(context, function (key, value) {
-                        message = message.replace('{' + key + '}', value);
-                    });
-                }
-                return message;
-            },
-
-            // Additional form data to be sent along with the file uploads can be set
-            // using this option, which accepts an array of objects with name and
-            // value properties, a function returning such an array, a FormData
-            // object (for XHR file uploads), or a simple object.
-            // The form of the first fileInput is given as parameter to the function:
-            formData: function (form) {
-                return form.serializeArray();
-            },
-
-            // The add callback is invoked as soon as files are added to the fileupload
-            // widget (via file input selection, drag & drop, paste or add API call).
-            // If the singleFileUploads option is enabled, this callback will be
-            // called once for each file in the selection for XHR file uploads, else
-            // once for each file selection.
-            //
-            // The upload starts when the submit method is invoked on the data parameter.
-            // The data object contains a files property holding the added files
-            // and allows you to override plugin options as well as define ajax settings.
-            //
-            // Listeners for this callback can also be bound the following way:
-            // .bind('fileuploadadd', func);
-            //
-            // data.submit() returns a Promise object and allows to attach additional
-            // handlers using jQuery's Deferred callbacks:
-            // data.submit().done(func).fail(func).always(func);
-            add: function (e, data) {
-                if (data.autoUpload || (data.autoUpload !== false &&
-                        $(this).fileupload('option', 'autoUpload'))) {
-                    data.process().done(function () {
-                        data.submit();
-                    });
-                }
-            },
-
-            // Other callbacks:
-
-            // Callback for the submit event of each file upload:
-            // submit: function (e, data) {}, // .bind('fileuploadsubmit', func);
-
-            // Callback for the start of each file upload request:
-            // send: function (e, data) {}, // .bind('fileuploadsend', func);
-
-            // Callback for successful uploads:
-            // done: function (e, data) {}, // .bind('fileuploaddone', func);
-
-            // Callback for failed (abort or error) uploads:
-            // fail: function (e, data) {}, // .bind('fileuploadfail', func);
-
-            // Callback for completed (success, abort or error) requests:
-            // always: function (e, data) {}, // .bind('fileuploadalways', func);
-
-            // Callback for upload progress events:
-            // progress: function (e, data) {}, // .bind('fileuploadprogress', func);
-
-            // Callback for global upload progress events:
-            // progressall: function (e, data) {}, // .bind('fileuploadprogressall', func);
-
-            // Callback for uploads start, equivalent to the global ajaxStart event:
-            // start: function (e) {}, // .bind('fileuploadstart', func);
-
-            // Callback for uploads stop, equivalent to the global ajaxStop event:
-            // stop: function (e) {}, // .bind('fileuploadstop', func);
-
-            // Callback for change events of the fileInput(s):
-            // change: function (e, data) {}, // .bind('fileuploadchange', func);
-
-            // Callback for paste events to the pasteZone(s):
-            // paste: function (e, data) {}, // .bind('fileuploadpaste', func);
-
-            // Callback for drop events of the dropZone(s):
-            // drop: function (e, data) {}, // .bind('fileuploaddrop', func);
-
-            // Callback for dragover events of the dropZone(s):
-            // dragover: function (e) {}, // .bind('fileuploaddragover', func);
-
-            // Callback for the start of each chunk upload request:
-            // chunksend: function (e, data) {}, // .bind('fileuploadchunksend', func);
-
-            // Callback for successful chunk uploads:
-            // chunkdone: function (e, data) {}, // .bind('fileuploadchunkdone', func);
-
-            // Callback for failed (abort or error) chunk uploads:
-            // chunkfail: function (e, data) {}, // .bind('fileuploadchunkfail', func);
-
-            // Callback for completed (success, abort or error) chunk upload requests:
-            // chunkalways: function (e, data) {}, // .bind('fileuploadchunkalways', func);
-
-            // The plugin options are used as settings object for the ajax calls.
-            // The following are jQuery ajax settings required for the file uploads:
-            processData: false,
-            contentType: false,
-            cache: false
-        },
-
-        // A list of options that require reinitializing event listeners and/or
-        // special initialization code:
-        _specialOptions: [
-            'fileInput',
-            'dropZone',
-            'pasteZone',
-            'multipart',
-            'forceIframeTransport'
-        ],
-
-        _blobSlice: $.support.blobSlice && function () {
-            var slice = this.slice || this.webkitSlice || this.mozSlice;
-            return slice.apply(this, arguments);
-        },
-
-        _BitrateTimer: function () {
-            this.timestamp = ((Date.now) ? Date.now() : (new Date()).getTime());
-            this.loaded = 0;
-            this.bitrate = 0;
-            this.getBitrate = function (now, loaded, interval) {
-                var timeDiff = now - this.timestamp;
-                if (!this.bitrate || !interval || timeDiff > interval) {
-                    this.bitrate = (loaded - this.loaded) * (1000 / timeDiff) * 8;
-                    this.loaded = loaded;
-                    this.timestamp = now;
-                }
-                return this.bitrate;
-            };
-        },
-
-        _isXHRUpload: function (options) {
-            return !options.forceIframeTransport &&
-                ((!options.multipart && $.support.xhrFileUpload) ||
-                $.support.xhrFormDataFileUpload);
-        },
-
-        _getFormData: function (options) {
-            var formData;
-            if (typeof options.formData === 'function') {
-                return options.formData(options.form);
-            }
-            if ($.isArray(options.formData)) {
-                return options.formData;
-            }
-            if ($.type(options.formData) === 'object') {
-                formData = [];
-                $.each(options.formData, function (name, value) {
-                    formData.push({name: name, value: value});
-                });
-                return formData;
-            }
-            return [];
-        },
-
-        _getTotal: function (files) {
-            var total = 0;
-            $.each(files, function (index, file) {
-                total += file.size || 1;
-            });
-            return total;
-        },
-
-        _initProgressObject: function (obj) {
-            var progress = {
-                loaded: 0,
-                total: 0,
-                bitrate: 0
-            };
-            if (obj._progress) {
-                $.extend(obj._progress, progress);
-            } else {
-                obj._progress = progress;
-            }
-        },
-
-        _initResponseObject: function (obj) {
-            var prop;
-            if (obj._response) {
-                for (prop in obj._response) {
-                    if (obj._response.hasOwnProperty(prop)) {
-                        delete obj._response[prop];
-                    }
-                }
-            } else {
-                obj._response = {};
-            }
-        },
-
-        _onProgress: function (e, data) {
-            if (e.lengthComputable) {
-                var now = ((Date.now) ? Date.now() : (new Date()).getTime()),
-                    loaded;
-                if (data._time && data.progressInterval &&
-                        (now - data._time < data.progressInterval) &&
-                        e.loaded !== e.total) {
-                    return;
-                }
-                data._time = now;
-                loaded = Math.floor(
-                    e.loaded / e.total * (data.chunkSize || data._progress.total)
-                ) + (data.uploadedBytes || 0);
-                // Add the difference from the previously loaded state
-                // to the global loaded counter:
-                this._progress.loaded += (loaded - data._progress.loaded);
-                this._progress.bitrate = this._bitrateTimer.getBitrate(
-                    now,
-                    this._progress.loaded,
-                    data.bitrateInterval
-                );
-                data._progress.loaded = data.loaded = loaded;
-                data._progress.bitrate = data.bitrate = data._bitrateTimer.getBitrate(
-                    now,
-                    loaded,
-                    data.bitrateInterval
-                );
-                // Trigger a custom progress event with a total data property set
-                // to the file size(s) of the current upload and a loaded data
-                // property calculated accordingly:
-                this._trigger('progress', e, data);
-                // Trigger a global progress event for all current file uploads,
-                // including ajax calls queued for sequential file uploads:
-                this._trigger('progressall', e, this._progress);
-            }
-        },
-
-        _initProgressListener: function (options) {
-            var that = this,
-                xhr = options.xhr ? options.xhr() : $.ajaxSettings.xhr();
-            // Accesss to the native XHR object is required to add event listeners
-            // for the upload progress event:
-            if (xhr.upload) {
-                $(xhr.upload).bind('progress', function (e) {
-                    var oe = e.originalEvent;
-                    // Make sure the progress event properties get copied over:
-                    e.lengthComputable = oe.lengthComputable;
-                    e.loaded = oe.loaded;
-                    e.total = oe.total;
-                    that._onProgress(e, options);
-                });
-                options.xhr = function () {
-                    return xhr;
-                };
-            }
-        },
-
-        _isInstanceOf: function (type, obj) {
-            // Cross-frame instanceof check
-            return Object.prototype.toString.call(obj) === '[object ' + type + ']';
-        },
-
-        _initXHRData: function (options) {
-            var that = this,
-                formData,
-                file = options.files[0],
-                // Ignore non-multipart setting if not supported:
-                multipart = options.multipart || !$.support.xhrFileUpload,
-                paramName = options.paramName[0];
-            options.headers = options.headers || {};
-            if (options.contentRange) {
-                options.headers['Content-Range'] = options.contentRange;
-            }
-            if (!multipart || options.blob || !this._isInstanceOf('File', file)) {
-                options.headers['Content-Disposition'] = 'attachment; filename="' +
-                    encodeURI(file.name) + '"';
-            }
-            if (!multipart) {
-                options.contentType = file.type;
-                options.data = options.blob || file;
-            } else if ($.support.xhrFormDataFileUpload) {
-                if (options.postMessage) {
-                    // window.postMessage does not allow sending FormData
-                    // objects, so we just add the File/Blob objects to
-                    // the formData array and let the postMessage window
-                    // create the FormData object out of this array:
-                    formData = this._getFormData(options);
-                    if (options.blob) {
-                        formData.push({
-                            name: paramName,
-                            value: options.blob
-                        });
-                    } else {
-                        $.each(options.files, function (index, file) {
-                            formData.push({
-                                name: options.paramName[index] || paramName,
-                                value: file
-                            });
-                        });
-                    }
-                } else {
-                    if (that._isInstanceOf('FormData', options.formData)) {
-                        formData = options.formData;
-                    } else {
-                        formData = new FormData();
-                        $.each(this._getFormData(options), function (index, field) {
-                            formData.append(field.name, field.value);
-                        });
-                    }
-                    if (options.blob) {
-                        formData.append(paramName, options.blob, file.name);
-                    } else {
-                        $.each(options.files, function (index, file) {
-                            // This check allows the tests to run with
-                            // dummy objects:
-                            if (that._isInstanceOf('File', file) ||
-                                    that._isInstanceOf('Blob', file)) {
-                                formData.append(
-                                    options.paramName[index] || paramName,
-                                    file,
-                                    file.name
-                                );
-                            }
-                        });
-                    }
-                }
-                options.data = formData;
-            }
-            // Blob reference is not needed anymore, free memory:
-            options.blob = null;
-        },
-
-        _initIframeSettings: function (options) {
-            var targetHost = $('<a></a>').prop('href', options.url).prop('host');
-            // Setting the dataType to iframe enables the iframe transport:
-            options.dataType = 'iframe ' + (options.dataType || '');
-            // The iframe transport accepts a serialized array as form data:
-            options.formData = this._getFormData(options);
-            // Add redirect url to form data on cross-domain uploads:
-            if (options.redirect && targetHost && targetHost !== location.host) {
-                options.formData.push({
-                    name: options.redirectParamName || 'redirect',
-                    value: options.redirect
-                });
-            }
-        },
-
-        _initDataSettings: function (options) {
-            if (this._isXHRUpload(options)) {
-                if (!this._chunkedUpload(options, true)) {
-                    if (!options.data) {
-                        this._initXHRData(options);
-                    }
-                    this._initProgressListener(options);
-                }
-                if (options.postMessage) {
-                    // Setting the dataType to postmessage enables the
-                    // postMessage transport:
-                    options.dataType = 'postmessage ' + (options.dataType || '');
-                }
-            } else {
-                this._initIframeSettings(options);
-            }
-        },
-
-        _getParamName: function (options) {
-            var fileInput = $(options.fileInput),
-                paramName = options.paramName;
-            if (!paramName) {
-                paramName = [];
-                fileInput.each(function () {
-                    var input = $(this),
-                        name = input.prop('name') || 'files[]',
-                        i = (input.prop('files') || [1]).length;
-                    while (i) {
-                        paramName.push(name);
-                        i -= 1;
-                    }
-                });
-                if (!paramName.length) {
-                    paramName = [fileInput.prop('name') || 'files[]'];
-                }
-            } else if (!$.isArray(paramName)) {
-                paramName = [paramName];
-            }
-            return paramName;
-        },
-
-        _initFormSettings: function (options) {
-            // Retrieve missing options from the input field and the
-            // associated form, if available:
-            if (!options.form || !options.form.length) {
-                options.form = $(options.fileInput.prop('form'));
-                // If the given file input doesn't have an associated form,
-                // use the default widget file input's form:
-                if (!options.form.length) {
-                    options.form = $(this.options.fileInput.prop('form'));
-                }
-            }
-            options.paramName = this._getParamName(options);
-            if (!options.url) {
-                options.url = options.form.prop('action') || location.href;
-            }
-            // The HTTP request method must be "POST" or "PUT":
-            options.type = (options.type || options.form.prop('method') || '')
-                .toUpperCase();
-            if (options.type !== 'POST' && options.type !== 'PUT' &&
-                    options.type !== 'PATCH') {
-                options.type = 'POST';
-            }
-            if (!options.formAcceptCharset) {
-                options.formAcceptCharset = options.form.attr('accept-charset');
-            }
-        },
-
-        _getAJAXSettings: function (data) {
-            var options = $.extend({}, this.options, data);
-            this._initFormSettings(options);
-            this._initDataSettings(options);
-            return options;
-        },
-
-        // jQuery 1.6 doesn't provide .state(),
-        // while jQuery 1.8+ removed .isRejected() and .isResolved():
-        _getDeferredState: function (deferred) {
-            if (deferred.state) {
-                return deferred.state();
-            }
-            if (deferred.isResolved()) {
-                return 'resolved';
-            }
-            if (deferred.isRejected()) {
-                return 'rejected';
-            }
-            return 'pending';
-        },
-
-        // Maps jqXHR callbacks to the equivalent
-        // methods of the given Promise object:
-        _enhancePromise: function (promise) {
-            promise.success = promise.done;
-            promise.error = promise.fail;
-            promise.complete = promise.always;
-            return promise;
-        },
-
-        // Creates and returns a Promise object enhanced with
-        // the jqXHR methods abort, success, error and complete:
-        _getXHRPromise: function (resolveOrReject, context, args) {
-            var dfd = $.Deferred(),
-                promise = dfd.promise();
-            context = context || this.options.context || promise;
-            if (resolveOrReject === true) {
-                dfd.resolveWith(context, args);
-            } else if (resolveOrReject === false) {
-                dfd.rejectWith(context, args);
-            }
-            promise.abort = dfd.promise;
-            return this._enhancePromise(promise);
-        },
-
-        // Adds convenience methods to the data callback argument:
-        _addConvenienceMethods: function (e, data) {
-            var that = this,
-                getPromise = function (data) {
-                    return $.Deferred().resolveWith(that, [data]).promise();
-                };
-            data.process = function (resolveFunc, rejectFunc) {
-                if (resolveFunc || rejectFunc) {
-                    data._processQueue = this._processQueue =
-                        (this._processQueue || getPromise(this))
-                            .pipe(resolveFunc, rejectFunc);
-                }
-                return this._processQueue || getPromise(this);
-            };
-            data.submit = function () {
-                if (this.state() !== 'pending') {
-                    data.jqXHR = this.jqXHR =
-                        (that._trigger('submit', e, this) !== false) &&
-                        that._onSend(e, this);
-                }
-                return this.jqXHR || that._getXHRPromise();
-            };
-            data.abort = function () {
-                if (this.jqXHR) {
-                    return this.jqXHR.abort();
-                }
-                return that._getXHRPromise();
-            };
-            data.state = function () {
-                if (this.jqXHR) {
-                    return that._getDeferredState(this.jqXHR);
-                }
-                if (this._processQueue) {
-                    return that._getDeferredState(this._processQueue);
-                }
-            };
-            data.progress = function () {
-                return this._progress;
-            };
-            data.response = function () {
-                return this._response;
-            };
-        },
-
-        // Parses the Range header from the server response
-        // and returns the uploaded bytes:
-        _getUploadedBytes: function (jqXHR) {
-            var range = jqXHR.getResponseHeader('Range'),
-                parts = range && range.split('-'),
-                upperBytesPos = parts && parts.length > 1 &&
-                    parseInt(parts[1], 10);
-            return upperBytesPos && upperBytesPos + 1;
-        },
-
-        // Uploads a file in multiple, sequential requests
-        // by splitting the file up in multiple blob chunks.
-        // If the second parameter is true, only tests if the file
-        // should be uploaded in chunks, but does not invoke any
-        // upload requests:
-        _chunkedUpload: function (options, testOnly) {
-            options.uploadedBytes = options.uploadedBytes || 0;
-            var that = this,
-                file = options.files[0],
-                fs = file.size,
-                ub = options.uploadedBytes,
-                mcs = options.maxChunkSize || fs,
-                slice = this._blobSlice,
-                dfd = $.Deferred(),
-                promise = dfd.promise(),
-                jqXHR,
-                upload;
-            if (!(this._isXHRUpload(options) && slice && (ub || mcs < fs)) ||
-                    options.data) {
-                return false;
-            }
-            if (testOnly) {
-                return true;
-            }
-            if (ub >= fs) {
-                file.error = options.i18n('uploadedBytes');
-                return this._getXHRPromise(
-                    false,
-                    options.context,
-                    [null, 'error', file.error]
-                );
-            }
-            // The chunk upload method:
-            upload = function () {
-                // Clone the options object for each chunk upload:
-                var o = $.extend({}, options),
-                    currentLoaded = o._progress.loaded;
-                o.blob = slice.call(
-                    file,
-                    ub,
-                    ub + mcs,
-                    file.type
-                );
-                // Store the current chunk size, as the blob itself
-                // will be dereferenced after data processing:
-                o.chunkSize = o.blob.size;
-                // Expose the chunk bytes position range:
-                o.contentRange = 'bytes ' + ub + '-' +
-                    (ub + o.chunkSize - 1) + '/' + fs;
-                // Process the upload data (the blob and potential form data):
-                that._initXHRData(o);
-                // Add progress listeners for this chunk upload:
-                that._initProgressListener(o);
-                jqXHR = ((that._trigger('chunksend', null, o) !== false && $.ajax(o)) ||
-                        that._getXHRPromise(false, o.context))
-                    .done(function (result, textStatus, jqXHR) {
-                        ub = that._getUploadedBytes(jqXHR) ||
-                            (ub + o.chunkSize);
-                        // Create a progress event if no final progress event
-                        // with loaded equaling total has been triggered
-                        // for this chunk:
-                        if (currentLoaded + o.chunkSize - o._progress.loaded) {
-                            that._onProgress($.Event('progress', {
-                                lengthComputable: true,
-                                loaded: ub - o.uploadedBytes,
-                                total: ub - o.uploadedBytes
-                            }), o);
-                        }
-                        options.uploadedBytes = o.uploadedBytes = ub;
-                        o.result = result;
-                        o.textStatus = textStatus;
-                        o.jqXHR = jqXHR;
-                        that._trigger('chunkdone', null, o);
-                        that._trigger('chunkalways', null, o);
-                        if (ub < fs) {
-                            // File upload not yet complete,
-                            // continue with the next chunk:
-                            upload();
-                        } else {
-                            dfd.resolveWith(
-                                o.context,
-                                [result, textStatus, jqXHR]
-                            );
-                        }
-                    })
-                    .fail(function (jqXHR, textStatus, errorThrown) {
-                        o.jqXHR = jqXHR;
-                        o.textStatus = textStatus;
-                        o.errorThrown = errorThrown;
-                        that._trigger('chunkfail', null, o);
-                        that._trigger('chunkalways', null, o);
-                        dfd.rejectWith(
-                            o.context,
-                            [jqXHR, textStatus, errorThrown]
-                        );
-                    });
-            };
-            this._enhancePromise(promise);
-            promise.abort = function () {
-                return jqXHR.abort();
-            };
-            upload();
-            return promise;
-        },
-
-        _beforeSend: function (e, data) {
-            if (this._active === 0) {
-                // the start callback is triggered when an upload starts
-                // and no other uploads are currently running,
-                // equivalent to the global ajaxStart event:
-                this._trigger('start');
-                // Set timer for global bitrate progress calculation:
-                this._bitrateTimer = new this._BitrateTimer();
-                // Reset the global progress values:
-                this._progress.loaded = this._progress.total = 0;
-                this._progress.bitrate = 0;
-            }
-            // Make sure the container objects for the .response() and
-            // .progress() methods on the data object are available
-            // and reset to their initial state:
-            this._initResponseObject(data);
-            this._initProgressObject(data);
-            data._progress.loaded = data.loaded = data.uploadedBytes || 0;
-            data._progress.total = data.total = this._getTotal(data.files) || 1;
-            data._progress.bitrate = data.bitrate = 0;
-            this._active += 1;
-            // Initialize the global progress values:
-            this._progress.loaded += data.loaded;
-            this._progress.total += data.total;
-        },
-
-        _onDone: function (result, textStatus, jqXHR, options) {
-            var total = options._progress.total,
-                response = options._response;
-            if (options._progress.loaded < total) {
-                // Create a progress event if no final progress event
-                // with loaded equaling total has been triggered:
-                this._onProgress($.Event('progress', {
-                    lengthComputable: true,
-                    loaded: total,
-                    total: total
-                }), options);
-            }
-            response.result = options.result = result;
-            response.textStatus = options.textStatus = textStatus;
-            response.jqXHR = options.jqXHR = jqXHR;
-            this._trigger('done', null, options);
-        },
-
-        _onFail: function (jqXHR, textStatus, errorThrown, options) {
-            var response = options._response;
-            if (options.recalculateProgress) {
-                // Remove the failed (error or abort) file upload from
-                // the global progress calculation:
-                this._progress.loaded -= options._progress.loaded;
-                this._progress.total -= options._progress.total;
-            }
-            response.jqXHR = options.jqXHR = jqXHR;
-            response.textStatus = options.textStatus = textStatus;
-            response.errorThrown = options.errorThrown = errorThrown;
-            this._trigger('fail', null, options);
-        },
-
-        _onAlways: function (jqXHRorResult, textStatus, jqXHRorError, options) {
-            // jqXHRorResult, textStatus and jqXHRorError are added to the
-            // options object via done and fail callbacks
-            this._trigger('always', null, options);
-        },
-
-        _onSend: function (e, data) {
-            if (!data.submit) {
-                this._addConvenienceMethods(e, data);
-            }
-            var that = this,
-                jqXHR,
-                aborted,
-                slot,
-                pipe,
-                options = that._getAJAXSettings(data),
-                send = function () {
-                    that._sending += 1;
-                    // Set timer for bitrate progress calculation:
-                    options._bitrateTimer = new that._BitrateTimer();
-                    jqXHR = jqXHR || (
-                        ((aborted || that._trigger('send', e, options) === false) &&
-                        that._getXHRPromise(false, options.context, aborted)) ||
-                        that._chunkedUpload(options) || $.ajax(options)
-                    ).done(function (result, textStatus, jqXHR) {
-                        that._onDone(result, textStatus, jqXHR, options);
-                    }).fail(function (jqXHR, textStatus, errorThrown) {
-                        that._onFail(jqXHR, textStatus, errorThrown, options);
-                    }).always(function (jqXHRorResult, textStatus, jqXHRorError) {
-                        that._onAlways(
-                            jqXHRorResult,
-                            textStatus,
-                            jqXHRorError,
-                            options
-                        );
-                        that._sending -= 1;
-                        that._active -= 1;
-                        if (options.limitConcurrentUploads &&
-                                options.limitConcurrentUploads > that._sending) {
-                            // Start the next queued upload,
-                            // that has not been aborted:
-                            var nextSlot = that._slots.shift();
-                            while (nextSlot) {
-                                if (that._getDeferredState(nextSlot) === 'pending') {
-                                    nextSlot.resolve();
-                                    break;
-                                }
-                                nextSlot = that._slots.shift();
-                            }
-                        }
-                        if (that._active === 0) {
-                            // The stop callback is triggered when all uploads have
-                            // been completed, equivalent to the global ajaxStop event:
-                            that._trigger('stop');
-                        }
-                    });
-                    return jqXHR;
-                };
-            this._beforeSend(e, options);
-            if (this.options.sequentialUploads ||
-                    (this.options.limitConcurrentUploads &&
-                    this.options.limitConcurrentUploads <= this._sending)) {
-                if (this.options.limitConcurrentUploads > 1) {
-                    slot = $.Deferred();
-                    this._slots.push(slot);
-                    pipe = slot.pipe(send);
-                } else {
-                    this._sequence = this._sequence.pipe(send, send);
-                    pipe = this._sequence;
-                }
-                // Return the piped Promise object, enhanced with an abort method,
-                // which is delegated to the jqXHR object of the current upload,
-                // and jqXHR callbacks mapped to the equivalent Promise methods:
-                pipe.abort = function () {
-                    aborted = [undefined, 'abort', 'abort'];
-                    if (!jqXHR) {
-                        if (slot) {
-                            slot.rejectWith(options.context, aborted);
-                        }
-                        return send();
-                    }
-                    return jqXHR.abort();
-                };
-                return this._enhancePromise(pipe);
-            }
-            return send();
-        },
-
-        _onAdd: function (e, data) {
-            var that = this,
-                result = true,
-                options = $.extend({}, this.options, data),
-                limit = options.limitMultiFileUploads,
-                paramName = this._getParamName(options),
-                paramNameSet,
-                paramNameSlice,
-                fileSet,
-                i;
-            if (!(options.singleFileUploads || limit) ||
-                    !this._isXHRUpload(options)) {
-                fileSet = [data.files];
-                paramNameSet = [paramName];
-            } else if (!options.singleFileUploads && limit) {
-                fileSet = [];
-                paramNameSet = [];
-                for (i = 0; i < data.files.length; i += limit) {
-                    fileSet.push(data.files.slice(i, i + limit));
-                    paramNameSlice = paramName.slice(i, i + limit);
-                    if (!paramNameSlice.length) {
-                        paramNameSlice = paramName;
-                    }
-                    paramNameSet.push(paramNameSlice);
-                }
-            } else {
-                paramNameSet = paramName;
-            }
-            data.originalFiles = data.files;
-            $.each(fileSet || data.files, function (index, element) {
-                var newData = $.extend({}, data);
-                newData.files = fileSet ? element : [element];
-                newData.paramName = paramNameSet[index];
-                that._initResponseObject(newData);
-                that._initProgressObject(newData);
-                that._addConvenienceMethods(e, newData);
-                result = that._trigger('add', e, newData);
-                return result;
-            });
-            return result;
-        },
-
-        _replaceFileInput: function (input) {
-            var inputClone = input.clone(true);
-            $('<form></form>').append(inputClone)[0].reset();
-            // Detaching allows to insert the fileInput on another form
-            // without loosing the file input value:
-            input.after(inputClone).detach();
-            // Avoid memory leaks with the detached file input:
-            $.cleanData(input.unbind('remove'));
-            // Replace the original file input element in the fileInput
-            // elements set with the clone, which has been copied including
-            // event handlers:
-            this.options.fileInput = this.options.fileInput.map(function (i, el) {
-                if (el === input[0]) {
-                    return inputClone[0];
-                }
-                return el;
-            });
-            // If the widget has been initialized on the file input itself,
-            // override this.element with the file input clone:
-            if (input[0] === this.element[0]) {
-                this.element = inputClone;
-            }
-        },
-
-        _handleFileTreeEntry: function (entry, path) {
-            var that = this,
-                dfd = $.Deferred(),
-                errorHandler = function (e) {
-                    if (e && !e.entry) {
-                        e.entry = entry;
-                    }
-                    // Since $.when returns immediately if one
-                    // Deferred is rejected, we use resolve instead.
-                    // This allows valid files and invalid items
-                    // to be returned together in one set:
-                    dfd.resolve([e]);
-                },
-                dirReader;
-            path = path || '';
-            if (entry.isFile) {
-                if (entry._file) {
-                    // Workaround for Chrome bug #149735
-                    entry._file.relativePath = path;
-                    dfd.resolve(entry._file);
-                } else {
-                    entry.file(function (file) {
-                        file.relativePath = path;
-                        dfd.resolve(file);
-                    }, errorHandler);
-                }
-            } else if (entry.isDirectory) {
-                dirReader = entry.createReader();
-                dirReader.readEntries(function (entries) {
-                    that._handleFileTreeEntries(
-                        entries,
-                        path + entry.name + '/'
-                    ).done(function (files) {
-                        dfd.resolve(files);
-                    }).fail(errorHandler);
-                }, errorHandler);
-            } else {
-                // Return an empy list for file system items
-                // other than files or directories:
-                dfd.resolve([]);
-            }
-            return dfd.promise();
-        },
-
-        _handleFileTreeEntries: function (entries, path) {
-            var that = this;
-            return $.when.apply(
-                $,
-                $.map(entries, function (entry) {
-                    return that._handleFileTreeEntry(entry, path);
-                })
-            ).pipe(function () {
-                return Array.prototype.concat.apply(
-                    [],
-                    arguments
-                );
-            });
-        },
-
-        _getDroppedFiles: function (dataTransfer) {
-            dataTransfer = dataTransfer || {};
-            var items = dataTransfer.items;
-            if (items && items.length && (items[0].webkitGetAsEntry ||
-                    items[0].getAsEntry)) {
-                return this._handleFileTreeEntries(
-                    $.map(items, function (item) {
-                        var entry;
-                        if (item.webkitGetAsEntry) {
-                            entry = item.webkitGetAsEntry();
-                            if (entry) {
-                                // Workaround for Chrome bug #149735:
-                                entry._file = item.getAsFile();
-                            }
-                            return entry;
-                        }
-                        return item.getAsEntry();
-                    })
-                );
-            }
-            return $.Deferred().resolve(
-                $.makeArray(dataTransfer.files)
-            ).promise();
-        },
-
-        _getSingleFileInputFiles: function (fileInput) {
-            fileInput = $(fileInput);
-            var entries = fileInput.prop('webkitEntries') ||
-                    fileInput.prop('entries'),
-                files,
-                value;
-            if (entries && entries.length) {
-                return this._handleFileTreeEntries(entries);
-            }
-            files = $.makeArray(fileInput.prop('files'));
-            if (!files.length) {
-                value = fileInput.prop('value');
-                if (!value) {
-                    return $.Deferred().resolve([]).promise();
-                }
-                // If the files property is not available, the browser does not
-                // support the File API and we add a pseudo File object with
-                // the input value as name with path information removed:
-                files = [{name: value.replace(/^.*\\/, '')}];
-            } else if (files[0].name === undefined && files[0].fileName) {
-                // File normalization for Safari 4 and Firefox 3:
-                $.each(files, function (index, file) {
-                    file.name = file.fileName;
-                    file.size = file.fileSize;
-                });
-            }
-            return $.Deferred().resolve(files).promise();
-        },
-
-        _getFileInputFiles: function (fileInput) {
-            if (!(fileInput instanceof $) || fileInput.length === 1) {
-                return this._getSingleFileInputFiles(fileInput);
-            }
-            return $.when.apply(
-                $,
-                $.map(fileInput, this._getSingleFileInputFiles)
-            ).pipe(function () {
-                return Array.prototype.concat.apply(
-                    [],
-                    arguments
-                );
-            });
-        },
-
-        _onChange: function (e) {
-            var that = this,
-                data = {
-                    fileInput: $(e.target),
-                    form: $(e.target.form)
-                };
-            this._getFileInputFiles(data.fileInput).always(function (files) {
-                data.files = files;
-                if (that.options.replaceFileInput) {
-                    that._replaceFileInput(data.fileInput);
-                }
-                if (that._trigger('change', e, data) !== false) {
-                    that._onAdd(e, data);
-                }
-            });
-        },
-
-        _onPaste: function (e) {
-            var items = e.originalEvent && e.originalEvent.clipboardData &&
-                    e.originalEvent.clipboardData.items,
-                data = {files: []};
-            if (items && items.length) {
-                $.each(items, function (index, item) {
-                    var file = item.getAsFile && item.getAsFile();
-                    if (file) {
-                        data.files.push(file);
-                    }
-                });
-                if (this._trigger('paste', e, data) === false ||
-                        this._onAdd(e, data) === false) {
-                    return false;
-                }
-            }
-        },
-
-        _onDrop: function (e) {
-            e.dataTransfer = e.originalEvent && e.originalEvent.dataTransfer;
-            var that = this,
-                dataTransfer = e.dataTransfer,
-                data = {};
-            if (dataTransfer && dataTransfer.files && dataTransfer.files.length) {
-                e.preventDefault();
-                this._getDroppedFiles(dataTransfer).always(function (files) {
-                    data.files = files;
-                    if (that._trigger('drop', e, data) !== false) {
-                        that._onAdd(e, data);
-                    }
-                });
-            }
-        },
-
-        _onDragOver: function (e) {
-            e.dataTransfer = e.originalEvent && e.originalEvent.dataTransfer;
-            var dataTransfer = e.dataTransfer;
-            if (dataTransfer) {
-                if (this._trigger('dragover', e) === false) {
-                    return false;
-                }
-                if ($.inArray('Files', dataTransfer.types) !== -1) {
-                    dataTransfer.dropEffect = 'copy';
-                    e.preventDefault();
-                }
-            }
-        },
-
-        _initEventHandlers: function () {
-            if (this._isXHRUpload(this.options)) {
-                this._on(this.options.dropZone, {
-                    dragover: this._onDragOver,
-                    drop: this._onDrop
-                });
-                this._on(this.options.pasteZone, {
-                    paste: this._onPaste
-                });
-            }
-            if ($.support.fileInput) {
-                this._on(this.options.fileInput, {
-                    change: this._onChange
-                });
-            }
-        },
-
-        _destroyEventHandlers: function () {
-            this._off(this.options.dropZone, 'dragover drop');
-            this._off(this.options.pasteZone, 'paste');
-            this._off(this.options.fileInput, 'change');
-        },
-
-        _setOption: function (key, value) {
-            var reinit = $.inArray(key, this._specialOptions) !== -1;
-            if (reinit) {
-                this._destroyEventHandlers();
-            }
-            this._super(key, value);
-            if (reinit) {
-                this._initSpecialOptions();
-                this._initEventHandlers();
-            }
-        },
-
-        _initSpecialOptions: function () {
-            var options = this.options;
-            if (options.fileInput === undefined) {
-                options.fileInput = this.element.is('input[type="file"]') ?
-                        this.element : this.element.find('input[type="file"]');
-            } else if (!(options.fileInput instanceof $)) {
-                options.fileInput = $(options.fileInput);
-            }
-            if (!(options.dropZone instanceof $)) {
-                options.dropZone = $(options.dropZone);
-            }
-            if (!(options.pasteZone instanceof $)) {
-                options.pasteZone = $(options.pasteZone);
-            }
-        },
-
-        _getRegExp: function (str) {
-            var parts = str.split('/'),
-                modifiers = parts.pop();
-            parts.shift();
-            return new RegExp(parts.join('/'), modifiers);
-        },
-
-        _isRegExpOption: function (key, value) {
-            return key !== 'url' && $.type(value) === 'string' &&
-                /^\/.*\/[igm]{0,3}$/.test(value);
-        },
-
-        _initDataAttributes: function () {
-            var that = this,
-                options = this.options;
-            // Initialize options set via HTML5 data-attributes:
-            $.each(
-                $(this.element[0].cloneNode(false)).data(),
-                function (key, value) {
-                    if (that._isRegExpOption(key, value)) {
-                        value = that._getRegExp(value);
-                    }
-                    options[key] = value;
-                }
-            );
-        },
-
-        _create: function () {
-            this._initDataAttributes();
-            this._initSpecialOptions();
-            this._slots = [];
-            this._sequence = this._getXHRPromise(true);
-            this._sending = this._active = 0;
-            this._initProgressObject(this);
-            this._initEventHandlers();
-        },
-
-        // This method is exposed to the widget API and allows to query
-        // the number of active uploads:
-        active: function () {
-            return this._active;
-        },
-
-        // This method is exposed to the widget API and allows to query
-        // the widget upload progress.
-        // It returns an object with loaded, total and bitrate properties
-        // for the running uploads:
-        progress: function () {
-            return this._progress;
-        },
-
-        // This method is exposed to the widget API and allows adding files
-        // using the fileupload API. The data parameter accepts an object which
-        // must have a files property and can contain additional options:
-        // .fileupload('add', {files: filesList});
-        add: function (data) {
-            var that = this;
-            if (!data || this.options.disabled) {
-                return;
-            }
-            if (data.fileInput && !data.files) {
-                this._getFileInputFiles(data.fileInput).always(function (files) {
-                    data.files = files;
-                    that._onAdd(null, data);
-                });
-            } else {
-                data.files = $.makeArray(data.files);
-                this._onAdd(null, data);
-            }
-        },
-
-        // This method is exposed to the widget API and allows sending files
-        // using the fileupload API. The data parameter accepts an object which
-        // must have a files or fileInput property and can contain additional options:
-        // .fileupload('send', {files: filesList});
-        // The method returns a Promise object for the file upload call.
-        send: function (data) {
-            if (data && !this.options.disabled) {
-                if (data.fileInput && !data.files) {
-                    var that = this,
-                        dfd = $.Deferred(),
-                        promise = dfd.promise(),
-                        jqXHR,
-                        aborted;
-                    promise.abort = function () {
-                        aborted = true;
-                        if (jqXHR) {
-                            return jqXHR.abort();
-                        }
-                        dfd.reject(null, 'abort', 'abort');
-                        return promise;
-                    };
-                    this._getFileInputFiles(data.fileInput).always(
-                        function (files) {
-                            if (aborted) {
-                                return;
-                            }
-                            if (!files.length) {
-                                dfd.reject();
-                                return;
-                            }
-                            data.files = files;
-                            jqXHR = that._onSend(null, data).then(
-                                function (result, textStatus, jqXHR) {
-                                    dfd.resolve(result, textStatus, jqXHR);
-                                },
-                                function (jqXHR, textStatus, errorThrown) {
-                                    dfd.reject(jqXHR, textStatus, errorThrown);
-                                }
-                            );
-                        }
-                    );
-                    return this._enhancePromise(promise);
-                }
-                data.files = $.makeArray(data.files);
-                if (data.files.length) {
-                    return this._onSend(null, data);
-                }
-            }
-            return this._getXHRPromise(false, data && data.context);
-        }
-
-    });
-
-}));
Index: admin/js/jsUpload/jquery.iframe-transport.js
===================================================================
--- admin/js/jsUpload/jquery.iframe-transport.js	(revision 1320)
+++ 	(revision )
@@ -1,205 +1,0 @@
-/*
- * jQuery Iframe Transport Plugin 1.7
- * https://github.com/blueimp/jQuery-File-Upload
- *
- * Copyright 2011, Sebastian Tschan
- * https://blueimp.net
- *
- * Licensed under the MIT license:
- * http://www.opensource.org/licenses/MIT
- */
-
-/*jslint unparam: true, nomen: true */
-/*global define, window, document */
-
-(function (factory) {
-    'use strict';
-    if (typeof define === 'function' && define.amd) {
-        // Register as an anonymous AMD module:
-        define(['jquery'], factory);
-    } else {
-        // Browser globals:
-        factory(window.jQuery);
-    }
-}(function ($) {
-    'use strict';
-
-    // Helper variable to create unique names for the transport iframes:
-    var counter = 0;
-
-    // The iframe transport accepts three additional options:
-    // options.fileInput: a jQuery collection of file input fields
-    // options.paramName: the parameter name for the file form data,
-    //  overrides the name property of the file input field(s),
-    //  can be a string or an array of strings.
-    // options.formData: an array of objects with name and value properties,
-    //  equivalent to the return data of .serializeArray(), e.g.:
-    //  [{name: 'a', value: 1}, {name: 'b', value: 2}]
-    $.ajaxTransport('iframe', function (options) {
-        if (options.async) {
-            var form,
-                iframe,
-                addParamChar;
-            return {
-                send: function (_, completeCallback) {
-                    form = $('<form style="display:none;"></form>');
-                    form.attr('accept-charset', options.formAcceptCharset);
-                    addParamChar = /\?/.test(options.url) ? '&' : '?';
-                    // XDomainRequest only supports GET and POST:
-                    if (options.type === 'DELETE') {
-                        options.url = options.url + addParamChar + '_method=DELETE';
-                        options.type = 'POST';
-                    } else if (options.type === 'PUT') {
-                        options.url = options.url + addParamChar + '_method=PUT';
-                        options.type = 'POST';
-                    } else if (options.type === 'PATCH') {
-                        options.url = options.url + addParamChar + '_method=PATCH';
-                        options.type = 'POST';
-                    }
-                    // javascript:false as initial iframe src
-                    // prevents warning popups on HTTPS in IE6.
-                    // IE versions below IE8 cannot set the name property of
-                    // elements that have already been added to the DOM,
-                    // so we set the name along with the iframe HTML markup:
-                    counter += 1;
-                    iframe = $(
-                        '<iframe src="javascript:false;" name="iframe-transport-' +
-                            counter + '"></iframe>'
-                    ).bind('load', function () {
-                        var fileInputClones,
-                            paramNames = $.isArray(options.paramName) ?
-                                    options.paramName : [options.paramName];
-                        iframe
-                            .unbind('load')
-                            .bind('load', function () {
-                                var response;
-                                // Wrap in a try/catch block to catch exceptions thrown
-                                // when trying to access cross-domain iframe contents:
-                                try {
-                                    response = iframe.contents();
-                                    // Google Chrome and Firefox do not throw an
-                                    // exception when calling iframe.contents() on
-                                    // cross-domain requests, so we unify the response:
-                                    if (!response.length || !response[0].firstChild) {
-                                        throw new Error();
-                                    }
-                                } catch (e) {
-                                    response = undefined;
-                                }
-                                // The complete callback returns the
-                                // iframe content document as response object:
-                                completeCallback(
-                                    200,
-                                    'success',
-                                    {'iframe': response}
-                                );
-                                // Fix for IE endless progress bar activity bug
-                                // (happens on form submits to iframe targets):
-                                $('<iframe src="javascript:false;"></iframe>')
-                                    .appendTo(form);
-                                window.setTimeout(function () {
-                                    // Removing the form in a setTimeout call
-                                    // allows Chrome's developer tools to display
-                                    // the response result
-                                    form.remove();
-                                }, 0);
-                            });
-                        form
-                            .prop('target', iframe.prop('name'))
-                            .prop('action', options.url)
-                            .prop('method', options.type);
-                        if (options.formData) {
-                            $.each(options.formData, function (index, field) {
-                                $('<input type="hidden"/>')
-                                    .prop('name', field.name)
-                                    .val(field.value)
-                                    .appendTo(form);
-                            });
-                        }
-                        if (options.fileInput && options.fileInput.length &&
-                                options.type === 'POST') {
-                            fileInputClones = options.fileInput.clone();
-                            // Insert a clone for each file input field:
-                            options.fileInput.after(function (index) {
-                                return fileInputClones[index];
-                            });
-                            if (options.paramName) {
-                                options.fileInput.each(function (index) {
-                                    $(this).prop(
-                                        'name',
-                                        paramNames[index] || options.paramName
-                                    );
-                                });
-                            }
-                            // Appending the file input fields to the hidden form
-                            // removes them from their original location:
-                            form
-                                .append(options.fileInput)
-                                .prop('enctype', 'multipart/form-data')
-                                // enctype must be set as encoding for IE:
-                                .prop('encoding', 'multipart/form-data');
-                        }
-                        form.submit();
-                        // Insert the file input fields at their original location
-                        // by replacing the clones with the originals:
-                        if (fileInputClones && fileInputClones.length) {
-                            options.fileInput.each(function (index, input) {
-                                var clone = $(fileInputClones[index]);
-                                $(input).prop('name', clone.prop('name'));
-                                clone.replaceWith(input);
-                            });
-                        }
-                    });
-                    form.append(iframe).appendTo(document.body);
-                },
-                abort: function () {
-                    if (iframe) {
-                        // javascript:false as iframe src aborts the request
-                        // and prevents warning popups on HTTPS in IE6.
-                        // concat is used to avoid the "Script URL" JSLint error:
-                        iframe
-                            .unbind('load')
-                            .prop('src', 'javascript'.concat(':false;'));
-                    }
-                    if (form) {
-                        form.remove();
-                    }
-                }
-            };
-        }
-    });
-
-    // The iframe transport returns the iframe content document as response.
-    // The following adds converters from iframe to text, json, html, xml
-    // and script.
-    // Please note that the Content-Type for JSON responses has to be text/plain
-    // or text/html, if the browser doesn't include application/json in the
-    // Accept header, else IE will show a download dialog.
-    // The Content-Type for XML responses on the other hand has to be always
-    // application/xml or text/xml, so IE properly parses the XML response.
-    // See also
-    // https://github.com/blueimp/jQuery-File-Upload/wiki/Setup#content-type-negotiation
-    $.ajaxSetup({
-        converters: {
-            'iframe text': function (iframe) {
-                return iframe && $(iframe[0].body).text();
-            },
-            'iframe json': function (iframe) {
-                return iframe && $.parseJSON($(iframe[0].body).text());
-            },
-            'iframe html': function (iframe) {
-                return iframe && $(iframe[0].body).html();
-            },
-            'iframe xml': function (iframe) {
-                var xmlDoc = iframe && iframe[0];
-                return xmlDoc && $.isXMLDoc(xmlDoc) ? xmlDoc :
-                        $.parseXML((xmlDoc.XMLDocument && xmlDoc.XMLDocument.xml) ||
-                            $(xmlDoc.body).html());
-            },
-            'iframe script': function (iframe) {
-                return iframe && $.globalEval($(iframe[0].body).text());
-            }
-        }
-    });
-
-}));
Index: admin/js/jsUpload/load-image.js
===================================================================
--- admin/js/jsUpload/load-image.js	(revision 3897)
+++ 	(revision )
@@ -1,381 +1,0 @@
-/*
- * JavaScript Load Image 1.6
- * https://github.com/blueimp/JavaScript-Load-Image
- *
- * Copyright 2011, Sebastian Tschan
- * https://blueimp.net
- *
- * iOS image scaling fixes based on
- * https://github.com/stomita/ios-imagefile-megapixel
- *
- * Licensed under the MIT license:
- * http://www.opensource.org/licenses/MIT
- */
-
-/*jslint nomen: true, bitwise: true */
-/*global window, document, URL, webkitURL, FileReader, define */
-
-(function ($) {
-    'use strict';
-
-    // Loads an image for a given File object.
-    // Invokes the callback with an img or optional canvas
-    // element (if supported by the browser) as parameter:
-    var loadImage = function (file, callback, options) {
-            var img = document.createElement('img'),
-                url,
-                oUrl;
-            img.onerror = callback;
-            img.onload = function () {
-                if (oUrl && !(options && options.noRevoke)) {
-                    loadImage.revokeObjectURL(oUrl);
-                }
-                if (callback) {
-                    callback(loadImage.scale(img, options));
-                }
-            };
-            if (loadImage.isInstanceOf('Blob', file) ||
-                    // Files are also Blob instances, but some browsers
-                    // (Firefox 3.6) support the File API but not Blobs:
-                    loadImage.isInstanceOf('File', file)) {
-                url = oUrl = loadImage.createObjectURL(file);
-                // Store the file type for resize processing:
-                img._type = file.type;
-            } else if (typeof file === 'string') {
-                url = file;
-                if (options && options.crossOrigin) {
-                    img.crossOrigin = options.crossOrigin;
-                }
-            } else {
-                return false;
-            }
-            if (url) {
-                img.src = url;
-                return img;
-            }
-            return loadImage.readFile(file, function (e) {
-                var target = e.target;
-                if (target && target.result) {
-                    img.src = target.result;
-                } else {
-                    if (callback) {
-                        callback(e);
-                    }
-                }
-            });
-        },
-        // The check for URL.revokeObjectURL fixes an issue with Opera 12,
-        // which provides URL.createObjectURL but doesn't properly implement it:
-        urlAPI = (window.createObjectURL && window) ||
-            (window.URL && URL.revokeObjectURL && URL) ||
-            (window.webkitURL && webkitURL);
-
-    loadImage.isInstanceOf = function (type, obj) {
-        // Cross-frame instanceof check
-        return Object.prototype.toString.call(obj) === '[object ' + type + ']';
-    };
-
-    // Transform image orientation based on the given EXIF orientation data:
-    loadImage.transformCoordinates = function (canvas, orientation) {
-        var ctx = canvas.getContext('2d'),
-            width = canvas.width,
-            height = canvas.height;
-        if (orientation > 4) {
-            canvas.width = height;
-            canvas.height = width;
-        }
-        switch (orientation) {
-        case 2:
-            // horizontal flip
-            ctx.translate(width, 0);
-            ctx.scale(-1, 1);
-            break;
-        case 3:
-            // 180 rotate left
-            ctx.translate(width, height);
-            ctx.rotate(Math.PI);
-            break;
-        case 4:
-            // vertical flip
-            ctx.translate(0, height);
-            ctx.scale(1, -1);
-            break;
-        case 5:
-            // vertical flip + 90 rotate right
-            ctx.rotate(0.5 * Math.PI);
-            ctx.scale(1, -1);
-            break;
-        case 6:
-            // 90 rotate right
-            ctx.rotate(0.5 * Math.PI);
-            ctx.translate(0, -height);
-            break;
-        case 7:
-            // horizontal flip + 90 rotate right
-            ctx.rotate(0.5 * Math.PI);
-            ctx.translate(width, -height);
-            ctx.scale(-1, 1);
-            break;
-        case 8:
-            // 90 rotate left
-            ctx.rotate(-0.5 * Math.PI);
-            ctx.translate(-width, 0);
-            break;
-        }
-    };
-
-    // Detects subsampling in JPEG images:
-    loadImage.detectSubsampling = function (img) {
-        var canvas,
-            context;
-        if (img.width * img.height > 1024 * 1024) { // only consider mexapixel images
-            canvas = document.createElement('canvas');
-            canvas.width = canvas.height = 1;
-            context = canvas.getContext('2d');
-            context.drawImage(img, -img.width + 1, 0);
-            // subsampled image becomes half smaller in rendering size.
-            // check alpha channel value to confirm image is covering edge pixel or not.
-            // if alpha value is 0 image is not covering, hence subsampled.
-            return context.getImageData(0, 0, 1, 1).data[3] === 0;
-        }
-        return false;
-    };
-
-    // Detects vertical squash in JPEG images:
-    loadImage.detectVerticalSquash = function (img, correctedHeight) {
-        var canvas = document.createElement('canvas'),
-            context = canvas.getContext('2d'),
-            data,
-            sy,
-            ey,
-            py,
-            alpha;
-        canvas.width = 1;
-        canvas.height = correctedHeight;
-        context.drawImage(img, 0, 0);
-        data = context.getImageData(0, 0, 1, correctedHeight).data;
-        // search image edge pixel position in case it is squashed vertically:
-        sy = 0;
-        ey = correctedHeight;
-        py = correctedHeight;
-        while (py > sy) {
-            alpha = data[(py - 1) * 4 + 3];
-            if (alpha === 0) {
-                ey = py;
-            } else {
-                sy = py;
-            }
-            py = (ey + sy) >> 1;
-        }
-        return (py / correctedHeight) || 1;
-    };
-
-    // Renders image to canvas while working around iOS image scaling bugs:
-    // https://github.com/blueimp/JavaScript-Load-Image/issues/13
-    loadImage.renderImageToCanvas = function (
-        canvas,
-        img,
-        sourceX,
-        sourceY,
-        sourceWidth,
-        sourceHeight,
-        destX,
-        destY,
-        destWidth,
-        destHeight
-    ) {
-        var context = canvas.getContext('2d'),
-            tmpCanvas = document.createElement('canvas'),
-            tileSize = tmpCanvas.width = tmpCanvas.height = 1024,
-            tmpContext = tmpCanvas.getContext('2d'),
-            vertSquashRatio,
-            tileX,
-            tileY;
-        context.save();
-        if (loadImage.detectSubsampling(img)) {
-            sourceWidth /= 2;
-            sourceHeight /= 2;
-        }
-        vertSquashRatio = loadImage.detectVerticalSquash(img, sourceHeight);
-        destWidth = Math.ceil(tileSize * destWidth / sourceWidth);
-        destHeight = Math.ceil(
-            tileSize * destHeight / sourceHeight / vertSquashRatio
-        );
-        destY = 0;
-        tileY = 0;
-        while (tileY < sourceHeight) {
-            destX = 0;
-            tileX = 0;
-            while (tileX < sourceWidth) {
-                tmpContext.clearRect(0, 0, tileSize, tileSize);
-                tmpContext.drawImage(
-                    img,
-                    sourceX,
-                    sourceY,
-                    sourceWidth,
-                    sourceHeight,
-                    -tileX,
-                    -tileY,
-                    sourceWidth,
-                    sourceHeight
-                );
-                context.drawImage(
-                    tmpCanvas,
-                    0,
-                    0,
-                    tileSize,
-                    tileSize,
-                    destX,
-                    destY,
-                    destWidth,
-                    destHeight
-                );
-                tileX += tileSize;
-                destX += destWidth;
-            }
-            tileY += tileSize;
-            destY += destHeight;
-        }
-        context.restore();
-    };
-
-    // Scales the given image (img or canvas HTML element)
-    // using the given options.
-    // Returns a canvas object if the browser supports canvas
-    // and the canvas or crop option is true or a canvas object
-    // is passed as image, else the scaled image:
-    loadImage.scale = function (img, options) {
-        options = options || {};
-        var canvas = document.createElement('canvas'),
-            useCanvas = img.getContext ||
-                ((options.canvas || options.crop || options.orientation) &&
-                    canvas.getContext),
-            width = img.width,
-            height = img.height,
-            sourceWidth = width,
-            sourceHeight = height,
-            sourceX = 0,
-            sourceY = 0,
-            destX = 0,
-            destY = 0,
-            maxWidth,
-            maxHeight,
-            minWidth,
-            minHeight,
-            destWidth,
-            destHeight,
-            scale;
-        if (useCanvas && options.orientation > 4) {
-            maxWidth = options.maxHeight;
-            maxHeight = options.maxWidth;
-            minWidth = options.minHeight;
-            minHeight = options.minWidth;
-        } else {
-            maxWidth = options.maxWidth;
-            maxHeight = options.maxHeight;
-            minWidth = options.minWidth;
-            minHeight = options.minHeight;
-        }
-        if (useCanvas && maxWidth && maxHeight && options.crop) {
-            destWidth = maxWidth;
-            destHeight = maxHeight;
-            if (width / height < maxWidth / maxHeight) {
-                sourceHeight = maxHeight * width / maxWidth;
-                sourceY = (height - sourceHeight) / 2;
-            } else {
-                sourceWidth = maxWidth * height / maxHeight;
-                sourceX = (width - sourceWidth) / 2;
-            }
-        } else {
-            destWidth = width;
-            destHeight = height;
-            scale = Math.max(
-                (minWidth || destWidth) / destWidth,
-                (minHeight || destHeight) / destHeight
-            );
-            if (scale > 1) {
-                destWidth = Math.ceil(destWidth * scale);
-                destHeight = Math.ceil(destHeight * scale);
-            }
-            scale = Math.min(
-                (maxWidth || destWidth) / destWidth,
-                (maxHeight || destHeight) / destHeight
-            );
-            if (scale < 1) {
-                destWidth = Math.ceil(destWidth * scale);
-                destHeight = Math.ceil(destHeight * scale);
-            }
-        }
-        if (useCanvas) {
-            canvas.width = destWidth;
-            canvas.height = destHeight;
-            loadImage.transformCoordinates(
-                canvas,
-                options.orientation
-            );
-            if (img._type === 'image/jpeg') {
-                loadImage.renderImageToCanvas(
-                    canvas,
-                    img,
-                    sourceX,
-                    sourceY,
-                    sourceWidth,
-                    sourceHeight,
-                    destX,
-                    destY,
-                    destWidth,
-                    destHeight
-                );
-            } else {
-                canvas.getContext('2d').drawImage(
-                    img,
-                    sourceX,
-                    sourceY,
-                    sourceWidth,
-                    sourceHeight,
-                    destX,
-                    destY,
-                    destWidth,
-                    destHeight
-                );
-            }
-            return canvas;
-        }
-        img.width = destWidth;
-        img.height = destHeight;
-        return img;
-    };
-
-    loadImage.createObjectURL = function (file) {
-        return urlAPI ? urlAPI.createObjectURL(file) : false;
-    };
-
-    loadImage.revokeObjectURL = function (url) {
-        return urlAPI ? urlAPI.revokeObjectURL(url) : false;
-    };
-
-    // Loads a given File object via FileReader interface,
-    // invokes the callback with the event object (load or error).
-    // The result can be read via event.target.result:
-    loadImage.readFile = function (file, callback, method) {
-        if (window.FileReader && FileReader.prototype.readAsDataURL) {
-            var fileReader = new FileReader();
-            fileReader.onload = fileReader.onerror = callback;
-            method = method || 'readAsDataURL';
-            if (!fileReader[method]) {
-                return false;
-            }
-            fileReader[method](file);
-            return fileReader;
-        }
-        return false;
-    };
-
-    if (typeof define === 'function' && define.amd) {
-        define(function () {
-            return loadImage;
-        });
-    } else {
-        $.loadImage = loadImage;
-    }
-}(this));
Index: admin/js/jsUpload/template-download.js
===================================================================
--- admin/js/jsUpload/template-download.js	(revision 3897)
+++ 	(revision )
@@ -1,5 +1,0 @@
-/*global tmpl, dotclear */
-/*exported template_download */
-'use strict';
-
-const template_download = tmpl('{% for (var i=0, file; file=o.files[i]; i++) { %}<li class="template-download fade"><div class="upload-file"><div class="upload-fileinfo"><span class="upload-filename">{%=file.name%}</span><span class="upload-filesize">({%=o.formatFileSize(file.size)%})</span><span class="upload-filemsg{% if (file.error) { %} upload-error{% } %}">{% if (file.error) { %}' + dotclear.jsUpload.msg.error + ' {%=file.error%}{% } else { %}' + dotclear.jsUpload.msg.file_successfully_uploaded + '{% } %}</span></div><div class="upload-progress">{% if (!file.error) { %}<div class="bar" style="width:100%;">100%</div>{% } %}</div></li>{% } %}');
Index: admin/js/jsUpload/template-upload.js
===================================================================
--- admin/js/jsUpload/template-upload.js	(revision 3897)
+++ 	(revision )
@@ -1,5 +1,0 @@
-/*global tmpl, dotclear */
-/*exported template_upload */
-'use strict';
-
-const template_upload = tmpl('{% for (var i=0, file; file=o.files[i]; i++) { %}<li class="template-upload fade"><div class="upload-file"><div class="upload-fileinfo"><span class="upload-filename">{%=file.name%}</span><span class="upload-filesize">({%=o.formatFileSize(file.size)%})</span><span class="upload-filecancel cancel">' + dotclear.jsUpload.msg.cancel + '</span>{% if (!o.files.error && !i && !o.options.autoUpload) { %}<input type="submit" class="button start"  value="' + dotclear.jsUpload.msg.send + '"/>{% } %}<span class="upload-filemsg"></span></div>{% if (!o.files.error) { %}<div class="upload-progress progress progress-success progress-striped active"><div class="bar" style="width:0%;"></div></div>{% } %}</li>{% } %}');
Index: admin/js/jsUpload/tmpl.js
===================================================================
--- admin/js/jsUpload/tmpl.js	(revision 1144)
+++ 	(revision )
@@ -1,86 +1,0 @@
-/*
- * JavaScript Templates 2.1.0
- * https://github.com/blueimp/JavaScript-Templates
- *
- * Copyright 2011, Sebastian Tschan
- * https://blueimp.net
- *
- * Licensed under the MIT license:
- * http://www.opensource.org/licenses/MIT
- *
- * Inspired by John Resig's JavaScript Micro-Templating:
- * http://ejohn.org/blog/javascript-micro-templating/
- */
-
-/*jslint evil: true, regexp: true */
-/*global document, define */
-
-(function ($) {
-    "use strict";
-    var tmpl = function (str, data) {
-        var f = !/[^\w\-\.:]/.test(str) ? tmpl.cache[str] = tmpl.cache[str] ||
-                tmpl(tmpl.load(str)) :
-                    new Function(
-                        tmpl.arg + ',tmpl',
-                        "var _e=tmpl.encode" + tmpl.helper + ",_s='" +
-                            str.replace(tmpl.regexp, tmpl.func) +
-                            "';return _s;"
-                    );
-        return data ? f(data, tmpl) : function (data) {
-            return f(data, tmpl);
-        };
-    };
-    tmpl.cache = {};
-    tmpl.load = function (id) {
-        return document.getElementById(id).innerHTML;
-    };
-    tmpl.regexp = /([\s'\\])(?![^%]*%\})|(?:\{%(=|#)([\s\S]+?)%\})|(\{%)|(%\})/g;
-    tmpl.func = function (s, p1, p2, p3, p4, p5) {
-        if (p1) { // whitespace, quote and backspace in interpolation context
-            return {
-                "\n": "\\n",
-                "\r": "\\r",
-                "\t": "\\t",
-                " " : " "
-            }[s] || "\\" + s;
-        }
-        if (p2) { // interpolation: {%=prop%}, or unescaped: {%#prop%}
-            if (p2 === "=") {
-                return "'+_e(" + p3 + ")+'";
-            }
-            return "'+(" + p3 + "||'')+'";
-        }
-        if (p4) { // evaluation start tag: {%
-            return "';";
-        }
-        if (p5) { // evaluation end tag: %}
-            return "_s+='";
-        }
-    };
-    tmpl.encReg = /[<>&"'\x00]/g;
-    tmpl.encMap = {
-        "<"   : "&lt;",
-        ">"   : "&gt;",
-        "&"   : "&amp;",
-        "\""  : "&quot;",
-        "'"   : "&#39;"
-    };
-    tmpl.encode = function (s) {
-        return String(s || "").replace(
-            tmpl.encReg,
-            function (c) {
-                return tmpl.encMap[c] || "";
-            }
-        );
-    };
-    tmpl.arg = "o";
-    tmpl.helper = ",print=function(s,e){_s+=e&&(s||'')||_e(s);}" +
-        ",include=function(s,d){_s+=tmpl(s,d);}";
-    if (typeof define === "function" && define.amd) {
-        define(function () {
-            return tmpl;
-        });
-    } else {
-        $.tmpl = tmpl;
-    }
-}(this));
Index: admin/js/meta-editor.js
===================================================================
--- admin/js/meta-editor.js	(revision 3880)
+++ admin/js/meta-editor.js	(revision 0)
@@ -1,303 +1,273 @@
-/*global $, dotclear */
-'use strict';
-
 //~ metaEditor & metaEditor.prototype should go to the core.
-function metaEditor(target, meta_field, meta_type, meta_options) {
-  this.target = target;
-  this.meta_field = meta_field;
-  this.meta_type = meta_type;
-
-  // options
-  meta_options = meta_options || {};
-  this.meta_url = meta_options.meta_url || this.meta_url;
-  this.list_type = meta_options.list_type || this.list_type;
-  this.text_confirm_remove = meta_options.text_confirm_remove || this.text_confirm_remove;
-  this.text_add_meta = meta_options.text_add_meta || this.text_add_meta;
-  this.text_choose = meta_options.text_choose || this.text_choose;
-  this.text_all = meta_options.text_all || this.text_all;
-  this.text_separation = meta_options.text_separation || this.text_separation;
-}
+function metaEditor(target,meta_field,meta_type) {
+	this.target = target;
+	this.meta_field = meta_field;
+	this.meta_type = meta_type;
+};
 
 metaEditor.prototype = {
-  meta_url: '',
-  text_confirm_remove: 'Are you sure you want to remove this %s?',
-  text_add_meta: 'Add a %s to this entry',
-  text_choose: 'Choose from list',
-  text_all: 'all',
-  text_separation: 'Separate each %s by comas',
-  list_type: 'more',
-
-  target: null,
-  meta_type: null,
-  meta_dialog: null,
-  meta_field: null,
-  submit_button: null,
-  post_id: false,
-
-  service_uri: 'services.php',
-
-  displayMeta: function(type, post_id) {
-    this.meta_type = type;
-    this.post_id = post_id;
-    this.target.empty();
-
-    this.meta_dialog = $('<input type="text" class="ib" />');
-    this.meta_dialog.attr('title', this.text_add_meta.replace(/%s/, this.meta_type));
-    this.meta_dialog.attr('id', 'post_meta_input');
-    // Meta dialog input
-    this.meta_dialog.keypress(function(evt) { // We don't want to submit form!
-      if (evt.keyCode == 13) {
-        This.addMeta(this.value);
-        return false;
-      }
-      return true;
-    });
-
-    const This = this;
-
-    this.submit_button = $('<input type="button" value="ok" class="ib meta-helper" />');
-    this.submit_button.click(function() {
-      const v = This.meta_dialog.val();
-      This.addMeta(v);
-      return false;
-    });
-
-    this.addMetaDialog();
-
-    if (this.post_id == false) {
-      this.target.append(this.meta_field);
-    }
-    this.displayMetaList();
-  },
-
-  displayMetaList: function() {
-    let li;
-    if (this.meta_list == undefined) {
-      this.meta_list = $('<ul class="metaList"></ul>');
-      this.target.prepend(this.meta_list);
-    }
-
-    if (this.post_id == false) {
-      const meta = this.splitMetaValues(this.meta_field.val());
-
-      this.meta_list.empty();
-      for (let i = 0; i < meta.length; i++) {
-        li = $('<li>' + meta[i] + '</li>');
-        const a_remove = $('<button type="button" class="metaRemove meta-helper"><img src="images/trash.png" alt="remove" /></button>');
-        a_remove.get(0).caller = this;
-        a_remove.get(0).meta_id = meta[i];
-        a_remove.click(function() {
-          this.caller.removeMeta(this.meta_id);
-          return false;
-        });
-        li.prepend('&nbsp;').prepend(a_remove);
-        this.meta_list.append(li);
-      }
-    } else {
-      const This = this;
-      const params = {
-        f: 'getMeta',
-        metaType: this.meta_type,
-        sortby: 'metaId,asc',
-        postId: this.post_id
-      };
-
-      $.get(this.service_uri, params, function(data) {
-        data = $(data);
-
-        if (data.find('rsp').attr('status') != 'ok') {
-          return;
-        }
-
-        This.meta_list.empty();
-        data.find('meta').each(function() {
-          const meta_id = $(this).text();
-          li = $('<li><a href="' + This.meta_url + $(this).attr('uri') + '">' + meta_id + '</a></li>');
-          const a_remove = $('<button type="button" class="metaRemove meta-helper"><img src="images/trash.png" alt="remove" /></button>');
-          a_remove.get(0).caller = This;
-          a_remove.get(0).meta_id = meta_id;
-          a_remove.click(function() {
-            this.caller.removeMeta(this.meta_id);
-            return false;
-          });
-          li.prepend('&nbsp;').prepend(a_remove);
-          This.meta_list.append(li);
-        });
-      });
-    }
-  },
-
-  addMetaDialog: function() {
-
-    if (this.submit_button == null) {
-      this.target.append($('<p></p>').append(this.meta_dialog));
-    } else {
-      this.target.append($('<p></p>').append(this.meta_dialog).append(' ').append(this.submit_button));
-    }
-
-    if (this.text_separation != '') {
-      this.target.append($('<p></p>').addClass('form-note').append(this.text_separation.replace(/%s/, this.meta_type)));
-    }
-
-    this.showMetaList(this.list_type, this.target);
-
-  },
-
-  showMetaList: function(list_type, target) {
-    const params = {
-      f: 'getMeta',
-      metaType: this.meta_type,
-      sortby: 'metaId,asc'
-    };
-
-    if (list_type == 'more') {
-      params.limit = '30';
-    }
-
-    const This = this;
-
-    $.get(this.service_uri, params, function(data) {
-
-      const pl = $('<p class="addMeta"></p>');
-
-      $(target).find('.addMeta').remove();
-
-      if ($(data).find('meta').length > 0) {
-        pl.empty();
-
-        $(data).find('meta').each(function(i) {
-          const meta_link = $('<button type="button" class="metaItem meta-helper">' + $(this).text() + '</button>');
-          meta_link.get(0).meta_id = $(this).text();
-          meta_link.click(function() {
-            const v = This.splitMetaValues(This.meta_dialog.val() + ',' + this.meta_id);
-            This.meta_dialog.val(v.join(','));
-            return false;
-          });
-
-          if (i > 0) {
-            pl.append(', ');
-          }
-          pl.append(meta_link);
-        });
-
-        if (list_type == 'more') {
-          const a_more = $('<button type="button" class="button metaGetMore meta-helper"></button>');
-          a_more.append(This.text_all + String.fromCharCode(160) + String.fromCharCode(187));
-          a_more.click(function() {
-            This.showMetaList('more-all', target);
-            return false;
-          });
-          pl.append(', ').append(a_more);
-        }
-
-        if (list_type != 'more-all') {
-          pl.addClass('hide');
-
-          const pa = $('<p></p>');
-          target.append(pa);
-
-          const a = $(`<button type="button" class="button metaGetList meta-helper">${This.text_choose}</button>`);
-          a.click(function() {
-            $(this).parent().next().removeClass('hide');
-            $(this).remove();
-            return false;
-          });
-
-          pa.append(a);
-        }
-
-        target.append(pl);
-
-      } else {
-        pl.empty();
-      }
-    });
-  },
-
-  addMeta: function(str) {
-    str = this.splitMetaValues(str).join(',');
-    if (this.post_id == false) {
-      str = this.splitMetaValues(this.meta_field.val() + ',' + str);
-      this.meta_field.val(str);
-
-      this.meta_dialog.val('');
-      this.displayMetaList();
-    } else {
-      const params = {
-        xd_check: dotclear.nonce,
-        f: 'setPostMeta',
-        postId: this.post_id,
-        metaType: this.meta_type,
-        meta: str
-      };
-
-      const This = this;
-      $.post(this.service_uri, params, function(data) {
-        if ($(data).find('rsp').attr('status') == 'ok') {
-          This.meta_dialog.val('');
-          This.displayMetaList();
-        } else {
-          window.alert($(data).find('message').text());
-        }
-      });
-    }
-  },
-
-  removeMeta: function(meta_id) {
-    if (this.post_id == false) {
-      let meta = this.splitMetaValues(this.meta_field.val());
-      for (let i = 0; i < meta.length; i++) {
-        if (meta[i] == meta_id) {
-          meta.splice(i, 1);
-          break;
-        }
-      }
-      this.meta_field.val(meta.join(','));
-      this.displayMetaList();
-    } else {
-      const text_confirm_msg = this.text_confirm_remove.replace(/%s/, this.meta_type);
-
-      if (window.confirm(text_confirm_msg)) {
-        const This = this;
-        const params = {
-          xd_check: dotclear.nonce,
-          f: 'delMeta',
-          postId: this.post_id,
-          metaId: meta_id,
-          metaType: this.meta_type
-        };
-
-        $.post(this.service_uri, params, function(data) {
-          if ($(data).find('rsp').attr('status') == 'ok') {
-            This.displayMetaList();
-          } else {
-            window.alert($(data).find('message').text());
-          }
-        });
-      }
-    }
-  },
-
-  splitMetaValues: function(str) {
-    function inArray(needle, stack) {
-      for (var i = 0; i < stack.length; i++) {
-        if (stack[i] == needle) {
-          return true;
-        }
-      }
-      return false;
-    }
-
-    let res = [];
-    let v = str.split(',');
-    v.sort();
-    for (let i = 0; i < v.length; i++) {
-      v[i] = v[i].replace(/^\s*/, '').replace(/\s*$/, '');
-      if (v[i] != '' && !inArray(v[i], res)) {
-        res.push(v[i]);
-      }
-    }
-    res.sort();
-    return res;
-  }
+	meta_url: '',
+	text_confirm_remove: 'Are you sure you want to remove this %s?',
+	text_add_meta: 'Add a %s to this entry',
+	text_choose: 'Choose from list',
+	text_all: 'all',
+	text_separation: 'Separate each %s by comas',
+	
+	target: null,
+	meta_type: null,
+	meta_dialog: null,
+	meta_field: null,
+	submit_button: null,
+	post_id: false,
+	
+	service_uri: 'services.php',
+	
+	displayMeta: function(type,post_id) {
+		this.meta_type = type;
+		this.post_id = post_id;
+		this.target.empty();
+		
+		this.meta_dialog = $('<input type="text" />');
+		this.meta_dialog.attr('title',this.text_add_meta.replace(/%s/,this.meta_type));
+		this.meta_dialog.attr('id','post_meta_input');
+		// Meta dialog input
+		this.meta_dialog.keypress(function(evt) { // We don't want to submit form!
+			if (evt.keyCode == 13) {
+				This.addMeta(this.value);
+				return false;
+			}
+			return true;
+		});
+		
+		var This = this;
+		
+		this.submit_button = $('<input type="button" value="ok" />');
+		this.submit_button.click(function() {
+			var v = This.meta_dialog.val();
+			This.addMeta(v);
+			return false;
+		});
+		
+		this.addMetaDialog();
+		
+		if (this.post_id == false) {
+			this.target.append(this.meta_field);
+		}
+		this.displayMetaList();
+	},
+	
+	displayMetaList: function() {
+		var li;
+		if (this.meta_list == undefined) {
+			this.meta_list = $('<ul class="metaList"></ul>');
+			this.target.prepend(this.meta_list);
+		}
+		
+		if (this.post_id == false) {
+			var meta = this.splitMetaValues(this.meta_field.val());
+			
+			this.meta_list.empty();
+			for (var i=0; i<meta.length; i++) {
+				li = $('<li>'+meta[i]+'</li>');
+				a_remove = $('<a class="metaRemove" href="#">[x]</a>');
+				a_remove.get(0).caller = this;
+				a_remove.get(0).meta_id = meta[i];
+				a_remove.click(function() {
+					this.caller.removeMeta(this.meta_id);
+					return false;
+				});
+				li.append('&nbsp;').append(a_remove);
+				this.meta_list.append(li);
+			}
+		} else {
+			var This = this;
+			var params = {
+				f: 'getMeta',
+				metaType: this.meta_type,
+				sortby: 'metaId,asc',
+				postId: this.post_id
+			};
+			
+			$.get(this.service_uri,params,function(data) {
+				data = $(data);
+				
+				if (data.find('rsp').attr('status') != 'ok') { return; }
+				
+				This.meta_list.empty();
+				data.find('meta').each(function() {
+					var meta_id = $(this).text();
+					li = $('<li><a href="' + This.meta_url + $(this).attr('uri') + '">'+meta_id+'</a></li>');
+					a_remove = $('<a class="metaRemove" href="#">[x]</a>');
+					a_remove.get(0).caller = This;
+					a_remove.get(0).meta_id = meta_id;
+					a_remove.click(function() {
+						this.caller.removeMeta(this.meta_id);
+						return false;
+					});
+					li.append('&nbsp;').append(a_remove);
+					This.meta_list.append(li);
+				});
+			});
+		}
+	},
+	
+	addMetaDialog: function() {
+		var This = this;
+		
+		if (this.submit_button == null) {
+			this.target.append($('<p></p>').append(this.meta_dialog));
+		} else {
+			this.target.append($('<p></p>').append(this.meta_dialog).append(' ').append(this.submit_button));
+		}
+		
+		// View meta list
+		var a = $('<a href="#">' + this.text_choose + '</a>');
+		a.click(function() {
+			This.showMetaList(metaEditor.prototype.meta_type,$(this).parent());
+			return false;
+		});
+		if (this.text_separation != '') {
+			this.target.append($('<p></p>').addClass('form-note').append(this.text_separation.replace(/%s/,this.meta_type)));
+		}
+		this.target.append($('<p></p>').append(a));
+	},
+	
+	showMetaList: function(type,target) {
+		target.empty();
+		target.append('...');
+		target.addClass('addMeta');
+		
+		var params = {
+			f: 'getMeta',
+			metaType: this.meta_type,
+			sortby: 'metaId,asc'
+		};
+		
+		if (type == 'more') {
+			params.limit = '30';
+		}
+		
+		var This = this;
+		
+		$.get(this.service_uri,params,function(data) {
+			if ($(data).find('meta').length > 0) {
+				target.empty();
+				var meta_link;
+				
+				$(data).find('meta').each(function(i) {
+					meta_link = $('<a href="#">' + $(this).text() + '</a>');
+					meta_link.get(0).meta_id = $(this).text();
+					meta_link.click(function() {
+						var v = This.splitMetaValues(This.meta_dialog.val() + ',' + this.meta_id);
+						This.meta_dialog.val(v.join(','));
+						return false;
+					});
+					
+					if (i>0) {
+						target.append(', ');
+					}
+					target.append(meta_link);
+				});
+				
+				if (type == 'more') {
+					var a_more = $('<a href="#" class="metaGetMore"></a>');
+					a_more.append(This.text_all + String.fromCharCode(160)+String.fromCharCode(187));
+					a_more.click(function() {
+						This.showMetaList('all',target);
+						return false;
+					});
+					target.append(', ').append(a_more);
+				}
+			} else {
+				target.empty();
+			}
+		});
+	},
+	
+	addMeta: function(str) {
+		str = this.splitMetaValues(str).join(',');
+		if (this.post_id == false) {
+			str = this.splitMetaValues(this.meta_field.val() + ',' + str);
+			this.meta_field.val(str);
+			
+			this.meta_dialog.val('');
+			this.displayMetaList();
+		} else {
+			var params = {
+				xd_check: dotclear.nonce,
+				f: 'setPostMeta',
+				postId: this.post_id,
+				metaType: this.meta_type,
+				meta: str
+			};
+			
+			var This = this;
+			$.post(this.service_uri,params,function(data) {
+				if ($(data).find('rsp').attr('status') == 'ok') {
+					This.meta_dialog.val('');
+					This.displayMetaList();
+				} else {
+					alert($(data).find('message').text());
+				}
+			});
+		}
+	},
+	
+	removeMeta: function(meta_id) {
+		if (this.post_id == false) {
+			var meta = this.splitMetaValues(this.meta_field.val());
+			for (var i=0; i<meta.length; i++) {
+				if (meta[i] == meta_id) {
+					meta.splice(i,1);
+					break;
+				}
+			}
+			this.meta_field.val(meta.join(','));
+			this.displayMetaList();
+		} else {
+			var text_confirm_msg = this.text_confirm_remove.replace(/%s/,this.meta_type);
+			
+			if (window.confirm(text_confirm_msg)) {
+				var This = this;
+				var params = {
+					xd_check: dotclear.nonce,
+					f: 'delMeta',
+					postId: this.post_id,
+					metaId: meta_id,
+					metaType: this.meta_type
+				};
+				
+				$.post(this.service_uri,params,function(data) {
+					if ($(data).find('rsp').attr('status') == 'ok') {
+						This.displayMetaList();
+					} else {
+						alert($(data).find('message').text());
+					}
+				});
+			}
+		}
+	},
+	
+	splitMetaValues: function(str) {
+		function inArray(needle,stack) {
+			for (var i=0; i<stack.length; i++) {
+				if (stack[i] == needle) {
+					return true;
+				}
+			}
+			return false;
+		}
+		
+		var res = new Array();
+		var v = str.split(',');
+		v.sort();
+		for (var i=0; i<v.length; i++) {
+			v[i] = v[i].replace(/^\s*/,'').replace(/\s*$/,'');
+			if (v[i] != '' && !inArray(v[i],res)) {
+				res.push(v[i]);
+			}
+		}
+		res.sort();
+		return res;
+	}
 };
Index: admin/js/page-tabs.js
===================================================================
--- admin/js/page-tabs.js	(revision 3928)
+++ 	(revision )
@@ -1,5 +1,0 @@
-/*global $, getData */
-'use strict';
-
-const page_tabs = getData('page_tabs');
-$(function() {$.pageTabs(page_tabs.default);});
Index: admin/js/prelude.js
===================================================================
--- admin/js/prelude.js	(revision 3706)
+++ 	(revision )
@@ -1,18 +1,0 @@
-/*global $ */
-'use strict';
-
-$(function() {
-  if ($('#prelude').length > 0) {
-    $('#prelude a')
-      .addClass('hidden')
-      .focus(function() {
-        $('#prelude a').removeClass('hidden');
-        $('#wrapper, #help-button, #collapser').addClass('with-prelude');
-      });
-
-    $('body').on('click', '#prelude a[href="#help"]', function(e) {
-      e.preventDefault();
-      $('#help-button a').focus();
-    });
-  }
-});
Index: admin/js/prepend.js
===================================================================
--- admin/js/prepend.js	(revision 3945)
+++ 	(revision )
@@ -1,44 +1,0 @@
-/*exported getData, isObject, mergeDeep */
-'use strict';
-
-function getData(id, clear = true) {
-  let data = {};
-  // Read the JSON-formatted data from the DOM. (from https://mathiasbynens.be/notes/json-dom-csp)
-  // To be use with: <script type="application/json" id="myid-data">{"key":value, …}</script>
-  const element = document.getElementById(`${id}-data`);
-  if (element) {
-    try {
-      data = JSON.parse(element.textContent);
-      if (clear) {
-        // Clear the element’s contents
-        element.innerHTML = '';
-      }
-    } catch (e) {}
-  }
-  return data;
-}
-
-function isObject(item) {
-  return (item && typeof item === 'object' && !Array.isArray(item));
-}
-
-/**
- * Deep merge two objects.
- * @param target
- * @param ...sources
- */
-function mergeDeep(target, ...sources) {
-  if (!sources.length) return target;
-  const source = sources.shift();
-  if (isObject(target) && isObject(source)) {
-    for (const key in source) {
-      if (isObject(source[key])) {
-        if (!target[key]) Object.assign(target, { [key]: {} });
-        mergeDeep(target[key], source[key]);
-      } else {
-        Object.assign(target, { [key]: source[key] });
-      }
-    }
-  }
-  return mergeDeep(target, ...sources);
-}
Index: admin/js/services.js
===================================================================
--- admin/js/services.js	(revision 3880)
+++ 	(revision )
@@ -1,174 +1,0 @@
-/*global $, dotclear */
-'use strict';
-
-/**
- * Gets the entry (post, page, …) content.
- *
- * @param      numeric     postId    The post identifier
- * @param      function    callback  The callback
- * @param      object      options   The options
- */
-dotclear.getEntryContent = function(postId, callback, options) {
-  let res = '';
-  const opt = $.extend({
-    // Entry type (default: post)
-    type: '',
-    // Alert on error
-    alert: true,
-    // Clean content (useful for potential XSS in spam)
-    clean: false,
-    // Cut content after length chars (-1 to not cut)
-    length: -1,
-  }, options);
-
-  // Check callback fn()
-  if (!$.isFunction(callback)) {
-    return;
-  }
-
-  // Get entry content
-  $.get('services.php', {
-      f: 'getPostById',
-      id: postId,
-      post_type: opt.type,
-      xd_check: dotclear.nonce
-    })
-    .done(function(data) {
-      // Response received
-      const rsp = $(data).children('rsp')[0];
-      if (rsp.attributes[0].value == 'ok') {
-        let excerpt = $(rsp).find('post_display_excerpt').text();
-        let content = $(rsp).find('post_display_content').text();
-        if (excerpt || content) {
-          // Clean content if requested
-          if (opt.clean) {
-            const text = document.createElement('textarea');
-            if (excerpt) {
-              text.textContent = excerpt;
-              excerpt = text.innerHTML;
-            }
-            if (content) {
-              text.textContent = content;
-              content = text.innerHTML;
-            }
-          }
-          // Compose full content
-          if (!opt.clean) {
-            content = (excerpt ? `${excerpt}<hr />` : '') + content;
-          }
-          // Cut content if requested
-          if (opt.length > -1) {
-            content = content.substr(0, opt.length);
-          }
-          if (opt.clean && content) {
-            content = `<pre>${content}</pre>`;
-          }
-          res = content;
-        }
-      } else {
-        if (opt.alert) {
-          window.alert($(rsp).find('message').text());
-        }
-      }
-    })
-    .fail(function(jqXHR, textStatus, errorThrown) {
-      // No response
-      window.console.log(`AJAX ${textStatus} (status: ${jqXHR.status} ${errorThrown})`);
-      if (opt.alert) {
-        window.alert('Server error');
-      }
-    })
-    .always(function() {
-      // Finally
-      callback(res);
-    });
-};
-
-/**
- * Gets the comment content.
- *
- * @param      numeric     commentId  The comment identifier
- * @param      function    callback   The callback
- * @param      object      options    The options
- */
-dotclear.getCommentContent = function(commentId, callback, options) {
-  let res = '';
-  const opt = $.extend({
-    // Get comment metadata (email, site, …)
-    metadata: true,
-    // Show IP in metadata
-    ip: true,
-    // Alert on error
-    alert: true,
-    // Clean content (useful for potential XSS in spam)
-    clean: false,
-    // Cut content after length chars (-1 to not cut)
-    length: -1,
-  }, options);
-
-  // Check callback fn()
-  if (!$.isFunction(callback)) {
-    return;
-  }
-
-  // Get comment content
-  $.get('services.php', {
-      f: 'getCommentById',
-      id: commentId,
-      xd_check: dotclear.nonce
-    })
-    .done(function(data) {
-      // Response received
-      const rsp = $(data).children('rsp')[0];
-      if (rsp.attributes[0].value == 'ok') {
-        let content = $(rsp).find('comment_display_content').text();
-        if (content) {
-          // Clean content if requested
-          if (opt.clean) {
-            const text = document.createElement('textarea');
-            text.textContent = content;
-            content = text.innerHTML;
-          }
-          // Cut content if requested
-          if (opt.length > -1) {
-            content = content.substr(0, opt.length);
-          }
-          if (opt.clean && content) {
-            content = `<pre>${content}</pre>`;
-          }
-          // Get metadata (if requested)
-          if (opt.metadata) {
-            const comment_email = $(rsp).find('comment_email').text();
-            const comment_site = $(rsp).find('comment_site').text();
-            const comment_ip = $(rsp).find('comment_ip').text();
-            const comment_spam_disp = $(rsp).find('comment_spam_disp').text();
-
-            content += `<p>
-              <strong>${dotclear.msg.website}</strong> ${comment_site}<br />
-              <strong>${dotclear.msg.email}</strong> ${comment_email}`;
-            if (opt.ip) {
-              content += `<br />
-                <strong>${dotclear.msg.ip_address}</strong> <a href="comments.php?ip=${comment_ip}">${comment_ip}</a>`;
-            }
-            content += `</p>${comment_spam_disp}`;
-          }
-          res = content;
-        }
-      } else {
-        if (opt.alert) {
-          window.alert($(rsp).find('message').text());
-        }
-      }
-    })
-    .fail(function(jqXHR, textStatus, errorThrown) {
-      // No response
-      window.console.log(`AJAX ${textStatus} (status: ${jqXHR.status} ${errorThrown})`);
-      if (opt.alert) {
-        window.alert('Server error');
-      }
-    })
-    .always(function() {
-      // Finally
-      callback(res);
-    });
-};
Index: admin/js/toggles.js
===================================================================
--- admin/js/toggles.js	(revision 3931)
+++ 	(revision )
@@ -1,4 +1,0 @@
-/*global dotclear, getData */
-'use strict';
-
-dotclear.unfolded_sections = getData('dotclear_toggles');
Index: admin/js/tool-man/cookies.js
===================================================================
--- admin/js/tool-man/cookies.js	(revision 0)
+++ admin/js/tool-man/cookies.js	(revision 0)
@@ -0,0 +1,34 @@
+/* Copyright (c) 2005 Tim Taylor Consulting (see LICENSE.txt)
+
+based on http://www.quirksmode.org/js/cookies.html
+*/
+
+ToolMan._cookieOven = {
+	
+	set : function(name, value, expirationInDays) {
+		if (expirationInDays) {
+			var date = new Date()
+			date.setTime(date.getTime() + (expirationInDays * 24 * 60 * 60 * 1000))
+			var expires = "; expires=" + date.toGMTString()
+		} else {
+			var expires = ""
+		}
+		document.cookie = name + "=" + value + expires + "; path=/"
+	},
+	
+	get : function(name) {
+		var namePattern = name + "="
+		var cookies = document.cookie.split(';')
+		for(var i = 0, n = cookies.length; i < n; i++) {
+			var c = cookies[i]
+			while (c.charAt(0) == ' ') c = c.substring(1, c.length)
+			if (c.indexOf(namePattern) == 0)
+				return c.substring(namePattern.length, c.length)
+		}
+		return null
+	},
+	
+	eraseCookie : function(name) {
+		createCookie(name, "", -1)
+	}
+};
Index: admin/js/tool-man/coordinates.js
===================================================================
--- admin/js/tool-man/coordinates.js	(revision 0)
+++ admin/js/tool-man/coordinates.js	(revision 0)
@@ -0,0 +1,154 @@
+/* Copyright (c) 2005 Tim Taylor Consulting (see LICENSE.txt) */
+
+/* FIXME: assumes position styles are specified in 'px' */
+
+ToolMan._coordinatesFactory = {
+	
+	create : function(x, y) {
+		// FIXME: Safari won't parse 'throw' and aborts trying to do anything with this file
+		//if (isNaN(x) || isNaN(y)) throw "invalid x,y: " + x + "," + y
+		return new _ToolManCoordinate(this, x, y)
+	},
+	
+	origin : function() {
+		return this.create(0, 0)
+	},
+	
+	/*
+	 * FIXME: Safari 1.2, returns (0,0) on absolutely positioned elements
+	 */
+	topLeftPosition : function(element) {
+		var left = parseInt(ToolMan.css().readStyle(element, "left"))
+		var left = isNaN(left) ? 0 : left
+		var top = parseInt(ToolMan.css().readStyle(element, "top"))
+		var top = isNaN(top) ? 0 : top
+		
+		return this.create(left, top)
+	},
+	
+	bottomRightPosition : function(element) {
+		return this.topLeftPosition(element).plus(this._size(element))
+	},
+	
+	topLeftOffset : function(element) {
+		var offset = this._offset(element) 
+		
+		var parent = element.offsetParent
+		while (parent) {
+			offset = offset.plus(this._offset(parent))
+			parent = parent.offsetParent
+		}
+		return offset
+	},
+	
+	bottomRightOffset : function(element) {
+		return this.topLeftOffset(element).plus(
+				this.create(element.offsetWidth, element.offsetHeight))
+	},
+	
+	scrollOffset : function() {
+		if (window.pageXOffset) {
+			return this.create(window.pageXOffset, window.pageYOffset)
+		} else if (document.documentElement) {
+			return this.create(
+					document.body.scrollLeft + document.documentElement.scrollLeft, 
+					document.body.scrollTop + document.documentElement.scrollTop)
+		} else if (document.body.scrollLeft >= 0) {
+			return this.create(document.body.scrollLeft, document.body.scrollTop)
+		} else {
+			return this.create(0, 0)
+		}
+	},
+	
+	clientSize : function() {
+		if (window.innerHeight >= 0) {
+			return this.create(window.innerWidth, window.innerHeight)
+		} else if (document.documentElement) {
+			return this.create(document.documentElement.clientWidth,
+					document.documentElement.clientHeight)
+		} else if (document.body.clientHeight >= 0) {
+			return this.create(document.body.clientWidth,
+					document.body.clientHeight)
+		} else {
+			return this.create(0, 0)
+		}
+	},
+	
+	/**
+	 * mouse coordinate relative to the window (technically the
+	 * browser client area) i.e. the part showing your page
+	 *
+	 * NOTE: in Safari the coordinate is relative to the document
+	 */
+	mousePosition : function(event) {
+		event = ToolMan.events().fix(event)
+		return this.create(event.clientX, event.clientY)
+	},
+	
+	/**
+	 * mouse coordinate relative to the document
+	 */
+	mouseOffset : function(event) {
+		event = ToolMan.events().fix(event)
+		if (event.pageX >= 0 || event.pageX < 0) {
+			return this.create(event.pageX, event.pageY)
+		} else if (event.clientX >= 0 || event.clientX < 0) {
+			return this.mousePosition(event).plus(this.scrollOffset())
+		}
+	},
+	
+	_size : function(element) {
+	/* TODO: move to a Dimension class */
+		return this.create(element.offsetWidth, element.offsetHeight)
+	},
+	
+	_offset : function(element) {
+		return this.create(element.offsetLeft, element.offsetTop)
+	}
+}
+
+function _ToolManCoordinate(factory, x, y) {
+	this.factory = factory
+	this.x = isNaN(x) ? 0 : x
+	this.y = isNaN(y) ? 0 : y
+}
+
+_ToolManCoordinate.prototype = {
+	toString : function() {
+		return "(" + this.x + "," + this.y + ")"
+	},
+	
+	plus : function(that) {
+		return this.factory.create(this.x + that.x, this.y + that.y)
+	},
+	
+	minus : function(that) {
+		return this.factory.create(this.x - that.x, this.y - that.y)
+	},
+	
+	min : function(that) {
+		return this.factory.create(
+				Math.min(this.x , that.x), Math.min(this.y , that.y))
+	},
+	
+	max : function(that) {
+		return this.factory.create(
+				Math.max(this.x , that.x), Math.max(this.y , that.y))
+	},
+	
+	constrainTo : function (one, two) {
+		var min = one.min(two)
+		var max = one.max(two)
+		
+		return this.max(min).min(max)
+	},
+	
+	distance : function (that) {
+		return Math.sqrt(Math.pow(this.x - that.x, 2) + Math.pow(this.y - that.y, 2))
+	},
+	
+	reposition : function(element) {
+		element.style["top"] = this.y + "px"
+		element.style["left"] = this.x + "px"
+	}
+}
Index: admin/js/tool-man/core.js
===================================================================
--- admin/js/tool-man/core.js	(revision 0)
+++ admin/js/tool-man/core.js	(revision 0)
@@ -0,0 +1,170 @@
+/*
+Copyright (c) 2005 Tim Taylor Consulting <http://tool-man.org/>
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+IN THE SOFTWARE.
+*/
+
+var ToolMan = {
+	events : function() {
+		if (!ToolMan._eventsFactory) throw "ToolMan Events module isn't loaded";
+		return ToolMan._eventsFactory
+	},
+	
+	css : function() {
+		if (!ToolMan._cssFactory) throw "ToolMan CSS module isn't loaded";
+		return ToolMan._cssFactory
+	},
+	
+	coordinates : function() {
+		if (!ToolMan._coordinatesFactory) throw "ToolMan Coordinates module isn't loaded";
+		return ToolMan._coordinatesFactory
+	},
+	
+	drag : function() {
+		if (!ToolMan._dragFactory) throw "ToolMan Drag module isn't loaded";
+		return ToolMan._dragFactory
+	},
+	
+	dragsort : function() {
+		if (!ToolMan._dragsortFactory) throw "ToolMan DragSort module isn't loaded";
+		return ToolMan._dragsortFactory
+	},
+	
+	helpers : function() {
+		return ToolMan._helpers
+	},
+	
+	cookies : function() {
+		if (!ToolMan._cookieOven) throw "ToolMan Cookie module isn't loaded";
+		return ToolMan._cookieOven
+	},
+	
+	junkdrawer : function() {
+		return ToolMan._junkdrawer
+	}
+	
+}
+
+ToolMan._helpers = {
+	map : function(array, func) {
+		for (var i = 0, n = array.length; i < n; i++) func(array[i])
+	},
+	
+	nextItem : function(item, nodeName) {
+		if (item == null) return false;
+		var next = item.nextSibling
+		while (next != null) {
+			if (next.nodeName == nodeName) return next
+			next = next.nextSibling
+		}
+		return null
+	},
+	
+	previousItem : function(item, nodeName) {
+		var previous = item.previousSibling
+		while (previous != null) {
+			if (previous.nodeName == nodeName) return previous
+			previous = previous.previousSibling
+		}
+		return null
+	},
+	
+	moveBefore : function(item1, item2) {
+		var parent = item1.parentNode
+		parent.removeChild(item1)
+		parent.insertBefore(item1, item2)
+	},
+	
+	moveAfter : function(item1, item2) {
+		var parent = item1.parentNode
+		parent.removeChild(item1)
+		parent.insertBefore(item1, item2 ? item2.nextSibling : null)
+	}
+}
+
+/** 
+ * scripts without a proper home
+ *
+ * stuff here is subject to change unapologetically and without warning
+ */
+ToolMan._junkdrawer = {
+	serializeList : function(list) {
+		var items = list.getElementsByTagName("li")
+		var array = new Array()
+		for (var i = 0, n = items.length; i < n; i++) {
+			var item = items[i]
+			
+			array.push(ToolMan.junkdrawer()._identifier(item))
+		}
+		return array.join('|')
+	},
+	
+	inspectListOrder : function(id) {
+		alert(ToolMan.junkdrawer().serializeList(document.getElementById(id)))
+	},
+	
+	restoreListOrder : function(listID) {
+		var list = document.getElementById(listID)
+		if (list == null) return
+		
+		var cookie = ToolMan.cookies().get("list-" + listID)
+		if (!cookie) return;
+		
+		var IDs = cookie.split('|')
+		var items = ToolMan.junkdrawer()._itemsByID(list)
+		
+		for (var i = 0, n = IDs.length; i < n; i++) {
+			var itemID = IDs[i]
+			if (itemID in items) {
+				var item = items[itemID]
+				list.removeChild(item)
+				list.insertBefore(item, null)
+			}
+		}
+	},
+	
+	_identifier : function(item) {
+		var trim = ToolMan.junkdrawer().trim
+		var identifier
+		
+		identifier = trim(item.getAttribute("id"))
+		if (identifier != null && identifier.length > 0) return identifier;
+		
+		identifier = trim(item.getAttribute("itemID"))
+		if (identifier != null && identifier.length > 0) return identifier;
+		
+		// FIXME: strip out special chars or make this an MD5 hash or something
+		return trim(item.innerHTML)
+	},
+	
+	_itemsByID : function(list) {
+		var array = new Array()
+		var items = list.getElementsByTagName('li')
+		for (var i = 0, n = items.length; i < n; i++) {
+			var item = items[i]
+			array[ToolMan.junkdrawer()._identifier(item)] = item
+		}
+		return array
+	},
+	
+	trim : function(text) {
+		if (text == null) return null
+		return text.replace(/^(\s+)?(.*\S)(\s+)?$/, '$2')
+	}
+}
Index: admin/js/tool-man/css.js
===================================================================
--- admin/js/tool-man/css.js	(revision 0)
+++ admin/js/tool-man/css.js	(revision 0)
@@ -0,0 +1,17 @@
+/* Copyright (c) 2005 Tim Taylor Consulting (see LICENSE.txt) */
+
+// TODO: write unit tests
+ToolMan._cssFactory = {
+	readStyle : function(element, property) {
+		if (element.style[property]) {
+			return element.style[property]
+		} else if (element.currentStyle) {
+			return element.currentStyle[property]
+		} else if (document.defaultView && document.defaultView.getComputedStyle) {
+			var style = document.defaultView.getComputedStyle(element, null)
+			return style.getPropertyValue(property)
+		} else {
+			return null
+		}
+	}
+}
Index: admin/js/tool-man/drag.js
===================================================================
--- admin/js/tool-man/drag.js	(revision 0)
+++ admin/js/tool-man/drag.js	(revision 0)
@@ -0,0 +1,249 @@
+/* Copyright (c) 2005 Tim Taylor Consulting (see LICENSE.txt) */
+
+ToolMan._dragFactory = {
+	createSimpleGroup : function(element, handle) {
+		handle = handle ? handle : element
+		var group = this.createGroup(element)
+		group.setHandle(handle)
+		//group.transparentDrag()
+		group.onTopWhileDragging()
+		return group
+	},
+	
+	createGroup : function(element) {
+		var group = new _ToolManDragGroup(this, element)
+		
+		var position = ToolMan.css().readStyle(element, 'position')
+		if (position == 'static') {
+			element.style["position"] = 'relative'
+		} else if (position == 'absolute') {
+			/* for Safari 1.2 */
+			ToolMan.coordinates().topLeftOffset(element).reposition(element)
+		}
+		
+		// TODO: only if ToolMan.isDebugging()
+		group.register('draginit', this._showDragEventStatus)
+		group.register('dragmove', this._showDragEventStatus)
+		group.register('dragend', this._showDragEventStatus)
+		
+		return group
+	},
+	
+	_showDragEventStatus : function(dragEvent) {
+		window.status = dragEvent.toString()
+	},
+	
+	constraints : function() {
+		return this._constraintFactory
+	},
+	
+	_createEvent : function(type, event, group) {
+		return new _ToolManDragEvent(type, event, group)
+	}
+}
+
+function _ToolManDragGroup(factory, element) {
+	this.factory = factory
+	this.element = element
+	this._handle = null
+	this._thresholdDistance = 0
+	this._transforms = new Array()
+	// TODO: refactor into a helper object, move into events.js
+	this._listeners = new Array()
+	this._listeners['draginit'] = new Array()
+	this._listeners['dragstart'] = new Array()
+	this._listeners['dragmove'] = new Array()
+	this._listeners['dragend'] = new Array()
+}
+
+_ToolManDragGroup.prototype = {
+	/*
+	 * TODO:
+	 *   - unregister(type, func)
+	 *   - move custom event listener stuff into Event library
+	 *   - keyboard nudging of "selected" group
+	 */
+	
+	setHandle : function(handle) {
+		var events = ToolMan.events()
+		
+		handle.toolManDragGroup = this
+		events.register(handle, 'mousedown', this._dragInit)
+		//handle.onmousedown = function() { return false }
+		
+		if (this.element != handle)
+			events.unregister(this.element, 'mousedown', this._dragInit)
+	},
+	
+	register : function(type, func) {
+		this._listeners[type].push(func)
+	},
+	
+	addTransform : function(transformFunc) {
+		this._transforms.push(transformFunc)
+	},
+	
+	verticalOnly : function() {
+		this.addTransform(this.factory.constraints().vertical())
+	},
+	
+	horizontalOnly : function() {
+		this.addTransform(this.factory.constraints().horizontal())
+	},
+	
+	setThreshold : function(thresholdDistance) {
+		this._thresholdDistance = thresholdDistance
+	},
+	
+	transparentDrag : function(opacity) {
+		if (typeof(opacity) == "undefined") {
+			opacity = 0.75;
+		}
+		var originalOpacity = ToolMan.css().readStyle(this.element, "opacity")
+		
+		this.register('dragstart', function(dragEvent) {
+			var element = dragEvent.group.element
+			element.style.opacity = opacity
+			element.style.filter = 'alpha(opacity=' + (opacity * 100) + ')'
+		})
+		this.register('dragend', function(dragEvent) {
+			var element = dragEvent.group.element
+			element.style.opacity = originalOpacity
+			element.style.filter = 'alpha(opacity=100)'
+		})
+	},
+	
+	onTopWhileDragging : function(zIndex) {
+		if (typeof(zIndex) == "undefined") {
+			zIndex = 100000;
+		}
+		
+		var originalZIndex = ToolMan.css().readStyle(this.element, "z-index")
+		
+		this.register('dragstart', function(dragEvent) {
+			dragEvent.group.element.style.zIndex = zIndex
+		})
+		this.register('dragend', function(dragEvent) {
+			if (typeof(originalZIndex) != "undefined") {
+				dragEvent.group.element.style.zIndex = originalZIndex
+			}
+			//dragEvent.group.element.style.backgroundColor = '#f00';
+		})
+	},
+	
+	_dragInit : function(event) {
+		event = ToolMan.events().fix(event)
+		var group = document.toolManDragGroup = this.toolManDragGroup
+		var dragEvent = group.factory._createEvent('draginit', event, group)
+		
+		group._isThresholdExceeded = false
+		group._initialMouseOffset = dragEvent.mouseOffset
+		group._grabOffset = dragEvent.mouseOffset.minus(dragEvent.topLeftOffset)
+		ToolMan.events().register(document, 'mousemove', group._drag)
+		document.onmousemove = function() { return false }
+		ToolMan.events().register(document, 'mouseup', group._dragEnd)
+		
+		ToolMan.events().register(document, 'mousedown',group._drag);
+		document.onmousedown = function() { return false; };
+		
+		group._notifyListeners(dragEvent)
+	},
+	
+	_drag : function(event) {
+		event = ToolMan.events().fix(event)
+		var coordinates = ToolMan.coordinates()
+		var group = this.toolManDragGroup
+		if (!group) return
+		var dragEvent = group.factory._createEvent('dragmove', event, group)
+		
+		var newTopLeftOffset = dragEvent.mouseOffset.minus(group._grabOffset)
+		
+		// TODO: replace with DragThreshold object
+		if (!group._isThresholdExceeded) {
+			var distance = 
+					dragEvent.mouseOffset.distance(group._initialMouseOffset)
+			if (distance < group._thresholdDistance) return
+			group._isThresholdExceeded = true
+			group._notifyListeners(
+					group.factory._createEvent('dragstart', event, group))
+		}
+		
+		for (i in group._transforms) {
+			var transform = group._transforms[i]
+			newTopLeftOffset = transform(newTopLeftOffset, dragEvent)
+		}
+		
+		var dragDelta = newTopLeftOffset.minus(dragEvent.topLeftOffset)
+		var newTopLeftPosition = dragEvent.topLeftPosition.plus(dragDelta)
+		newTopLeftPosition.reposition(group.element)
+		dragEvent.transformedMouseOffset = newTopLeftOffset.plus(group._grabOffset)
+		
+		group._notifyListeners(dragEvent)
+		
+		var errorDelta = newTopLeftOffset.minus(coordinates.topLeftOffset(group.element))
+		if (errorDelta.x != 0 || errorDelta.y != 0) {
+			coordinates.topLeftPosition(group.element).plus(errorDelta).reposition(group.element)
+		}
+	},
+	
+	_dragEnd : function(event) {
+		event = ToolMan.events().fix(event)
+		var group = this.toolManDragGroup
+		var dragEvent = group.factory._createEvent('dragend', event, group)
+		
+		group._notifyListeners(dragEvent)
+		
+		this.toolManDragGroup = null
+		ToolMan.events().unregister(document, 'mousemove', group._drag)
+		document.onmousemove = null
+		ToolMan.events().unregister(document, 'mouseup', group._dragEnd)
+		
+		ToolMan.events().register(document, 'mousedown', group._drag);
+		document.onmousedown = function() { return true };
+	},
+	
+	_notifyListeners : function(dragEvent) {
+		var listeners = this._listeners[dragEvent.type]
+		for (i in listeners) {
+			listeners[i](dragEvent)
+		}
+	}
+}
+
+function _ToolManDragEvent(type, event, group) {
+	this.type = type
+	this.group = group
+	this.mousePosition = ToolMan.coordinates().mousePosition(event)
+	this.mouseOffset = ToolMan.coordinates().mouseOffset(event)
+	this.transformedMouseOffset = this.mouseOffset
+	this.topLeftPosition = ToolMan.coordinates().topLeftPosition(group.element)
+	this.topLeftOffset = ToolMan.coordinates().topLeftOffset(group.element)
+}
+
+_ToolManDragEvent.prototype = {
+	toString : function() {
+		return "mouse: " + this.mousePosition + this.mouseOffset + "    " +
+				"xmouse: " + this.transformedMouseOffset + "    " +
+				"left,top: " + this.topLeftPosition + this.topLeftOffset
+	}
+}
+
+ToolMan._dragFactory._constraintFactory = {
+	vertical : function() {
+		return function(coordinate, dragEvent) {
+			var x = dragEvent.topLeftOffset.x
+			return coordinate.x != x
+					? coordinate.factory.create(x, coordinate.y) 
+					: coordinate
+		}
+	},
+	
+	horizontal : function() {
+		return function(coordinate, dragEvent) {
+			var y = dragEvent.topLeftOffset.y
+			return coordinate.y != y
+					? coordinate.factory.create(coordinate.x, y) 
+					: coordinate
+		}
+	}
+}
Index: admin/js/tool-man/dragsort.js
===================================================================
--- admin/js/tool-man/dragsort.js	(revision 0)
+++ admin/js/tool-man/dragsort.js	(revision 0)
@@ -0,0 +1,87 @@
+/* Copyright (c) 2005 Tim Taylor Consulting (see LICENSE.txt) */
+
+ToolMan._dragsortFactory = {
+	makeSortable : function(item) {
+		var group = ToolMan.drag().createSimpleGroup(item)
+		
+		group.register('dragstart', this._onDragStart)
+		group.register('dragmove', this._onDragMove)
+		group.register('dragend', this._onDragEnd)
+		
+		return group
+	},
+	
+	/** 
+	 * Iterates over a list's items, making them sortable, applying
+	 * optional functions to each item.
+	 *
+	 * example: makeListSortable(myList, myFunc1, myFunc2, ... , myFuncN)
+	 */
+	makeListSortable : function(list) {
+		var helpers = ToolMan.helpers()
+		var coordinates = ToolMan.coordinates()
+		var items = list.getElementsByTagName("li")
+		
+		helpers.map(items, function(item) {
+			var dragGroup = dragsort.makeSortable(item)
+			dragGroup.setThreshold(4)
+			var min, max
+			dragGroup.addTransform(function(coordinate, dragEvent) {
+				return coordinate.constrainTo(min, max)
+			})
+			dragGroup.register('dragstart', function() {
+				var items = list.getElementsByTagName("li")
+				min = max = coordinates.topLeftOffset(items[0])
+				for (var i = 1, n = items.length; i < n; i++) {
+					var offset = coordinates.topLeftOffset(items[i])
+					min = min.min(offset)
+					max = max.max(offset)
+				}
+			})
+		})
+		for (var i = 1, n = arguments.length; i < n; i++)
+			helpers.map(items, arguments[i])
+	},
+	
+	_onDragStart : function(dragEvent) {
+	},
+	
+	_onDragMove : function(dragEvent) {
+		var helpers = ToolMan.helpers()
+		var coordinates = ToolMan.coordinates()
+		
+		var item = dragEvent.group.element
+		var xmouse = dragEvent.transformedMouseOffset
+		var moveTo = null
+		
+		var previous = helpers.previousItem(item, item.nodeName)
+		while (previous != null) {
+			var bottomRight = coordinates.bottomRightOffset(previous)
+			if (xmouse.y <= bottomRight.y && xmouse.x <= bottomRight.x) {
+				moveTo = previous
+			}
+			previous = helpers.previousItem(previous, item.nodeName)
+		}
+		if (moveTo != null) {
+			helpers.moveBefore(item, moveTo)
+			return
+		}
+		
+		var next = helpers.nextItem(item, item.nodeName)
+		while (next != null) {
+			var topLeft = coordinates.topLeftOffset(next)
+			if (topLeft.y <= xmouse.y && topLeft.x <= xmouse.x) {
+				moveTo = next
+			}
+			next = helpers.nextItem(next, item.nodeName)
+		}
+		if (moveTo != null) {
+			helpers.moveBefore(item, helpers.nextItem(moveTo, item.nodeName))
+			return
+		}
+	},
+	
+	_onDragEnd : function(dragEvent) {
+		ToolMan.coordinates().create(0, 0).reposition(dragEvent.group.element)
+	}
+}
Index: admin/js/tool-man/events.js
===================================================================
--- admin/js/tool-man/events.js	(revision 0)
+++ admin/js/tool-man/events.js	(revision 0)
@@ -0,0 +1,43 @@
+/* Copyright (c) 2005 Tim Taylor Consulting (see LICENSE.txt) */
+
+ToolMan._eventsFactory = {
+	fix : function(event) {
+		if (!event) event = window.event
+		
+		if (event.target) {
+			if (event.target.nodeType == 3) event.target = event.target.parentNode
+		} else if (event.srcElement) {
+			event.target = event.srcElement
+		}
+		
+		return event
+	},
+	
+	register : function(element, type, func) {
+		if (element.addEventListener) {
+			element.addEventListener(type, func, false)
+		} else if (element.attachEvent) {
+			if (!element._listeners) element._listeners = new Array()
+			if (!element._listeners[type]) element._listeners[type] = new Array()
+			var workaroundFunc = function() {
+				func.apply(element, new Array())
+			}
+			element._listeners[type][func] = workaroundFunc
+			element.attachEvent('on' + type, workaroundFunc)
+		}
+	},
+	
+	unregister : function(element, type, func) {
+		if (element.removeEventListener) {
+			element.removeEventListener(type, func, false)
+		} else if (element.detachEvent) {
+			if (element._listeners 
+					&& element._listeners[type] 
+					&& element._listeners[type][func]) {
+						
+				element.detachEvent('on' + type, 
+						element._listeners[type][func])
+			}
+		}
+	}
+}
