venue-js 1.4.0-next.5 → 1.4.0-next.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.mts +19 -8
- package/dist/index.d.ts +19 -8
- package/dist/index.js +1399 -7
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1406 -14
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -452,8 +452,8 @@ var createPopulator = ({
|
|
|
452
452
|
anchor_id,
|
|
453
453
|
venue_id,
|
|
454
454
|
local_category_ids,
|
|
455
|
-
promotion_ids,
|
|
456
|
-
privilege_ids,
|
|
455
|
+
promotion_ids = [],
|
|
456
|
+
privilege_ids = [],
|
|
457
457
|
kiosk_id,
|
|
458
458
|
unit_id,
|
|
459
459
|
kiosk_ids = [],
|
|
@@ -550,6 +550,20 @@ var createPopulator = ({
|
|
|
550
550
|
}
|
|
551
551
|
};
|
|
552
552
|
};
|
|
553
|
+
const populateModel3D = async (model3d) => {
|
|
554
|
+
const level = await internalFindById(model3d.properties.level_id);
|
|
555
|
+
try {
|
|
556
|
+
return {
|
|
557
|
+
...model3d,
|
|
558
|
+
properties: {
|
|
559
|
+
...model3d.properties,
|
|
560
|
+
level: await populateLevel(level)
|
|
561
|
+
}
|
|
562
|
+
};
|
|
563
|
+
} catch (err) {
|
|
564
|
+
console.log(`error finding level`, { model3d, level });
|
|
565
|
+
}
|
|
566
|
+
};
|
|
553
567
|
const populateFeature = (feature2) => Promise.resolve(feature2);
|
|
554
568
|
return {
|
|
555
569
|
address: populateAddress,
|
|
@@ -574,12 +588,1378 @@ var createPopulator = ({
|
|
|
574
588
|
section: populateSection,
|
|
575
589
|
unit: populateUnit,
|
|
576
590
|
venue: populateVenue,
|
|
577
|
-
taxonomy: populateTaxonomy
|
|
591
|
+
taxonomy: populateTaxonomy,
|
|
592
|
+
model3d: populateModel3D
|
|
593
|
+
};
|
|
594
|
+
};
|
|
595
|
+
|
|
596
|
+
// ../../node_modules/fuse.js/dist/fuse.mjs
|
|
597
|
+
function isArray(value) {
|
|
598
|
+
return !Array.isArray ? getTag(value) === "[object Array]" : Array.isArray(value);
|
|
599
|
+
}
|
|
600
|
+
var INFINITY = 1 / 0;
|
|
601
|
+
function baseToString(value) {
|
|
602
|
+
if (typeof value == "string") {
|
|
603
|
+
return value;
|
|
604
|
+
}
|
|
605
|
+
let result = value + "";
|
|
606
|
+
return result == "0" && 1 / value == -INFINITY ? "-0" : result;
|
|
607
|
+
}
|
|
608
|
+
function toString(value) {
|
|
609
|
+
return value == null ? "" : baseToString(value);
|
|
610
|
+
}
|
|
611
|
+
function isString(value) {
|
|
612
|
+
return typeof value === "string";
|
|
613
|
+
}
|
|
614
|
+
function isNumber(value) {
|
|
615
|
+
return typeof value === "number";
|
|
616
|
+
}
|
|
617
|
+
function isBoolean(value) {
|
|
618
|
+
return value === true || value === false || isObjectLike(value) && getTag(value) == "[object Boolean]";
|
|
619
|
+
}
|
|
620
|
+
function isObject(value) {
|
|
621
|
+
return typeof value === "object";
|
|
622
|
+
}
|
|
623
|
+
function isObjectLike(value) {
|
|
624
|
+
return isObject(value) && value !== null;
|
|
625
|
+
}
|
|
626
|
+
function isDefined(value) {
|
|
627
|
+
return value !== void 0 && value !== null;
|
|
628
|
+
}
|
|
629
|
+
function isBlank(value) {
|
|
630
|
+
return !value.trim().length;
|
|
631
|
+
}
|
|
632
|
+
function getTag(value) {
|
|
633
|
+
return value == null ? value === void 0 ? "[object Undefined]" : "[object Null]" : Object.prototype.toString.call(value);
|
|
634
|
+
}
|
|
635
|
+
var INCORRECT_INDEX_TYPE = "Incorrect 'index' type";
|
|
636
|
+
var LOGICAL_SEARCH_INVALID_QUERY_FOR_KEY = (key) => `Invalid value for key ${key}`;
|
|
637
|
+
var PATTERN_LENGTH_TOO_LARGE = (max2) => `Pattern length exceeds max of ${max2}.`;
|
|
638
|
+
var MISSING_KEY_PROPERTY = (name) => `Missing ${name} property in key`;
|
|
639
|
+
var INVALID_KEY_WEIGHT_VALUE = (key) => `Property 'weight' in key '${key}' must be a positive integer`;
|
|
640
|
+
var hasOwn = Object.prototype.hasOwnProperty;
|
|
641
|
+
var KeyStore = class {
|
|
642
|
+
constructor(keys) {
|
|
643
|
+
this._keys = [];
|
|
644
|
+
this._keyMap = {};
|
|
645
|
+
let totalWeight = 0;
|
|
646
|
+
keys.forEach((key) => {
|
|
647
|
+
let obj = createKey(key);
|
|
648
|
+
this._keys.push(obj);
|
|
649
|
+
this._keyMap[obj.id] = obj;
|
|
650
|
+
totalWeight += obj.weight;
|
|
651
|
+
});
|
|
652
|
+
this._keys.forEach((key) => {
|
|
653
|
+
key.weight /= totalWeight;
|
|
654
|
+
});
|
|
655
|
+
}
|
|
656
|
+
get(keyId) {
|
|
657
|
+
return this._keyMap[keyId];
|
|
658
|
+
}
|
|
659
|
+
keys() {
|
|
660
|
+
return this._keys;
|
|
661
|
+
}
|
|
662
|
+
toJSON() {
|
|
663
|
+
return JSON.stringify(this._keys);
|
|
664
|
+
}
|
|
665
|
+
};
|
|
666
|
+
function createKey(key) {
|
|
667
|
+
let path = null;
|
|
668
|
+
let id = null;
|
|
669
|
+
let src = null;
|
|
670
|
+
let weight = 1;
|
|
671
|
+
let getFn = null;
|
|
672
|
+
if (isString(key) || isArray(key)) {
|
|
673
|
+
src = key;
|
|
674
|
+
path = createKeyPath(key);
|
|
675
|
+
id = createKeyId(key);
|
|
676
|
+
} else {
|
|
677
|
+
if (!hasOwn.call(key, "name")) {
|
|
678
|
+
throw new Error(MISSING_KEY_PROPERTY("name"));
|
|
679
|
+
}
|
|
680
|
+
const name = key.name;
|
|
681
|
+
src = name;
|
|
682
|
+
if (hasOwn.call(key, "weight")) {
|
|
683
|
+
weight = key.weight;
|
|
684
|
+
if (weight <= 0) {
|
|
685
|
+
throw new Error(INVALID_KEY_WEIGHT_VALUE(name));
|
|
686
|
+
}
|
|
687
|
+
}
|
|
688
|
+
path = createKeyPath(name);
|
|
689
|
+
id = createKeyId(name);
|
|
690
|
+
getFn = key.getFn;
|
|
691
|
+
}
|
|
692
|
+
return { path, id, weight, src, getFn };
|
|
693
|
+
}
|
|
694
|
+
function createKeyPath(key) {
|
|
695
|
+
return isArray(key) ? key : key.split(".");
|
|
696
|
+
}
|
|
697
|
+
function createKeyId(key) {
|
|
698
|
+
return isArray(key) ? key.join(".") : key;
|
|
699
|
+
}
|
|
700
|
+
function get(obj, path) {
|
|
701
|
+
let list = [];
|
|
702
|
+
let arr = false;
|
|
703
|
+
const deepGet = (obj2, path2, index) => {
|
|
704
|
+
if (!isDefined(obj2)) {
|
|
705
|
+
return;
|
|
706
|
+
}
|
|
707
|
+
if (!path2[index]) {
|
|
708
|
+
list.push(obj2);
|
|
709
|
+
} else {
|
|
710
|
+
let key = path2[index];
|
|
711
|
+
const value = obj2[key];
|
|
712
|
+
if (!isDefined(value)) {
|
|
713
|
+
return;
|
|
714
|
+
}
|
|
715
|
+
if (index === path2.length - 1 && (isString(value) || isNumber(value) || isBoolean(value))) {
|
|
716
|
+
list.push(toString(value));
|
|
717
|
+
} else if (isArray(value)) {
|
|
718
|
+
arr = true;
|
|
719
|
+
for (let i = 0, len = value.length; i < len; i += 1) {
|
|
720
|
+
deepGet(value[i], path2, index + 1);
|
|
721
|
+
}
|
|
722
|
+
} else if (path2.length) {
|
|
723
|
+
deepGet(value, path2, index + 1);
|
|
724
|
+
}
|
|
725
|
+
}
|
|
726
|
+
};
|
|
727
|
+
deepGet(obj, isString(path) ? path.split(".") : path, 0);
|
|
728
|
+
return arr ? list : list[0];
|
|
729
|
+
}
|
|
730
|
+
var MatchOptions = {
|
|
731
|
+
// Whether the matches should be included in the result set. When `true`, each record in the result
|
|
732
|
+
// set will include the indices of the matched characters.
|
|
733
|
+
// These can consequently be used for highlighting purposes.
|
|
734
|
+
includeMatches: false,
|
|
735
|
+
// When `true`, the matching function will continue to the end of a search pattern even if
|
|
736
|
+
// a perfect match has already been located in the string.
|
|
737
|
+
findAllMatches: false,
|
|
738
|
+
// Minimum number of characters that must be matched before a result is considered a match
|
|
739
|
+
minMatchCharLength: 1
|
|
740
|
+
};
|
|
741
|
+
var BasicOptions = {
|
|
742
|
+
// When `true`, the algorithm continues searching to the end of the input even if a perfect
|
|
743
|
+
// match is found before the end of the same input.
|
|
744
|
+
isCaseSensitive: false,
|
|
745
|
+
// When `true`, the algorithm will ignore diacritics (accents) in comparisons
|
|
746
|
+
ignoreDiacritics: false,
|
|
747
|
+
// When true, the matching function will continue to the end of a search pattern even if
|
|
748
|
+
includeScore: false,
|
|
749
|
+
// List of properties that will be searched. This also supports nested properties.
|
|
750
|
+
keys: [],
|
|
751
|
+
// Whether to sort the result list, by score
|
|
752
|
+
shouldSort: true,
|
|
753
|
+
// Default sort function: sort by ascending score, ascending index
|
|
754
|
+
sortFn: (a, b) => a.score === b.score ? a.idx < b.idx ? -1 : 1 : a.score < b.score ? -1 : 1
|
|
755
|
+
};
|
|
756
|
+
var FuzzyOptions = {
|
|
757
|
+
// Approximately where in the text is the pattern expected to be found?
|
|
758
|
+
location: 0,
|
|
759
|
+
// At what point does the match algorithm give up. A threshold of '0.0' requires a perfect match
|
|
760
|
+
// (of both letters and location), a threshold of '1.0' would match anything.
|
|
761
|
+
threshold: 0.6,
|
|
762
|
+
// Determines how close the match must be to the fuzzy location (specified above).
|
|
763
|
+
// An exact letter match which is 'distance' characters away from the fuzzy location
|
|
764
|
+
// would score as a complete mismatch. A distance of '0' requires the match be at
|
|
765
|
+
// the exact location specified, a threshold of '1000' would require a perfect match
|
|
766
|
+
// to be within 800 characters of the fuzzy location to be found using a 0.8 threshold.
|
|
767
|
+
distance: 100
|
|
768
|
+
};
|
|
769
|
+
var AdvancedOptions = {
|
|
770
|
+
// When `true`, it enables the use of unix-like search commands
|
|
771
|
+
useExtendedSearch: false,
|
|
772
|
+
// The get function to use when fetching an object's properties.
|
|
773
|
+
// The default will search nested paths *ie foo.bar.baz*
|
|
774
|
+
getFn: get,
|
|
775
|
+
// When `true`, search will ignore `location` and `distance`, so it won't matter
|
|
776
|
+
// where in the string the pattern appears.
|
|
777
|
+
// More info: https://fusejs.io/concepts/scoring-theory.html#fuzziness-score
|
|
778
|
+
ignoreLocation: false,
|
|
779
|
+
// When `true`, the calculation for the relevance score (used for sorting) will
|
|
780
|
+
// ignore the field-length norm.
|
|
781
|
+
// More info: https://fusejs.io/concepts/scoring-theory.html#field-length-norm
|
|
782
|
+
ignoreFieldNorm: false,
|
|
783
|
+
// The weight to determine how much field length norm effects scoring.
|
|
784
|
+
fieldNormWeight: 1
|
|
785
|
+
};
|
|
786
|
+
var Config = {
|
|
787
|
+
...BasicOptions,
|
|
788
|
+
...MatchOptions,
|
|
789
|
+
...FuzzyOptions,
|
|
790
|
+
...AdvancedOptions
|
|
791
|
+
};
|
|
792
|
+
var SPACE = /[^ ]+/g;
|
|
793
|
+
function norm(weight = 1, mantissa = 3) {
|
|
794
|
+
const cache = /* @__PURE__ */ new Map();
|
|
795
|
+
const m = Math.pow(10, mantissa);
|
|
796
|
+
return {
|
|
797
|
+
get(value) {
|
|
798
|
+
const numTokens = value.match(SPACE).length;
|
|
799
|
+
if (cache.has(numTokens)) {
|
|
800
|
+
return cache.get(numTokens);
|
|
801
|
+
}
|
|
802
|
+
const norm2 = 1 / Math.pow(numTokens, 0.5 * weight);
|
|
803
|
+
const n = parseFloat(Math.round(norm2 * m) / m);
|
|
804
|
+
cache.set(numTokens, n);
|
|
805
|
+
return n;
|
|
806
|
+
},
|
|
807
|
+
clear() {
|
|
808
|
+
cache.clear();
|
|
809
|
+
}
|
|
810
|
+
};
|
|
811
|
+
}
|
|
812
|
+
var FuseIndex = class {
|
|
813
|
+
constructor({
|
|
814
|
+
getFn = Config.getFn,
|
|
815
|
+
fieldNormWeight = Config.fieldNormWeight
|
|
816
|
+
} = {}) {
|
|
817
|
+
this.norm = norm(fieldNormWeight, 3);
|
|
818
|
+
this.getFn = getFn;
|
|
819
|
+
this.isCreated = false;
|
|
820
|
+
this.setIndexRecords();
|
|
821
|
+
}
|
|
822
|
+
setSources(docs = []) {
|
|
823
|
+
this.docs = docs;
|
|
824
|
+
}
|
|
825
|
+
setIndexRecords(records = []) {
|
|
826
|
+
this.records = records;
|
|
827
|
+
}
|
|
828
|
+
setKeys(keys = []) {
|
|
829
|
+
this.keys = keys;
|
|
830
|
+
this._keysMap = {};
|
|
831
|
+
keys.forEach((key, idx) => {
|
|
832
|
+
this._keysMap[key.id] = idx;
|
|
833
|
+
});
|
|
834
|
+
}
|
|
835
|
+
create() {
|
|
836
|
+
if (this.isCreated || !this.docs.length) {
|
|
837
|
+
return;
|
|
838
|
+
}
|
|
839
|
+
this.isCreated = true;
|
|
840
|
+
if (isString(this.docs[0])) {
|
|
841
|
+
this.docs.forEach((doc, docIndex) => {
|
|
842
|
+
this._addString(doc, docIndex);
|
|
843
|
+
});
|
|
844
|
+
} else {
|
|
845
|
+
this.docs.forEach((doc, docIndex) => {
|
|
846
|
+
this._addObject(doc, docIndex);
|
|
847
|
+
});
|
|
848
|
+
}
|
|
849
|
+
this.norm.clear();
|
|
850
|
+
}
|
|
851
|
+
// Adds a doc to the end of the index
|
|
852
|
+
add(doc) {
|
|
853
|
+
const idx = this.size();
|
|
854
|
+
if (isString(doc)) {
|
|
855
|
+
this._addString(doc, idx);
|
|
856
|
+
} else {
|
|
857
|
+
this._addObject(doc, idx);
|
|
858
|
+
}
|
|
859
|
+
}
|
|
860
|
+
// Removes the doc at the specified index of the index
|
|
861
|
+
removeAt(idx) {
|
|
862
|
+
this.records.splice(idx, 1);
|
|
863
|
+
for (let i = idx, len = this.size(); i < len; i += 1) {
|
|
864
|
+
this.records[i].i -= 1;
|
|
865
|
+
}
|
|
866
|
+
}
|
|
867
|
+
getValueForItemAtKeyId(item, keyId) {
|
|
868
|
+
return item[this._keysMap[keyId]];
|
|
869
|
+
}
|
|
870
|
+
size() {
|
|
871
|
+
return this.records.length;
|
|
872
|
+
}
|
|
873
|
+
_addString(doc, docIndex) {
|
|
874
|
+
if (!isDefined(doc) || isBlank(doc)) {
|
|
875
|
+
return;
|
|
876
|
+
}
|
|
877
|
+
let record = {
|
|
878
|
+
v: doc,
|
|
879
|
+
i: docIndex,
|
|
880
|
+
n: this.norm.get(doc)
|
|
881
|
+
};
|
|
882
|
+
this.records.push(record);
|
|
883
|
+
}
|
|
884
|
+
_addObject(doc, docIndex) {
|
|
885
|
+
let record = { i: docIndex, $: {} };
|
|
886
|
+
this.keys.forEach((key, keyIndex) => {
|
|
887
|
+
let value = key.getFn ? key.getFn(doc) : this.getFn(doc, key.path);
|
|
888
|
+
if (!isDefined(value)) {
|
|
889
|
+
return;
|
|
890
|
+
}
|
|
891
|
+
if (isArray(value)) {
|
|
892
|
+
let subRecords = [];
|
|
893
|
+
const stack = [{ nestedArrIndex: -1, value }];
|
|
894
|
+
while (stack.length) {
|
|
895
|
+
const { nestedArrIndex, value: value2 } = stack.pop();
|
|
896
|
+
if (!isDefined(value2)) {
|
|
897
|
+
continue;
|
|
898
|
+
}
|
|
899
|
+
if (isString(value2) && !isBlank(value2)) {
|
|
900
|
+
let subRecord = {
|
|
901
|
+
v: value2,
|
|
902
|
+
i: nestedArrIndex,
|
|
903
|
+
n: this.norm.get(value2)
|
|
904
|
+
};
|
|
905
|
+
subRecords.push(subRecord);
|
|
906
|
+
} else if (isArray(value2)) {
|
|
907
|
+
value2.forEach((item, k) => {
|
|
908
|
+
stack.push({
|
|
909
|
+
nestedArrIndex: k,
|
|
910
|
+
value: item
|
|
911
|
+
});
|
|
912
|
+
});
|
|
913
|
+
} else ;
|
|
914
|
+
}
|
|
915
|
+
record.$[keyIndex] = subRecords;
|
|
916
|
+
} else if (isString(value) && !isBlank(value)) {
|
|
917
|
+
let subRecord = {
|
|
918
|
+
v: value,
|
|
919
|
+
n: this.norm.get(value)
|
|
920
|
+
};
|
|
921
|
+
record.$[keyIndex] = subRecord;
|
|
922
|
+
}
|
|
923
|
+
});
|
|
924
|
+
this.records.push(record);
|
|
925
|
+
}
|
|
926
|
+
toJSON() {
|
|
927
|
+
return {
|
|
928
|
+
keys: this.keys,
|
|
929
|
+
records: this.records
|
|
930
|
+
};
|
|
931
|
+
}
|
|
932
|
+
};
|
|
933
|
+
function createIndex(keys, docs, { getFn = Config.getFn, fieldNormWeight = Config.fieldNormWeight } = {}) {
|
|
934
|
+
const myIndex = new FuseIndex({ getFn, fieldNormWeight });
|
|
935
|
+
myIndex.setKeys(keys.map(createKey));
|
|
936
|
+
myIndex.setSources(docs);
|
|
937
|
+
myIndex.create();
|
|
938
|
+
return myIndex;
|
|
939
|
+
}
|
|
940
|
+
function parseIndex(data, { getFn = Config.getFn, fieldNormWeight = Config.fieldNormWeight } = {}) {
|
|
941
|
+
const { keys, records } = data;
|
|
942
|
+
const myIndex = new FuseIndex({ getFn, fieldNormWeight });
|
|
943
|
+
myIndex.setKeys(keys);
|
|
944
|
+
myIndex.setIndexRecords(records);
|
|
945
|
+
return myIndex;
|
|
946
|
+
}
|
|
947
|
+
function computeScore$1(pattern, {
|
|
948
|
+
errors = 0,
|
|
949
|
+
currentLocation = 0,
|
|
950
|
+
expectedLocation = 0,
|
|
951
|
+
distance = Config.distance,
|
|
952
|
+
ignoreLocation = Config.ignoreLocation
|
|
953
|
+
} = {}) {
|
|
954
|
+
const accuracy = errors / pattern.length;
|
|
955
|
+
if (ignoreLocation) {
|
|
956
|
+
return accuracy;
|
|
957
|
+
}
|
|
958
|
+
const proximity = Math.abs(expectedLocation - currentLocation);
|
|
959
|
+
if (!distance) {
|
|
960
|
+
return proximity ? 1 : accuracy;
|
|
961
|
+
}
|
|
962
|
+
return accuracy + proximity / distance;
|
|
963
|
+
}
|
|
964
|
+
function convertMaskToIndices(matchmask = [], minMatchCharLength = Config.minMatchCharLength) {
|
|
965
|
+
let indices = [];
|
|
966
|
+
let start = -1;
|
|
967
|
+
let end = -1;
|
|
968
|
+
let i = 0;
|
|
969
|
+
for (let len = matchmask.length; i < len; i += 1) {
|
|
970
|
+
let match = matchmask[i];
|
|
971
|
+
if (match && start === -1) {
|
|
972
|
+
start = i;
|
|
973
|
+
} else if (!match && start !== -1) {
|
|
974
|
+
end = i - 1;
|
|
975
|
+
if (end - start + 1 >= minMatchCharLength) {
|
|
976
|
+
indices.push([start, end]);
|
|
977
|
+
}
|
|
978
|
+
start = -1;
|
|
979
|
+
}
|
|
980
|
+
}
|
|
981
|
+
if (matchmask[i - 1] && i - start >= minMatchCharLength) {
|
|
982
|
+
indices.push([start, i - 1]);
|
|
983
|
+
}
|
|
984
|
+
return indices;
|
|
985
|
+
}
|
|
986
|
+
var MAX_BITS = 32;
|
|
987
|
+
function search(text, pattern, patternAlphabet, {
|
|
988
|
+
location = Config.location,
|
|
989
|
+
distance = Config.distance,
|
|
990
|
+
threshold = Config.threshold,
|
|
991
|
+
findAllMatches = Config.findAllMatches,
|
|
992
|
+
minMatchCharLength = Config.minMatchCharLength,
|
|
993
|
+
includeMatches = Config.includeMatches,
|
|
994
|
+
ignoreLocation = Config.ignoreLocation
|
|
995
|
+
} = {}) {
|
|
996
|
+
if (pattern.length > MAX_BITS) {
|
|
997
|
+
throw new Error(PATTERN_LENGTH_TOO_LARGE(MAX_BITS));
|
|
998
|
+
}
|
|
999
|
+
const patternLen = pattern.length;
|
|
1000
|
+
const textLen = text.length;
|
|
1001
|
+
const expectedLocation = Math.max(0, Math.min(location, textLen));
|
|
1002
|
+
let currentThreshold = threshold;
|
|
1003
|
+
let bestLocation = expectedLocation;
|
|
1004
|
+
const computeMatches = minMatchCharLength > 1 || includeMatches;
|
|
1005
|
+
const matchMask = computeMatches ? Array(textLen) : [];
|
|
1006
|
+
let index;
|
|
1007
|
+
while ((index = text.indexOf(pattern, bestLocation)) > -1) {
|
|
1008
|
+
let score = computeScore$1(pattern, {
|
|
1009
|
+
currentLocation: index,
|
|
1010
|
+
expectedLocation,
|
|
1011
|
+
distance,
|
|
1012
|
+
ignoreLocation
|
|
1013
|
+
});
|
|
1014
|
+
currentThreshold = Math.min(score, currentThreshold);
|
|
1015
|
+
bestLocation = index + patternLen;
|
|
1016
|
+
if (computeMatches) {
|
|
1017
|
+
let i = 0;
|
|
1018
|
+
while (i < patternLen) {
|
|
1019
|
+
matchMask[index + i] = 1;
|
|
1020
|
+
i += 1;
|
|
1021
|
+
}
|
|
1022
|
+
}
|
|
1023
|
+
}
|
|
1024
|
+
bestLocation = -1;
|
|
1025
|
+
let lastBitArr = [];
|
|
1026
|
+
let finalScore = 1;
|
|
1027
|
+
let binMax = patternLen + textLen;
|
|
1028
|
+
const mask = 1 << patternLen - 1;
|
|
1029
|
+
for (let i = 0; i < patternLen; i += 1) {
|
|
1030
|
+
let binMin = 0;
|
|
1031
|
+
let binMid = binMax;
|
|
1032
|
+
while (binMin < binMid) {
|
|
1033
|
+
const score2 = computeScore$1(pattern, {
|
|
1034
|
+
errors: i,
|
|
1035
|
+
currentLocation: expectedLocation + binMid,
|
|
1036
|
+
expectedLocation,
|
|
1037
|
+
distance,
|
|
1038
|
+
ignoreLocation
|
|
1039
|
+
});
|
|
1040
|
+
if (score2 <= currentThreshold) {
|
|
1041
|
+
binMin = binMid;
|
|
1042
|
+
} else {
|
|
1043
|
+
binMax = binMid;
|
|
1044
|
+
}
|
|
1045
|
+
binMid = Math.floor((binMax - binMin) / 2 + binMin);
|
|
1046
|
+
}
|
|
1047
|
+
binMax = binMid;
|
|
1048
|
+
let start = Math.max(1, expectedLocation - binMid + 1);
|
|
1049
|
+
let finish = findAllMatches ? textLen : Math.min(expectedLocation + binMid, textLen) + patternLen;
|
|
1050
|
+
let bitArr = Array(finish + 2);
|
|
1051
|
+
bitArr[finish + 1] = (1 << i) - 1;
|
|
1052
|
+
for (let j = finish; j >= start; j -= 1) {
|
|
1053
|
+
let currentLocation = j - 1;
|
|
1054
|
+
let charMatch = patternAlphabet[text.charAt(currentLocation)];
|
|
1055
|
+
if (computeMatches) {
|
|
1056
|
+
matchMask[currentLocation] = +!!charMatch;
|
|
1057
|
+
}
|
|
1058
|
+
bitArr[j] = (bitArr[j + 1] << 1 | 1) & charMatch;
|
|
1059
|
+
if (i) {
|
|
1060
|
+
bitArr[j] |= (lastBitArr[j + 1] | lastBitArr[j]) << 1 | 1 | lastBitArr[j + 1];
|
|
1061
|
+
}
|
|
1062
|
+
if (bitArr[j] & mask) {
|
|
1063
|
+
finalScore = computeScore$1(pattern, {
|
|
1064
|
+
errors: i,
|
|
1065
|
+
currentLocation,
|
|
1066
|
+
expectedLocation,
|
|
1067
|
+
distance,
|
|
1068
|
+
ignoreLocation
|
|
1069
|
+
});
|
|
1070
|
+
if (finalScore <= currentThreshold) {
|
|
1071
|
+
currentThreshold = finalScore;
|
|
1072
|
+
bestLocation = currentLocation;
|
|
1073
|
+
if (bestLocation <= expectedLocation) {
|
|
1074
|
+
break;
|
|
1075
|
+
}
|
|
1076
|
+
start = Math.max(1, 2 * expectedLocation - bestLocation);
|
|
1077
|
+
}
|
|
1078
|
+
}
|
|
1079
|
+
}
|
|
1080
|
+
const score = computeScore$1(pattern, {
|
|
1081
|
+
errors: i + 1,
|
|
1082
|
+
currentLocation: expectedLocation,
|
|
1083
|
+
expectedLocation,
|
|
1084
|
+
distance,
|
|
1085
|
+
ignoreLocation
|
|
1086
|
+
});
|
|
1087
|
+
if (score > currentThreshold) {
|
|
1088
|
+
break;
|
|
1089
|
+
}
|
|
1090
|
+
lastBitArr = bitArr;
|
|
1091
|
+
}
|
|
1092
|
+
const result = {
|
|
1093
|
+
isMatch: bestLocation >= 0,
|
|
1094
|
+
// Count exact matches (those with a score of 0) to be "almost" exact
|
|
1095
|
+
score: Math.max(1e-3, finalScore)
|
|
1096
|
+
};
|
|
1097
|
+
if (computeMatches) {
|
|
1098
|
+
const indices = convertMaskToIndices(matchMask, minMatchCharLength);
|
|
1099
|
+
if (!indices.length) {
|
|
1100
|
+
result.isMatch = false;
|
|
1101
|
+
} else if (includeMatches) {
|
|
1102
|
+
result.indices = indices;
|
|
1103
|
+
}
|
|
1104
|
+
}
|
|
1105
|
+
return result;
|
|
1106
|
+
}
|
|
1107
|
+
function createPatternAlphabet(pattern) {
|
|
1108
|
+
let mask = {};
|
|
1109
|
+
for (let i = 0, len = pattern.length; i < len; i += 1) {
|
|
1110
|
+
const char = pattern.charAt(i);
|
|
1111
|
+
mask[char] = (mask[char] || 0) | 1 << len - i - 1;
|
|
1112
|
+
}
|
|
1113
|
+
return mask;
|
|
1114
|
+
}
|
|
1115
|
+
var stripDiacritics = String.prototype.normalize ? ((str) => str.normalize("NFD").replace(/[\u0300-\u036F\u0483-\u0489\u0591-\u05BD\u05BF\u05C1\u05C2\u05C4\u05C5\u05C7\u0610-\u061A\u064B-\u065F\u0670\u06D6-\u06DC\u06DF-\u06E4\u06E7\u06E8\u06EA-\u06ED\u0711\u0730-\u074A\u07A6-\u07B0\u07EB-\u07F3\u07FD\u0816-\u0819\u081B-\u0823\u0825-\u0827\u0829-\u082D\u0859-\u085B\u08D3-\u08E1\u08E3-\u0903\u093A-\u093C\u093E-\u094F\u0951-\u0957\u0962\u0963\u0981-\u0983\u09BC\u09BE-\u09C4\u09C7\u09C8\u09CB-\u09CD\u09D7\u09E2\u09E3\u09FE\u0A01-\u0A03\u0A3C\u0A3E-\u0A42\u0A47\u0A48\u0A4B-\u0A4D\u0A51\u0A70\u0A71\u0A75\u0A81-\u0A83\u0ABC\u0ABE-\u0AC5\u0AC7-\u0AC9\u0ACB-\u0ACD\u0AE2\u0AE3\u0AFA-\u0AFF\u0B01-\u0B03\u0B3C\u0B3E-\u0B44\u0B47\u0B48\u0B4B-\u0B4D\u0B56\u0B57\u0B62\u0B63\u0B82\u0BBE-\u0BC2\u0BC6-\u0BC8\u0BCA-\u0BCD\u0BD7\u0C00-\u0C04\u0C3E-\u0C44\u0C46-\u0C48\u0C4A-\u0C4D\u0C55\u0C56\u0C62\u0C63\u0C81-\u0C83\u0CBC\u0CBE-\u0CC4\u0CC6-\u0CC8\u0CCA-\u0CCD\u0CD5\u0CD6\u0CE2\u0CE3\u0D00-\u0D03\u0D3B\u0D3C\u0D3E-\u0D44\u0D46-\u0D48\u0D4A-\u0D4D\u0D57\u0D62\u0D63\u0D82\u0D83\u0DCA\u0DCF-\u0DD4\u0DD6\u0DD8-\u0DDF\u0DF2\u0DF3\u0E31\u0E34-\u0E3A\u0E47-\u0E4E\u0EB1\u0EB4-\u0EB9\u0EBB\u0EBC\u0EC8-\u0ECD\u0F18\u0F19\u0F35\u0F37\u0F39\u0F3E\u0F3F\u0F71-\u0F84\u0F86\u0F87\u0F8D-\u0F97\u0F99-\u0FBC\u0FC6\u102B-\u103E\u1056-\u1059\u105E-\u1060\u1062-\u1064\u1067-\u106D\u1071-\u1074\u1082-\u108D\u108F\u109A-\u109D\u135D-\u135F\u1712-\u1714\u1732-\u1734\u1752\u1753\u1772\u1773\u17B4-\u17D3\u17DD\u180B-\u180D\u1885\u1886\u18A9\u1920-\u192B\u1930-\u193B\u1A17-\u1A1B\u1A55-\u1A5E\u1A60-\u1A7C\u1A7F\u1AB0-\u1ABE\u1B00-\u1B04\u1B34-\u1B44\u1B6B-\u1B73\u1B80-\u1B82\u1BA1-\u1BAD\u1BE6-\u1BF3\u1C24-\u1C37\u1CD0-\u1CD2\u1CD4-\u1CE8\u1CED\u1CF2-\u1CF4\u1CF7-\u1CF9\u1DC0-\u1DF9\u1DFB-\u1DFF\u20D0-\u20F0\u2CEF-\u2CF1\u2D7F\u2DE0-\u2DFF\u302A-\u302F\u3099\u309A\uA66F-\uA672\uA674-\uA67D\uA69E\uA69F\uA6F0\uA6F1\uA802\uA806\uA80B\uA823-\uA827\uA880\uA881\uA8B4-\uA8C5\uA8E0-\uA8F1\uA8FF\uA926-\uA92D\uA947-\uA953\uA980-\uA983\uA9B3-\uA9C0\uA9E5\uAA29-\uAA36\uAA43\uAA4C\uAA4D\uAA7B-\uAA7D\uAAB0\uAAB2-\uAAB4\uAAB7\uAAB8\uAABE\uAABF\uAAC1\uAAEB-\uAAEF\uAAF5\uAAF6\uABE3-\uABEA\uABEC\uABED\uFB1E\uFE00-\uFE0F\uFE20-\uFE2F]/g, "")) : ((str) => str);
|
|
1116
|
+
var BitapSearch = class {
|
|
1117
|
+
constructor(pattern, {
|
|
1118
|
+
location = Config.location,
|
|
1119
|
+
threshold = Config.threshold,
|
|
1120
|
+
distance = Config.distance,
|
|
1121
|
+
includeMatches = Config.includeMatches,
|
|
1122
|
+
findAllMatches = Config.findAllMatches,
|
|
1123
|
+
minMatchCharLength = Config.minMatchCharLength,
|
|
1124
|
+
isCaseSensitive = Config.isCaseSensitive,
|
|
1125
|
+
ignoreDiacritics = Config.ignoreDiacritics,
|
|
1126
|
+
ignoreLocation = Config.ignoreLocation
|
|
1127
|
+
} = {}) {
|
|
1128
|
+
this.options = {
|
|
1129
|
+
location,
|
|
1130
|
+
threshold,
|
|
1131
|
+
distance,
|
|
1132
|
+
includeMatches,
|
|
1133
|
+
findAllMatches,
|
|
1134
|
+
minMatchCharLength,
|
|
1135
|
+
isCaseSensitive,
|
|
1136
|
+
ignoreDiacritics,
|
|
1137
|
+
ignoreLocation
|
|
1138
|
+
};
|
|
1139
|
+
pattern = isCaseSensitive ? pattern : pattern.toLowerCase();
|
|
1140
|
+
pattern = ignoreDiacritics ? stripDiacritics(pattern) : pattern;
|
|
1141
|
+
this.pattern = pattern;
|
|
1142
|
+
this.chunks = [];
|
|
1143
|
+
if (!this.pattern.length) {
|
|
1144
|
+
return;
|
|
1145
|
+
}
|
|
1146
|
+
const addChunk = (pattern2, startIndex) => {
|
|
1147
|
+
this.chunks.push({
|
|
1148
|
+
pattern: pattern2,
|
|
1149
|
+
alphabet: createPatternAlphabet(pattern2),
|
|
1150
|
+
startIndex
|
|
1151
|
+
});
|
|
1152
|
+
};
|
|
1153
|
+
const len = this.pattern.length;
|
|
1154
|
+
if (len > MAX_BITS) {
|
|
1155
|
+
let i = 0;
|
|
1156
|
+
const remainder = len % MAX_BITS;
|
|
1157
|
+
const end = len - remainder;
|
|
1158
|
+
while (i < end) {
|
|
1159
|
+
addChunk(this.pattern.substr(i, MAX_BITS), i);
|
|
1160
|
+
i += MAX_BITS;
|
|
1161
|
+
}
|
|
1162
|
+
if (remainder) {
|
|
1163
|
+
const startIndex = len - MAX_BITS;
|
|
1164
|
+
addChunk(this.pattern.substr(startIndex), startIndex);
|
|
1165
|
+
}
|
|
1166
|
+
} else {
|
|
1167
|
+
addChunk(this.pattern, 0);
|
|
1168
|
+
}
|
|
1169
|
+
}
|
|
1170
|
+
searchIn(text) {
|
|
1171
|
+
const { isCaseSensitive, ignoreDiacritics, includeMatches } = this.options;
|
|
1172
|
+
text = isCaseSensitive ? text : text.toLowerCase();
|
|
1173
|
+
text = ignoreDiacritics ? stripDiacritics(text) : text;
|
|
1174
|
+
if (this.pattern === text) {
|
|
1175
|
+
let result2 = {
|
|
1176
|
+
isMatch: true,
|
|
1177
|
+
score: 0
|
|
1178
|
+
};
|
|
1179
|
+
if (includeMatches) {
|
|
1180
|
+
result2.indices = [[0, text.length - 1]];
|
|
1181
|
+
}
|
|
1182
|
+
return result2;
|
|
1183
|
+
}
|
|
1184
|
+
const {
|
|
1185
|
+
location,
|
|
1186
|
+
distance,
|
|
1187
|
+
threshold,
|
|
1188
|
+
findAllMatches,
|
|
1189
|
+
minMatchCharLength,
|
|
1190
|
+
ignoreLocation
|
|
1191
|
+
} = this.options;
|
|
1192
|
+
let allIndices = [];
|
|
1193
|
+
let totalScore = 0;
|
|
1194
|
+
let hasMatches = false;
|
|
1195
|
+
this.chunks.forEach(({ pattern, alphabet, startIndex }) => {
|
|
1196
|
+
const { isMatch, score, indices } = search(text, pattern, alphabet, {
|
|
1197
|
+
location: location + startIndex,
|
|
1198
|
+
distance,
|
|
1199
|
+
threshold,
|
|
1200
|
+
findAllMatches,
|
|
1201
|
+
minMatchCharLength,
|
|
1202
|
+
includeMatches,
|
|
1203
|
+
ignoreLocation
|
|
1204
|
+
});
|
|
1205
|
+
if (isMatch) {
|
|
1206
|
+
hasMatches = true;
|
|
1207
|
+
}
|
|
1208
|
+
totalScore += score;
|
|
1209
|
+
if (isMatch && indices) {
|
|
1210
|
+
allIndices = [...allIndices, ...indices];
|
|
1211
|
+
}
|
|
1212
|
+
});
|
|
1213
|
+
let result = {
|
|
1214
|
+
isMatch: hasMatches,
|
|
1215
|
+
score: hasMatches ? totalScore / this.chunks.length : 1
|
|
1216
|
+
};
|
|
1217
|
+
if (hasMatches && includeMatches) {
|
|
1218
|
+
result.indices = allIndices;
|
|
1219
|
+
}
|
|
1220
|
+
return result;
|
|
1221
|
+
}
|
|
1222
|
+
};
|
|
1223
|
+
var BaseMatch = class {
|
|
1224
|
+
constructor(pattern) {
|
|
1225
|
+
this.pattern = pattern;
|
|
1226
|
+
}
|
|
1227
|
+
static isMultiMatch(pattern) {
|
|
1228
|
+
return getMatch(pattern, this.multiRegex);
|
|
1229
|
+
}
|
|
1230
|
+
static isSingleMatch(pattern) {
|
|
1231
|
+
return getMatch(pattern, this.singleRegex);
|
|
1232
|
+
}
|
|
1233
|
+
search() {
|
|
1234
|
+
}
|
|
1235
|
+
};
|
|
1236
|
+
function getMatch(pattern, exp) {
|
|
1237
|
+
const matches = pattern.match(exp);
|
|
1238
|
+
return matches ? matches[1] : null;
|
|
1239
|
+
}
|
|
1240
|
+
var ExactMatch = class extends BaseMatch {
|
|
1241
|
+
constructor(pattern) {
|
|
1242
|
+
super(pattern);
|
|
1243
|
+
}
|
|
1244
|
+
static get type() {
|
|
1245
|
+
return "exact";
|
|
1246
|
+
}
|
|
1247
|
+
static get multiRegex() {
|
|
1248
|
+
return /^="(.*)"$/;
|
|
1249
|
+
}
|
|
1250
|
+
static get singleRegex() {
|
|
1251
|
+
return /^=(.*)$/;
|
|
1252
|
+
}
|
|
1253
|
+
search(text) {
|
|
1254
|
+
const isMatch = text === this.pattern;
|
|
1255
|
+
return {
|
|
1256
|
+
isMatch,
|
|
1257
|
+
score: isMatch ? 0 : 1,
|
|
1258
|
+
indices: [0, this.pattern.length - 1]
|
|
1259
|
+
};
|
|
1260
|
+
}
|
|
1261
|
+
};
|
|
1262
|
+
var InverseExactMatch = class extends BaseMatch {
|
|
1263
|
+
constructor(pattern) {
|
|
1264
|
+
super(pattern);
|
|
1265
|
+
}
|
|
1266
|
+
static get type() {
|
|
1267
|
+
return "inverse-exact";
|
|
1268
|
+
}
|
|
1269
|
+
static get multiRegex() {
|
|
1270
|
+
return /^!"(.*)"$/;
|
|
1271
|
+
}
|
|
1272
|
+
static get singleRegex() {
|
|
1273
|
+
return /^!(.*)$/;
|
|
1274
|
+
}
|
|
1275
|
+
search(text) {
|
|
1276
|
+
const index = text.indexOf(this.pattern);
|
|
1277
|
+
const isMatch = index === -1;
|
|
1278
|
+
return {
|
|
1279
|
+
isMatch,
|
|
1280
|
+
score: isMatch ? 0 : 1,
|
|
1281
|
+
indices: [0, text.length - 1]
|
|
1282
|
+
};
|
|
1283
|
+
}
|
|
1284
|
+
};
|
|
1285
|
+
var PrefixExactMatch = class extends BaseMatch {
|
|
1286
|
+
constructor(pattern) {
|
|
1287
|
+
super(pattern);
|
|
1288
|
+
}
|
|
1289
|
+
static get type() {
|
|
1290
|
+
return "prefix-exact";
|
|
1291
|
+
}
|
|
1292
|
+
static get multiRegex() {
|
|
1293
|
+
return /^\^"(.*)"$/;
|
|
1294
|
+
}
|
|
1295
|
+
static get singleRegex() {
|
|
1296
|
+
return /^\^(.*)$/;
|
|
1297
|
+
}
|
|
1298
|
+
search(text) {
|
|
1299
|
+
const isMatch = text.startsWith(this.pattern);
|
|
1300
|
+
return {
|
|
1301
|
+
isMatch,
|
|
1302
|
+
score: isMatch ? 0 : 1,
|
|
1303
|
+
indices: [0, this.pattern.length - 1]
|
|
1304
|
+
};
|
|
1305
|
+
}
|
|
1306
|
+
};
|
|
1307
|
+
var InversePrefixExactMatch = class extends BaseMatch {
|
|
1308
|
+
constructor(pattern) {
|
|
1309
|
+
super(pattern);
|
|
1310
|
+
}
|
|
1311
|
+
static get type() {
|
|
1312
|
+
return "inverse-prefix-exact";
|
|
1313
|
+
}
|
|
1314
|
+
static get multiRegex() {
|
|
1315
|
+
return /^!\^"(.*)"$/;
|
|
1316
|
+
}
|
|
1317
|
+
static get singleRegex() {
|
|
1318
|
+
return /^!\^(.*)$/;
|
|
1319
|
+
}
|
|
1320
|
+
search(text) {
|
|
1321
|
+
const isMatch = !text.startsWith(this.pattern);
|
|
1322
|
+
return {
|
|
1323
|
+
isMatch,
|
|
1324
|
+
score: isMatch ? 0 : 1,
|
|
1325
|
+
indices: [0, text.length - 1]
|
|
1326
|
+
};
|
|
1327
|
+
}
|
|
1328
|
+
};
|
|
1329
|
+
var SuffixExactMatch = class extends BaseMatch {
|
|
1330
|
+
constructor(pattern) {
|
|
1331
|
+
super(pattern);
|
|
1332
|
+
}
|
|
1333
|
+
static get type() {
|
|
1334
|
+
return "suffix-exact";
|
|
1335
|
+
}
|
|
1336
|
+
static get multiRegex() {
|
|
1337
|
+
return /^"(.*)"\$$/;
|
|
1338
|
+
}
|
|
1339
|
+
static get singleRegex() {
|
|
1340
|
+
return /^(.*)\$$/;
|
|
1341
|
+
}
|
|
1342
|
+
search(text) {
|
|
1343
|
+
const isMatch = text.endsWith(this.pattern);
|
|
1344
|
+
return {
|
|
1345
|
+
isMatch,
|
|
1346
|
+
score: isMatch ? 0 : 1,
|
|
1347
|
+
indices: [text.length - this.pattern.length, text.length - 1]
|
|
1348
|
+
};
|
|
1349
|
+
}
|
|
1350
|
+
};
|
|
1351
|
+
var InverseSuffixExactMatch = class extends BaseMatch {
|
|
1352
|
+
constructor(pattern) {
|
|
1353
|
+
super(pattern);
|
|
1354
|
+
}
|
|
1355
|
+
static get type() {
|
|
1356
|
+
return "inverse-suffix-exact";
|
|
1357
|
+
}
|
|
1358
|
+
static get multiRegex() {
|
|
1359
|
+
return /^!"(.*)"\$$/;
|
|
1360
|
+
}
|
|
1361
|
+
static get singleRegex() {
|
|
1362
|
+
return /^!(.*)\$$/;
|
|
1363
|
+
}
|
|
1364
|
+
search(text) {
|
|
1365
|
+
const isMatch = !text.endsWith(this.pattern);
|
|
1366
|
+
return {
|
|
1367
|
+
isMatch,
|
|
1368
|
+
score: isMatch ? 0 : 1,
|
|
1369
|
+
indices: [0, text.length - 1]
|
|
1370
|
+
};
|
|
1371
|
+
}
|
|
1372
|
+
};
|
|
1373
|
+
var FuzzyMatch = class extends BaseMatch {
|
|
1374
|
+
constructor(pattern, {
|
|
1375
|
+
location = Config.location,
|
|
1376
|
+
threshold = Config.threshold,
|
|
1377
|
+
distance = Config.distance,
|
|
1378
|
+
includeMatches = Config.includeMatches,
|
|
1379
|
+
findAllMatches = Config.findAllMatches,
|
|
1380
|
+
minMatchCharLength = Config.minMatchCharLength,
|
|
1381
|
+
isCaseSensitive = Config.isCaseSensitive,
|
|
1382
|
+
ignoreDiacritics = Config.ignoreDiacritics,
|
|
1383
|
+
ignoreLocation = Config.ignoreLocation
|
|
1384
|
+
} = {}) {
|
|
1385
|
+
super(pattern);
|
|
1386
|
+
this._bitapSearch = new BitapSearch(pattern, {
|
|
1387
|
+
location,
|
|
1388
|
+
threshold,
|
|
1389
|
+
distance,
|
|
1390
|
+
includeMatches,
|
|
1391
|
+
findAllMatches,
|
|
1392
|
+
minMatchCharLength,
|
|
1393
|
+
isCaseSensitive,
|
|
1394
|
+
ignoreDiacritics,
|
|
1395
|
+
ignoreLocation
|
|
1396
|
+
});
|
|
1397
|
+
}
|
|
1398
|
+
static get type() {
|
|
1399
|
+
return "fuzzy";
|
|
1400
|
+
}
|
|
1401
|
+
static get multiRegex() {
|
|
1402
|
+
return /^"(.*)"$/;
|
|
1403
|
+
}
|
|
1404
|
+
static get singleRegex() {
|
|
1405
|
+
return /^(.*)$/;
|
|
1406
|
+
}
|
|
1407
|
+
search(text) {
|
|
1408
|
+
return this._bitapSearch.searchIn(text);
|
|
1409
|
+
}
|
|
1410
|
+
};
|
|
1411
|
+
var IncludeMatch = class extends BaseMatch {
|
|
1412
|
+
constructor(pattern) {
|
|
1413
|
+
super(pattern);
|
|
1414
|
+
}
|
|
1415
|
+
static get type() {
|
|
1416
|
+
return "include";
|
|
1417
|
+
}
|
|
1418
|
+
static get multiRegex() {
|
|
1419
|
+
return /^'"(.*)"$/;
|
|
1420
|
+
}
|
|
1421
|
+
static get singleRegex() {
|
|
1422
|
+
return /^'(.*)$/;
|
|
1423
|
+
}
|
|
1424
|
+
search(text) {
|
|
1425
|
+
let location = 0;
|
|
1426
|
+
let index;
|
|
1427
|
+
const indices = [];
|
|
1428
|
+
const patternLen = this.pattern.length;
|
|
1429
|
+
while ((index = text.indexOf(this.pattern, location)) > -1) {
|
|
1430
|
+
location = index + patternLen;
|
|
1431
|
+
indices.push([index, location - 1]);
|
|
1432
|
+
}
|
|
1433
|
+
const isMatch = !!indices.length;
|
|
1434
|
+
return {
|
|
1435
|
+
isMatch,
|
|
1436
|
+
score: isMatch ? 0 : 1,
|
|
1437
|
+
indices
|
|
1438
|
+
};
|
|
1439
|
+
}
|
|
1440
|
+
};
|
|
1441
|
+
var searchers = [
|
|
1442
|
+
ExactMatch,
|
|
1443
|
+
IncludeMatch,
|
|
1444
|
+
PrefixExactMatch,
|
|
1445
|
+
InversePrefixExactMatch,
|
|
1446
|
+
InverseSuffixExactMatch,
|
|
1447
|
+
SuffixExactMatch,
|
|
1448
|
+
InverseExactMatch,
|
|
1449
|
+
FuzzyMatch
|
|
1450
|
+
];
|
|
1451
|
+
var searchersLen = searchers.length;
|
|
1452
|
+
var SPACE_RE = / +(?=(?:[^\"]*\"[^\"]*\")*[^\"]*$)/;
|
|
1453
|
+
var OR_TOKEN = "|";
|
|
1454
|
+
function parseQuery(pattern, options = {}) {
|
|
1455
|
+
return pattern.split(OR_TOKEN).map((item) => {
|
|
1456
|
+
let query = item.trim().split(SPACE_RE).filter((item2) => item2 && !!item2.trim());
|
|
1457
|
+
let results = [];
|
|
1458
|
+
for (let i = 0, len = query.length; i < len; i += 1) {
|
|
1459
|
+
const queryItem = query[i];
|
|
1460
|
+
let found = false;
|
|
1461
|
+
let idx = -1;
|
|
1462
|
+
while (!found && ++idx < searchersLen) {
|
|
1463
|
+
const searcher = searchers[idx];
|
|
1464
|
+
let token = searcher.isMultiMatch(queryItem);
|
|
1465
|
+
if (token) {
|
|
1466
|
+
results.push(new searcher(token, options));
|
|
1467
|
+
found = true;
|
|
1468
|
+
}
|
|
1469
|
+
}
|
|
1470
|
+
if (found) {
|
|
1471
|
+
continue;
|
|
1472
|
+
}
|
|
1473
|
+
idx = -1;
|
|
1474
|
+
while (++idx < searchersLen) {
|
|
1475
|
+
const searcher = searchers[idx];
|
|
1476
|
+
let token = searcher.isSingleMatch(queryItem);
|
|
1477
|
+
if (token) {
|
|
1478
|
+
results.push(new searcher(token, options));
|
|
1479
|
+
break;
|
|
1480
|
+
}
|
|
1481
|
+
}
|
|
1482
|
+
}
|
|
1483
|
+
return results;
|
|
1484
|
+
});
|
|
1485
|
+
}
|
|
1486
|
+
var MultiMatchSet = /* @__PURE__ */ new Set([FuzzyMatch.type, IncludeMatch.type]);
|
|
1487
|
+
var ExtendedSearch = class {
|
|
1488
|
+
constructor(pattern, {
|
|
1489
|
+
isCaseSensitive = Config.isCaseSensitive,
|
|
1490
|
+
ignoreDiacritics = Config.ignoreDiacritics,
|
|
1491
|
+
includeMatches = Config.includeMatches,
|
|
1492
|
+
minMatchCharLength = Config.minMatchCharLength,
|
|
1493
|
+
ignoreLocation = Config.ignoreLocation,
|
|
1494
|
+
findAllMatches = Config.findAllMatches,
|
|
1495
|
+
location = Config.location,
|
|
1496
|
+
threshold = Config.threshold,
|
|
1497
|
+
distance = Config.distance
|
|
1498
|
+
} = {}) {
|
|
1499
|
+
this.query = null;
|
|
1500
|
+
this.options = {
|
|
1501
|
+
isCaseSensitive,
|
|
1502
|
+
ignoreDiacritics,
|
|
1503
|
+
includeMatches,
|
|
1504
|
+
minMatchCharLength,
|
|
1505
|
+
findAllMatches,
|
|
1506
|
+
ignoreLocation,
|
|
1507
|
+
location,
|
|
1508
|
+
threshold,
|
|
1509
|
+
distance
|
|
1510
|
+
};
|
|
1511
|
+
pattern = isCaseSensitive ? pattern : pattern.toLowerCase();
|
|
1512
|
+
pattern = ignoreDiacritics ? stripDiacritics(pattern) : pattern;
|
|
1513
|
+
this.pattern = pattern;
|
|
1514
|
+
this.query = parseQuery(this.pattern, this.options);
|
|
1515
|
+
}
|
|
1516
|
+
static condition(_6, options) {
|
|
1517
|
+
return options.useExtendedSearch;
|
|
1518
|
+
}
|
|
1519
|
+
searchIn(text) {
|
|
1520
|
+
const query = this.query;
|
|
1521
|
+
if (!query) {
|
|
1522
|
+
return {
|
|
1523
|
+
isMatch: false,
|
|
1524
|
+
score: 1
|
|
1525
|
+
};
|
|
1526
|
+
}
|
|
1527
|
+
const { includeMatches, isCaseSensitive, ignoreDiacritics } = this.options;
|
|
1528
|
+
text = isCaseSensitive ? text : text.toLowerCase();
|
|
1529
|
+
text = ignoreDiacritics ? stripDiacritics(text) : text;
|
|
1530
|
+
let numMatches = 0;
|
|
1531
|
+
let allIndices = [];
|
|
1532
|
+
let totalScore = 0;
|
|
1533
|
+
for (let i = 0, qLen = query.length; i < qLen; i += 1) {
|
|
1534
|
+
const searchers2 = query[i];
|
|
1535
|
+
allIndices.length = 0;
|
|
1536
|
+
numMatches = 0;
|
|
1537
|
+
for (let j = 0, pLen = searchers2.length; j < pLen; j += 1) {
|
|
1538
|
+
const searcher = searchers2[j];
|
|
1539
|
+
const { isMatch, indices, score } = searcher.search(text);
|
|
1540
|
+
if (isMatch) {
|
|
1541
|
+
numMatches += 1;
|
|
1542
|
+
totalScore += score;
|
|
1543
|
+
if (includeMatches) {
|
|
1544
|
+
const type = searcher.constructor.type;
|
|
1545
|
+
if (MultiMatchSet.has(type)) {
|
|
1546
|
+
allIndices = [...allIndices, ...indices];
|
|
1547
|
+
} else {
|
|
1548
|
+
allIndices.push(indices);
|
|
1549
|
+
}
|
|
1550
|
+
}
|
|
1551
|
+
} else {
|
|
1552
|
+
totalScore = 0;
|
|
1553
|
+
numMatches = 0;
|
|
1554
|
+
allIndices.length = 0;
|
|
1555
|
+
break;
|
|
1556
|
+
}
|
|
1557
|
+
}
|
|
1558
|
+
if (numMatches) {
|
|
1559
|
+
let result = {
|
|
1560
|
+
isMatch: true,
|
|
1561
|
+
score: totalScore / numMatches
|
|
1562
|
+
};
|
|
1563
|
+
if (includeMatches) {
|
|
1564
|
+
result.indices = allIndices;
|
|
1565
|
+
}
|
|
1566
|
+
return result;
|
|
1567
|
+
}
|
|
1568
|
+
}
|
|
1569
|
+
return {
|
|
1570
|
+
isMatch: false,
|
|
1571
|
+
score: 1
|
|
1572
|
+
};
|
|
1573
|
+
}
|
|
1574
|
+
};
|
|
1575
|
+
var registeredSearchers = [];
|
|
1576
|
+
function register(...args) {
|
|
1577
|
+
registeredSearchers.push(...args);
|
|
1578
|
+
}
|
|
1579
|
+
function createSearcher(pattern, options) {
|
|
1580
|
+
for (let i = 0, len = registeredSearchers.length; i < len; i += 1) {
|
|
1581
|
+
let searcherClass = registeredSearchers[i];
|
|
1582
|
+
if (searcherClass.condition(pattern, options)) {
|
|
1583
|
+
return new searcherClass(pattern, options);
|
|
1584
|
+
}
|
|
1585
|
+
}
|
|
1586
|
+
return new BitapSearch(pattern, options);
|
|
1587
|
+
}
|
|
1588
|
+
var LogicalOperator = {
|
|
1589
|
+
AND: "$and",
|
|
1590
|
+
OR: "$or"
|
|
1591
|
+
};
|
|
1592
|
+
var KeyType = {
|
|
1593
|
+
PATH: "$path",
|
|
1594
|
+
PATTERN: "$val"
|
|
1595
|
+
};
|
|
1596
|
+
var isExpression = (query) => !!(query[LogicalOperator.AND] || query[LogicalOperator.OR]);
|
|
1597
|
+
var isPath = (query) => !!query[KeyType.PATH];
|
|
1598
|
+
var isLeaf = (query) => !isArray(query) && isObject(query) && !isExpression(query);
|
|
1599
|
+
var convertToExplicit = (query) => ({
|
|
1600
|
+
[LogicalOperator.AND]: Object.keys(query).map((key) => ({
|
|
1601
|
+
[key]: query[key]
|
|
1602
|
+
}))
|
|
1603
|
+
});
|
|
1604
|
+
function parse(query, options, { auto = true } = {}) {
|
|
1605
|
+
const next = (query2) => {
|
|
1606
|
+
let keys = Object.keys(query2);
|
|
1607
|
+
const isQueryPath = isPath(query2);
|
|
1608
|
+
if (!isQueryPath && keys.length > 1 && !isExpression(query2)) {
|
|
1609
|
+
return next(convertToExplicit(query2));
|
|
1610
|
+
}
|
|
1611
|
+
if (isLeaf(query2)) {
|
|
1612
|
+
const key = isQueryPath ? query2[KeyType.PATH] : keys[0];
|
|
1613
|
+
const pattern = isQueryPath ? query2[KeyType.PATTERN] : query2[key];
|
|
1614
|
+
if (!isString(pattern)) {
|
|
1615
|
+
throw new Error(LOGICAL_SEARCH_INVALID_QUERY_FOR_KEY(key));
|
|
1616
|
+
}
|
|
1617
|
+
const obj = {
|
|
1618
|
+
keyId: createKeyId(key),
|
|
1619
|
+
pattern
|
|
1620
|
+
};
|
|
1621
|
+
if (auto) {
|
|
1622
|
+
obj.searcher = createSearcher(pattern, options);
|
|
1623
|
+
}
|
|
1624
|
+
return obj;
|
|
1625
|
+
}
|
|
1626
|
+
let node = {
|
|
1627
|
+
children: [],
|
|
1628
|
+
operator: keys[0]
|
|
1629
|
+
};
|
|
1630
|
+
keys.forEach((key) => {
|
|
1631
|
+
const value = query2[key];
|
|
1632
|
+
if (isArray(value)) {
|
|
1633
|
+
value.forEach((item) => {
|
|
1634
|
+
node.children.push(next(item));
|
|
1635
|
+
});
|
|
1636
|
+
}
|
|
1637
|
+
});
|
|
1638
|
+
return node;
|
|
1639
|
+
};
|
|
1640
|
+
if (!isExpression(query)) {
|
|
1641
|
+
query = convertToExplicit(query);
|
|
1642
|
+
}
|
|
1643
|
+
return next(query);
|
|
1644
|
+
}
|
|
1645
|
+
function computeScore(results, { ignoreFieldNorm = Config.ignoreFieldNorm }) {
|
|
1646
|
+
results.forEach((result) => {
|
|
1647
|
+
let totalScore = 1;
|
|
1648
|
+
result.matches.forEach(({ key, norm: norm2, score }) => {
|
|
1649
|
+
const weight = key ? key.weight : null;
|
|
1650
|
+
totalScore *= Math.pow(
|
|
1651
|
+
score === 0 && weight ? Number.EPSILON : score,
|
|
1652
|
+
(weight || 1) * (ignoreFieldNorm ? 1 : norm2)
|
|
1653
|
+
);
|
|
1654
|
+
});
|
|
1655
|
+
result.score = totalScore;
|
|
1656
|
+
});
|
|
1657
|
+
}
|
|
1658
|
+
function transformMatches(result, data) {
|
|
1659
|
+
const matches = result.matches;
|
|
1660
|
+
data.matches = [];
|
|
1661
|
+
if (!isDefined(matches)) {
|
|
1662
|
+
return;
|
|
1663
|
+
}
|
|
1664
|
+
matches.forEach((match) => {
|
|
1665
|
+
if (!isDefined(match.indices) || !match.indices.length) {
|
|
1666
|
+
return;
|
|
1667
|
+
}
|
|
1668
|
+
const { indices, value } = match;
|
|
1669
|
+
let obj = {
|
|
1670
|
+
indices,
|
|
1671
|
+
value
|
|
1672
|
+
};
|
|
1673
|
+
if (match.key) {
|
|
1674
|
+
obj.key = match.key.src;
|
|
1675
|
+
}
|
|
1676
|
+
if (match.idx > -1) {
|
|
1677
|
+
obj.refIndex = match.idx;
|
|
1678
|
+
}
|
|
1679
|
+
data.matches.push(obj);
|
|
1680
|
+
});
|
|
1681
|
+
}
|
|
1682
|
+
function transformScore(result, data) {
|
|
1683
|
+
data.score = result.score;
|
|
1684
|
+
}
|
|
1685
|
+
function format(results, docs, {
|
|
1686
|
+
includeMatches = Config.includeMatches,
|
|
1687
|
+
includeScore = Config.includeScore
|
|
1688
|
+
} = {}) {
|
|
1689
|
+
const transformers = [];
|
|
1690
|
+
if (includeMatches) transformers.push(transformMatches);
|
|
1691
|
+
if (includeScore) transformers.push(transformScore);
|
|
1692
|
+
return results.map((result) => {
|
|
1693
|
+
const { idx } = result;
|
|
1694
|
+
const data = {
|
|
1695
|
+
item: docs[idx],
|
|
1696
|
+
refIndex: idx
|
|
1697
|
+
};
|
|
1698
|
+
if (transformers.length) {
|
|
1699
|
+
transformers.forEach((transformer) => {
|
|
1700
|
+
transformer(result, data);
|
|
1701
|
+
});
|
|
1702
|
+
}
|
|
1703
|
+
return data;
|
|
1704
|
+
});
|
|
1705
|
+
}
|
|
1706
|
+
var Fuse = class {
|
|
1707
|
+
constructor(docs, options = {}, index) {
|
|
1708
|
+
this.options = { ...Config, ...options };
|
|
1709
|
+
if (this.options.useExtendedSearch && false) {
|
|
1710
|
+
throw new Error(EXTENDED_SEARCH_UNAVAILABLE);
|
|
1711
|
+
}
|
|
1712
|
+
this._keyStore = new KeyStore(this.options.keys);
|
|
1713
|
+
this.setCollection(docs, index);
|
|
1714
|
+
}
|
|
1715
|
+
setCollection(docs, index) {
|
|
1716
|
+
this._docs = docs;
|
|
1717
|
+
if (index && !(index instanceof FuseIndex)) {
|
|
1718
|
+
throw new Error(INCORRECT_INDEX_TYPE);
|
|
1719
|
+
}
|
|
1720
|
+
this._myIndex = index || createIndex(this.options.keys, this._docs, {
|
|
1721
|
+
getFn: this.options.getFn,
|
|
1722
|
+
fieldNormWeight: this.options.fieldNormWeight
|
|
1723
|
+
});
|
|
1724
|
+
}
|
|
1725
|
+
add(doc) {
|
|
1726
|
+
if (!isDefined(doc)) {
|
|
1727
|
+
return;
|
|
1728
|
+
}
|
|
1729
|
+
this._docs.push(doc);
|
|
1730
|
+
this._myIndex.add(doc);
|
|
1731
|
+
}
|
|
1732
|
+
remove(predicate = () => false) {
|
|
1733
|
+
const results = [];
|
|
1734
|
+
for (let i = 0, len = this._docs.length; i < len; i += 1) {
|
|
1735
|
+
const doc = this._docs[i];
|
|
1736
|
+
if (predicate(doc, i)) {
|
|
1737
|
+
this.removeAt(i);
|
|
1738
|
+
i -= 1;
|
|
1739
|
+
len -= 1;
|
|
1740
|
+
results.push(doc);
|
|
1741
|
+
}
|
|
1742
|
+
}
|
|
1743
|
+
return results;
|
|
1744
|
+
}
|
|
1745
|
+
removeAt(idx) {
|
|
1746
|
+
this._docs.splice(idx, 1);
|
|
1747
|
+
this._myIndex.removeAt(idx);
|
|
1748
|
+
}
|
|
1749
|
+
getIndex() {
|
|
1750
|
+
return this._myIndex;
|
|
1751
|
+
}
|
|
1752
|
+
search(query, { limit = -1 } = {}) {
|
|
1753
|
+
const {
|
|
1754
|
+
includeMatches,
|
|
1755
|
+
includeScore,
|
|
1756
|
+
shouldSort,
|
|
1757
|
+
sortFn,
|
|
1758
|
+
ignoreFieldNorm
|
|
1759
|
+
} = this.options;
|
|
1760
|
+
let results = isString(query) ? isString(this._docs[0]) ? this._searchStringList(query) : this._searchObjectList(query) : this._searchLogical(query);
|
|
1761
|
+
computeScore(results, { ignoreFieldNorm });
|
|
1762
|
+
if (shouldSort) {
|
|
1763
|
+
results.sort(sortFn);
|
|
1764
|
+
}
|
|
1765
|
+
if (isNumber(limit) && limit > -1) {
|
|
1766
|
+
results = results.slice(0, limit);
|
|
1767
|
+
}
|
|
1768
|
+
return format(results, this._docs, {
|
|
1769
|
+
includeMatches,
|
|
1770
|
+
includeScore
|
|
1771
|
+
});
|
|
1772
|
+
}
|
|
1773
|
+
_searchStringList(query) {
|
|
1774
|
+
const searcher = createSearcher(query, this.options);
|
|
1775
|
+
const { records } = this._myIndex;
|
|
1776
|
+
const results = [];
|
|
1777
|
+
records.forEach(({ v: text, i: idx, n: norm2 }) => {
|
|
1778
|
+
if (!isDefined(text)) {
|
|
1779
|
+
return;
|
|
1780
|
+
}
|
|
1781
|
+
const { isMatch, score, indices } = searcher.searchIn(text);
|
|
1782
|
+
if (isMatch) {
|
|
1783
|
+
results.push({
|
|
1784
|
+
item: text,
|
|
1785
|
+
idx,
|
|
1786
|
+
matches: [{ score, value: text, norm: norm2, indices }]
|
|
1787
|
+
});
|
|
1788
|
+
}
|
|
1789
|
+
});
|
|
1790
|
+
return results;
|
|
1791
|
+
}
|
|
1792
|
+
_searchLogical(query) {
|
|
1793
|
+
const expression = parse(query, this.options);
|
|
1794
|
+
const evaluate = (node, item, idx) => {
|
|
1795
|
+
if (!node.children) {
|
|
1796
|
+
const { keyId, searcher } = node;
|
|
1797
|
+
const matches = this._findMatches({
|
|
1798
|
+
key: this._keyStore.get(keyId),
|
|
1799
|
+
value: this._myIndex.getValueForItemAtKeyId(item, keyId),
|
|
1800
|
+
searcher
|
|
1801
|
+
});
|
|
1802
|
+
if (matches && matches.length) {
|
|
1803
|
+
return [
|
|
1804
|
+
{
|
|
1805
|
+
idx,
|
|
1806
|
+
item,
|
|
1807
|
+
matches
|
|
1808
|
+
}
|
|
1809
|
+
];
|
|
1810
|
+
}
|
|
1811
|
+
return [];
|
|
1812
|
+
}
|
|
1813
|
+
const res = [];
|
|
1814
|
+
for (let i = 0, len = node.children.length; i < len; i += 1) {
|
|
1815
|
+
const child = node.children[i];
|
|
1816
|
+
const result = evaluate(child, item, idx);
|
|
1817
|
+
if (result.length) {
|
|
1818
|
+
res.push(...result);
|
|
1819
|
+
} else if (node.operator === LogicalOperator.AND) {
|
|
1820
|
+
return [];
|
|
1821
|
+
}
|
|
1822
|
+
}
|
|
1823
|
+
return res;
|
|
1824
|
+
};
|
|
1825
|
+
const records = this._myIndex.records;
|
|
1826
|
+
const resultMap = {};
|
|
1827
|
+
const results = [];
|
|
1828
|
+
records.forEach(({ $: item, i: idx }) => {
|
|
1829
|
+
if (isDefined(item)) {
|
|
1830
|
+
let expResults = evaluate(expression, item, idx);
|
|
1831
|
+
if (expResults.length) {
|
|
1832
|
+
if (!resultMap[idx]) {
|
|
1833
|
+
resultMap[idx] = { idx, item, matches: [] };
|
|
1834
|
+
results.push(resultMap[idx]);
|
|
1835
|
+
}
|
|
1836
|
+
expResults.forEach(({ matches }) => {
|
|
1837
|
+
resultMap[idx].matches.push(...matches);
|
|
1838
|
+
});
|
|
1839
|
+
}
|
|
1840
|
+
}
|
|
1841
|
+
});
|
|
1842
|
+
return results;
|
|
1843
|
+
}
|
|
1844
|
+
_searchObjectList(query) {
|
|
1845
|
+
const searcher = createSearcher(query, this.options);
|
|
1846
|
+
const { keys, records } = this._myIndex;
|
|
1847
|
+
const results = [];
|
|
1848
|
+
records.forEach(({ $: item, i: idx }) => {
|
|
1849
|
+
if (!isDefined(item)) {
|
|
1850
|
+
return;
|
|
1851
|
+
}
|
|
1852
|
+
let matches = [];
|
|
1853
|
+
keys.forEach((key, keyIndex) => {
|
|
1854
|
+
matches.push(
|
|
1855
|
+
...this._findMatches({
|
|
1856
|
+
key,
|
|
1857
|
+
value: item[keyIndex],
|
|
1858
|
+
searcher
|
|
1859
|
+
})
|
|
1860
|
+
);
|
|
1861
|
+
});
|
|
1862
|
+
if (matches.length) {
|
|
1863
|
+
results.push({
|
|
1864
|
+
idx,
|
|
1865
|
+
item,
|
|
1866
|
+
matches
|
|
1867
|
+
});
|
|
1868
|
+
}
|
|
1869
|
+
});
|
|
1870
|
+
return results;
|
|
1871
|
+
}
|
|
1872
|
+
_findMatches({ key, value, searcher }) {
|
|
1873
|
+
if (!isDefined(value)) {
|
|
1874
|
+
return [];
|
|
1875
|
+
}
|
|
1876
|
+
let matches = [];
|
|
1877
|
+
if (isArray(value)) {
|
|
1878
|
+
value.forEach(({ v: text, i: idx, n: norm2 }) => {
|
|
1879
|
+
if (!isDefined(text)) {
|
|
1880
|
+
return;
|
|
1881
|
+
}
|
|
1882
|
+
const { isMatch, score, indices } = searcher.searchIn(text);
|
|
1883
|
+
if (isMatch) {
|
|
1884
|
+
matches.push({
|
|
1885
|
+
score,
|
|
1886
|
+
key,
|
|
1887
|
+
value: text,
|
|
1888
|
+
idx,
|
|
1889
|
+
norm: norm2,
|
|
1890
|
+
indices
|
|
1891
|
+
});
|
|
1892
|
+
}
|
|
1893
|
+
});
|
|
1894
|
+
} else {
|
|
1895
|
+
const { v: text, n: norm2 } = value;
|
|
1896
|
+
const { isMatch, score, indices } = searcher.searchIn(text);
|
|
1897
|
+
if (isMatch) {
|
|
1898
|
+
matches.push({ score, key, value: text, norm: norm2, indices });
|
|
1899
|
+
}
|
|
1900
|
+
}
|
|
1901
|
+
return matches;
|
|
1902
|
+
}
|
|
1903
|
+
};
|
|
1904
|
+
Fuse.version = "7.1.0";
|
|
1905
|
+
Fuse.createIndex = createIndex;
|
|
1906
|
+
Fuse.parseIndex = parseIndex;
|
|
1907
|
+
Fuse.config = Config;
|
|
1908
|
+
{
|
|
1909
|
+
Fuse.parseQuery = parse;
|
|
1910
|
+
}
|
|
1911
|
+
{
|
|
1912
|
+
register(ExtendedSearch);
|
|
1913
|
+
}
|
|
1914
|
+
|
|
1915
|
+
// src/data/search/utils/sanitizeInput.ts
|
|
1916
|
+
var sanitizeInput = (str) => str.replace(/[\u200E\u200F\u202A-\u202E\u2066-\u2069]/g, "").replace(/[\-–—_./()]+/g, "").normalize("NFC").trim();
|
|
1917
|
+
|
|
1918
|
+
// src/data/search/getSearchClient.ts
|
|
1919
|
+
var getSearchClient = ({ occupants, amenities }) => {
|
|
1920
|
+
const fuseAmenities = new Fuse(amenities, { threshold: 0.2 });
|
|
1921
|
+
const fuseOccupants = new Fuse(occupants, {
|
|
1922
|
+
threshold: 0.3,
|
|
1923
|
+
// 0.2 is too strict (can't find Mo-Mo Paradise with "momo" search string)
|
|
1924
|
+
includeScore: true,
|
|
1925
|
+
keys: [
|
|
1926
|
+
{ name: "properties.name", "weight": 4, getFn: (obj) => Object.values(obj.properties.name) },
|
|
1927
|
+
{ name: "properties.category", "weight": 0.25 },
|
|
1928
|
+
{
|
|
1929
|
+
name: "properties.local_categories",
|
|
1930
|
+
"weight": 0.25,
|
|
1931
|
+
getFn: (occ) => occ.properties.local_categories.map((cat3) => Object.values(cat3.properties.name)).flat()
|
|
1932
|
+
},
|
|
1933
|
+
{ name: "properties.keywords", "weight": 0.25 },
|
|
1934
|
+
{ name: "properties.description", "weight": 0.25, getFn: (occ) => Object.values(occ.properties.description || {}) },
|
|
1935
|
+
{ name: "properties.unit.properties.name", "weight": 0.25, getFn: (obj) => Object.values(obj.properties.unit?.properties.name || {}) },
|
|
1936
|
+
{ name: "properties.kiosk.properties.name", "weight": 0.25, getFn: (obj) => Object.values(obj.properties.kiosk?.properties.name || {}) }
|
|
1937
|
+
]
|
|
1938
|
+
});
|
|
1939
|
+
const fuseFuzzyAmenities = new Fuse(amenities, {
|
|
1940
|
+
threshold: 0.2,
|
|
1941
|
+
keys: [
|
|
1942
|
+
{ name: "properties.category", weight: 4 }
|
|
1943
|
+
]
|
|
1944
|
+
});
|
|
1945
|
+
const search2 = (value) => {
|
|
1946
|
+
const sanitizedValue = sanitizeInput(value);
|
|
1947
|
+
const matchedAmenities = fuseAmenities.search(sanitizedValue);
|
|
1948
|
+
if (matchedAmenities.length > 0) return matchedAmenities;
|
|
1949
|
+
const matchedOccupants = fuseOccupants.search(sanitizedValue);
|
|
1950
|
+
if (matchedOccupants.length > 0) return matchedOccupants;
|
|
1951
|
+
const matchedFuzzyAmenities = fuseFuzzyAmenities.search(sanitizedValue);
|
|
1952
|
+
if (matchedFuzzyAmenities.length > 0) return matchedFuzzyAmenities;
|
|
1953
|
+
return [];
|
|
1954
|
+
};
|
|
1955
|
+
return {
|
|
1956
|
+
search: search2
|
|
578
1957
|
};
|
|
579
1958
|
};
|
|
580
1959
|
|
|
581
1960
|
// src/data/getDataClient.ts
|
|
582
1961
|
var getDataClient = (options) => {
|
|
1962
|
+
let searchClient;
|
|
583
1963
|
const observers = /* @__PURE__ */ new Map();
|
|
584
1964
|
const queryClient = options.queryClient ?? new QueryClient();
|
|
585
1965
|
const { mode = "delivery", projectId, apiKey, baseUrl, previewToken } = options;
|
|
@@ -608,7 +1988,7 @@ var getDataClient = (options) => {
|
|
|
608
1988
|
}
|
|
609
1989
|
};
|
|
610
1990
|
const internalFindById = async (id) => {
|
|
611
|
-
if (id === null) return null;
|
|
1991
|
+
if (id === null || id === void 0) return null;
|
|
612
1992
|
const featureType = id.slice(0, id.lastIndexOf("-"));
|
|
613
1993
|
const feature2 = await queryClient.ensureQueryData({
|
|
614
1994
|
queryKey: ["_deliveryapi", featureType, id],
|
|
@@ -691,6 +2071,17 @@ var getDataClient = (options) => {
|
|
|
691
2071
|
const feature2 = await queryClient.ensureQueryData(findQueryOptions);
|
|
692
2072
|
return feature2;
|
|
693
2073
|
}
|
|
2074
|
+
const searchFn = async (txt) => {
|
|
2075
|
+
if (!searchClient) {
|
|
2076
|
+
const [occupants, amenities] = await Promise.all([
|
|
2077
|
+
filterByType("occupant", { populate: true }),
|
|
2078
|
+
filterByType("amenity")
|
|
2079
|
+
]);
|
|
2080
|
+
const haystack = { occupants, amenities };
|
|
2081
|
+
searchClient = getSearchClient(haystack);
|
|
2082
|
+
}
|
|
2083
|
+
return searchClient.search(txt);
|
|
2084
|
+
};
|
|
694
2085
|
return {
|
|
695
2086
|
projectId,
|
|
696
2087
|
queryClient,
|
|
@@ -700,7 +2091,8 @@ var getDataClient = (options) => {
|
|
|
700
2091
|
createFilterByTypeQueryOptions,
|
|
701
2092
|
createFindByIdQueryOptions,
|
|
702
2093
|
filterByType,
|
|
703
|
-
findById
|
|
2094
|
+
findById,
|
|
2095
|
+
search: searchFn
|
|
704
2096
|
};
|
|
705
2097
|
};
|
|
706
2098
|
|
|
@@ -758,7 +2150,7 @@ function point(coordinates, properties, options = {}) {
|
|
|
758
2150
|
if (coordinates.length < 2) {
|
|
759
2151
|
throw new Error("coordinates must be at least 2 numbers long");
|
|
760
2152
|
}
|
|
761
|
-
if (!
|
|
2153
|
+
if (!isNumber2(coordinates[0]) || !isNumber2(coordinates[1])) {
|
|
762
2154
|
throw new Error("coordinates must contain numbers");
|
|
763
2155
|
}
|
|
764
2156
|
const geom = {
|
|
@@ -817,7 +2209,7 @@ function multiPoint(coordinates, properties, options = {}) {
|
|
|
817
2209
|
};
|
|
818
2210
|
return feature(geom, properties, options);
|
|
819
2211
|
}
|
|
820
|
-
function
|
|
2212
|
+
function isNumber2(num) {
|
|
821
2213
|
return !isNaN(num) && num !== null && !Array.isArray(num);
|
|
822
2214
|
}
|
|
823
2215
|
|
|
@@ -2710,7 +4102,7 @@ import {
|
|
|
2710
4102
|
PlaneGeometry
|
|
2711
4103
|
} from "three";
|
|
2712
4104
|
import { largestRect } from "d3plus-shape";
|
|
2713
|
-
import { max, merge, isNumber as
|
|
4105
|
+
import { max, merge, isNumber as isNumber3, isArray as isArray2, range } from "lodash-es";
|
|
2714
4106
|
var OPTIONS3 = {
|
|
2715
4107
|
// Allowing click through and prevent interaction
|
|
2716
4108
|
interactive: false,
|
|
@@ -2856,7 +4248,7 @@ var GroundLabel = class extends BaseObject4 {
|
|
|
2856
4248
|
strokeStyle,
|
|
2857
4249
|
lineWidth
|
|
2858
4250
|
});
|
|
2859
|
-
const rectAngles =
|
|
4251
|
+
const rectAngles = isArray2(angle) ? angle : [angle];
|
|
2860
4252
|
material.needsUpdate = true;
|
|
2861
4253
|
const rect = largestRect(bound, {
|
|
2862
4254
|
cache: true,
|
|
@@ -2929,32 +4321,32 @@ var GroundLabel = class extends BaseObject4 {
|
|
|
2929
4321
|
return { x: this.#offsetX, y: this.#offsetY };
|
|
2930
4322
|
}
|
|
2931
4323
|
set offsetX(value) {
|
|
2932
|
-
if (
|
|
4324
|
+
if (isNumber3(value)) {
|
|
2933
4325
|
this.#offsetX = value;
|
|
2934
4326
|
this.#updatePosition();
|
|
2935
4327
|
}
|
|
2936
4328
|
}
|
|
2937
4329
|
set offsetY(value) {
|
|
2938
|
-
if (
|
|
4330
|
+
if (isNumber3(value)) {
|
|
2939
4331
|
this.#offsetY = value;
|
|
2940
4332
|
this.#updatePosition();
|
|
2941
4333
|
}
|
|
2942
4334
|
}
|
|
2943
4335
|
set angle(newAngle) {
|
|
2944
|
-
if (
|
|
4336
|
+
if (isNumber3(newAngle)) {
|
|
2945
4337
|
this.#angle = newAngle;
|
|
2946
4338
|
this.getObject3d().rotation.z = Math.PI / 180 * this.#angle;
|
|
2947
4339
|
}
|
|
2948
4340
|
}
|
|
2949
4341
|
setOffset(offsetX, offsetY) {
|
|
2950
|
-
if (
|
|
4342
|
+
if (isNumber3(offsetX) && isNumber3(offsetY)) {
|
|
2951
4343
|
this.#offsetX = offsetX;
|
|
2952
4344
|
this.#offsetY = offsetY;
|
|
2953
4345
|
this.#updatePosition();
|
|
2954
4346
|
}
|
|
2955
4347
|
}
|
|
2956
4348
|
addOffset(deltaX, deltaY) {
|
|
2957
|
-
if (
|
|
4349
|
+
if (isNumber3(deltaX) && isNumber3(deltaY)) {
|
|
2958
4350
|
this.#offsetX += deltaX;
|
|
2959
4351
|
this.#offsetY += deltaY;
|
|
2960
4352
|
this.#updatePosition();
|