Food - The New York Times

" }), n("bloodhound", ["jquery/nyt"], function(t) { var e = function() { return { isMsie: function() { return /(msie|trident)/i.test(navigator.userAgent) ? navigator.userAgent.match(/(msie |rv:)(\d+(.\d+)?)/i)[2] : !1 }, isBlankString: function(t) { return !t || /^\s*$/.test(t) }, escapeRegExChars: function(t) { return t.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&") }, isString: function(t) { return "string" == typeof t }, isNumber: function(t) { return "number" == typeof t }, isArray: t.isArray, isFunction: t.isFunction, isObject: t.isPlainObject, isUndefined: function(t) { return "undefined" == typeof t }, toStr: function(t) { return e.isUndefined(t) || null === t ? "" : t + "" }, bind: t.proxy, each: function(e, n) { function i(t, e) { return n(e, t) } t.each(e, i) }, map: t.map, filter: t.grep, every: function(e, n) { var i = !0; return e ? (t.each(e, function(t, r) { return (i = n.call(null, r, t, e)) ? void 0 : !1 }), !!i) : i }, some: function(e, n) { var i = !1; return e ? (t.each(e, function(t, r) { return (i = n.call(null, r, t, e)) ? !1 : void 0 }), !!i) : i }, mixin: t.extend, getUniqueId: function() { var t = 0; return function() { return t++ } }(), templatify: function(e) { function n() { return String(e) } return t.isFunction(e) ? e : n }, defer: function(t) { setTimeout(t, 0) }, debounce: function(t, e, n) { var i, r; return function() { var s, o, u = this, a = arguments; return s = function() { i = null, n || (r = t.apply(u, a)) }, o = n && !i, clearTimeout(i), i = setTimeout(s, e), o && (r = t.apply(u, a)), r } }, throttle: function(t, e) { var n, i, r, s, o, u; return o = 0, u = function() { o = new Date, r = null, s = t.apply(n, i) }, function() { var a = new Date, c = e - (a - o); return n = this, i = arguments, 0 >= c ? (clearTimeout(r), r = null, o = a, s = t.apply(n, i)) : r || (r = setTimeout(u, c)), s } }, noop: function() {} } }(), n = "0.10.5", i = function() { function t(t) { return t = e.toStr(t), t ? t.split(/\s+/) : [] } function n(t) { return t = e.toStr(t), t ? t.split(/\W+/) : [] } function i(t) { return function() { var n = [].slice.call(arguments, 0); return function(i) { var r = []; return e.each(n, function(n) { r = r.concat(t(e.toStr(i[n]))) }), r } } } return { nonword: n, whitespace: t, obj: { nonword: i(n), whitespace: i(t) } } }(), r = function() { function n(n) { this.maxSize = e.isNumber(n) ? n : 100, this.reset(), this.maxSize = this.maxSize && (this.list.remove(i), delete this.hash[i.key]), (n = this.hash[t]) ? (n.val = e, this.list.moveToFront(n)) : (n = new r(t, e), this.list.add(n), this.hash[t] = n, this.size++) }, get: function(t) { var e = this.hash[t]; return e ? (this.list.moveToFront(e), e.val) : void 0 }, reset: function() { this.size = 0, this.hash = {}, this.list = new i } }), e.mixin(i.prototype, { add: function(t) { this.head && (t.next = this.head, this.head.prev = t), this.head = t, this.tail = this.tail || t }, remove: function(t) { t.prev ? t.prev.next = t.next : this.head = t.next, t.next ? t.next.prev = t.prev : this.tail = t.prev }, moveToFront: function(t) { this.remove(t), this.add(t) } }), n }(), s = function() { function t(t) { this.prefix = ["__", t, "__"].join(""), this.ttlKey = "__ttl__", this.keyMatcher = new RegExp("^" + e.escapeRegExChars(this.prefix)) } function n() { return (new Date).getTime() } function i(t) { return JSON.stringify(e.isUndefined(t) ? null : t) } function r(t) { return JSON.parse(t) } var s, o; try { s = window.localStorage, s.setItem("~~~", "!"), s.removeItem("~~~") } catch (u) { s = null } return o = s && window.JSON ? { _prefix: function(t) { return this.prefix + t }, _ttlKey: function(t) { return this._prefix(t) + this.ttlKey }, get: function(t) { return this.isExpired(t) && this.remove(t), r(s.getItem(this._prefix(t))) }, set: function(t, r, o) { return e.isNumber(o) ? s.setItem(this._ttlKey(t), i(n() + o)) : s.removeItem(this._ttlKey(t)), s.setItem(this._prefix(t), i(r)) }, remove: function(t) { return s.removeItem(this._ttlKey(t)), s.removeItem(this._prefix(t)), this }, clear: function() { var t, e, n = [], i = s.length; for (t = 0; i > t; t++)(e = s.key(t)).match(this.keyMatcher) && n.push(e.replace(this.keyMatcher, "")); for (t = n.length; t--;) this.remove(n[t]); return this }, isExpired: function(t) { var i = r(s.getItem(this._ttlKey(t))); return e.isNumber(i) && n() > i ? !0 : !1 } } : { get: e.noop, set: e.noop, remove: e.noop, clear: e.noop, isExpired: e.noop }, e.mixin(t.prototype, o), t }(), o = function() { function n(e) { e = e || {}, this.cancelled = !1, this.lastUrl = null, this._send = e.transport ? i(e.transport) : t.ajax, this._get = e.rateLimiter ? e.rateLimiter(this._get) : this._get, this._cache = e.cache === !1 ? new r(0) : a } function i(n) { return function(i, r) { function s(t) { e.defer(function() { u.resolve(t) }) } function o(t) { e.defer(function() { u.reject(t) }) } var u = t.Deferred(); return n(i, r, s, o), u } } var s = 0, o = {}, u = 6, a = new r(10); return n.setMaxPendingRequests = function(t) { u = t }, n.resetCache = function() { a.reset() }, e.mixin(n.prototype, { _get: function(t, e, n) { function i(e) { n && n(null, e), l._cache.set(t, e) } function r() { n && n(!0) } function a() { s--, delete o[t], l.onDeckRequestArgs && (l._get.apply(l, l.onDeckRequestArgs), l.onDeckRequestArgs = null) } var c, l = this; this.cancelled || t !== this.lastUrl || ((c = o[t]) ? c.done(i).fail(r) : u > s ? (s++, o[t] = this._send(t, e).done(i).fail(r).always(a)) : this.onDeckRequestArgs = [].slice.call(arguments, 0)) }, get: function(t, n, i) { var r; return e.isFunction(n) && (i = n, n = {}), this.cancelled = !1, this.lastUrl = t, (r = this._cache.get(t)) ? e.defer(function() { i && i(null, r) }) : this._get(t, n, i), !!r }, cancel: function() { this.cancelled = !0 } }), n }(), u = function() { function n(e) { e = e || {}, e.datumTokenizer && e.queryTokenizer || t.error("datumTokenizer and queryTokenizer are both required"), this.datumTokenizer = e.datumTokenizer, this.queryTokenizer = e.queryTokenizer, this.reset() } function i(t) { return t = e.filter(t, function(t) { return !!t }), t = e.map(t, function(t) { return t.toLowerCase() }) } function r() { return { ids: [], children: {} } } function s(t) { for (var e = {}, n = [], i = 0, r = t.length; r > i; i++) e[t[i]] || (e[t[i]] = !0, n.push(t[i])); return n } function o(t, e) { function n(t, e) { return t - e } var i = 0, r = 0, s = []; t = t.sort(n), e = e.sort(n); for (var o = t.length, u = e.length; o > i && u > r;) t[i] e[r] ? r++ : (s.push(t[i]), i++, r++); return s } return e.mixin(n.prototype, { bootstrap: function(t) { this.datums = t.datums, this.trie = t.trie }, add: function(t) { var n = this; t = e.isArray(t) ? t : [t], e.each(t, function(t) { var s, o; s = n.datums.push(t) - 1, o = i(n.datumTokenizer(t)), e.each(o, function(t) { var e, i, o; for (e = n.trie, i = t.split(""); o = i.shift();) e = e.children[o] || (e.children[o] = r()), e.ids.push(s) }) }) }, get: function(t) { var n, r, u = this; return n = i(this.queryTokenizer(t)), e.each(n, function(t) { var e, n, i, s; if (r && 0 === r.length) return !1; for (e = u.trie, n = t.split(""); e && (i = n.shift());) e = e.children[i]; return e && 0 === n.length ? (s = e.ids.slice(0), void(r = r ? o(r, s) : s)) : (r = [], !1) }), r ? e.map(s(r), function(t) { return u.datums[t] }) : [] }, reset: function() { this.datums = [], this.trie = r() }, serialize: function() { return { datums: this.datums, trie: this.trie } } }), n }(), a = function() { function i(t) { return t.local || null } function r(i) { var r, s; return s = { url: null, thumbprint: "", ttl: 864e5, filter: null, ajax: {} }, (r = i.prefetch || null) && (r = e.isString(r) ? { url: r } : r, r = e.mixin(s, r), r.thumbprint = n + r.thumbprint, r.ajax.type = r.ajax.type || "GET", r.ajax.dataType = r.ajax.dataType || "json", !r.url && t.error("prefetch requires url to be set")), r } function s(n) { function i(t) { return function(n) { return e.debounce(n, t) } } function r(t) { return function(n) { return e.throttle(n, t) } } var s, o; return o = { url: null, cache: !0, wildcard: "%QUERY", replace: null, rateLimitBy: "debounce", rateLimitWait: 300, send: null, filter: null, ajax: {} }, (s = n.remote || null) && (s = e.isString(s) ? { url: s } : s, s = e.mixin(o, s), s.rateLimiter = /^throttle$/i.test(s.rateLimitBy) ? r(s.rateLimitWait) : i(s.rateLimitWait), s.ajax.type = s.ajax.type || "GET", s.ajax.dataType = s.ajax.dataType || "json", delete s.rateLimitBy, delete s.rateLimitWait, !s.url && t.error("remote requires url to be set")), s } return { local: i, prefetch: r, remote: s } }(), c = function(n) { function r(e) { e && (e.local || e.prefetch || e.remote) || t.error("one of local, prefetch, or remote is required"), this.limit = e.limit || 5, this.sorter = c(e.sorter), this.dupDetector = e.dupDetector || l, this.local = a.local(e), this.prefetch = a.prefetch(e), this.remote = a.remote(e), this.cacheKey = this.prefetch ? this.prefetch.cacheKey || this.prefetch.url : null, this.index = new u({ datumTokenizer: e.datumTokenizer, queryTokenizer: e.queryTokenizer }), this.storage = this.cacheKey ? new s(this.cacheKey) : null } function c(t) { function n(e) { return e.sort(t) } function i(t) { return t } return e.isFunction(t) ? n : i } function l() { return !1 } var h, f; return h = n.Bloodhound, f = { data: "data", protocol: "protocol", thumbprint: "thumbprint" }, n.Bloodhound = r, r.noConflict = function() { return n.Bloodhound = h, r }, r.tokenizers = i, e.mixin(r.prototype, { _loadPrefetch: function(e) { function n(t) { s.clear(), s.add(e.filter ? e.filter(t) : t), s._saveToStorage(s.index.serialize(), e.thumbprint, e.ttl) } var i, r, s = this; return (i = this._readFromStorage(e.thumbprint)) ? (this.index.bootstrap(i), r = t.Deferred().resolve()) : r = t.ajax(e.url, e.ajax).done(n), r }, _getFromRemote: function(t, e) { function n(t, n) { e(t ? [] : s.remote.filter ? s.remote.filter(n) : n) } var i, r, s = this; return this.transport ? (t = t || "", r = encodeURIComponent(t), i = this.remote.replace ? this.remote.replace(this.remote.url, t) : this.remote.url.replace(this.remote.wildcard, r), this.transport.get(i, this.remote.ajax, n)) : void 0 }, _cancelLastRemoteRequest: function() { this.transport && this.transport.cancel() }, _saveToStorage: function(t, e, n) { this.storage && (this.storage.set(f.data, t, n), this.storage.set(f.protocol, location.protocol, n), this.storage.set(f.thumbprint, e, n)) }, _readFromStorage: function(t) { var e, n = {}; return this.storage && (n.data = this.storage.get(f.data), n.protocol = this.storage.get(f.protocol), n.thumbprint = this.storage.get(f.thumbprint)), e = n.thumbprint !== t || n.protocol !== location.protocol, n.data && !e ? n.data : null }, _initialize: function() { function n() { r.add(e.isFunction(s) ? s() : s) } var i, r = this, s = this.local; return i = this.prefetch ? this._loadPrefetch(this.prefetch) : t.Deferred().resolve(), s && i.done(n), this.transport = this.remote ? new o(this.remote) : null, this.initPromise = i.promise() }, initialize: function(t) { return !this.initPromise || t ? this._initialize() : this.initPromise }, add: function(t) { this.index.add(t) }, get: function(t, n) { function i(t) { var i = s.slice(0); e.each(t, function(t) { var n; return n = e.some(i, function(e) { return r.dupDetector(t, e) }), !n && i.push(t), i.length 0 || !this.transport) && n && n(s) }, clear: function() { this.index.reset() }, clearPrefetchCache: function() { this.storage && this.storage.clear() }, clearRemoteCache: function() { this.transport && o.resetCache() }, ttAdapter: function() { return e.bind(this.get, this) } }), r }(this); return c }), n("typeahead", ["jquery/nyt"], function(t) { var e = function() { return { isMsie: function() { return /(msie|trident)/i.test(navigator.userAgent) ? navigator.userAgent.match(/(msie |rv:)(\d+(.\d+)?)/i)[2] : !1 }, isBlankString: function(t) { return !t || /^\s*$/.test(t) }, escapeRegExChars: function(t) { return t.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&") }, isString: function(t) { return "string" == typeof t }, isNumber: function(t) { return "number" == typeof t }, isArray: t.isArray, isFunction: t.isFunction, isObject: t.isPlainObject, isUndefined: function(t) { return "undefined" == typeof t }, toStr: function(t) { return e.isUndefined(t) || null === t ? "" : t + "" }, bind: t.proxy, each: function(e, n) { function i(t, e) { return n(e, t) } t.each(e, i) }, map: t.map, filter: t.grep, every: function(e, n) { var i = !0; return e ? (t.each(e, function(t, r) { return (i = n.call(null, r, t, e)) ? void 0 : !1 }), !!i) : i }, some: function(e, n) { var i = !1; return e ? (t.each(e, function(t, r) { return (i = n.call(null, r, t, e)) ? !1 : void 0 }), !!i) : i }, mixin: t.extend, getUniqueId: function() { var t = 0; return function() { return t++ } }(), templatify: function(e) { function n() { return String(e) } return t.isFunction(e) ? e : n }, defer: function(t) { setTimeout(t, 0) }, debounce: function(t, e, n) { var i, r; return function() { var s, o, u = this, a = arguments; return s = function() { i = null, n || (r = t.apply(u, a)) }, o = n && !i, clearTimeout(i), i = setTimeout(s, e), o && (r = t.apply(u, a)), r } }, throttle: function(t, e) { var n, i, r, s, o, u; return o = 0, u = function() { o = new Date, r = null, s = t.apply(n, i) }, function() { var a = new Date, c = e - (a - o); return n = this, i = arguments, 0 >= c ? (clearTimeout(r), r = null, o = a, s = t.apply(n, i)) : r || (r = setTimeout(u, c)), s } }, noop: function() {} } }(), n = function() { return { wrapper: '', dropdown: '', dataset: '', suggestions: '', suggestion: '' } }(), i = function() { var t = { wrapper: { position: "relative", display: "inline-block" }, hint: { position: "absolute", top: "0", left: "0", borderColor: "transparent", boxShadow: "none", opacity: "1" }, input: { position: "relative", verticalAlign: "top", backgroundColor: "transparent" }, inputWithNoHint: { position: "relative", verticalAlign: "top" }, dropdown: { position: "absolute", top: "100%", left: "0", zIndex: "100", display: "none" }, suggestions: { display: "block" }, suggestion: { whiteSpace: "nowrap", cursor: "pointer" }, suggestionChild: { whiteSpace: "normal" }, ltr: { left: "0", right: "auto" }, rtl: { left: "auto", right: " 0" } }; return e.isMsie() && e.mixin(t.input, { backgroundImage: "url(data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7)" }), e.isMsie() && e.isMsie() r; r += 1) i = t[r].apply(e, n) === !1; return !i } return i } function o() { var t; return t = window.setImmediate ? function(t) { setImmediate(function() { t() }) } : function(t) { setTimeout(function() { t() }, 0) } } function u(t, e) { return t.bind ? t.bind(e) : function() { t.apply(e, [].slice.call(arguments, 0)) } } var a = /\s+/, c = o(); return { onSync: n, onAsync: e, off: i, trigger: r } }(), o = function(t) { function n(t, n, i) { for (var r, s = [], o = 0, u = t.length; u > o; o++) s.push(e.escapeRegExChars(t[o])); return r = i ? "\\b(" + s.join("|") + ")\\b" : "(" + s.join("|") + ")", n ? new RegExp(r) : new RegExp(r, "i") } var i = { node: null, pattern: null, tagName: "strong", className: null, wordsOnly: !1, caseSensitive: !1 }; return function(r) { function s(e) { var n, i, s; return (n = u.exec(e.data)) && (s = t.createElement(r.tagName), r.className && (s.className = r.className), i = e.splitText(n.index), i.splitText(n[0].length), s.appendChild(i.cloneNode(!0)), e.parentNode.replaceChild(s, i)), !!n } function o(t, e) { for (var n, i = 3, r = 0; r ').css({ position: "absolute", visibility: "hidden", whiteSpace: "pre", fontFamily: e.css("font-family"), fontSize: e.css("font-size"), fontStyle: e.css("font-style"), fontVariant: e.css("font-variant"), fontWeight: e.css("font-weight"), wordSpacing: e.css("word-spacing"), letterSpacing: e.css("letter-spacing"), textIndent: e.css("text-indent"), textRendering: e.css("text-rendering"), textTransform: e.css("text-transform") }).insertAfter(e) } function r(t, e) { return n.normalizeQuery(t) === n.normalizeQuery(e) } function o(t) { return t.altKey || t.ctrlKey || t.metaKey || t.shiftKey } var u; return u = { 9: "tab", 27: "esc", 37: "left", 39: "right", 13: "enter", 38: "up", 40: "down" }, n.normalizeQuery = function(t) { return (t || "").replace(/^\s*/g, "").replace(/\s{2,}/g, " ") }, e.mixin(n.prototype, s, { _onBlur: function() { this.resetInputValue(), this.trigger("blurred") }, _onFocus: function() { this.trigger("focused") }, _onKeydown: function(t) { var e = u[t.which || t.keyCode]; this._managePreventDefault(e, t), e && this._shouldTrigger(e, t) && this.trigger(e + "Keyed", t) }, _onInput: function() { this._checkInputValue() }, _managePreventDefault: function(t, e) { var n, i, r; switch (t) { case "tab": i = this.getHint(), r = this.getInputValue(), n = i && i !== r && !o(e); break; case "up": case "down": n = !o(e); break; default: n = !1 } n && e.preventDefault() }, _shouldTrigger: function(t, e) { var n; switch (t) { case "tab": n = !o(e); break; default: n = !0 } return n }, _checkInputValue: function() { var t, e, n; t = this.getInputValue(), e = r(t, this.query), n = e ? this.query.length !== t.length : !1, this.query = t, e ? n && this.trigger("whitespaceChanged", this.query) : this.trigger("queryChanged", this.query) }, focus: function() { this.$input.focus() }, blur: function() { this.$input.blur() }, getQuery: function() { return this.query }, setQuery: function(t) { this.query = t }, getInputValue: function() { return this.$input.val() }, setInputValue: function(t, e) { this.$input.val(t), e ? this.clearHint() : this._checkInputValue() }, resetInputValue: function() { this.setInputValue(this.query, !0) }, getHint: function() { return this.$hint.val() }, setHint: function(t) { this.$hint.val(t) }, clearHint: function() { this.setHint("") }, clearHintIfInvalid: function() { var t, e, n, i; t = this.getInputValue(), e = this.getHint(), n = t !== e && 0 === e.indexOf(t), i = "" !== t && n && !this.hasOverflow(), !i && this.clearHint() }, getLanguageDirection: function() { return (this.$input.css("direction") || "ltr").toLowerCase() }, hasOverflow: function() { var t = this.$input.width() - 2; return this.$overflowHelper.text(this.getInputValue()), this.$overflowHelper.width() >= t }, isCursorAtEnd: function() { var t, n, i; return t = this.$input.val().length, n = this.$input[0].selectionStart, e.isNumber(n) ? n === t : document.selection ? (i = document.selection.createRange(), i.moveStart("character", -t), t === i.text.length) : !0 }, destroy: function() { this.$hint.off(".tt"), this.$input.off(".tt"), this.$hint = this.$input = this.$overflowHelper = null } }), n }(), a = function() { function r(i) { i = i || {}, i.templates = i.templates || {}, i.source || t.error("missing source"), i.name && !c(i.name) && t.error("invalid dataset name: " + i.name), this.query = null, this.highlight = !!i.highlight, this.name = i.name || e.getUniqueId(), this.source = i.source, this.displayFn = u(i.display || i.displayKey), this.templates = a(i.templates, this.displayFn), this.$el = t(n.dataset.replace("%CLASS%", this.name)) } function u(t) { function n(e) { return e[t] } return t = t || "value", e.isFunction(t) ? t : n } function a(t, n) { function i(t) { return "

" + n(t) + "

" } return { empty: t.empty && e.templatify(t.empty), header: t.header && e.templatify(t.header), footer: t.footer && e.templatify(t.footer), suggestion: t.suggestion || i } } function c(t) { return /^[_a-zA-Z0-9-]+$/.test(t) } var l = "ttDataset", h = "ttValue", f = "ttDatum"; return r.extractDatasetName = function(e) { return t(e).data(l) }, r.extractValue = function(e) { return t(e).data(h) }, r.extractDatum = function(e) { return t(e).data(f) }, e.mixin(r.prototype, s, { _render: function(r, s) { function u() { return g.templates.empty({ query: r, isEmpty: !0 }) } function a() { function u(e) { var r; return r = t(n.suggestion).append(g.templates.suggestion(e)).data(l, g.name).data(h, g.displayFn(e)).data(f, e), r.children().each(function() { t(this).css(i.suggestionChild) }), r } var a, c; return a = t(n.suggestions).css(i.suggestions), c = e.map(s, u), a.append.apply(a, c), g.highlight && o({ className: "tt-highlight", node: a[0], pattern: r }), a } function c() { return g.templates.header({ query: r, isEmpty: !d }) } function p() { return g.templates.footer({ query: r, isEmpty: !d }) } if (this.$el) { var d, g = this; this.$el.empty(), d = s && s.length, !d && this.templates.empty ? this.$el.html(u()).prepend(g.templates.header ? c() : null).append(g.templates.footer ? p() : null) : d && this.$el.html(a()).prepend(g.templates.header ? c() : null).append(g.templates.footer ? p() : null), this.trigger("rendered") } }, getRoot: function() { return this.$el }, update: function(t) { function e(e) { n.canceled || t !== n.query || n._render(t, e) } var n = this; this.query = t, this.canceled = !1, this.source(t, e) }, cancel: function() { this.canceled = !0 }, clear: function() { this.cancel(), this.$el.empty(), this.trigger("rendered") }, isEmpty: function() { return this.$el.is(":empty") }, destroy: function() { this.$el = null } }), r }(), c = function() { function n(n) { var i, s, o, u = this; n = n || {}, n.menu || t.error("menu is required"), this.isOpen = !1, this.isEmpty = !0, this.datasets = e.map(n.datasets, r), i = e.bind(this._onSuggestionClick, this), s = e.bind(this._onSuggestionMouseEnter, this), o = e.bind(this._onSuggestionMouseLeave, this), this.$menu = t(n.menu).on("click.tt", ".tt-suggestion", i).on("mouseenter.tt", ".tt-suggestion", s).on("mouseleave.tt", ".tt-suggestion", o), e.each(this.datasets, function(t) { u.$menu.append(t.getRoot()), t.onSync("rendered", u._onRendered, u) }) } function r(t) { return new a(t) } return e.mixin(n.prototype, s, { _onSuggestionClick: function(e) { this.trigger("suggestionClicked", t(e.currentTarget)) }, _onSuggestionMouseEnter: function(e) { this._removeCursor(), this._setCursor(t(e.currentTarget), !0) }, _onSuggestionMouseLeave: function() { this._removeCursor() }, _onRendered: function() { function t(t) { return t.isEmpty() } this.isEmpty = e.every(this.datasets, t), this.isEmpty ? this._hide() : this.isOpen && this._show(), this.trigger("datasetRendered") }, _hide: function() { this.$menu.hide() }, _show: function() { this.$menu.css("display", "block") }, _getSuggestions: function() { return this.$menu.find(".tt-suggestion") }, _getCursor: function() { return this.$menu.find(".tt-cursor").first() }, _setCursor: function(t, e) { t.first().addClass("tt-cursor"), !e && this.trigger("cursorMoved") }, _removeCursor: function() { this._getCursor().removeClass("tt-cursor") }, _moveCursor: function(t) { var e, n, i, r; if (this.isOpen) { if (n = this._getCursor(), e = this._getSuggestions(), this._removeCursor(), i = e.index(n) + t, i = (i + 1) % (e.length + 1) - 1, -1 === i) return void this.trigger("cursorRemoved"); - 1 > i && (i = e.length - 1), this._setCursor(r = e.eq(i)), this._ensureVisible(r) } }, _ensureVisible: function(t) { var e, n, i, r; e = t.position().top, n = e + t.outerHeight(!0), i = this.$menu.scrollTop(), r = this.$menu.height() + parseInt(this.$menu.css("paddingTop"), 10) + parseInt(this.$menu.css("paddingBottom"), 10), 0 > e ? this.$menu.scrollTop(i + e) : n > r && this.$menu.scrollTop(i + (n - r)) }, close: function() { this.isOpen && (this.isOpen = !1, this._removeCursor(), this._hide(), this.trigger("closed")) }, open: function() { this.isOpen || (this.isOpen = !0, !this.isEmpty && this._show(), this.trigger("opened")) }, setLanguageDirection: function(t) { this.$menu.css("ltr" === t ? i.ltr : i.rtl) }, moveCursorUp: function() { this._moveCursor(-1) }, moveCursorDown: function() { this._moveCursor(1) }, getDatumForSuggestion: function(t) { var e = null; return t.length && (e = { raw: a.extractDatum(t), value: a.extractValue(t), datasetName: a.extractDatasetName(t) }), e }, getDatumForCursor: function() { return this.getDatumForSuggestion(this._getCursor().first()) }, getDatumForTopSuggestion: function() { return this.getDatumForSuggestion(this._getSuggestions().first()) }, update: function(t) { function n(e) { e.update(t) } e.each(this.datasets, n) }, empty: function() { function t(t) { t.clear() } e.each(this.datasets, t), this.isEmpty = !0 }, isVisible: function() { return this.isOpen && !this.isEmpty }, destroy: function() { function t(t) { t.destroy() } this.$menu.off(".tt"), this.$menu = null, e.each(this.datasets, t) } }), n }(), l = function() { function s(n) { var i, s, a; n = n || {}, n.input || t.error("missing input"), this.isActivated = !1, this.autoselect = !!n.autoselect, this.minLength = e.isNumber(n.minLength) ? n.minLength : 1, this.$node = o(n.input, n.withHint), i = this.$node.find(".tt-dropdown-menu"), s = this.$node.find(".tt-input"), a = this.$node.find(".tt-hint"), s.on("blur.tt", function(t) { var n, r, o; n = document.activeElement, r = i.is(n), o = i.has(n).length > 0, e.isMsie() && (r || o) && (t.preventDefault(), t.stopImmediatePropagation(), e.defer(function() { s.focus() })) }), i.on("mousedown.tt", function(t) { t.preventDefault() }), this.eventBus = n.eventBus || new r({ el: s }), this.dropdown = new c({ menu: i, datasets: n.datasets }).onSync("suggestionClicked", this._onSuggestionClicked, this).onSync("cursorMoved", this._onCursorMoved, this).onSync("cursorRemoved", this._onCursorRemoved, this).onSync("opened", this._onOpened, this).onSync("closed", this._onClosed, this).onAsync("datasetRendered", this._onDatasetRendered, this), this.input = new u({ input: s, hint: a }).onSync("focused", this._onFocused, this).onSync("blurred", this._onBlurred, this).onSync("enterKeyed", this._onEnterKeyed, this).onSync("tabKeyed", this._onTabKeyed, this).onSync("escKeyed", this._onEscKeyed, this).onSync("upKeyed", this._onUpKeyed, this).onSync("downKeyed", this._onDownKeyed, this).onSync("leftKeyed", this._onLeftKeyed, this).onSync("rightKeyed", this._onRightKeyed, this).onSync("queryChanged", this._onQueryChanged, this).onSync("whitespaceChanged", this._onWhitespaceChanged, this), this._setLanguageDirection() } function o(e, r) { var s, o, u, c; s = t(e), o = t(n.wrapper).css(i.wrapper), u = t(n.dropdown).css(i.dropdown), c = s.clone().css(i.hint).css(a(s)), c.val("").removeData().addClass("tt-hint").removeAttr("id name placeholder required").prop("readonly", !0).attr({ autocomplete: "off", spellcheck: "false", tabindex: -1 }), s.data(h, { dir: s.attr("dir"), autocomplete: s.attr("autocomplete"), spellcheck: s.attr("spellcheck"), style: s.attr("style") }), s.addClass("tt-input").attr({ autocomplete: "off", spellcheck: !1 }).css(r ? i.input : i.inputWithNoHint); try { !s.attr("dir") && s.attr("dir", "auto") } catch (l) {} return s.wrap(o).parent().prepend(r ? c : null).append(u) } function a(t) { return { backgroundAttachment: t.css("background-attachment"), backgroundClip: t.css("background-clip"), backgroundColor: t.css("background-color"), backgroundImage: t.css("background-image"), backgroundOrigin: t.css("background-origin"), backgroundPosition: t.css("background-position"), backgroundRepeat: t.css("background-repeat"), backgroundSize: t.css("background-size") } } function l(t) { var n = t.find(".tt-input"); e.each(n.data(h), function(t, i) { e.isUndefined(t) ? n.removeAttr(i) : n.attr(i, t) }), n.detach().removeData(h).removeClass("tt-input").insertAfter(t), t.remove() } var h = "ttAttrs"; return e.mixin(s.prototype, { _onSuggestionClicked: function(t, e) { var n; (n = this.dropdown.getDatumForSuggestion(e)) && this._select(n) }, _onCursorMoved: function() { var t = this.dropdown.getDatumForCursor(); this.input.setInputValue(t.value, !0), this.eventBus.trigger("cursorchanged", t.raw, t.datasetName) }, _onCursorRemoved: function() { this.input.resetInputValue(), this._updateHint() }, _onDatasetRendered: function() { this._updateHint() }, _onOpened: function() { this._updateHint(), this.eventBus.trigger("opened") }, _onClosed: function() { this.input.clearHint(), this.eventBus.trigger("closed") }, _onFocused: function() { this.isActivated = !0, this.dropdown.open() }, _onBlurred: function() { this.isActivated = !1, this.dropdown.empty(), this.dropdown.close() }, _onEnterKeyed: function(t, e) { var n, i; n = this.dropdown.getDatumForCursor(), i = this.dropdown.getDatumForTopSuggestion(), n ? (this._select(n), e.preventDefault()) : this.autoselect && i && (this._select(i), e.preventDefault()) }, _onTabKeyed: function(t, e) { var n; (n = this.dropdown.getDatumForCursor()) ? (this._select(n), e.preventDefault()) : this._autocomplete(!0) }, _onEscKeyed: function() { this.dropdown.close(), this.input.resetInputValue() }, _onUpKeyed: function() { var t = this.input.getQuery(); this.dropdown.isEmpty && t.length >= this.minLength ? this.dropdown.update(t) : this.dropdown.moveCursorUp(), this.dropdown.open() }, _onDownKeyed: function() { var t = this.input.getQuery(); this.dropdown.isEmpty && t.length >= this.minLength ? this.dropdown.update(t) : this.dropdown.moveCursorDown(), this.dropdown.open() }, _onLeftKeyed: function() { "rtl" === this.dir && this._autocomplete() }, _onRightKeyed: function() { "ltr" === this.dir && this._autocomplete() }, _onQueryChanged: function(t, e) { this.input.clearHintIfInvalid(), e.length >= this.minLength ? this.dropdown.update(e) : this.dropdown.empty(), this.dropdown.open(), this._setLanguageDirection() }, _onWhitespaceChanged: function() { this._updateHint(), this.dropdown.open() }, _setLanguageDirection: function() { var t; this.dir !== (t = this.input.getLanguageDirection()) && (this.dir = t, this.$node.css("direction", t), this.dropdown.setLanguageDirection(t)) }, _updateHint: function() { var t, n, i, r, s, o; t = this.dropdown.getDatumForTopSuggestion(), t && this.dropdown.isVisible() && !this.input.hasOverflow() ? (n = this.input.getInputValue(), i = u.normalizeQuery(n), r = e.escapeRegExChars(i), s = new RegExp("^(?:" + r + ")(.+$)", "i"), o = s.exec(t.value), o ? this.input.setHint(n + o[1]) : this.input.clearHint()) : this.input.clearHint() }, _autocomplete: function(t) { var e, n, i, r; e = this.input.getHint(), n = this.input.getQuery(), i = t || this.input.isCursorAtEnd(), e && n !== e && i && (r = this.dropdown.getDatumForTopSuggestion(), r && this.input.setInputValue(r.value), this.eventBus.trigger("autocompleted", r.raw, r.datasetName)) }, _select: function(t) { this.input.setQuery(t.value), this.input.setInputValue(t.value, !0), this._setLanguageDirection(), this.eventBus.trigger("selected", t.raw, t.datasetName), this.dropdown.close(), e.defer(e.bind(this.dropdown.empty, this.dropdown)) }, open: function() { this.dropdown.open() }, close: function() { this.dropdown.close() }, setVal: function(t) { t = e.toStr(t), this.isActivated ? this.input.setInputValue(t) : (this.input.setQuery(t), this.input.setInputValue(t, !0)), this._setLanguageDirection() }, getVal: function() { return this.input.getQuery() }, destroy: function() { this.input.destroy(), this.dropdown.destroy(), l(this.$node), this.$node = null } }), s }(); ! function() { var n, i, s; n = t.fn.typeahead, i = "ttTypeahead", s = { initialize: function(n, s) { function o() { var o, u, a = t(this); e.each(s, function(t) { t.highlight = !!n.highlight }), u = new l({ input: a, eventBus: o = new r({ el: a }), withHint: e.isUndefined(n.hint) ? !0 : !!n.hint, minLength: n.minLength, autoselect: n.autoselect, datasets: s }), a.data(i, u) } return s = e.isArray(s) ? s : [].slice.call(arguments, 1), n = n || {}, this.each(o) }, open: function() { function e() { var e, n = t(this); (e = n.data(i)) && e.open() } return this.each(e) }, close: function() { function e() { var e, n = t(this); (e = n.data(i)) && e.close() } return this.each(e) }, val: function(e) { function n() { var n, r = t(this); (n = r.data(i)) && n.setVal(e) } function r(t) { var e, n; return (e = t.data(i)) && (n = e.getVal()), n } return arguments.length ? this.each(n) : r(this.first()) }, destroy: function() { function e() { var e, n = t(this); (e = n.data(i)) && (e.destroy(), n.removeData(i)) } return this.each(e) } }, t.fn.typeahead = function(e) { var n; return s[e] && "initialize" !== e ? (n = this.filter(function() { return !!t(this).data(i) }), s[e].apply(n, [].slice.call(arguments, 1))) : s.initialize.apply(this, arguments) }, t.fn.typeahead.noConflict = function() { return t.fn.typeahead = n, this } }() }), n("recipe_search/search", ["jquery/nyt", "underscore/nyt", "backbone/nyt", "text!recipe_search/autocomplete.html", "bloodhound", "typeahead"], function(t, e, n, i, r) { var s; switch (window.location.hostname) { case "www.nytimes.com": case "preview.www.prd.nytimes.com": s = "https://cooking.nytimes.com"; break; case "www.stg.nytimes.com": s = "https://cooking.stg.nytimes.com"; break; default: s = "https://cooking.nytimes.com" } var o = n.View.extend({ initialize: function() { this.initializeAutocomplete() }, initializeAutocomplete: function() { var n = 40, o = new r({ datumTokenizer: r.tokenizers.whitespace, queryTokenizer: r.tokenizers.whitespace, remote: { url: s + "/api/autocomplete?q=", replace: function(t, e) { return e.length > n && (e = e.substring(0, n)), t + e } } }), u = new r({ datumTokenizer: r.tokenizers.whitespace, queryTokenizer: r.tokenizers.whitespace, remote: { url: s + "/api/autocomplete_terms?q=", replace: function(t, e) { return e.length > n && (e = e.substring(0, n)), t + e } } }); u.initialize(), o.initialize(), t("#nytcooking-recipe-search").typeahead({ highlight: !1, hint: !1 }, { source: u.ttAdapter(), displayKey: "name" }, { source: o.ttAdapter(), displayKey: "name", templates: { header: '

Suggested Recipes

', suggestion: e.template(i) } }).on("typeahead:selected", function(e, n) { n.id ? window.location = s + "/recipes/" + n.id : t("#nyt-cooking-search-form").submit() }) } }); return o }), n("recipe_search/search-nyt4", ["recipe_search/search"], function(t) { return t }), window["recipe_search/search-nyt4"] = e("recipe_search/search-nyt4"), window.$ = window.jqueryNytCapture }();

© 2014-2017 Read news. All Rights Reserved. 975.09 kB of 10 MB used, 222 of unlimited files used, cache missed 0 time(s) NC Version 1.1.5