venue-js 1.4.0-next.1 → 1.4.0-next.10

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.mjs CHANGED
@@ -364,6 +364,7 @@ var createPopulator = ({
364
364
  ...amenity.properties,
365
365
  ordinal: defaultLevel.properties.ordinal,
366
366
  level_name: defaultLevel.properties.name.en,
367
+ level: defaultLevel,
367
368
  units: populatedUnits,
368
369
  venue,
369
370
  _experimental_kiosk: kiosk ? await populateKiosk(kiosk) : null
@@ -372,6 +373,7 @@ var createPopulator = ({
372
373
  };
373
374
  const populateAnchor = async (anchor) => {
374
375
  const unit = await internalFindById(anchor.properties.unit_id);
376
+ const venue = await internalFindById(unit.properties.venue_id);
375
377
  const level = await internalFindById(unit.properties.level_id);
376
378
  const sections = await internalFilterByType("section");
377
379
  const section = sections.find((section2) => booleanWithin(anchor, section2));
@@ -381,7 +383,9 @@ var createPopulator = ({
381
383
  ...anchor.properties,
382
384
  level: await populateLevel(level),
383
385
  unit: await populateUnit(unit),
384
- section: section ? await populateSection(section) : null
386
+ section: section ? await populateSection(section) : null,
387
+ venue: await populateVenue(venue),
388
+ ordinal: level.properties.ordinal
385
389
  }
386
390
  };
387
391
  };
@@ -448,8 +452,8 @@ var createPopulator = ({
448
452
  anchor_id,
449
453
  venue_id,
450
454
  local_category_ids,
451
- promotion_ids,
452
- privilege_ids,
455
+ promotion_ids = [],
456
+ privilege_ids = [],
453
457
  kiosk_id,
454
458
  unit_id,
455
459
  kiosk_ids = [],
@@ -546,6 +550,20 @@ var createPopulator = ({
546
550
  }
547
551
  };
548
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
+ };
549
567
  const populateFeature = (feature2) => Promise.resolve(feature2);
550
568
  return {
551
569
  address: populateAddress,
@@ -570,12 +588,1378 @@ var createPopulator = ({
570
588
  section: populateSection,
571
589
  unit: populateUnit,
572
590
  venue: populateVenue,
573
- 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
574
1957
  };
575
1958
  };
576
1959
 
577
1960
  // src/data/getDataClient.ts
578
1961
  var getDataClient = (options) => {
1962
+ let searchClient;
579
1963
  const observers = /* @__PURE__ */ new Map();
580
1964
  const queryClient = options.queryClient ?? new QueryClient();
581
1965
  const { mode = "delivery", projectId, apiKey, baseUrl, previewToken } = options;
@@ -604,7 +1988,7 @@ var getDataClient = (options) => {
604
1988
  }
605
1989
  };
606
1990
  const internalFindById = async (id) => {
607
- if (id === null) return null;
1991
+ if (id === null || id === void 0) return null;
608
1992
  const featureType = id.slice(0, id.lastIndexOf("-"));
609
1993
  const feature2 = await queryClient.ensureQueryData({
610
1994
  queryKey: ["_deliveryapi", featureType, id],
@@ -687,6 +2071,17 @@ var getDataClient = (options) => {
687
2071
  const feature2 = await queryClient.ensureQueryData(findQueryOptions);
688
2072
  return feature2;
689
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
+ };
690
2085
  return {
691
2086
  projectId,
692
2087
  queryClient,
@@ -696,7 +2091,8 @@ var getDataClient = (options) => {
696
2091
  createFilterByTypeQueryOptions,
697
2092
  createFindByIdQueryOptions,
698
2093
  filterByType,
699
- findById
2094
+ findById,
2095
+ search: searchFn
700
2096
  };
701
2097
  };
702
2098
 
@@ -754,7 +2150,7 @@ function point(coordinates, properties, options = {}) {
754
2150
  if (coordinates.length < 2) {
755
2151
  throw new Error("coordinates must be at least 2 numbers long");
756
2152
  }
757
- if (!isNumber(coordinates[0]) || !isNumber(coordinates[1])) {
2153
+ if (!isNumber2(coordinates[0]) || !isNumber2(coordinates[1])) {
758
2154
  throw new Error("coordinates must contain numbers");
759
2155
  }
760
2156
  const geom = {
@@ -813,7 +2209,7 @@ function multiPoint(coordinates, properties, options = {}) {
813
2209
  };
814
2210
  return feature(geom, properties, options);
815
2211
  }
816
- function isNumber(num) {
2212
+ function isNumber2(num) {
817
2213
  return !isNaN(num) && num !== null && !Array.isArray(num);
818
2214
  }
819
2215
 
@@ -2706,7 +4102,7 @@ import {
2706
4102
  PlaneGeometry
2707
4103
  } from "three";
2708
4104
  import { largestRect } from "d3plus-shape";
2709
- import { max, merge, isNumber as isNumber2, isArray, range } from "lodash-es";
4105
+ import { max, merge, isNumber as isNumber3, isArray as isArray2, range } from "lodash-es";
2710
4106
  var OPTIONS3 = {
2711
4107
  // Allowing click through and prevent interaction
2712
4108
  interactive: false,
@@ -2852,7 +4248,7 @@ var GroundLabel = class extends BaseObject4 {
2852
4248
  strokeStyle,
2853
4249
  lineWidth
2854
4250
  });
2855
- const rectAngles = isArray(angle) ? angle : [angle];
4251
+ const rectAngles = isArray2(angle) ? angle : [angle];
2856
4252
  material.needsUpdate = true;
2857
4253
  const rect = largestRect(bound, {
2858
4254
  cache: true,
@@ -2925,32 +4321,32 @@ var GroundLabel = class extends BaseObject4 {
2925
4321
  return { x: this.#offsetX, y: this.#offsetY };
2926
4322
  }
2927
4323
  set offsetX(value) {
2928
- if (isNumber2(value)) {
4324
+ if (isNumber3(value)) {
2929
4325
  this.#offsetX = value;
2930
4326
  this.#updatePosition();
2931
4327
  }
2932
4328
  }
2933
4329
  set offsetY(value) {
2934
- if (isNumber2(value)) {
4330
+ if (isNumber3(value)) {
2935
4331
  this.#offsetY = value;
2936
4332
  this.#updatePosition();
2937
4333
  }
2938
4334
  }
2939
4335
  set angle(newAngle) {
2940
- if (isNumber2(newAngle)) {
4336
+ if (isNumber3(newAngle)) {
2941
4337
  this.#angle = newAngle;
2942
4338
  this.getObject3d().rotation.z = Math.PI / 180 * this.#angle;
2943
4339
  }
2944
4340
  }
2945
4341
  setOffset(offsetX, offsetY) {
2946
- if (isNumber2(offsetX) && isNumber2(offsetY)) {
4342
+ if (isNumber3(offsetX) && isNumber3(offsetY)) {
2947
4343
  this.#offsetX = offsetX;
2948
4344
  this.#offsetY = offsetY;
2949
4345
  this.#updatePosition();
2950
4346
  }
2951
4347
  }
2952
4348
  addOffset(deltaX, deltaY) {
2953
- if (isNumber2(deltaX) && isNumber2(deltaY)) {
4349
+ if (isNumber3(deltaX) && isNumber3(deltaY)) {
2954
4350
  this.#offsetX += deltaX;
2955
4351
  this.#offsetY += deltaY;
2956
4352
  this.#updatePosition();