ucb_rails_user 6.1.1 → 6.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,953 @@
1
+ /*!
2
+ * typeahead.js 1.3.3
3
+ * https://github.com/corejavascript/typeahead.js
4
+ * Copyright 2013-2024 Twitter, Inc. and other contributors; Licensed MIT
5
+ */
6
+
7
+ /* hacked on by Darin Wilson to make it more ESM-friendly */
8
+
9
+ var VERSION = "1.3.3";
10
+
11
+ var _ = function() {
12
+ "use strict";
13
+ return {
14
+ isMsie: function() {
15
+ return /(msie|trident)/i.test(navigator.userAgent) ? navigator.userAgent.match(/(msie |rv:)(\d+(.\d+)?)/i)[2] : false;
16
+ },
17
+ isBlankString: function(str) {
18
+ return !str || /^\s*$/.test(str);
19
+ },
20
+ escapeRegExChars: function(str) {
21
+ return str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&");
22
+ },
23
+ isString: function(obj) {
24
+ return typeof obj === "string";
25
+ },
26
+ isNumber: function(obj) {
27
+ return typeof obj === "number";
28
+ },
29
+ isArray: $.isArray,
30
+ isFunction: $.isFunction,
31
+ isObject: $.isPlainObject,
32
+ isUndefined: function(obj) {
33
+ return typeof obj === "undefined";
34
+ },
35
+ isElement: function(obj) {
36
+ return !!(obj && obj.nodeType === 1);
37
+ },
38
+ isJQuery: function(obj) {
39
+ return obj instanceof $;
40
+ },
41
+ toStr: function toStr(s) {
42
+ return _.isUndefined(s) || s === null ? "" : s + "";
43
+ },
44
+ bind: $.proxy,
45
+ each: function(collection, cb) {
46
+ $.each(collection, reverseArgs);
47
+ function reverseArgs(index, value) {
48
+ return cb(value, index);
49
+ }
50
+ },
51
+ map: $.map,
52
+ filter: $.grep,
53
+ every: function(obj, test) {
54
+ var result = true;
55
+ if (!obj) {
56
+ return result;
57
+ }
58
+ $.each(obj, function(key, val) {
59
+ if (!(result = test.call(null, val, key, obj))) {
60
+ return false;
61
+ }
62
+ });
63
+ return !!result;
64
+ },
65
+ some: function(obj, test) {
66
+ var result = false;
67
+ if (!obj) {
68
+ return result;
69
+ }
70
+ $.each(obj, function(key, val) {
71
+ if (result = test.call(null, val, key, obj)) {
72
+ return false;
73
+ }
74
+ });
75
+ return !!result;
76
+ },
77
+ mixin: $.extend,
78
+ identity: function(x) {
79
+ return x;
80
+ },
81
+ clone: function(obj) {
82
+ return $.extend(true, {}, obj);
83
+ },
84
+ getIdGenerator: function() {
85
+ var counter = 0;
86
+ return function() {
87
+ return counter++;
88
+ };
89
+ },
90
+ templatify: function templatify(obj) {
91
+ return $.isFunction(obj) ? obj : template;
92
+ function template() {
93
+ return String(obj);
94
+ }
95
+ },
96
+ defer: function(fn) {
97
+ setTimeout(fn, 0);
98
+ },
99
+ debounce: function(func, wait, immediate) {
100
+ var timeout, result;
101
+ return function() {
102
+ var context = this, args = arguments, later, callNow;
103
+ later = function() {
104
+ timeout = null;
105
+ if (!immediate) {
106
+ result = func.apply(context, args);
107
+ }
108
+ };
109
+ callNow = immediate && !timeout;
110
+ clearTimeout(timeout);
111
+ timeout = setTimeout(later, wait);
112
+ if (callNow) {
113
+ result = func.apply(context, args);
114
+ }
115
+ return result;
116
+ };
117
+ },
118
+ throttle: function(func, wait) {
119
+ var context, args, timeout, result, previous, later;
120
+ previous = 0;
121
+ later = function() {
122
+ previous = new Date();
123
+ timeout = null;
124
+ result = func.apply(context, args);
125
+ };
126
+ return function() {
127
+ var now = new Date(), remaining = wait - (now - previous);
128
+ context = this;
129
+ args = arguments;
130
+ if (remaining <= 0) {
131
+ clearTimeout(timeout);
132
+ timeout = null;
133
+ previous = now;
134
+ result = func.apply(context, args);
135
+ } else if (!timeout) {
136
+ timeout = setTimeout(later, remaining);
137
+ }
138
+ return result;
139
+ };
140
+ },
141
+ stringify: function(val) {
142
+ return _.isString(val) ? val : JSON.stringify(val);
143
+ },
144
+ guid: function() {
145
+ function _p8(s) {
146
+ var p = (Math.random().toString(16) + "000000000").substr(2, 8);
147
+ return s ? "-" + p.substr(0, 4) + "-" + p.substr(4, 4) : p;
148
+ }
149
+ return "tt-" + _p8() + _p8(true) + _p8(true) + _p8();
150
+ },
151
+ noop: function() {}
152
+ };
153
+ }();
154
+
155
+ var tokenizers = function() {
156
+ "use strict";
157
+ return {
158
+ nonword: nonword,
159
+ whitespace: whitespace,
160
+ ngram: ngram,
161
+ obj: {
162
+ nonword: getObjTokenizer(nonword),
163
+ whitespace: getObjTokenizer(whitespace),
164
+ ngram: getObjTokenizer(ngram)
165
+ }
166
+ };
167
+ function whitespace(str) {
168
+ str = _.toStr(str);
169
+ return str ? str.split(/\s+/) : [];
170
+ }
171
+ function nonword(str) {
172
+ str = _.toStr(str);
173
+ return str ? str.split(/\W+/) : [];
174
+ }
175
+ function ngram(str) {
176
+ str = _.toStr(str);
177
+ var tokens = [], word = "";
178
+ _.each(str.split(""), function(char) {
179
+ if (char.match(/\s+/)) {
180
+ word = "";
181
+ } else {
182
+ tokens.push(word + char);
183
+ word += char;
184
+ }
185
+ });
186
+ return tokens;
187
+ }
188
+ function getObjTokenizer(tokenizer) {
189
+ return function setKey(keys) {
190
+ keys = _.isArray(keys) ? keys : [].slice.call(arguments, 0);
191
+ return function tokenize(o) {
192
+ var tokens = [];
193
+ _.each(keys, function(k) {
194
+ tokens = tokens.concat(tokenizer(_.toStr(o[k])));
195
+ });
196
+ return tokens;
197
+ };
198
+ };
199
+ }
200
+ }();
201
+
202
+ var LruCache = function() {
203
+ "use strict";
204
+ function LruCache(maxSize) {
205
+ this.maxSize = _.isNumber(maxSize) ? maxSize : 100;
206
+ this.reset();
207
+ if (this.maxSize <= 0) {
208
+ this.set = this.get = $.noop;
209
+ }
210
+ }
211
+ _.mixin(LruCache.prototype, {
212
+ set: function set(key, val) {
213
+ var tailItem = this.list.tail, node;
214
+ if (this.size >= this.maxSize) {
215
+ this.list.remove(tailItem);
216
+ delete this.hash[tailItem.key];
217
+ this.size--;
218
+ }
219
+ if (node = this.hash[key]) {
220
+ node.val = val;
221
+ this.list.moveToFront(node);
222
+ } else {
223
+ node = new Node(key, val);
224
+ this.list.add(node);
225
+ this.hash[key] = node;
226
+ this.size++;
227
+ }
228
+ },
229
+ get: function get(key) {
230
+ var node = this.hash[key];
231
+ if (node) {
232
+ this.list.moveToFront(node);
233
+ return node.val;
234
+ }
235
+ },
236
+ reset: function reset() {
237
+ this.size = 0;
238
+ this.hash = {};
239
+ this.list = new List();
240
+ }
241
+ });
242
+ function List() {
243
+ this.head = this.tail = null;
244
+ }
245
+ _.mixin(List.prototype, {
246
+ add: function add(node) {
247
+ if (this.head) {
248
+ node.next = this.head;
249
+ this.head.prev = node;
250
+ }
251
+ this.head = node;
252
+ this.tail = this.tail || node;
253
+ },
254
+ remove: function remove(node) {
255
+ node.prev ? node.prev.next = node.next : this.head = node.next;
256
+ node.next ? node.next.prev = node.prev : this.tail = node.prev;
257
+ },
258
+ moveToFront: function(node) {
259
+ this.remove(node);
260
+ this.add(node);
261
+ }
262
+ });
263
+ function Node(key, val) {
264
+ this.key = key;
265
+ this.val = val;
266
+ this.prev = this.next = null;
267
+ }
268
+ return LruCache;
269
+ }();
270
+
271
+ var PersistentStorage = function() {
272
+ "use strict";
273
+ var LOCAL_STORAGE;
274
+ try {
275
+ LOCAL_STORAGE = window.localStorage;
276
+ LOCAL_STORAGE.setItem("~~~", "!");
277
+ LOCAL_STORAGE.removeItem("~~~");
278
+ } catch (err) {
279
+ LOCAL_STORAGE = null;
280
+ }
281
+ function PersistentStorage(namespace, override) {
282
+ this.prefix = [ "__", namespace, "__" ].join("");
283
+ this.ttlKey = "__ttl__";
284
+ this.keyMatcher = new RegExp("^" + _.escapeRegExChars(this.prefix));
285
+ this.ls = override || LOCAL_STORAGE;
286
+ !this.ls && this._noop();
287
+ }
288
+ _.mixin(PersistentStorage.prototype, {
289
+ _prefix: function(key) {
290
+ return this.prefix + key;
291
+ },
292
+ _ttlKey: function(key) {
293
+ return this._prefix(key) + this.ttlKey;
294
+ },
295
+ _noop: function() {
296
+ this.get = this.set = this.remove = this.clear = this.isExpired = _.noop;
297
+ },
298
+ _safeSet: function(key, val) {
299
+ try {
300
+ this.ls.setItem(key, val);
301
+ } catch (err) {
302
+ if (err.name === "QuotaExceededError") {
303
+ this.clear();
304
+ this._noop();
305
+ }
306
+ }
307
+ },
308
+ get: function(key) {
309
+ if (this.isExpired(key)) {
310
+ this.remove(key);
311
+ }
312
+ return decode(this.ls.getItem(this._prefix(key)));
313
+ },
314
+ set: function(key, val, ttl) {
315
+ if (_.isNumber(ttl)) {
316
+ this._safeSet(this._ttlKey(key), encode(now() + ttl));
317
+ } else {
318
+ this.ls.removeItem(this._ttlKey(key));
319
+ }
320
+ return this._safeSet(this._prefix(key), encode(val));
321
+ },
322
+ remove: function(key) {
323
+ this.ls.removeItem(this._ttlKey(key));
324
+ this.ls.removeItem(this._prefix(key));
325
+ return this;
326
+ },
327
+ clear: function() {
328
+ var i, keys = gatherMatchingKeys(this.keyMatcher);
329
+ for (i = keys.length; i--; ) {
330
+ this.remove(keys[i]);
331
+ }
332
+ return this;
333
+ },
334
+ isExpired: function(key) {
335
+ var ttl = decode(this.ls.getItem(this._ttlKey(key)));
336
+ return _.isNumber(ttl) && now() > ttl ? true : false;
337
+ }
338
+ });
339
+ return PersistentStorage;
340
+ function now() {
341
+ return new Date().getTime();
342
+ }
343
+ function encode(val) {
344
+ return JSON.stringify(_.isUndefined(val) ? null : val);
345
+ }
346
+ function decode(val) {
347
+ return $.parseJSON(val);
348
+ }
349
+ function gatherMatchingKeys(keyMatcher) {
350
+ var i, key, keys = [], len = LOCAL_STORAGE.length;
351
+ for (i = 0; i < len; i++) {
352
+ if ((key = LOCAL_STORAGE.key(i)).match(keyMatcher)) {
353
+ keys.push(key.replace(keyMatcher, ""));
354
+ }
355
+ }
356
+ return keys;
357
+ }
358
+ }();
359
+
360
+ var Transport = function() {
361
+ "use strict";
362
+ var pendingRequestsCount = 0, pendingRequests = {}, sharedCache = new LruCache(10);
363
+ function Transport(o) {
364
+ o = o || {};
365
+ this.maxPendingRequests = o.maxPendingRequests || 6;
366
+ this.cancelled = false;
367
+ this.lastReq = null;
368
+ this._send = o.transport;
369
+ this._get = o.limiter ? o.limiter(this._get) : this._get;
370
+ this._cache = o.cache === false ? new LruCache(0) : sharedCache;
371
+ }
372
+ Transport.setMaxPendingRequests = function setMaxPendingRequests(num) {
373
+ this.maxPendingRequests = num;
374
+ };
375
+ Transport.resetCache = function resetCache() {
376
+ sharedCache.reset();
377
+ };
378
+ _.mixin(Transport.prototype, {
379
+ _fingerprint: function fingerprint(o) {
380
+ o = o || {};
381
+ return o.url + o.type + $.param(o.data || {});
382
+ },
383
+ _get: function(o, cb) {
384
+ var that = this, fingerprint, jqXhr;
385
+ fingerprint = this._fingerprint(o);
386
+ if (this.cancelled || fingerprint !== this.lastReq) {
387
+ return;
388
+ }
389
+ if (jqXhr = pendingRequests[fingerprint]) {
390
+ jqXhr.done(done).fail(fail);
391
+ } else if (pendingRequestsCount < this.maxPendingRequests) {
392
+ pendingRequestsCount++;
393
+ pendingRequests[fingerprint] = this._send(o).done(done).fail(fail).always(always);
394
+ } else {
395
+ this.onDeckRequestArgs = [].slice.call(arguments, 0);
396
+ }
397
+ function done(resp) {
398
+ cb(null, resp);
399
+ that._cache.set(fingerprint, resp);
400
+ }
401
+ function fail() {
402
+ cb(true);
403
+ }
404
+ function always() {
405
+ pendingRequestsCount--;
406
+ delete pendingRequests[fingerprint];
407
+ if (that.onDeckRequestArgs) {
408
+ that._get.apply(that, that.onDeckRequestArgs);
409
+ that.onDeckRequestArgs = null;
410
+ }
411
+ }
412
+ },
413
+ get: function(o, cb) {
414
+ var resp, fingerprint;
415
+ cb = cb || $.noop;
416
+ o = _.isString(o) ? {
417
+ url: o
418
+ } : o || {};
419
+ fingerprint = this._fingerprint(o);
420
+ this.cancelled = false;
421
+ this.lastReq = fingerprint;
422
+ if (resp = this._cache.get(fingerprint)) {
423
+ cb(null, resp);
424
+ } else {
425
+ this._get(o, cb);
426
+ }
427
+ },
428
+ cancel: function() {
429
+ this.cancelled = true;
430
+ }
431
+ });
432
+ return Transport;
433
+ }();
434
+
435
+ var SearchIndex = window.SearchIndex = function() {
436
+ "use strict";
437
+ var CHILDREN = "c", IDS = "i";
438
+ function SearchIndex(o) {
439
+ o = o || {};
440
+ if (!o.datumTokenizer || !o.queryTokenizer) {
441
+ $.error("datumTokenizer and queryTokenizer are both required");
442
+ }
443
+ this.identify = o.identify || _.stringify;
444
+ this.datumTokenizer = o.datumTokenizer;
445
+ this.queryTokenizer = o.queryTokenizer;
446
+ this.matchAnyQueryToken = o.matchAnyQueryToken;
447
+ this.reset();
448
+ }
449
+ _.mixin(SearchIndex.prototype, {
450
+ bootstrap: function bootstrap(o) {
451
+ this.datums = o.datums;
452
+ this.trie = o.trie;
453
+ },
454
+ add: function(data) {
455
+ var that = this;
456
+ data = _.isArray(data) ? data : [ data ];
457
+ _.each(data, function(datum) {
458
+ var id, tokens;
459
+ that.datums[id = that.identify(datum)] = datum;
460
+ tokens = normalizeTokens(that.datumTokenizer(datum));
461
+ _.each(tokens, function(token) {
462
+ var node, chars, ch;
463
+ node = that.trie;
464
+ chars = token.split("");
465
+ while (ch = chars.shift()) {
466
+ node = node[CHILDREN][ch] || (node[CHILDREN][ch] = newNode());
467
+ node[IDS].push(id);
468
+ }
469
+ });
470
+ });
471
+ },
472
+ get: function get(ids) {
473
+ var that = this;
474
+ return _.map(ids, function(id) {
475
+ return that.datums[id];
476
+ });
477
+ },
478
+ search: function search(query) {
479
+ var that = this, tokens, matches;
480
+ tokens = normalizeTokens(this.queryTokenizer(query));
481
+ _.each(tokens, function(token) {
482
+ var node, chars, ch, ids;
483
+ if (matches && matches.length === 0 && !that.matchAnyQueryToken) {
484
+ return false;
485
+ }
486
+ node = that.trie;
487
+ chars = token.split("");
488
+ while (node && (ch = chars.shift())) {
489
+ node = node[CHILDREN][ch];
490
+ }
491
+ if (node && chars.length === 0) {
492
+ ids = node[IDS].slice(0);
493
+ matches = matches ? getIntersection(matches, ids) : ids;
494
+ } else {
495
+ if (!that.matchAnyQueryToken) {
496
+ matches = [];
497
+ return false;
498
+ }
499
+ }
500
+ });
501
+ return matches ? _.map(unique(matches), function(id) {
502
+ return that.datums[id];
503
+ }) : [];
504
+ },
505
+ all: function all() {
506
+ var values = [];
507
+ for (var key in this.datums) {
508
+ values.push(this.datums[key]);
509
+ }
510
+ return values;
511
+ },
512
+ reset: function reset() {
513
+ this.datums = {};
514
+ this.trie = newNode();
515
+ },
516
+ serialize: function serialize() {
517
+ return {
518
+ datums: this.datums,
519
+ trie: this.trie
520
+ };
521
+ }
522
+ });
523
+ return SearchIndex;
524
+ function normalizeTokens(tokens) {
525
+ tokens = _.filter(tokens, function(token) {
526
+ return !!token;
527
+ });
528
+ tokens = _.map(tokens, function(token) {
529
+ return token.toLowerCase();
530
+ });
531
+ return tokens;
532
+ }
533
+ function newNode() {
534
+ var node = {};
535
+ node[IDS] = [];
536
+ node[CHILDREN] = {};
537
+ return node;
538
+ }
539
+ function unique(array) {
540
+ var seen = {}, uniques = [];
541
+ for (var i = 0, len = array.length; i < len; i++) {
542
+ if (!seen[array[i]]) {
543
+ seen[array[i]] = true;
544
+ uniques.push(array[i]);
545
+ }
546
+ }
547
+ return uniques;
548
+ }
549
+ function getIntersection(arrayA, arrayB) {
550
+ var ai = 0, bi = 0, intersection = [];
551
+ arrayA = arrayA.sort();
552
+ arrayB = arrayB.sort();
553
+ var lenArrayA = arrayA.length, lenArrayB = arrayB.length;
554
+ while (ai < lenArrayA && bi < lenArrayB) {
555
+ if (arrayA[ai] < arrayB[bi]) {
556
+ ai++;
557
+ } else if (arrayA[ai] > arrayB[bi]) {
558
+ bi++;
559
+ } else {
560
+ intersection.push(arrayA[ai]);
561
+ ai++;
562
+ bi++;
563
+ }
564
+ }
565
+ return intersection;
566
+ }
567
+ }();
568
+
569
+ var Prefetch = function() {
570
+ "use strict";
571
+ var keys;
572
+ keys = {
573
+ data: "data",
574
+ protocol: "protocol",
575
+ thumbprint: "thumbprint"
576
+ };
577
+ function Prefetch(o) {
578
+ this.url = o.url;
579
+ this.ttl = o.ttl;
580
+ this.cache = o.cache;
581
+ this.prepare = o.prepare;
582
+ this.transform = o.transform;
583
+ this.transport = o.transport;
584
+ this.thumbprint = o.thumbprint;
585
+ this.storage = new PersistentStorage(o.cacheKey);
586
+ }
587
+ _.mixin(Prefetch.prototype, {
588
+ _settings: function settings() {
589
+ return {
590
+ url: this.url,
591
+ type: "GET",
592
+ dataType: "json"
593
+ };
594
+ },
595
+ store: function store(data) {
596
+ if (!this.cache) {
597
+ return;
598
+ }
599
+ this.storage.set(keys.data, data, this.ttl);
600
+ this.storage.set(keys.protocol, location.protocol, this.ttl);
601
+ this.storage.set(keys.thumbprint, this.thumbprint, this.ttl);
602
+ },
603
+ fromCache: function fromCache() {
604
+ var stored = {}, isExpired;
605
+ if (!this.cache) {
606
+ return null;
607
+ }
608
+ stored.data = this.storage.get(keys.data);
609
+ stored.protocol = this.storage.get(keys.protocol);
610
+ stored.thumbprint = this.storage.get(keys.thumbprint);
611
+ isExpired = stored.thumbprint !== this.thumbprint || stored.protocol !== location.protocol;
612
+ return stored.data && !isExpired ? stored.data : null;
613
+ },
614
+ fromNetwork: function(cb) {
615
+ var that = this, settings;
616
+ if (!cb) {
617
+ return;
618
+ }
619
+ settings = this.prepare(this._settings());
620
+ this.transport(settings).fail(onError).done(onResponse);
621
+ function onError() {
622
+ cb(true);
623
+ }
624
+ function onResponse(resp) {
625
+ cb(null, that.transform(resp));
626
+ }
627
+ },
628
+ clear: function clear() {
629
+ this.storage.clear();
630
+ return this;
631
+ }
632
+ });
633
+ return Prefetch;
634
+ }();
635
+
636
+ var Remote = function() {
637
+ "use strict";
638
+ function Remote(o) {
639
+ this.url = o.url;
640
+ this.prepare = o.prepare;
641
+ this.transform = o.transform;
642
+ this.indexResponse = o.indexResponse;
643
+ this.transport = new Transport({
644
+ cache: o.cache,
645
+ limiter: o.limiter,
646
+ transport: o.transport,
647
+ maxPendingRequests: o.maxPendingRequests
648
+ });
649
+ }
650
+ _.mixin(Remote.prototype, {
651
+ _settings: function settings() {
652
+ return {
653
+ url: this.url,
654
+ type: "GET",
655
+ dataType: "json"
656
+ };
657
+ },
658
+ get: function get(query, cb) {
659
+ var that = this, settings;
660
+ if (!cb) {
661
+ return;
662
+ }
663
+ query = query || "";
664
+ settings = this.prepare(query, this._settings());
665
+ return this.transport.get(settings, onResponse);
666
+ function onResponse(err, resp) {
667
+ err ? cb([]) : cb(that.transform(resp));
668
+ }
669
+ },
670
+ cancelLastRequest: function cancelLastRequest() {
671
+ this.transport.cancel();
672
+ }
673
+ });
674
+ return Remote;
675
+ }();
676
+
677
+ var oParser = function() {
678
+ "use strict";
679
+ return function parse(o) {
680
+ var defaults, sorter;
681
+ defaults = {
682
+ initialize: true,
683
+ identify: _.stringify,
684
+ datumTokenizer: null,
685
+ queryTokenizer: null,
686
+ matchAnyQueryToken: false,
687
+ sufficient: 5,
688
+ indexRemote: false,
689
+ sorter: null,
690
+ local: [],
691
+ prefetch: null,
692
+ remote: null
693
+ };
694
+ o = _.mixin(defaults, o || {});
695
+ !o.datumTokenizer && $.error("datumTokenizer is required");
696
+ !o.queryTokenizer && $.error("queryTokenizer is required");
697
+ sorter = o.sorter;
698
+ o.sorter = sorter ? function(x) {
699
+ return x.sort(sorter);
700
+ } : _.identity;
701
+ o.local = _.isFunction(o.local) ? o.local() : o.local;
702
+ o.prefetch = parsePrefetch(o.prefetch);
703
+ o.remote = parseRemote(o.remote);
704
+ return o;
705
+ };
706
+ function parsePrefetch(o) {
707
+ var defaults;
708
+ if (!o) {
709
+ return null;
710
+ }
711
+ defaults = {
712
+ url: null,
713
+ ttl: 24 * 60 * 60 * 1e3,
714
+ cache: true,
715
+ cacheKey: null,
716
+ thumbprint: "",
717
+ prepare: _.identity,
718
+ transform: _.identity,
719
+ transport: null
720
+ };
721
+ o = _.isString(o) ? {
722
+ url: o
723
+ } : o;
724
+ o = _.mixin(defaults, o);
725
+ !o.url && $.error("prefetch requires url to be set");
726
+ o.transform = o.filter || o.transform;
727
+ o.cacheKey = o.cacheKey || o.url;
728
+ o.thumbprint = VERSION + o.thumbprint;
729
+ o.transport = o.transport ? callbackToDeferred(o.transport) : $.ajax;
730
+ return o;
731
+ }
732
+ function parseRemote(o) {
733
+ var defaults;
734
+ if (!o) {
735
+ return;
736
+ }
737
+ defaults = {
738
+ url: null,
739
+ cache: true,
740
+ prepare: null,
741
+ replace: null,
742
+ wildcard: null,
743
+ limiter: null,
744
+ rateLimitBy: "debounce",
745
+ rateLimitWait: 300,
746
+ transform: _.identity,
747
+ transport: null
748
+ };
749
+ o = _.isString(o) ? {
750
+ url: o
751
+ } : o;
752
+ o = _.mixin(defaults, o);
753
+ !o.url && $.error("remote requires url to be set");
754
+ o.transform = o.filter || o.transform;
755
+ o.prepare = toRemotePrepare(o);
756
+ o.limiter = toLimiter(o);
757
+ o.transport = o.transport ? callbackToDeferred(o.transport) : $.ajax;
758
+ delete o.replace;
759
+ delete o.wildcard;
760
+ delete o.rateLimitBy;
761
+ delete o.rateLimitWait;
762
+ return o;
763
+ }
764
+ function toRemotePrepare(o) {
765
+ var prepare, replace, wildcard;
766
+ prepare = o.prepare;
767
+ replace = o.replace;
768
+ wildcard = o.wildcard;
769
+ if (prepare) {
770
+ return prepare;
771
+ }
772
+ if (replace) {
773
+ prepare = prepareByReplace;
774
+ } else if (o.wildcard) {
775
+ prepare = prepareByWildcard;
776
+ } else {
777
+ prepare = identityPrepare;
778
+ }
779
+ return prepare;
780
+ function prepareByReplace(query, settings) {
781
+ settings.url = replace(settings.url, query);
782
+ return settings;
783
+ }
784
+ function prepareByWildcard(query, settings) {
785
+ settings.url = settings.url.replace(wildcard, encodeURIComponent(query));
786
+ return settings;
787
+ }
788
+ function identityPrepare(query, settings) {
789
+ return settings;
790
+ }
791
+ }
792
+ function toLimiter(o) {
793
+ var limiter, method, wait;
794
+ limiter = o.limiter;
795
+ method = o.rateLimitBy;
796
+ wait = o.rateLimitWait;
797
+ if (!limiter) {
798
+ limiter = /^throttle$/i.test(method) ? throttle(wait) : debounce(wait);
799
+ }
800
+ return limiter;
801
+ function debounce(wait) {
802
+ return function debounce(fn) {
803
+ return _.debounce(fn, wait);
804
+ };
805
+ }
806
+ function throttle(wait) {
807
+ return function throttle(fn) {
808
+ return _.throttle(fn, wait);
809
+ };
810
+ }
811
+ }
812
+ function callbackToDeferred(fn) {
813
+ return function wrapper(o) {
814
+ var deferred = $.Deferred();
815
+ fn(o, onSuccess, onError);
816
+ return deferred;
817
+ function onSuccess(resp) {
818
+ _.defer(function() {
819
+ deferred.resolve(resp);
820
+ });
821
+ }
822
+ function onError(err) {
823
+ _.defer(function() {
824
+ deferred.reject(err);
825
+ });
826
+ }
827
+ };
828
+ }
829
+ }();
830
+
831
+ var Bloodhound = function() {
832
+ "use strict";
833
+ var old;
834
+ old = window && window.Bloodhound;
835
+ function Bloodhound(o) {
836
+ o = oParser(o);
837
+ this.sorter = o.sorter;
838
+ this.identify = o.identify;
839
+ this.sufficient = o.sufficient;
840
+ this.indexRemote = o.indexRemote;
841
+ this.local = o.local;
842
+ this.remote = o.remote ? new Remote(o.remote) : null;
843
+ this.prefetch = o.prefetch ? new Prefetch(o.prefetch) : null;
844
+ this.index = new SearchIndex({
845
+ identify: this.identify,
846
+ datumTokenizer: o.datumTokenizer,
847
+ queryTokenizer: o.queryTokenizer
848
+ });
849
+ o.initialize !== false && this.initialize();
850
+ }
851
+ Bloodhound.noConflict = function noConflict() {
852
+ window && (window.Bloodhound = old);
853
+ return Bloodhound;
854
+ };
855
+ Bloodhound.tokenizers = tokenizers;
856
+ _.mixin(Bloodhound.prototype, {
857
+ __ttAdapter: function ttAdapter() {
858
+ var that = this;
859
+ return this.remote ? withAsync : withoutAsync;
860
+ function withAsync(query, sync, async) {
861
+ return that.search(query, sync, async);
862
+ }
863
+ function withoutAsync(query, sync) {
864
+ return that.search(query, sync);
865
+ }
866
+ },
867
+ _loadPrefetch: function loadPrefetch() {
868
+ var that = this, deferred, serialized;
869
+ deferred = $.Deferred();
870
+ if (!this.prefetch) {
871
+ deferred.resolve();
872
+ } else if (serialized = this.prefetch.fromCache()) {
873
+ this.index.bootstrap(serialized);
874
+ deferred.resolve();
875
+ } else {
876
+ this.prefetch.fromNetwork(done);
877
+ }
878
+ return deferred.promise();
879
+ function done(err, data) {
880
+ if (err) {
881
+ return deferred.reject();
882
+ }
883
+ that.add(data);
884
+ that.prefetch.store(that.index.serialize());
885
+ deferred.resolve();
886
+ }
887
+ },
888
+ _initialize: function initialize() {
889
+ var that = this, deferred;
890
+ this.clear();
891
+ (this.initPromise = this._loadPrefetch()).done(addLocalToIndex);
892
+ return this.initPromise;
893
+ function addLocalToIndex() {
894
+ that.add(that.local);
895
+ }
896
+ },
897
+ initialize: function initialize(force) {
898
+ return !this.initPromise || force ? this._initialize() : this.initPromise;
899
+ },
900
+ add: function add(data) {
901
+ this.index.add(data);
902
+ return this;
903
+ },
904
+ get: function get(ids) {
905
+ ids = _.isArray(ids) ? ids : [].slice.call(arguments);
906
+ return this.index.get(ids);
907
+ },
908
+ search: function search(query, sync, async) {
909
+ var that = this, local;
910
+ sync = sync || _.noop;
911
+ async = async || _.noop;
912
+ local = this.sorter(this.index.search(query));
913
+ sync(this.remote ? local.slice() : local);
914
+ if (this.remote && local.length < this.sufficient) {
915
+ this.remote.get(query, processRemote);
916
+ } else if (this.remote) {
917
+ this.remote.cancelLastRequest();
918
+ }
919
+ return this;
920
+ function processRemote(remote) {
921
+ var nonDuplicates = [];
922
+ _.each(remote, function(r) {
923
+ !_.some(local, function(l) {
924
+ return that.identify(r) === that.identify(l);
925
+ }) && nonDuplicates.push(r);
926
+ });
927
+ that.indexRemote && that.add(nonDuplicates);
928
+ async(nonDuplicates);
929
+ }
930
+ },
931
+ all: function all() {
932
+ return this.index.all();
933
+ },
934
+ clear: function clear() {
935
+ this.index.reset();
936
+ return this;
937
+ },
938
+ clearPrefetchCache: function clearPrefetchCache() {
939
+ this.prefetch && this.prefetch.clear();
940
+ return this;
941
+ },
942
+ clearRemoteCache: function clearRemoteCache() {
943
+ Transport.resetCache();
944
+ return this;
945
+ },
946
+ ttAdapter: function ttAdapter() {
947
+ return this.__ttAdapter();
948
+ }
949
+ });
950
+ return Bloodhound;
951
+ }();
952
+
953
+ export default Bloodhound;