diff --git a/core/assets/vendor/awesomplete/awesomplete.base.css b/core/assets/vendor/awesomplete/awesomplete.base.css
new file mode 100755
index 0000000000..8e5ec1250f
--- /dev/null
+++ b/core/assets/vendor/awesomplete/awesomplete.base.css
@@ -0,0 +1,33 @@
+.awesomplete [hidden] {
+    display: none;
+}
+
+.awesomplete .visually-hidden {
+    position: absolute;
+    clip: rect(0, 0, 0, 0);
+}
+
+.awesomplete {
+    display: inline-block;
+    position: relative;
+}
+
+.awesomplete > input {
+    display: block;
+}
+
+.awesomplete > ul {
+    position: absolute;
+    left: 0;
+    z-index: 1;
+    min-width: 100%;
+    box-sizing: border-box;
+    list-style: none;
+    padding: 0;
+    margin: 0;
+    background: #fff;
+}
+
+.awesomplete > ul:empty {
+    display: none;
+}
diff --git a/core/assets/vendor/awesomplete/awesomplete.css b/core/assets/vendor/awesomplete/awesomplete.css
new file mode 100755
index 0000000000..0b2ea34fe6
--- /dev/null
+++ b/core/assets/vendor/awesomplete/awesomplete.css
@@ -0,0 +1,104 @@
+.awesomplete [hidden] {
+    display: none;
+}
+
+.awesomplete .visually-hidden {
+    position: absolute;
+    clip: rect(0, 0, 0, 0);
+}
+
+.awesomplete {
+    display: inline-block;
+    position: relative;
+}
+
+.awesomplete > input {
+    display: block;
+}
+
+.awesomplete > ul {
+    position: absolute;
+    left: 0;
+    z-index: 1;
+    min-width: 100%;
+    box-sizing: border-box;
+    list-style: none;
+    padding: 0;
+    margin: 0;
+    background: #fff;
+}
+
+.awesomplete > ul:empty {
+    display: none;
+}
+
+.awesomplete > ul {
+	border-radius: .3em;
+	margin: .2em 0 0;
+	background: hsla(0,0%,100%,.9);
+	background: linear-gradient(to bottom right, white, hsla(0,0%,100%,.8));
+	border: 1px solid rgba(0,0,0,.3);
+	box-shadow: .05em .2em .6em rgba(0,0,0,.2);
+	text-shadow: none;
+}
+
+@supports (transform: scale(0)) {
+	.awesomplete > ul {
+		transition: .3s cubic-bezier(.4,.2,.5,1.4);
+		transform-origin: 1.43em -.43em;
+	}
+	
+	.awesomplete > ul[hidden],
+	.awesomplete > ul:empty {
+		opacity: 0;
+		transform: scale(0);
+		display: block;
+		transition-timing-function: ease;
+	}
+}
+
+	/* Pointer */
+	.awesomplete > ul:before {
+		content: "";
+		position: absolute;
+		top: -.43em;
+		left: 1em;
+		width: 0; height: 0;
+		padding: .4em;
+		background: white;
+		border: inherit;
+		border-right: 0;
+		border-bottom: 0;
+		-webkit-transform: rotate(45deg);
+		transform: rotate(45deg);
+	}
+
+	.awesomplete > ul > li {
+		position: relative;
+		padding: .2em .5em;
+		cursor: pointer;
+	}
+	
+	.awesomplete > ul > li:hover {
+		background: hsl(200, 40%, 80%);
+		color: black;
+	}
+	
+	.awesomplete > ul > li[aria-selected="true"] {
+		background: hsl(205, 40%, 40%);
+		color: white;
+	}
+	
+		.awesomplete mark {
+			background: hsl(65, 100%, 50%);
+		}
+		
+		.awesomplete li:hover mark {
+			background: hsl(68, 100%, 41%);
+		}
+		
+		.awesomplete li[aria-selected="true"] mark {
+			background: hsl(86, 100%, 21%);
+			color: inherit;
+		}
+/*# sourceMappingURL=awesomplete.css.map */
diff --git a/core/assets/vendor/awesomplete/awesomplete.css.map b/core/assets/vendor/awesomplete/awesomplete.css.map
new file mode 100755
index 0000000000..3d57839754
--- /dev/null
+++ b/core/assets/vendor/awesomplete/awesomplete.css.map
@@ -0,0 +1 @@
+{"version":3,"sources":["awesomplete.base.css","awesomplete.theme.css"],"names":[],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;ACjCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA","file":"awesomplete.css","sourcesContent":[".awesomplete [hidden] {\n    display: none;\n}\n\n.awesomplete .visually-hidden {\n    position: absolute;\n    clip: rect(0, 0, 0, 0);\n}\n\n.awesomplete {\n    display: inline-block;\n    position: relative;\n}\n\n.awesomplete > input {\n    display: block;\n}\n\n.awesomplete > ul {\n    position: absolute;\n    left: 0;\n    z-index: 1;\n    min-width: 100%;\n    box-sizing: border-box;\n    list-style: none;\n    padding: 0;\n    margin: 0;\n    background: #fff;\n}\n\n.awesomplete > ul:empty {\n    display: none;\n}\n",".awesomplete > ul {\n\tborder-radius: .3em;\n\tmargin: .2em 0 0;\n\tbackground: hsla(0,0%,100%,.9);\n\tbackground: linear-gradient(to bottom right, white, hsla(0,0%,100%,.8));\n\tborder: 1px solid rgba(0,0,0,.3);\n\tbox-shadow: .05em .2em .6em rgba(0,0,0,.2);\n\ttext-shadow: none;\n}\n\n@supports (transform: scale(0)) {\n\t.awesomplete > ul {\n\t\ttransition: .3s cubic-bezier(.4,.2,.5,1.4);\n\t\ttransform-origin: 1.43em -.43em;\n\t}\n\t\n\t.awesomplete > ul[hidden],\n\t.awesomplete > ul:empty {\n\t\topacity: 0;\n\t\ttransform: scale(0);\n\t\tdisplay: block;\n\t\ttransition-timing-function: ease;\n\t}\n}\n\n\t/* Pointer */\n\t.awesomplete > ul:before {\n\t\tcontent: \"\";\n\t\tposition: absolute;\n\t\ttop: -.43em;\n\t\tleft: 1em;\n\t\twidth: 0; height: 0;\n\t\tpadding: .4em;\n\t\tbackground: white;\n\t\tborder: inherit;\n\t\tborder-right: 0;\n\t\tborder-bottom: 0;\n\t\t-webkit-transform: rotate(45deg);\n\t\ttransform: rotate(45deg);\n\t}\n\n\t.awesomplete > ul > li {\n\t\tposition: relative;\n\t\tpadding: .2em .5em;\n\t\tcursor: pointer;\n\t}\n\t\n\t.awesomplete > ul > li:hover {\n\t\tbackground: hsl(200, 40%, 80%);\n\t\tcolor: black;\n\t}\n\t\n\t.awesomplete > ul > li[aria-selected=\"true\"] {\n\t\tbackground: hsl(205, 40%, 40%);\n\t\tcolor: white;\n\t}\n\t\n\t\t.awesomplete mark {\n\t\t\tbackground: hsl(65, 100%, 50%);\n\t\t}\n\t\t\n\t\t.awesomplete li:hover mark {\n\t\t\tbackground: hsl(68, 100%, 41%);\n\t\t}\n\t\t\n\t\t.awesomplete li[aria-selected=\"true\"] mark {\n\t\t\tbackground: hsl(86, 100%, 21%);\n\t\t\tcolor: inherit;\n\t\t}"]}
\ No newline at end of file
diff --git a/core/assets/vendor/awesomplete/awesomplete.js b/core/assets/vendor/awesomplete/awesomplete.js
new file mode 100755
index 0000000000..396fb7118d
--- /dev/null
+++ b/core/assets/vendor/awesomplete/awesomplete.js
@@ -0,0 +1,552 @@
+/**
+ * Simple, lightweight, usable local autocomplete library for modern browsers
+ * Because there weren’t enough autocomplete scripts in the world? Because I’m completely insane and have NIH syndrome? Probably both. :P
+ * @author Lea Verou http://leaverou.github.io/awesomplete
+ * MIT license
+ */
+
+(function () {
+
+var _ = function (input, o) {
+	var me = this;
+
+    // Keep track of number of instances for unique IDs
+    _.count = (_.count || 0) + 1;
+    this.count = _.count;
+
+	// Setup
+
+	this.isOpened = false;
+
+	this.input = $(input);
+	this.input.setAttribute("autocomplete", "off");
+	this.input.setAttribute("aria-expanded", "false");
+	this.input.setAttribute("aria-owns", "awesomplete_list_" + this.count);
+	this.input.setAttribute("role", "combobox");
+
+	// store constructor options in case we need to distinguish
+	// between default and customized behavior later on
+	this.options = o = o || {};
+
+	configure(this, {
+		minChars: 2,
+		maxItems: 10,
+		autoFirst: false,
+		data: _.DATA,
+		filter: _.FILTER_CONTAINS,
+		sort: o.sort === false ? false : _.SORT_BYLENGTH,
+		container: _.CONTAINER,
+		item: _.ITEM,
+		replace: _.REPLACE,
+		tabSelect: false
+	}, o);
+
+	this.index = -1;
+
+	// Create necessary elements
+
+	this.container = this.container(input);
+
+	this.ul = $.create("ul", {
+		hidden: "hidden",
+        role: "listbox",
+        id: "awesomplete_list_" + this.count,
+		inside: this.container
+	});
+
+	this.status = $.create("span", {
+		className: "visually-hidden",
+		role: "status",
+		"aria-live": "assertive",
+        "aria-atomic": true,
+        inside: this.container,
+        textContent: this.minChars != 0 ? ("Type " + this.minChars + " or more characters for results.") : "Begin typing for results."
+	});
+
+	// Bind events
+
+	this._events = {
+		input: {
+			"input": this.evaluate.bind(this),
+			"blur": this.close.bind(this, { reason: "blur" }),
+			"keydown": function(evt) {
+				var c = evt.keyCode;
+
+				// If the dropdown `ul` is in view, then act on keydown for the following keys:
+				// Enter / Esc / Up / Down
+				if(me.opened) {
+					if (c === 13 && me.selected) { // Enter
+						evt.preventDefault();
+						me.select(undefined, undefined, evt);
+					}
+					else if (c === 9 && me.selected && me.tabSelect) {
+						me.select(undefined, undefined, evt);
+					}
+					else if (c === 27) { // Esc
+						me.close({ reason: "esc" });
+					}
+					else if (c === 38 || c === 40) { // Down/Up arrow
+						evt.preventDefault();
+						me[c === 38? "previous" : "next"]();
+					}
+				}
+			}
+		},
+		form: {
+			"submit": this.close.bind(this, { reason: "submit" })
+		},
+		ul: {
+			// Prevent the default mousedowm, which ensures the input is not blurred.
+			// The actual selection will happen on click. This also ensures dragging the
+			// cursor away from the list item will cancel the selection
+			"mousedown": function(evt) {
+				evt.preventDefault();
+			},
+			// The click event is fired even if the corresponding mousedown event has called preventDefault
+			"click": function(evt) {
+				var li = evt.target;
+
+				if (li !== this) {
+
+					while (li && !/li/i.test(li.nodeName)) {
+						li = li.parentNode;
+					}
+
+					if (li && evt.button === 0) {  // Only select on left click
+						evt.preventDefault();
+						me.select(li, evt.target, evt);
+					}
+				}
+			}
+		}
+	};
+
+	$.bind(this.input, this._events.input);
+	$.bind(this.input.form, this._events.form);
+	$.bind(this.ul, this._events.ul);
+
+	if (this.input.hasAttribute("list")) {
+		this.list = "#" + this.input.getAttribute("list");
+		this.input.removeAttribute("list");
+	}
+	else {
+		this.list = this.input.getAttribute("data-list") || o.list || [];
+	}
+
+	_.all.push(this);
+};
+
+_.prototype = {
+	set list(list) {
+		if (Array.isArray(list)) {
+			this._list = list;
+		}
+		else if (typeof list === "string" && list.indexOf(",") > -1) {
+				this._list = list.split(/\s*,\s*/);
+		}
+		else { // Element or CSS selector
+			list = $(list);
+
+			if (list && list.children) {
+				var items = [];
+				slice.apply(list.children).forEach(function (el) {
+					if (!el.disabled) {
+						var text = el.textContent.trim();
+						var value = el.value || text;
+						var label = el.label || text;
+						if (value !== "") {
+							items.push({ label: label, value: value });
+						}
+					}
+				});
+				this._list = items;
+			}
+		}
+
+		if (document.activeElement === this.input) {
+			this.evaluate();
+		}
+	},
+
+	get selected() {
+		return this.index > -1;
+	},
+
+	get opened() {
+		return this.isOpened;
+	},
+
+	close: function (o) {
+		if (!this.opened) {
+			return;
+		}
+
+		this.input.setAttribute("aria-expanded", "false");
+		this.ul.setAttribute("hidden", "");
+		this.isOpened = false;
+		this.index = -1;
+
+		this.status.setAttribute("hidden", "");
+
+		$.fire(this.input, "awesomplete-close", o || {});
+	},
+
+	open: function () {
+		this.input.setAttribute("aria-expanded", "true");
+		this.ul.removeAttribute("hidden");
+		this.isOpened = true;
+
+		this.status.removeAttribute("hidden");
+
+		if (this.autoFirst && this.index === -1) {
+			this.goto(0);
+		}
+
+		$.fire(this.input, "awesomplete-open");
+	},
+
+	destroy: function() {
+		//remove events from the input and its form
+		$.unbind(this.input, this._events.input);
+		$.unbind(this.input.form, this._events.form);
+
+		// cleanup container if it was created by Awesomplete but leave it alone otherwise
+		if (!this.options.container) {
+			//move the input out of the awesomplete container and remove the container and its children
+			var parentNode = this.container.parentNode;
+
+			parentNode.insertBefore(this.input, this.container);
+			parentNode.removeChild(this.container);
+		}
+
+		//remove autocomplete and aria-autocomplete attributes
+		this.input.removeAttribute("autocomplete");
+		this.input.removeAttribute("aria-autocomplete");
+
+		//remove this awesomeplete instance from the global array of instances
+		var indexOfAwesomplete = _.all.indexOf(this);
+
+		if (indexOfAwesomplete !== -1) {
+			_.all.splice(indexOfAwesomplete, 1);
+		}
+	},
+
+	next: function () {
+		var count = this.ul.children.length;
+		this.goto(this.index < count - 1 ? this.index + 1 : (count ? 0 : -1) );
+	},
+
+	previous: function () {
+		var count = this.ul.children.length;
+		var pos = this.index - 1;
+
+		this.goto(this.selected && pos !== -1 ? pos : count - 1);
+	},
+
+	// Should not be used, highlights specific item without any checks!
+	goto: function (i) {
+		var lis = this.ul.children;
+
+		if (this.selected) {
+			lis[this.index].setAttribute("aria-selected", "false");
+		}
+
+		this.index = i;
+
+		if (i > -1 && lis.length > 0) {
+			lis[i].setAttribute("aria-selected", "true");
+
+			this.status.textContent = lis[i].textContent + ", list item " + (i + 1) + " of " + lis.length;
+
+            this.input.setAttribute("aria-activedescendant", this.ul.id + "_item_" + this.index);
+
+			// scroll to highlighted element in case parent's height is fixed
+			this.ul.scrollTop = lis[i].offsetTop - this.ul.clientHeight + lis[i].clientHeight;
+
+			$.fire(this.input, "awesomplete-highlight", {
+				text: this.suggestions[this.index]
+			});
+		}
+	},
+
+	select: function (selected, origin, originalEvent) {
+		if (selected) {
+			this.index = $.siblingIndex(selected);
+		} else {
+			selected = this.ul.children[this.index];
+		}
+
+		if (selected) {
+			var suggestion = this.suggestions[this.index];
+
+			var allowed = $.fire(this.input, "awesomplete-select", {
+				text: suggestion,
+				origin: origin || selected,
+				originalEvent: originalEvent
+			});
+
+			if (allowed) {
+				this.replace(suggestion);
+				this.close({ reason: "select" });
+				$.fire(this.input, "awesomplete-selectcomplete", {
+					text: suggestion,
+					originalEvent: originalEvent
+				});
+			}
+		}
+	},
+
+	evaluate: function() {
+		var me = this;
+		var value = this.input.value;
+
+		if (value.length >= this.minChars && this._list && this._list.length > 0) {
+			this.index = -1;
+			// Populate list with options that match
+			this.ul.innerHTML = "";
+
+			this.suggestions = this._list
+				.map(function(item) {
+					return new Suggestion(me.data(item, value));
+				})
+				.filter(function(item) {
+					return me.filter(item, value);
+				});
+
+			if (this.sort !== false) {
+				this.suggestions = this.suggestions.sort(this.sort);
+			}
+
+			this.suggestions = this.suggestions.slice(0, this.maxItems);
+
+			this.suggestions.forEach(function(text, index) {
+					me.ul.appendChild(me.item(text, value, index));
+				});
+
+			if (this.ul.children.length === 0) {
+
+                this.status.textContent = "No results found";
+
+				this.close({ reason: "nomatches" });
+
+			} else {
+				this.open();
+
+                this.status.textContent = this.ul.children.length + " results found";
+			}
+		}
+		else {
+			this.close({ reason: "nomatches" });
+
+                this.status.textContent = "No results found";
+		}
+	}
+};
+
+// Static methods/properties
+
+_.all = [];
+
+_.FILTER_CONTAINS = function (text, input) {
+	return RegExp($.regExpEscape(input.trim()), "i").test(text);
+};
+
+_.FILTER_STARTSWITH = function (text, input) {
+	return RegExp("^" + $.regExpEscape(input.trim()), "i").test(text);
+};
+
+_.SORT_BYLENGTH = function (a, b) {
+	if (a.length !== b.length) {
+		return a.length - b.length;
+	}
+
+	return a < b? -1 : 1;
+};
+
+_.CONTAINER = function (input) {
+	return $.create("div", {
+		className: "awesomplete",
+		around: input
+	});
+}
+
+_.ITEM = function (text, input, item_id) {
+	var html = input.trim() === "" ? text : text.replace(RegExp($.regExpEscape(input.trim()), "gi"), "<mark>$&</mark>");
+	return $.create("li", {
+		innerHTML: html,
+		"role": "option",
+		"aria-selected": "false",
+		"id": "awesomplete_list_" + this.count + "_item_" + item_id
+	});
+};
+
+_.REPLACE = function (text) {
+	this.input.value = text.value;
+};
+
+_.DATA = function (item/*, input*/) { return item; };
+
+// Private functions
+
+function Suggestion(data) {
+	var o = Array.isArray(data)
+	  ? { label: data[0], value: data[1] }
+	  : typeof data === "object" && "label" in data && "value" in data ? data : { label: data, value: data };
+
+	this.label = o.label || o.value;
+	this.value = o.value;
+}
+Object.defineProperty(Suggestion.prototype = Object.create(String.prototype), "length", {
+	get: function() { return this.label.length; }
+});
+Suggestion.prototype.toString = Suggestion.prototype.valueOf = function () {
+	return "" + this.label;
+};
+
+function configure(instance, properties, o) {
+	for (var i in properties) {
+		var initial = properties[i],
+		    attrValue = instance.input.getAttribute("data-" + i.toLowerCase());
+
+		if (typeof initial === "number") {
+			instance[i] = parseInt(attrValue);
+		}
+		else if (initial === false) { // Boolean options must be false by default anyway
+			instance[i] = attrValue !== null;
+		}
+		else if (initial instanceof Function) {
+			instance[i] = null;
+		}
+		else {
+			instance[i] = attrValue;
+		}
+
+		if (!instance[i] && instance[i] !== 0) {
+			instance[i] = (i in o)? o[i] : initial;
+		}
+	}
+}
+
+// Helpers
+
+var slice = Array.prototype.slice;
+
+function $(expr, con) {
+	return typeof expr === "string"? (con || document).querySelector(expr) : expr || null;
+}
+
+function $$(expr, con) {
+	return slice.call((con || document).querySelectorAll(expr));
+}
+
+$.create = function(tag, o) {
+	var element = document.createElement(tag);
+
+	for (var i in o) {
+		var val = o[i];
+
+		if (i === "inside") {
+			$(val).appendChild(element);
+		}
+		else if (i === "around") {
+			var ref = $(val);
+			ref.parentNode.insertBefore(element, ref);
+			element.appendChild(ref);
+
+			if (ref.getAttribute("autofocus") != null) {
+				ref.focus();
+			}
+		}
+		else if (i in element) {
+			element[i] = val;
+		}
+		else {
+			element.setAttribute(i, val);
+		}
+	}
+
+	return element;
+};
+
+$.bind = function(element, o) {
+	if (element) {
+		for (var event in o) {
+			var callback = o[event];
+
+			event.split(/\s+/).forEach(function (event) {
+				element.addEventListener(event, callback);
+			});
+		}
+	}
+};
+
+$.unbind = function(element, o) {
+	if (element) {
+		for (var event in o) {
+			var callback = o[event];
+
+			event.split(/\s+/).forEach(function(event) {
+				element.removeEventListener(event, callback);
+			});
+		}
+	}
+};
+
+$.fire = function(target, type, properties) {
+	var evt = document.createEvent("HTMLEvents");
+
+	evt.initEvent(type, true, true );
+
+	for (var j in properties) {
+		evt[j] = properties[j];
+	}
+
+	return target.dispatchEvent(evt);
+};
+
+$.regExpEscape = function (s) {
+	return s.replace(/[-\\^$*+?.()|[\]{}]/g, "\\$&");
+};
+
+$.siblingIndex = function (el) {
+	/* eslint-disable no-cond-assign */
+	for (var i = 0; el = el.previousElementSibling; i++);
+	return i;
+};
+
+// Initialization
+
+function init() {
+	$$("input.awesomplete").forEach(function (input) {
+		new _(input);
+	});
+}
+
+// Make sure to export Awesomplete on self when in a browser
+if (typeof self !== "undefined") {
+	self.Awesomplete = _;
+}
+
+// Are we in a browser? Check for Document constructor
+if (typeof Document !== "undefined") {
+	// DOM already loaded?
+	if (document.readyState !== "loading") {
+		init();
+	}
+	else {
+		// Wait for it
+		document.addEventListener("DOMContentLoaded", init);
+	}
+}
+
+_.$ = $;
+_.$$ = $$;
+
+// Expose Awesomplete as a CJS module
+if (typeof module === "object" && module.exports) {
+	module.exports = _;
+}
+
+return _;
+
+}());
diff --git a/core/assets/vendor/awesomplete/awesomplete.min.js b/core/assets/vendor/awesomplete/awesomplete.min.js
new file mode 100755
index 0000000000..a895194633
--- /dev/null
+++ b/core/assets/vendor/awesomplete/awesomplete.min.js
@@ -0,0 +1,3 @@
+// Awesomplete - Lea Verou - MIT license
+!function(){function t(t){var e=Array.isArray(t)?{label:t[0],value:t[1]}:"object"==typeof t&&"label"in t&&"value"in t?t:{label:t,value:t};this.label=e.label||e.value,this.value=e.value}function e(t,e,i){for(var n in e){var s=e[n],r=t.input.getAttribute("data-"+n.toLowerCase());"number"==typeof s?t[n]=parseInt(r):!1===s?t[n]=null!==r:s instanceof Function?t[n]=null:t[n]=r,t[n]||0===t[n]||(t[n]=n in i?i[n]:s)}}function i(t,e){return"string"==typeof t?(e||document).querySelector(t):t||null}function n(t,e){return o.call((e||document).querySelectorAll(t))}function s(){n("input.awesomplete").forEach(function(t){new r(t)})}var r=function(t,n){var s=this;r.count=(r.count||0)+1,this.count=r.count,this.isOpened=!1,this.input=i(t),this.input.setAttribute("autocomplete","off"),this.input.setAttribute("aria-expanded","false"),this.input.setAttribute("aria-owns","awesomplete_list_"+this.count),this.input.setAttribute("role","combobox"),this.options=n=n||{},e(this,{minChars:2,maxItems:10,autoFirst:!1,data:r.DATA,filter:r.FILTER_CONTAINS,sort:!1!==n.sort&&r.SORT_BYLENGTH,container:r.CONTAINER,item:r.ITEM,replace:r.REPLACE,tabSelect:!1},n),this.index=-1,this.container=this.container(t),this.ul=i.create("ul",{hidden:"hidden",role:"listbox",id:"awesomplete_list_"+this.count,inside:this.container}),this.status=i.create("span",{className:"visually-hidden",role:"status","aria-live":"assertive","aria-atomic":!0,inside:this.container,textContent:0!=this.minChars?"Type "+this.minChars+" or more characters for results.":"Begin typing for results."}),this._events={input:{input:this.evaluate.bind(this),blur:this.close.bind(this,{reason:"blur"}),keydown:function(t){var e=t.keyCode;s.opened&&(13===e&&s.selected?(t.preventDefault(),s.select()):9===e&&s.selected&&s.tabSelect?s.select():27===e?s.close({reason:"esc"}):38!==e&&40!==e||(t.preventDefault(),s[38===e?"previous":"next"]()))}},form:{submit:this.close.bind(this,{reason:"submit"})},ul:{mousedown:function(t){t.preventDefault()},click:function(t){var e=t.target;if(e!==this){for(;e&&!/li/i.test(e.nodeName);)e=e.parentNode;e&&0===t.button&&(t.preventDefault(),s.select(e,t.target))}}}},i.bind(this.input,this._events.input),i.bind(this.input.form,this._events.form),i.bind(this.ul,this._events.ul),this.input.hasAttribute("list")?(this.list="#"+this.input.getAttribute("list"),this.input.removeAttribute("list")):this.list=this.input.getAttribute("data-list")||n.list||[],r.all.push(this)};r.prototype={set list(t){if(Array.isArray(t))this._list=t;else if("string"==typeof t&&t.indexOf(",")>-1)this._list=t.split(/\s*,\s*/);else if((t=i(t))&&t.children){var e=[];o.apply(t.children).forEach(function(t){if(!t.disabled){var i=t.textContent.trim(),n=t.value||i,s=t.label||i;""!==n&&e.push({label:s,value:n})}}),this._list=e}document.activeElement===this.input&&this.evaluate()},get selected(){return this.index>-1},get opened(){return this.isOpened},close:function(t){this.opened&&(this.input.setAttribute("aria-expanded","false"),this.ul.setAttribute("hidden",""),this.isOpened=!1,this.index=-1,this.status.setAttribute("hidden",""),i.fire(this.input,"awesomplete-close",t||{}))},open:function(){this.input.setAttribute("aria-expanded","true"),this.ul.removeAttribute("hidden"),this.isOpened=!0,this.status.removeAttribute("hidden"),this.autoFirst&&-1===this.index&&this.goto(0),i.fire(this.input,"awesomplete-open")},destroy:function(){if(i.unbind(this.input,this._events.input),i.unbind(this.input.form,this._events.form),!this.options.container){var t=this.container.parentNode;t.insertBefore(this.input,this.container),t.removeChild(this.container)}this.input.removeAttribute("autocomplete"),this.input.removeAttribute("aria-autocomplete");var e=r.all.indexOf(this);-1!==e&&r.all.splice(e,1)},next:function(){var t=this.ul.children.length;this.goto(this.index<t-1?this.index+1:t?0:-1)},previous:function(){var t=this.ul.children.length,e=this.index-1;this.goto(this.selected&&-1!==e?e:t-1)},goto:function(t){var e=this.ul.children;this.selected&&e[this.index].setAttribute("aria-selected","false"),this.index=t,t>-1&&e.length>0&&(e[t].setAttribute("aria-selected","true"),this.status.textContent=e[t].textContent+", list item "+(t+1)+" of "+e.length,this.input.setAttribute("aria-activedescendant",this.ul.id+"_item_"+this.index),this.ul.scrollTop=e[t].offsetTop-this.ul.clientHeight+e[t].clientHeight,i.fire(this.input,"awesomplete-highlight",{text:this.suggestions[this.index]}))},select:function(t,e){if(t?this.index=i.siblingIndex(t):t=this.ul.children[this.index],t){var n=this.suggestions[this.index];i.fire(this.input,"awesomplete-select",{text:n,origin:e||t})&&(this.replace(n),this.close({reason:"select"}),i.fire(this.input,"awesomplete-selectcomplete",{text:n}))}},evaluate:function(){var e=this,i=this.input.value;i.length>=this.minChars&&this._list&&this._list.length>0?(this.index=-1,this.ul.innerHTML="",this.suggestions=this._list.map(function(n){return new t(e.data(n,i))}).filter(function(t){return e.filter(t,i)}),!1!==this.sort&&(this.suggestions=this.suggestions.sort(this.sort)),this.suggestions=this.suggestions.slice(0,this.maxItems),this.suggestions.forEach(function(t,n){e.ul.appendChild(e.item(t,i,n))}),0===this.ul.children.length?(this.status.textContent="No results found",this.close({reason:"nomatches"})):(this.open(),this.status.textContent=this.ul.children.length+" results found")):(this.close({reason:"nomatches"}),this.status.textContent="No results found")}},r.all=[],r.FILTER_CONTAINS=function(t,e){return RegExp(i.regExpEscape(e.trim()),"i").test(t)},r.FILTER_STARTSWITH=function(t,e){return RegExp("^"+i.regExpEscape(e.trim()),"i").test(t)},r.SORT_BYLENGTH=function(t,e){return t.length!==e.length?t.length-e.length:t<e?-1:1},r.CONTAINER=function(t){return i.create("div",{className:"awesomplete",around:t})},r.ITEM=function(t,e,n){return i.create("li",{innerHTML:""===e.trim()?t:t.replace(RegExp(i.regExpEscape(e.trim()),"gi"),"<mark>$&</mark>"),role:"option","aria-selected":"false",id:"awesomplete_list_"+this.count+"_item_"+n})},r.REPLACE=function(t){this.input.value=t.value},r.DATA=function(t){return t},Object.defineProperty(t.prototype=Object.create(String.prototype),"length",{get:function(){return this.label.length}}),t.prototype.toString=t.prototype.valueOf=function(){return""+this.label};var o=Array.prototype.slice;i.create=function(t,e){var n=document.createElement(t);for(var s in e){var r=e[s];if("inside"===s)i(r).appendChild(n);else if("around"===s){var o=i(r);o.parentNode.insertBefore(n,o),n.appendChild(o),null!=o.getAttribute("autofocus")&&o.focus()}else s in n?n[s]=r:n.setAttribute(s,r)}return n},i.bind=function(t,e){if(t)for(var i in e){var n=e[i];i.split(/\s+/).forEach(function(e){t.addEventListener(e,n)})}},i.unbind=function(t,e){if(t)for(var i in e){var n=e[i];i.split(/\s+/).forEach(function(e){t.removeEventListener(e,n)})}},i.fire=function(t,e,i){var n=document.createEvent("HTMLEvents");n.initEvent(e,!0,!0);for(var s in i)n[s]=i[s];return t.dispatchEvent(n)},i.regExpEscape=function(t){return t.replace(/[-\\^$*+?.()|[\]{}]/g,"\\$&")},i.siblingIndex=function(t){for(var e=0;t=t.previousElementSibling;e++);return e},"undefined"!=typeof self&&(self.Awesomplete=r),"undefined"!=typeof Document&&("loading"!==document.readyState?s():document.addEventListener("DOMContentLoaded",s)),r.$=i,r.$$=n,"object"==typeof module&&module.exports&&(module.exports=r)}();
+//# sourceMappingURL=awesomplete.min.js.map
diff --git a/core/assets/vendor/awesomplete/awesomplete.min.js.map b/core/assets/vendor/awesomplete/awesomplete.min.js.map
new file mode 100755
index 0000000000..6ad1411ee2
--- /dev/null
+++ b/core/assets/vendor/awesomplete/awesomplete.min.js.map
@@ -0,0 +1 @@
+{"version":3,"sources":["awesomplete.js"],"names":["Suggestion","data","o","Array","isArray","label","value","this","configure","instance","properties","i","initial","attrValue","input","getAttribute","toLowerCase","parseInt","Function","$","expr","con","document","querySelector","$$","slice","call","querySelectorAll","init","forEach","_","me","count","isOpened","setAttribute","options","minChars","maxItems","autoFirst","DATA","filter","FILTER_CONTAINS","sort","SORT_BYLENGTH","container","CONTAINER","item","ITEM","replace","REPLACE","tabSelect","index","ul","create","hidden","role","id","inside","status","className","aria-live","aria-atomic","textContent","_events","evaluate","bind","blur","close","reason","keydown","evt","c","keyCode","opened","selected","preventDefault","select","form","submit","mousedown","click","li","target","test","nodeName","parentNode","button","hasAttribute","list","removeAttribute","all","push","prototype","_list","indexOf","split","children","items","apply","el","disabled","text","trim","activeElement","fire","open","goto","destroy","unbind","insertBefore","removeChild","indexOfAwesomplete","splice","next","length","previous","pos","lis","scrollTop","offsetTop","clientHeight","suggestions","origin","siblingIndex","suggestion","innerHTML","map","appendChild","RegExp","regExpEscape","FILTER_STARTSWITH","a","b","around","item_id","aria-selected","Object","defineProperty","String","get","toString","valueOf","tag","element","createElement","val","ref","focus","event","callback","addEventListener","removeEventListener","type","createEvent","initEvent","j","dispatchEvent","s","previousElementSibling","self","Awesomplete","Document","readyState","module","exports"],"mappings":"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","file":"awesomplete.min.js","sourcesContent":["/**\n * Simple, lightweight, usable local autocomplete library for modern browsers\n * Because there weren’t enough autocomplete scripts in the world? Because I’m completely insane and have NIH syndrome? Probably both. :P\n * @author Lea Verou http://leaverou.github.io/awesomplete\n * MIT license\n */\n\n(function () {\n\nvar _ = function (input, o) {\n\tvar me = this;\n\n    // Keep track of number of instances for unique IDs\n    _.count = (_.count || 0) + 1;\n    this.count = _.count;\n\n\t// Setup\n\n\tthis.isOpened = false;\n\n\tthis.input = $(input);\n\tthis.input.setAttribute(\"autocomplete\", \"off\");\n\tthis.input.setAttribute(\"aria-expanded\", \"false\");\n\tthis.input.setAttribute(\"aria-owns\", \"awesomplete_list_\" + this.count);\n\tthis.input.setAttribute(\"role\", \"combobox\");\n\n\t// store constructor options in case we need to distinguish\n\t// between default and customized behavior later on\n\tthis.options = o = o || {};\n\n\tconfigure(this, {\n\t\tminChars: 2,\n\t\tmaxItems: 10,\n\t\tautoFirst: false,\n\t\tdata: _.DATA,\n\t\tfilter: _.FILTER_CONTAINS,\n\t\tsort: o.sort === false ? false : _.SORT_BYLENGTH,\n\t\tcontainer: _.CONTAINER,\n\t\titem: _.ITEM,\n\t\treplace: _.REPLACE,\n\t\ttabSelect: false\n\t}, o);\n\n\tthis.index = -1;\n\n\t// Create necessary elements\n\n\tthis.container = this.container(input);\n\n\tthis.ul = $.create(\"ul\", {\n\t\thidden: \"hidden\",\n        role: \"listbox\",\n        id: \"awesomplete_list_\" + this.count,\n\t\tinside: this.container\n\t});\n\n\tthis.status = $.create(\"span\", {\n\t\tclassName: \"visually-hidden\",\n\t\trole: \"status\",\n\t\t\"aria-live\": \"assertive\",\n        \"aria-atomic\": true,\n        inside: this.container,\n        textContent: this.minChars != 0 ? (\"Type \" + this.minChars + \" or more characters for results.\") : \"Begin typing for results.\"\n\t});\n\n\t// Bind events\n\n\tthis._events = {\n\t\tinput: {\n\t\t\t\"input\": this.evaluate.bind(this),\n\t\t\t\"blur\": this.close.bind(this, { reason: \"blur\" }),\n\t\t\t\"keydown\": function(evt) {\n\t\t\t\tvar c = evt.keyCode;\n\n\t\t\t\t// If the dropdown `ul` is in view, then act on keydown for the following keys:\n\t\t\t\t// Enter / Esc / Up / Down\n\t\t\t\tif(me.opened) {\n\t\t\t\t\tif (c === 13 && me.selected) { // Enter\n\t\t\t\t\t\tevt.preventDefault();\n\t\t\t\t\t\tme.select();\n\t\t\t\t\t}\n\t\t\t\t\telse if (c === 9 && me.selected && me.tabSelect) {\n\t\t\t\t\t\tme.select();\n\t\t\t\t\t}\n\t\t\t\t\telse if (c === 27) { // Esc\n\t\t\t\t\t\tme.close({ reason: \"esc\" });\n\t\t\t\t\t}\n\t\t\t\t\telse if (c === 38 || c === 40) { // Down/Up arrow\n\t\t\t\t\t\tevt.preventDefault();\n\t\t\t\t\t\tme[c === 38? \"previous\" : \"next\"]();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\tform: {\n\t\t\t\"submit\": this.close.bind(this, { reason: \"submit\" })\n\t\t},\n\t\tul: {\n\t\t\t// Prevent the default mousedowm, which ensures the input is not blurred.\n\t\t\t// The actual selection will happen on click. This also ensures dragging the\n\t\t\t// cursor away from the list item will cancel the selection\n\t\t\t\"mousedown\": function(evt) {\n\t\t\t\tevt.preventDefault();\n\t\t\t},\n\t\t\t// The click event is fired even if the corresponding mousedown event has called preventDefault\n\t\t\t\"click\": function(evt) {\n\t\t\t\tvar li = evt.target;\n\n\t\t\t\tif (li !== this) {\n\n\t\t\t\t\twhile (li && !/li/i.test(li.nodeName)) {\n\t\t\t\t\t\tli = li.parentNode;\n\t\t\t\t\t}\n\n\t\t\t\t\tif (li && evt.button === 0) {  // Only select on left click\n\t\t\t\t\t\tevt.preventDefault();\n\t\t\t\t\t\tme.select(li, evt.target);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t};\n\n\t$.bind(this.input, this._events.input);\n\t$.bind(this.input.form, this._events.form);\n\t$.bind(this.ul, this._events.ul);\n\n\tif (this.input.hasAttribute(\"list\")) {\n\t\tthis.list = \"#\" + this.input.getAttribute(\"list\");\n\t\tthis.input.removeAttribute(\"list\");\n\t}\n\telse {\n\t\tthis.list = this.input.getAttribute(\"data-list\") || o.list || [];\n\t}\n\n\t_.all.push(this);\n};\n\n_.prototype = {\n\tset list(list) {\n\t\tif (Array.isArray(list)) {\n\t\t\tthis._list = list;\n\t\t}\n\t\telse if (typeof list === \"string\" && list.indexOf(\",\") > -1) {\n\t\t\t\tthis._list = list.split(/\\s*,\\s*/);\n\t\t}\n\t\telse { // Element or CSS selector\n\t\t\tlist = $(list);\n\n\t\t\tif (list && list.children) {\n\t\t\t\tvar items = [];\n\t\t\t\tslice.apply(list.children).forEach(function (el) {\n\t\t\t\t\tif (!el.disabled) {\n\t\t\t\t\t\tvar text = el.textContent.trim();\n\t\t\t\t\t\tvar value = el.value || text;\n\t\t\t\t\t\tvar label = el.label || text;\n\t\t\t\t\t\tif (value !== \"\") {\n\t\t\t\t\t\t\titems.push({ label: label, value: value });\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t\tthis._list = items;\n\t\t\t}\n\t\t}\n\n\t\tif (document.activeElement === this.input) {\n\t\t\tthis.evaluate();\n\t\t}\n\t},\n\n\tget selected() {\n\t\treturn this.index > -1;\n\t},\n\n\tget opened() {\n\t\treturn this.isOpened;\n\t},\n\n\tclose: function (o) {\n\t\tif (!this.opened) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis.input.setAttribute(\"aria-expanded\", \"false\");\n\t\tthis.ul.setAttribute(\"hidden\", \"\");\n\t\tthis.isOpened = false;\n\t\tthis.index = -1;\n\n\t\tthis.status.setAttribute(\"hidden\", \"\");\n\n\t\t$.fire(this.input, \"awesomplete-close\", o || {});\n\t},\n\n\topen: function () {\n\t\tthis.input.setAttribute(\"aria-expanded\", \"true\");\n\t\tthis.ul.removeAttribute(\"hidden\");\n\t\tthis.isOpened = true;\n\n\t\tthis.status.removeAttribute(\"hidden\");\n\n\t\tif (this.autoFirst && this.index === -1) {\n\t\t\tthis.goto(0);\n\t\t}\n\n\t\t$.fire(this.input, \"awesomplete-open\");\n\t},\n\n\tdestroy: function() {\n\t\t//remove events from the input and its form\n\t\t$.unbind(this.input, this._events.input);\n\t\t$.unbind(this.input.form, this._events.form);\n\n\t\t// cleanup container if it was created by Awesomplete but leave it alone otherwise\n\t\tif (!this.options.container) {\n\t\t\t//move the input out of the awesomplete container and remove the container and its children\n\t\t\tvar parentNode = this.container.parentNode;\n\n\t\t\tparentNode.insertBefore(this.input, this.container);\n\t\t\tparentNode.removeChild(this.container);\n\t\t}\n\n\t\t//remove autocomplete and aria-autocomplete attributes\n\t\tthis.input.removeAttribute(\"autocomplete\");\n\t\tthis.input.removeAttribute(\"aria-autocomplete\");\n\n\t\t//remove this awesomeplete instance from the global array of instances\n\t\tvar indexOfAwesomplete = _.all.indexOf(this);\n\n\t\tif (indexOfAwesomplete !== -1) {\n\t\t\t_.all.splice(indexOfAwesomplete, 1);\n\t\t}\n\t},\n\n\tnext: function () {\n\t\tvar count = this.ul.children.length;\n\t\tthis.goto(this.index < count - 1 ? this.index + 1 : (count ? 0 : -1) );\n\t},\n\n\tprevious: function () {\n\t\tvar count = this.ul.children.length;\n\t\tvar pos = this.index - 1;\n\n\t\tthis.goto(this.selected && pos !== -1 ? pos : count - 1);\n\t},\n\n\t// Should not be used, highlights specific item without any checks!\n\tgoto: function (i) {\n\t\tvar lis = this.ul.children;\n\n\t\tif (this.selected) {\n\t\t\tlis[this.index].setAttribute(\"aria-selected\", \"false\");\n\t\t}\n\n\t\tthis.index = i;\n\n\t\tif (i > -1 && lis.length > 0) {\n\t\t\tlis[i].setAttribute(\"aria-selected\", \"true\");\n\n\t\t\tthis.status.textContent = lis[i].textContent + \", list item \" + (i + 1) + \" of \" + lis.length;\n\n            this.input.setAttribute(\"aria-activedescendant\", this.ul.id + \"_item_\" + this.index);\n\n\t\t\t// scroll to highlighted element in case parent's height is fixed\n\t\t\tthis.ul.scrollTop = lis[i].offsetTop - this.ul.clientHeight + lis[i].clientHeight;\n\n\t\t\t$.fire(this.input, \"awesomplete-highlight\", {\n\t\t\t\ttext: this.suggestions[this.index]\n\t\t\t});\n\t\t}\n\t},\n\n\tselect: function (selected, origin) {\n\t\tif (selected) {\n\t\t\tthis.index = $.siblingIndex(selected);\n\t\t} else {\n\t\t\tselected = this.ul.children[this.index];\n\t\t}\n\n\t\tif (selected) {\n\t\t\tvar suggestion = this.suggestions[this.index];\n\n\t\t\tvar allowed = $.fire(this.input, \"awesomplete-select\", {\n\t\t\t\ttext: suggestion,\n\t\t\t\torigin: origin || selected\n\t\t\t});\n\n\t\t\tif (allowed) {\n\t\t\t\tthis.replace(suggestion);\n\t\t\t\tthis.close({ reason: \"select\" });\n\t\t\t\t$.fire(this.input, \"awesomplete-selectcomplete\", {\n\t\t\t\t\ttext: suggestion\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t},\n\n\tevaluate: function() {\n\t\tvar me = this;\n\t\tvar value = this.input.value;\n\n\t\tif (value.length >= this.minChars && this._list && this._list.length > 0) {\n\t\t\tthis.index = -1;\n\t\t\t// Populate list with options that match\n\t\t\tthis.ul.innerHTML = \"\";\n\n\t\t\tthis.suggestions = this._list\n\t\t\t\t.map(function(item) {\n\t\t\t\t\treturn new Suggestion(me.data(item, value));\n\t\t\t\t})\n\t\t\t\t.filter(function(item) {\n\t\t\t\t\treturn me.filter(item, value);\n\t\t\t\t});\n\n\t\t\tif (this.sort !== false) {\n\t\t\t\tthis.suggestions = this.suggestions.sort(this.sort);\n\t\t\t}\n\n\t\t\tthis.suggestions = this.suggestions.slice(0, this.maxItems);\n\n\t\t\tthis.suggestions.forEach(function(text, index) {\n\t\t\t\t\tme.ul.appendChild(me.item(text, value, index));\n\t\t\t\t});\n\n\t\t\tif (this.ul.children.length === 0) {\n\n                this.status.textContent = \"No results found\";\n\n\t\t\t\tthis.close({ reason: \"nomatches\" });\n\n\t\t\t} else {\n\t\t\t\tthis.open();\n\n                this.status.textContent = this.ul.children.length + \" results found\";\n\t\t\t}\n\t\t}\n\t\telse {\n\t\t\tthis.close({ reason: \"nomatches\" });\n\n                this.status.textContent = \"No results found\";\n\t\t}\n\t}\n};\n\n// Static methods/properties\n\n_.all = [];\n\n_.FILTER_CONTAINS = function (text, input) {\n\treturn RegExp($.regExpEscape(input.trim()), \"i\").test(text);\n};\n\n_.FILTER_STARTSWITH = function (text, input) {\n\treturn RegExp(\"^\" + $.regExpEscape(input.trim()), \"i\").test(text);\n};\n\n_.SORT_BYLENGTH = function (a, b) {\n\tif (a.length !== b.length) {\n\t\treturn a.length - b.length;\n\t}\n\n\treturn a < b? -1 : 1;\n};\n\n_.CONTAINER = function (input) {\n\treturn $.create(\"div\", {\n\t\tclassName: \"awesomplete\",\n\t\taround: input\n\t});\n}\n\n_.ITEM = function (text, input, item_id) {\n\tvar html = input.trim() === \"\" ? text : text.replace(RegExp($.regExpEscape(input.trim()), \"gi\"), \"<mark>$&</mark>\");\n\treturn $.create(\"li\", {\n\t\tinnerHTML: html,\n\t\t\"role\": \"option\",\n\t\t\"aria-selected\": \"false\",\n\t\t\"id\": \"awesomplete_list_\" + this.count + \"_item_\" + item_id\n\t});\n};\n\n_.REPLACE = function (text) {\n\tthis.input.value = text.value;\n};\n\n_.DATA = function (item/*, input*/) { return item; };\n\n// Private functions\n\nfunction Suggestion(data) {\n\tvar o = Array.isArray(data)\n\t  ? { label: data[0], value: data[1] }\n\t  : typeof data === \"object\" && \"label\" in data && \"value\" in data ? data : { label: data, value: data };\n\n\tthis.label = o.label || o.value;\n\tthis.value = o.value;\n}\nObject.defineProperty(Suggestion.prototype = Object.create(String.prototype), \"length\", {\n\tget: function() { return this.label.length; }\n});\nSuggestion.prototype.toString = Suggestion.prototype.valueOf = function () {\n\treturn \"\" + this.label;\n};\n\nfunction configure(instance, properties, o) {\n\tfor (var i in properties) {\n\t\tvar initial = properties[i],\n\t\t    attrValue = instance.input.getAttribute(\"data-\" + i.toLowerCase());\n\n\t\tif (typeof initial === \"number\") {\n\t\t\tinstance[i] = parseInt(attrValue);\n\t\t}\n\t\telse if (initial === false) { // Boolean options must be false by default anyway\n\t\t\tinstance[i] = attrValue !== null;\n\t\t}\n\t\telse if (initial instanceof Function) {\n\t\t\tinstance[i] = null;\n\t\t}\n\t\telse {\n\t\t\tinstance[i] = attrValue;\n\t\t}\n\n\t\tif (!instance[i] && instance[i] !== 0) {\n\t\t\tinstance[i] = (i in o)? o[i] : initial;\n\t\t}\n\t}\n}\n\n// Helpers\n\nvar slice = Array.prototype.slice;\n\nfunction $(expr, con) {\n\treturn typeof expr === \"string\"? (con || document).querySelector(expr) : expr || null;\n}\n\nfunction $$(expr, con) {\n\treturn slice.call((con || document).querySelectorAll(expr));\n}\n\n$.create = function(tag, o) {\n\tvar element = document.createElement(tag);\n\n\tfor (var i in o) {\n\t\tvar val = o[i];\n\n\t\tif (i === \"inside\") {\n\t\t\t$(val).appendChild(element);\n\t\t}\n\t\telse if (i === \"around\") {\n\t\t\tvar ref = $(val);\n\t\t\tref.parentNode.insertBefore(element, ref);\n\t\t\telement.appendChild(ref);\n\n\t\t\tif (ref.getAttribute(\"autofocus\") != null) {\n\t\t\t\tref.focus();\n\t\t\t}\n\t\t}\n\t\telse if (i in element) {\n\t\t\telement[i] = val;\n\t\t}\n\t\telse {\n\t\t\telement.setAttribute(i, val);\n\t\t}\n\t}\n\n\treturn element;\n};\n\n$.bind = function(element, o) {\n\tif (element) {\n\t\tfor (var event in o) {\n\t\t\tvar callback = o[event];\n\n\t\t\tevent.split(/\\s+/).forEach(function (event) {\n\t\t\t\telement.addEventListener(event, callback);\n\t\t\t});\n\t\t}\n\t}\n};\n\n$.unbind = function(element, o) {\n\tif (element) {\n\t\tfor (var event in o) {\n\t\t\tvar callback = o[event];\n\n\t\t\tevent.split(/\\s+/).forEach(function(event) {\n\t\t\t\telement.removeEventListener(event, callback);\n\t\t\t});\n\t\t}\n\t}\n};\n\n$.fire = function(target, type, properties) {\n\tvar evt = document.createEvent(\"HTMLEvents\");\n\n\tevt.initEvent(type, true, true );\n\n\tfor (var j in properties) {\n\t\tevt[j] = properties[j];\n\t}\n\n\treturn target.dispatchEvent(evt);\n};\n\n$.regExpEscape = function (s) {\n\treturn s.replace(/[-\\\\^$*+?.()|[\\]{}]/g, \"\\\\$&\");\n};\n\n$.siblingIndex = function (el) {\n\t/* eslint-disable no-cond-assign */\n\tfor (var i = 0; el = el.previousElementSibling; i++);\n\treturn i;\n};\n\n// Initialization\n\nfunction init() {\n\t$$(\"input.awesomplete\").forEach(function (input) {\n\t\tnew _(input);\n\t});\n}\n\n// Make sure to export Awesomplete on self when in a browser\nif (typeof self !== \"undefined\") {\n\tself.Awesomplete = _;\n}\n\n// Are we in a browser? Check for Document constructor\nif (typeof Document !== \"undefined\") {\n\t// DOM already loaded?\n\tif (document.readyState !== \"loading\") {\n\t\tinit();\n\t}\n\telse {\n\t\t// Wait for it\n\t\tdocument.addEventListener(\"DOMContentLoaded\", init);\n\t}\n}\n\n_.$ = $;\n_.$$ = $$;\n\n// Expose Awesomplete as a CJS module\nif (typeof module === \"object\" && module.exports) {\n\tmodule.exports = _;\n}\n\nreturn _;\n\n}());\n"]}
\ No newline at end of file
diff --git a/core/assets/vendor/awesomplete/awesomplete.theme.css b/core/assets/vendor/awesomplete/awesomplete.theme.css
new file mode 100755
index 0000000000..8a964f1173
--- /dev/null
+++ b/core/assets/vendor/awesomplete/awesomplete.theme.css
@@ -0,0 +1,69 @@
+.awesomplete > ul {
+	border-radius: .3em;
+	margin: .2em 0 0;
+	background: hsla(0,0%,100%,.9);
+	background: linear-gradient(to bottom right, white, hsla(0,0%,100%,.8));
+	border: 1px solid rgba(0,0,0,.3);
+	box-shadow: .05em .2em .6em rgba(0,0,0,.2);
+	text-shadow: none;
+}
+
+@supports (transform: scale(0)) {
+	.awesomplete > ul {
+		transition: .3s cubic-bezier(.4,.2,.5,1.4);
+		transform-origin: 1.43em -.43em;
+	}
+	
+	.awesomplete > ul[hidden],
+	.awesomplete > ul:empty {
+		opacity: 0;
+		transform: scale(0);
+		display: block;
+		transition-timing-function: ease;
+	}
+}
+
+	/* Pointer */
+	.awesomplete > ul:before {
+		content: "";
+		position: absolute;
+		top: -.43em;
+		left: 1em;
+		width: 0; height: 0;
+		padding: .4em;
+		background: white;
+		border: inherit;
+		border-right: 0;
+		border-bottom: 0;
+		-webkit-transform: rotate(45deg);
+		transform: rotate(45deg);
+	}
+
+	.awesomplete > ul > li {
+		position: relative;
+		padding: .2em .5em;
+		cursor: pointer;
+	}
+	
+	.awesomplete > ul > li:hover {
+		background: hsl(200, 40%, 80%);
+		color: black;
+	}
+	
+	.awesomplete > ul > li[aria-selected="true"] {
+		background: hsl(205, 40%, 40%);
+		color: white;
+	}
+	
+		.awesomplete mark {
+			background: hsl(65, 100%, 50%);
+		}
+		
+		.awesomplete li:hover mark {
+			background: hsl(68, 100%, 41%);
+		}
+		
+		.awesomplete li[aria-selected="true"] mark {
+			background: hsl(86, 100%, 21%);
+			color: inherit;
+		}
\ No newline at end of file
diff --git a/core/core.libraries.yml b/core/core.libraries.yml
index be7b678a9d..104475d134 100644
--- a/core/core.libraries.yml
+++ b/core/core.libraries.yml
@@ -104,16 +104,24 @@ drupal.announce:
     - core/drupal
     - core/drupal.debounce
 
+awesomplete:
+  version: VERSION
+  js:
+    assets/vendor/awesomplete/awesomplete.js: {}
+  css:
+    component:
+      assets/vendor/awesomplete/awesomplete.css: {}
+
 drupal.autocomplete:
   version: VERSION
   js:
-    misc/autocomplete.js: { weight: -1 }
+    misc/autocomplete.js: {}
   dependencies:
     - core/jquery
     - core/drupal
     - core/drupalSettings
     - core/drupal.ajax
-    - core/jquery.ui.autocomplete
+    - core/awesomplete
 
 drupal.batch:
   version: VERSION
diff --git a/core/lib/Drupal/Core/Entity/Element/EntityAutocomplete.php b/core/lib/Drupal/Core/Entity/Element/EntityAutocomplete.php
index 0691239dfa..b9433b33d3 100644
--- a/core/lib/Drupal/Core/Entity/Element/EntityAutocomplete.php
+++ b/core/lib/Drupal/Core/Entity/Element/EntityAutocomplete.php
@@ -8,6 +8,7 @@
 use Drupal\Core\Entity\EntityReferenceSelection\SelectionInterface;
 use Drupal\Core\Entity\EntityReferenceSelection\SelectionWithAutocreateInterface;
 use Drupal\Core\Form\FormStateInterface;
+use Drupal\Core\Render\Element;
 use Drupal\Core\Render\Element\Textfield;
 use Drupal\Core\Site\Settings;
 
@@ -141,6 +142,22 @@ public static function processEntityAutocomplete(array &$element, FormStateInter
       'selection_handler' => $element['#selection_handler'],
       'selection_settings_key' => $selection_settings_key,
     ];
+    $name = explode('[', $element["#name"])[0];
+    if ($complete_form[$name]["widget"]["#theme"] && $complete_form[$name]["widget"]["#theme"] === 'field_multiple_value_form') {
+      $cardinality = 1;
+    }
+    elseif (isset($complete_form[$name]["widget"]["#cardinality"])) {
+      $cardinality = $complete_form[$name]["widget"]["#cardinality"];
+    }
+    else {
+      $cardinality = 0;
+    }
+    foreach (Element::children($complete_form[$name]["widget"]) as $key) {
+      if (is_numeric($key)) {
+        //$complete_form[$name]["widget"][$key]['#attributes']['data-autocomplete-cardinality'] = $cardinality;
+      }
+    }
+    $complete_form[$name]['#attributes']['data-autocomplete-cardinality'] = $cardinality;
 
     return $element;
   }
diff --git a/core/misc/autocomplete.es6.js b/core/misc/autocomplete.es6.js
index 65f6332af6..27b86709b4 100644
--- a/core/misc/autocomplete.es6.js
+++ b/core/misc/autocomplete.es6.js
@@ -1,288 +1,112 @@
 /**
  * @file
- * Autocomplete based on jQuery UI.
+ * Autocomplete based on awesomcomplete.
  */
 
-(function($, Drupal) {
-  let autocomplete;
-
-  /**
-   * Helper splitting terms from the autocomplete value.
-   *
-   * @function Drupal.autocomplete.splitValues
-   *
-   * @param {string} value
-   *   The value being entered by the user.
-   *
-   * @return {Array}
-   *   Array of values, split by comma.
-   */
-  function autocompleteSplitValues(value) {
-    // We will match the value against comma-separated terms.
-    const result = [];
-    let quote = false;
-    let current = '';
-    const valueLength = value.length;
-    let character;
-
-    for (let i = 0; i < valueLength; i++) {
-      character = value.charAt(i);
-      if (character === '"') {
-        current += character;
-        quote = !quote;
-      } else if (character === ',' && !quote) {
-        result.push(current.trim());
-        current = '';
-      } else {
-        current += character;
-      }
-    }
-    if (value.length > 0) {
-      result.push($.trim(current));
-    }
-
-    return result;
-  }
-
-  /**
-   * Returns the last value of an multi-value textfield.
-   *
-   * @function Drupal.autocomplete.extractLastTerm
-   *
-   * @param {string} terms
-   *   The value of the field.
-   *
-   * @return {string}
-   *   The last value of the input field.
-   */
-  function extractLastTerm(terms) {
-    return autocomplete.splitValues(terms).pop();
-  }
-
-  /**
-   * The search handler is called before a search is performed.
-   *
-   * @function Drupal.autocomplete.options.search
-   *
-   * @param {object} event
-   *   The event triggered.
-   *
-   * @return {bool}
-   *   Whether to perform a search or not.
-   */
-  function searchHandler(event) {
-    const options = autocomplete.options;
-
-    if (options.isComposing) {
-      return false;
-    }
-
-    const term = autocomplete.extractLastTerm(event.target.value);
-    // Abort search if the first character is in firstCharacterBlacklist.
-    if (
-      term.length > 0 &&
-      options.firstCharacterBlacklist.indexOf(term[0]) !== -1
-    ) {
-      return false;
-    }
-    // Only search when the term is at least the minimum length.
-    return term.length >= options.minLength;
-  }
-
-  /**
-   * JQuery UI autocomplete source callback.
-   *
-   * @param {object} request
-   *   The request object.
-   * @param {function} response
-   *   The function to call with the response.
-   */
-  function sourceData(request, response) {
-    const elementId = this.element.attr('id');
-
-    if (!(elementId in autocomplete.cache)) {
-      autocomplete.cache[elementId] = {};
-    }
-
-    /**
-     * Filter through the suggestions removing all terms already tagged and
-     * display the available terms to the user.
-     *
-     * @param {object} suggestions
-     *   Suggestions returned by the server.
-     */
-    function showSuggestions(suggestions) {
-      const tagged = autocomplete.splitValues(request.term);
-      const il = tagged.length;
-      for (let i = 0; i < il; i++) {
-        const index = suggestions.indexOf(tagged[i]);
-        if (index >= 0) {
-          suggestions.splice(index, 1);
-        }
-      }
-      response(suggestions);
-    }
-
-    // Get the desired term and construct the autocomplete URL for it.
-    const term = autocomplete.extractLastTerm(request.term);
-
-    /**
-     * Transforms the data object into an array and update autocomplete results.
-     *
-     * @param {object} data
-     *   The data sent back from the server.
-     */
-    function sourceCallbackHandler(data) {
-      autocomplete.cache[elementId][term] = data;
-
-      // Send the new string array of terms to the jQuery UI list.
-      showSuggestions(data);
-    }
-
-    // Check if the term is already cached.
-    if (autocomplete.cache[elementId].hasOwnProperty(term)) {
-      showSuggestions(autocomplete.cache[elementId][term]);
-    } else {
-      const options = $.extend(
-        { success: sourceCallbackHandler, data: { q: term } },
-        autocomplete.ajax,
+((Drupal, $, Awesomplete) => {
+  Drupal.behaviors.awesomplete = {
+    attach(context) {
+      const autoCompleteInputs = context.querySelectorAll(
+        'input.form-autocomplete',
       );
-      $.ajax(this.element.attr('data-autocomplete-path'), options);
-    }
-  }
-
-  /**
-   * Handles an autocompletefocus event.
-   *
-   * @return {bool}
-   *   Always returns false.
-   */
-  function focusHandler() {
-    return false;
-  }
-
-  /**
-   * Handles an autocompleteselect event.
-   *
-   * @param {jQuery.Event} event
-   *   The event triggered.
-   * @param {object} ui
-   *   The jQuery UI settings object.
-   *
-   * @return {bool}
-   *   Returns false to indicate the event status.
-   */
-  function selectHandler(event, ui) {
-    const terms = autocomplete.splitValues(event.target.value);
-    // Remove the current input.
-    terms.pop();
-    // Add the selected item.
-    terms.push(ui.item.value);
-
-    event.target.value = terms.join(', ');
-    // Return false to tell jQuery UI that we've filled in the value already.
-    return false;
-  }
-
-  /**
-   * Override jQuery UI _renderItem function to output HTML by default.
-   *
-   * @param {jQuery} ul
-   *   jQuery collection of the ul element.
-   * @param {object} item
-   *   The list item to append.
-   *
-   * @return {jQuery}
-   *   jQuery collection of the ul element.
-   */
-  function renderItem(ul, item) {
-    return $('<li>')
-      .append($('<a>').html(item.label))
-      .appendTo(ul);
-  }
+      Array.prototype.forEach.call(autoCompleteInputs, element => {
+        let autocompleteInstructionsRead = false;
+        const cardinality = element
+          .closest('[data-autocomplete-cardinality]')
+          .getAttribute('data-autocomplete-cardinality');
+        const isMultiple = cardinality !== '1';
+        const lookupCache = {};
+        const apiUrl = element.getAttribute('data-autocomplete-path');
+        if (isMultiple) {
+          element.setAttribute('data-multiple', '');
+        }
 
-  /**
-   * Attaches the autocomplete behavior to all required fields.
-   *
-   * @type {Drupal~behavior}
-   *
-   * @prop {Drupal~behaviorAttach} attach
-   *   Attaches the autocomplete behaviors.
-   * @prop {Drupal~behaviorDetach} detach
-   *   Detaches the autocomplete behaviors.
-   */
-  Drupal.behaviors.autocomplete = {
-    attach(context) {
-      // Act on textfields with the "form-autocomplete" class.
-      const $autocomplete = $(context)
-        .find('input.form-autocomplete')
-        .once('autocomplete');
-      if ($autocomplete.length) {
-        // Allow options to be overridden per instance.
-        const blacklist = $autocomplete.attr(
-          'data-autocomplete-first-character-blacklist',
-        );
-        $.extend(autocomplete.options, {
-          firstCharacterBlacklist: blacklist || '',
-        });
-        // Use jQuery UI Autocomplete on the textfield.
-        $autocomplete.autocomplete(autocomplete.options).each(function() {
-          $(this).data('ui-autocomplete')._renderItem =
-            autocomplete.options.renderItem;
+        const label = element.closest('.form-item').querySelector('label');
+        label.innerHTML += `<span class="visually-hidden">(${Drupal.t(
+          'Autocomplete input',
+        )})</span>`;
+
+        const awesomplete = new Awesomplete(element, {
+          minChars: 1,
+          sort: false,
+          filter(text, input) {
+            const numItems =
+              this.input.value.match(/(".*?"|[^",\s]+)(?=\s*,|\s*$)/g).length -
+              0;
+            // Prevent suggestions if the maximum number of items is reached.
+            if (cardinality > 0 && numItems > cardinality) {
+              return;
+            }
+            return Awesomplete.FILTER_CONTAINS(text, input.match(/[^,]*$/)[0]);
+          },
+          item(text, input) {
+            return Awesomplete.ITEM(text, input.match(/[^,]*$/)[0]);
+          },
+          replace(item) {
+            const before = this.input.value.match(/^.+,\s*|/)[0];
+            this.input.value = `${before}${item.value},`;
+          },
         });
 
-        // Use CompositionEvent to handle IME inputs. It requests remote server on "compositionend" event only.
-        $autocomplete.on('compositionstart.autocomplete', () => {
-          autocomplete.options.isComposing = true;
+        // Change role to textbox, Awesomplete defaults to combobox. The
+        // screenreader instructions for combobox assume select options are
+        // already present, which is not the case with autocomplete fields.
+        element.setAttribute('role', 'textbox');
+
+        // Screenreader announces the number of results found, and if it is
+        // the first set of results for a field, additional instructions on
+        // navigating the results are provided.
+        const readResults = count => {
+          const beginning = Drupal.formatPlural(
+            count,
+            'There is one result available.',
+            'There are @count results available.',
+          );
+          const end = autocompleteInstructionsRead
+            ? ''
+            : ' Use up and down arrows to review and enter to select.  Touch device users, explore by touch or with swipe gestures.';
+          Drupal.announce(Drupal.t(`${beginning}${end}`), 'assertive');
+          autocompleteInstructionsRead = true;
+        };
+
+        // Responds to user input and generates autocomplete suggestions.
+        element.addEventListener('input', event => {
+          const input = event.target;
+          let inputValue = input.value;
+          if (inputValue.includes(',')) {
+            [inputValue] = inputValue.split(',').slice(-1);
+          }
+          if (inputValue.length >= 1) {
+            if (inputValue in lookupCache) {
+              awesomplete.list = lookupCache[inputValue];
+              awesomplete.evaluate();
+              readResults(lookupCache[inputValue].length);
+            } else {
+              const xhr = new XMLHttpRequest();
+              xhr.open('GET', `${apiUrl}?q=${inputValue}`);
+              xhr.onload = function() {
+                if (xhr.status === 200) {
+                  const results = JSON.parse(xhr.response);
+                  awesomplete.list = results;
+                  awesomplete.evaluate();
+                  lookupCache[inputValue] = results;
+                  readResults(results.length);
+                }
+              };
+              xhr.send();
+            }
+          }
         });
-        $autocomplete.on('compositionend.autocomplete', () => {
-          autocomplete.options.isComposing = false;
-        });
-      }
-    },
-    detach(context, settings, trigger) {
-      if (trigger === 'unload') {
-        $(context)
-          .find('input.form-autocomplete')
-          .removeOnce('autocomplete')
-          .autocomplete('destroy');
-      }
+      });
     },
-  };
-
-  /**
-   * Autocomplete object implementation.
-   *
-   * @namespace Drupal.autocomplete
-   */
-  autocomplete = {
-    cache: {},
-    // Exposes options to allow overriding by contrib.
-    splitValues: autocompleteSplitValues,
-    extractLastTerm,
-    // jQuery UI autocomplete options.
 
-    /**
-     * JQuery UI option object.
-     *
-     * @name Drupal.autocomplete.options
-     */
-    options: {
-      source: sourceData,
-      focus: focusHandler,
-      search: searchHandler,
-      select: selectHandler,
-      renderItem,
-      minLength: 1,
-      // Custom options, used by Drupal.autocomplete.
-      firstCharacterBlacklist: '',
-      // Custom options, indicate IME usage status.
-      isComposing: false,
-    },
-    ajax: {
-      dataType: 'json',
+    detach(context) {
+      const autoCompleteInputs = context.querySelectorAll(
+        'input.form-autocomplete',
+      );
+      Array.prototype.forEach.call(autoCompleteInputs, element => {
+        element.removeEventListener('input');
+      });
     },
   };
-
-  Drupal.autocomplete = autocomplete;
-})(jQuery, Drupal);
+})(Drupal, jQuery, Awesomplete);
diff --git a/core/misc/autocomplete.js b/core/misc/autocomplete.js
index 52ddfd2ab4..9bd385cc79 100644
--- a/core/misc/autocomplete.js
+++ b/core/misc/autocomplete.js
@@ -4,161 +4,92 @@
 * https://www.drupal.org/node/2815083
 * @preserve
 **/
+var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }();
 
-(function ($, Drupal) {
-  var autocomplete = void 0;
-
-  function autocompleteSplitValues(value) {
-    var result = [];
-    var quote = false;
-    var current = '';
-    var valueLength = value.length;
-    var character = void 0;
-
-    for (var i = 0; i < valueLength; i++) {
-      character = value.charAt(i);
-      if (character === '"') {
-        current += character;
-        quote = !quote;
-      } else if (character === ',' && !quote) {
-        result.push(current.trim());
-        current = '';
-      } else {
-        current += character;
-      }
-    }
-    if (value.length > 0) {
-      result.push($.trim(current));
-    }
-
-    return result;
-  }
-
-  function extractLastTerm(terms) {
-    return autocomplete.splitValues(terms).pop();
-  }
-
-  function searchHandler(event) {
-    var options = autocomplete.options;
-
-    if (options.isComposing) {
-      return false;
-    }
-
-    var term = autocomplete.extractLastTerm(event.target.value);
-
-    if (term.length > 0 && options.firstCharacterBlacklist.indexOf(term[0]) !== -1) {
-      return false;
-    }
-
-    return term.length >= options.minLength;
-  }
-
-  function sourceData(request, response) {
-    var elementId = this.element.attr('id');
-
-    if (!(elementId in autocomplete.cache)) {
-      autocomplete.cache[elementId] = {};
-    }
-
-    function showSuggestions(suggestions) {
-      var tagged = autocomplete.splitValues(request.term);
-      var il = tagged.length;
-      for (var i = 0; i < il; i++) {
-        var index = suggestions.indexOf(tagged[i]);
-        if (index >= 0) {
-          suggestions.splice(index, 1);
-        }
-      }
-      response(suggestions);
-    }
-
-    var term = autocomplete.extractLastTerm(request.term);
-
-    function sourceCallbackHandler(data) {
-      autocomplete.cache[elementId][term] = data;
-
-      showSuggestions(data);
-    }
-
-    if (autocomplete.cache[elementId].hasOwnProperty(term)) {
-      showSuggestions(autocomplete.cache[elementId][term]);
-    } else {
-      var options = $.extend({ success: sourceCallbackHandler, data: { q: term } }, autocomplete.ajax);
-      $.ajax(this.element.attr('data-autocomplete-path'), options);
-    }
-  }
-
-  function focusHandler() {
-    return false;
-  }
-
-  function selectHandler(event, ui) {
-    var terms = autocomplete.splitValues(event.target.value);
-
-    terms.pop();
-
-    terms.push(ui.item.value);
-
-    event.target.value = terms.join(', ');
-
-    return false;
-  }
-
-  function renderItem(ul, item) {
-    return $('<li>').append($('<a>').html(item.label)).appendTo(ul);
-  }
-
-  Drupal.behaviors.autocomplete = {
+(function (Drupal, $, Awesomplete) {
+  Drupal.behaviors.awesomplete = {
     attach: function attach(context) {
-      var $autocomplete = $(context).find('input.form-autocomplete').once('autocomplete');
-      if ($autocomplete.length) {
-        var blacklist = $autocomplete.attr('data-autocomplete-first-character-blacklist');
-        $.extend(autocomplete.options, {
-          firstCharacterBlacklist: blacklist || ''
-        });
+      var autoCompleteInputs = context.querySelectorAll('input.form-autocomplete');
+      Array.prototype.forEach.call(autoCompleteInputs, function (element) {
+        var autocompleteInstructionsRead = false;
+        var cardinality = element.closest('[data-autocomplete-cardinality]').getAttribute('data-autocomplete-cardinality');
+        var isMultiple = cardinality !== '1';
+        var lookupCache = {};
+        var apiUrl = element.getAttribute('data-autocomplete-path');
+        if (isMultiple) {
+          element.setAttribute('data-multiple', '');
+        }
 
-        $autocomplete.autocomplete(autocomplete.options).each(function () {
-          $(this).data('ui-autocomplete')._renderItem = autocomplete.options.renderItem;
+        var label = element.closest('.form-item').querySelector('label');
+        label.innerHTML += '<span class="visually-hidden">(' + Drupal.t('Autocomplete input') + ')</span>';
+
+        var awesomplete = new Awesomplete(element, {
+          minChars: 1,
+          sort: false,
+          filter: function filter(text, input) {
+            var numItems = this.input.value.match(/(".*?"|[^",\s]+)(?=\s*,|\s*$)/g).length - 0;
+
+            if (cardinality > 0 && numItems > cardinality) {
+              return;
+            }
+            return Awesomplete.FILTER_CONTAINS(text, input.match(/[^,]*$/)[0]);
+          },
+          item: function item(text, input) {
+            return Awesomplete.ITEM(text, input.match(/[^,]*$/)[0]);
+          },
+          replace: function replace(item) {
+            var before = this.input.value.match(/^.+,\s*|/)[0];
+            this.input.value = '' + before + item.value + ',';
+          }
         });
 
-        $autocomplete.on('compositionstart.autocomplete', function () {
-          autocomplete.options.isComposing = true;
-        });
-        $autocomplete.on('compositionend.autocomplete', function () {
-          autocomplete.options.isComposing = false;
+        element.setAttribute('role', 'textbox');
+
+        var readResults = function readResults(count) {
+          var beginning = Drupal.formatPlural(count, 'There is one result available.', 'There are @count results available.');
+          var end = autocompleteInstructionsRead ? '' : ' Use up and down arrows to review and enter to select.  Touch device users, explore by touch or with swipe gestures.';
+          Drupal.announce(Drupal.t('' + beginning + end), 'assertive');
+          autocompleteInstructionsRead = true;
+        };
+
+        element.addEventListener('input', function (event) {
+          var input = event.target;
+          var inputValue = input.value;
+          if (inputValue.includes(',')) {
+            var _inputValue$split$sli = inputValue.split(',').slice(-1);
+
+            var _inputValue$split$sli2 = _slicedToArray(_inputValue$split$sli, 1);
+
+            inputValue = _inputValue$split$sli2[0];
+          }
+          if (inputValue.length >= 1) {
+            if (inputValue in lookupCache) {
+              awesomplete.list = lookupCache[inputValue];
+              awesomplete.evaluate();
+              readResults(lookupCache[inputValue].length);
+            } else {
+              var xhr = new XMLHttpRequest();
+              xhr.open('GET', apiUrl + '?q=' + inputValue);
+              xhr.onload = function () {
+                if (xhr.status === 200) {
+                  var results = JSON.parse(xhr.response);
+                  awesomplete.list = results;
+                  awesomplete.evaluate();
+                  lookupCache[inputValue] = results;
+                  readResults(results.length);
+                }
+              };
+              xhr.send();
+            }
+          }
         });
-      }
+      });
     },
-    detach: function detach(context, settings, trigger) {
-      if (trigger === 'unload') {
-        $(context).find('input.form-autocomplete').removeOnce('autocomplete').autocomplete('destroy');
-      }
+    detach: function detach(context) {
+      var autoCompleteInputs = context.querySelectorAll('input.form-autocomplete');
+      Array.prototype.forEach.call(autoCompleteInputs, function (element) {
+        element.removeEventListener('input');
+      });
     }
   };
-
-  autocomplete = {
-    cache: {},
-
-    splitValues: autocompleteSplitValues,
-    extractLastTerm: extractLastTerm,
-
-    options: {
-      source: sourceData,
-      focus: focusHandler,
-      search: searchHandler,
-      select: selectHandler,
-      renderItem: renderItem,
-      minLength: 1,
-
-      firstCharacterBlacklist: '',
-
-      isComposing: false
-    },
-    ajax: {
-      dataType: 'json'
-    }
-  };
-
-  Drupal.autocomplete = autocomplete;
-})(jQuery, Drupal);
\ No newline at end of file
+})(Drupal, jQuery, Awesomplete);
\ No newline at end of file