2024-05-30 02:02:10 +00:00
var _ _defProp = Object . defineProperty ;
var _ _defNormalProp = ( obj , key , value ) => key in obj ? _ _defProp ( obj , key , { enumerable : true , configurable : true , writable : true , value } ) : obj [ key ] = value ;
var _ _publicField = ( obj , key , value ) => {
_ _defNormalProp ( obj , typeof key !== "symbol" ? key + "" : key , value ) ;
return value ;
} ;
2024-09-24 08:56:37 +00:00
import { Y as _ _vitePreload , j as ref , x as watch , an as unrefElement , ao as tryOnScopeDispose , d as defineComponent , G as shallowRef , ap as computedAsync , h as computed , aq as useSessionStorage , ar as useLocalStorage , y as watchEffect , as as watchDebounced , k as onMounted , S as nextTick , R as onKeyStroke , a6 as useRouter , at as useEventListener , Z as useScrollLock , V as inBrowser , au as onBeforeUnmount , o as openBlock , b as createBlock , l as createBaseVNode , a2 as withModifiers , m as unref , av as withDirectives , aw as vModelText , ax as isRef , c as createElementBlock , n as normalizeClass , e as createCommentVNode , E as renderList , F as Fragment , a as createTextVNode , t as toDisplayString , ay as Teleport , p as pushScopeId , q as popScopeId , az as markRaw , aA as createApp , ac as dataSymbol , ai as pathToFile , aB as escapeRegExp , _ as _export _sfc } from "./framework.B9AX-CPi.js" ;
2024-11-28 19:47:26 +00:00
import { u as useData , c as createSearchTranslate } from "./theme.CPi0LPa_.js" ;
const localSearchIndex = { "root" : ( ) => _ _vitePreload ( ( ) => import ( "./@localSearchIndexroot.DgmWZKo4.js" ) , true ? [ ] : void 0 ) } ;
2024-05-30 02:02:10 +00:00
/ * !
* tabbable 6.2 . 0
* @ license MIT , https : //github.com/focus-trap/tabbable/blob/master/LICENSE
* /
var candidateSelectors = [ "input:not([inert])" , "select:not([inert])" , "textarea:not([inert])" , "a[href]:not([inert])" , "button:not([inert])" , "[tabindex]:not(slot):not([inert])" , "audio[controls]:not([inert])" , "video[controls]:not([inert])" , '[contenteditable]:not([contenteditable="false"]):not([inert])' , "details>summary:first-of-type:not([inert])" , "details:not([inert])" ] ;
var candidateSelector = /* @__PURE__ */ candidateSelectors . join ( "," ) ;
var NoElement = typeof Element === "undefined" ;
var matches = NoElement ? function ( ) {
} : Element . prototype . matches || Element . prototype . msMatchesSelector || Element . prototype . webkitMatchesSelector ;
var getRootNode = ! NoElement && Element . prototype . getRootNode ? function ( element ) {
var _element$getRootNode ;
return element === null || element === void 0 ? void 0 : ( _element$getRootNode = element . getRootNode ) === null || _element$getRootNode === void 0 ? void 0 : _element$getRootNode . call ( element ) ;
} : function ( element ) {
return element === null || element === void 0 ? void 0 : element . ownerDocument ;
} ;
var isInert = function isInert2 ( node , lookUp ) {
var _node$getAttribute ;
if ( lookUp === void 0 ) {
lookUp = true ;
}
var inertAtt = node === null || node === void 0 ? void 0 : ( _node$getAttribute = node . getAttribute ) === null || _node$getAttribute === void 0 ? void 0 : _node$getAttribute . call ( node , "inert" ) ;
var inert = inertAtt === "" || inertAtt === "true" ;
var result = inert || lookUp && node && isInert2 ( node . parentNode ) ;
return result ;
} ;
var isContentEditable = function isContentEditable2 ( node ) {
var _node$getAttribute2 ;
var attValue = node === null || node === void 0 ? void 0 : ( _node$getAttribute2 = node . getAttribute ) === null || _node$getAttribute2 === void 0 ? void 0 : _node$getAttribute2 . call ( node , "contenteditable" ) ;
return attValue === "" || attValue === "true" ;
} ;
var getCandidates = function getCandidates2 ( el , includeContainer , filter ) {
if ( isInert ( el ) ) {
return [ ] ;
}
var candidates = Array . prototype . slice . apply ( el . querySelectorAll ( candidateSelector ) ) ;
if ( includeContainer && matches . call ( el , candidateSelector ) ) {
candidates . unshift ( el ) ;
}
candidates = candidates . filter ( filter ) ;
return candidates ;
} ;
var getCandidatesIteratively = function getCandidatesIteratively2 ( elements , includeContainer , options ) {
var candidates = [ ] ;
var elementsToCheck = Array . from ( elements ) ;
while ( elementsToCheck . length ) {
var element = elementsToCheck . shift ( ) ;
if ( isInert ( element , false ) ) {
continue ;
}
if ( element . tagName === "SLOT" ) {
var assigned = element . assignedElements ( ) ;
var content = assigned . length ? assigned : element . children ;
var nestedCandidates = getCandidatesIteratively2 ( content , true , options ) ;
if ( options . flatten ) {
candidates . push . apply ( candidates , nestedCandidates ) ;
} else {
candidates . push ( {
scopeParent : element ,
candidates : nestedCandidates
} ) ;
}
} else {
var validCandidate = matches . call ( element , candidateSelector ) ;
if ( validCandidate && options . filter ( element ) && ( includeContainer || ! elements . includes ( element ) ) ) {
candidates . push ( element ) ;
}
var shadowRoot = element . shadowRoot || // check for an undisclosed shadow
typeof options . getShadowRoot === "function" && options . getShadowRoot ( element ) ;
var validShadowRoot = ! isInert ( shadowRoot , false ) && ( ! options . shadowRootFilter || options . shadowRootFilter ( element ) ) ;
if ( shadowRoot && validShadowRoot ) {
var _nestedCandidates = getCandidatesIteratively2 ( shadowRoot === true ? element . children : shadowRoot . children , true , options ) ;
if ( options . flatten ) {
candidates . push . apply ( candidates , _nestedCandidates ) ;
} else {
candidates . push ( {
scopeParent : element ,
candidates : _nestedCandidates
} ) ;
}
} else {
elementsToCheck . unshift . apply ( elementsToCheck , element . children ) ;
}
}
}
return candidates ;
} ;
var hasTabIndex = function hasTabIndex2 ( node ) {
return ! isNaN ( parseInt ( node . getAttribute ( "tabindex" ) , 10 ) ) ;
} ;
var getTabIndex = function getTabIndex2 ( node ) {
if ( ! node ) {
throw new Error ( "No node provided" ) ;
}
if ( node . tabIndex < 0 ) {
if ( ( /^(AUDIO|VIDEO|DETAILS)$/ . test ( node . tagName ) || isContentEditable ( node ) ) && ! hasTabIndex ( node ) ) {
return 0 ;
}
}
return node . tabIndex ;
} ;
var getSortOrderTabIndex = function getSortOrderTabIndex2 ( node , isScope ) {
var tabIndex = getTabIndex ( node ) ;
if ( tabIndex < 0 && isScope && ! hasTabIndex ( node ) ) {
return 0 ;
}
return tabIndex ;
} ;
var sortOrderedTabbables = function sortOrderedTabbables2 ( a , b ) {
return a . tabIndex === b . tabIndex ? a . documentOrder - b . documentOrder : a . tabIndex - b . tabIndex ;
} ;
var isInput = function isInput2 ( node ) {
return node . tagName === "INPUT" ;
} ;
var isHiddenInput = function isHiddenInput2 ( node ) {
return isInput ( node ) && node . type === "hidden" ;
} ;
var isDetailsWithSummary = function isDetailsWithSummary2 ( node ) {
var r = node . tagName === "DETAILS" && Array . prototype . slice . apply ( node . children ) . some ( function ( child ) {
return child . tagName === "SUMMARY" ;
} ) ;
return r ;
} ;
var getCheckedRadio = function getCheckedRadio2 ( nodes , form ) {
for ( var i = 0 ; i < nodes . length ; i ++ ) {
if ( nodes [ i ] . checked && nodes [ i ] . form === form ) {
return nodes [ i ] ;
}
}
} ;
var isTabbableRadio = function isTabbableRadio2 ( node ) {
if ( ! node . name ) {
return true ;
}
var radioScope = node . form || getRootNode ( node ) ;
var queryRadios = function queryRadios2 ( name ) {
return radioScope . querySelectorAll ( 'input[type="radio"][name="' + name + '"]' ) ;
} ;
var radioSet ;
if ( typeof window !== "undefined" && typeof window . CSS !== "undefined" && typeof window . CSS . escape === "function" ) {
radioSet = queryRadios ( window . CSS . escape ( node . name ) ) ;
} else {
try {
radioSet = queryRadios ( node . name ) ;
} catch ( err ) {
console . error ( "Looks like you have a radio button with a name attribute containing invalid CSS selector characters and need the CSS.escape polyfill: %s" , err . message ) ;
return false ;
}
}
var checked = getCheckedRadio ( radioSet , node . form ) ;
return ! checked || checked === node ;
} ;
var isRadio = function isRadio2 ( node ) {
return isInput ( node ) && node . type === "radio" ;
} ;
var isNonTabbableRadio = function isNonTabbableRadio2 ( node ) {
return isRadio ( node ) && ! isTabbableRadio ( node ) ;
} ;
var isNodeAttached = function isNodeAttached2 ( node ) {
var _nodeRoot ;
var nodeRoot = node && getRootNode ( node ) ;
var nodeRootHost = ( _nodeRoot = nodeRoot ) === null || _nodeRoot === void 0 ? void 0 : _nodeRoot . host ;
var attached = false ;
if ( nodeRoot && nodeRoot !== node ) {
var _nodeRootHost , _nodeRootHost$ownerDo , _node$ownerDocument ;
attached = ! ! ( ( _nodeRootHost = nodeRootHost ) !== null && _nodeRootHost !== void 0 && ( _nodeRootHost$ownerDo = _nodeRootHost . ownerDocument ) !== null && _nodeRootHost$ownerDo !== void 0 && _nodeRootHost$ownerDo . contains ( nodeRootHost ) || node !== null && node !== void 0 && ( _node$ownerDocument = node . ownerDocument ) !== null && _node$ownerDocument !== void 0 && _node$ownerDocument . contains ( node ) ) ;
while ( ! attached && nodeRootHost ) {
var _nodeRoot2 , _nodeRootHost2 , _nodeRootHost2$ownerD ;
nodeRoot = getRootNode ( nodeRootHost ) ;
nodeRootHost = ( _nodeRoot2 = nodeRoot ) === null || _nodeRoot2 === void 0 ? void 0 : _nodeRoot2 . host ;
attached = ! ! ( ( _nodeRootHost2 = nodeRootHost ) !== null && _nodeRootHost2 !== void 0 && ( _nodeRootHost2$ownerD = _nodeRootHost2 . ownerDocument ) !== null && _nodeRootHost2$ownerD !== void 0 && _nodeRootHost2$ownerD . contains ( nodeRootHost ) ) ;
}
}
return attached ;
} ;
var isZeroArea = function isZeroArea2 ( node ) {
var _node$getBoundingClie = node . getBoundingClientRect ( ) , width = _node$getBoundingClie . width , height = _node$getBoundingClie . height ;
return width === 0 && height === 0 ;
} ;
var isHidden = function isHidden2 ( node , _ref ) {
var displayCheck = _ref . displayCheck , getShadowRoot = _ref . getShadowRoot ;
if ( getComputedStyle ( node ) . visibility === "hidden" ) {
return true ;
}
var isDirectSummary = matches . call ( node , "details>summary:first-of-type" ) ;
var nodeUnderDetails = isDirectSummary ? node . parentElement : node ;
if ( matches . call ( nodeUnderDetails , "details:not([open]) *" ) ) {
return true ;
}
if ( ! displayCheck || displayCheck === "full" || displayCheck === "legacy-full" ) {
if ( typeof getShadowRoot === "function" ) {
var originalNode = node ;
while ( node ) {
var parentElement = node . parentElement ;
var rootNode = getRootNode ( node ) ;
if ( parentElement && ! parentElement . shadowRoot && getShadowRoot ( parentElement ) === true ) {
return isZeroArea ( node ) ;
} else if ( node . assignedSlot ) {
node = node . assignedSlot ;
} else if ( ! parentElement && rootNode !== node . ownerDocument ) {
node = rootNode . host ;
} else {
node = parentElement ;
}
}
node = originalNode ;
}
if ( isNodeAttached ( node ) ) {
return ! node . getClientRects ( ) . length ;
}
if ( displayCheck !== "legacy-full" ) {
return true ;
}
} else if ( displayCheck === "non-zero-area" ) {
return isZeroArea ( node ) ;
}
return false ;
} ;
var isDisabledFromFieldset = function isDisabledFromFieldset2 ( node ) {
if ( /^(INPUT|BUTTON|SELECT|TEXTAREA)$/ . test ( node . tagName ) ) {
var parentNode = node . parentElement ;
while ( parentNode ) {
if ( parentNode . tagName === "FIELDSET" && parentNode . disabled ) {
for ( var i = 0 ; i < parentNode . children . length ; i ++ ) {
var child = parentNode . children . item ( i ) ;
if ( child . tagName === "LEGEND" ) {
return matches . call ( parentNode , "fieldset[disabled] *" ) ? true : ! child . contains ( node ) ;
}
}
return true ;
}
parentNode = parentNode . parentElement ;
}
}
return false ;
} ;
var isNodeMatchingSelectorFocusable = function isNodeMatchingSelectorFocusable2 ( options , node ) {
if ( node . disabled || // we must do an inert look up to filter out any elements inside an inert ancestor
// because we're limited in the type of selectors we can use in JSDom (see related
// note related to `candidateSelectors`)
isInert ( node ) || isHiddenInput ( node ) || isHidden ( node , options ) || // For a details element with a summary, the summary element gets the focus
isDetailsWithSummary ( node ) || isDisabledFromFieldset ( node ) ) {
return false ;
}
return true ;
} ;
var isNodeMatchingSelectorTabbable = function isNodeMatchingSelectorTabbable2 ( options , node ) {
if ( isNonTabbableRadio ( node ) || getTabIndex ( node ) < 0 || ! isNodeMatchingSelectorFocusable ( options , node ) ) {
return false ;
}
return true ;
} ;
var isValidShadowRootTabbable = function isValidShadowRootTabbable2 ( shadowHostNode ) {
var tabIndex = parseInt ( shadowHostNode . getAttribute ( "tabindex" ) , 10 ) ;
if ( isNaN ( tabIndex ) || tabIndex >= 0 ) {
return true ;
}
return false ;
} ;
var sortByOrder = function sortByOrder2 ( candidates ) {
var regularTabbables = [ ] ;
var orderedTabbables = [ ] ;
candidates . forEach ( function ( item , i ) {
var isScope = ! ! item . scopeParent ;
var element = isScope ? item . scopeParent : item ;
var candidateTabindex = getSortOrderTabIndex ( element , isScope ) ;
var elements = isScope ? sortByOrder2 ( item . candidates ) : element ;
if ( candidateTabindex === 0 ) {
isScope ? regularTabbables . push . apply ( regularTabbables , elements ) : regularTabbables . push ( element ) ;
} else {
orderedTabbables . push ( {
documentOrder : i ,
tabIndex : candidateTabindex ,
item ,
isScope ,
content : elements
} ) ;
}
} ) ;
return orderedTabbables . sort ( sortOrderedTabbables ) . reduce ( function ( acc , sortable ) {
sortable . isScope ? acc . push . apply ( acc , sortable . content ) : acc . push ( sortable . content ) ;
return acc ;
} , [ ] ) . concat ( regularTabbables ) ;
} ;
var tabbable = function tabbable2 ( container , options ) {
options = options || { } ;
var candidates ;
if ( options . getShadowRoot ) {
candidates = getCandidatesIteratively ( [ container ] , options . includeContainer , {
filter : isNodeMatchingSelectorTabbable . bind ( null , options ) ,
flatten : false ,
getShadowRoot : options . getShadowRoot ,
shadowRootFilter : isValidShadowRootTabbable
} ) ;
} else {
candidates = getCandidates ( container , options . includeContainer , isNodeMatchingSelectorTabbable . bind ( null , options ) ) ;
}
return sortByOrder ( candidates ) ;
} ;
var focusable = function focusable2 ( container , options ) {
options = options || { } ;
var candidates ;
if ( options . getShadowRoot ) {
candidates = getCandidatesIteratively ( [ container ] , options . includeContainer , {
filter : isNodeMatchingSelectorFocusable . bind ( null , options ) ,
flatten : true ,
getShadowRoot : options . getShadowRoot
} ) ;
} else {
candidates = getCandidates ( container , options . includeContainer , isNodeMatchingSelectorFocusable . bind ( null , options ) ) ;
}
return candidates ;
} ;
var isTabbable = function isTabbable2 ( node , options ) {
options = options || { } ;
if ( ! node ) {
throw new Error ( "No node provided" ) ;
}
if ( matches . call ( node , candidateSelector ) === false ) {
return false ;
}
return isNodeMatchingSelectorTabbable ( options , node ) ;
} ;
var focusableCandidateSelector = /* @__PURE__ */ candidateSelectors . concat ( "iframe" ) . join ( "," ) ;
var isFocusable = function isFocusable2 ( node , options ) {
options = options || { } ;
if ( ! node ) {
throw new Error ( "No node provided" ) ;
}
if ( matches . call ( node , focusableCandidateSelector ) === false ) {
return false ;
}
return isNodeMatchingSelectorFocusable ( options , node ) ;
} ;
/ * !
* focus - trap 7.5 . 4
* @ license MIT , https : //github.com/focus-trap/focus-trap/blob/master/LICENSE
* /
function ownKeys ( e , r ) {
var t = Object . keys ( e ) ;
if ( Object . getOwnPropertySymbols ) {
var o = Object . getOwnPropertySymbols ( e ) ;
r && ( o = o . filter ( function ( r2 ) {
return Object . getOwnPropertyDescriptor ( e , r2 ) . enumerable ;
} ) ) , t . push . apply ( t , o ) ;
}
return t ;
}
function _objectSpread2 ( e ) {
for ( var r = 1 ; r < arguments . length ; r ++ ) {
var t = null != arguments [ r ] ? arguments [ r ] : { } ;
r % 2 ? ownKeys ( Object ( t ) , true ) . forEach ( function ( r2 ) {
_defineProperty ( e , r2 , t [ r2 ] ) ;
} ) : Object . getOwnPropertyDescriptors ? Object . defineProperties ( e , Object . getOwnPropertyDescriptors ( t ) ) : ownKeys ( Object ( t ) ) . forEach ( function ( r2 ) {
Object . defineProperty ( e , r2 , Object . getOwnPropertyDescriptor ( t , r2 ) ) ;
} ) ;
}
return e ;
}
function _defineProperty ( obj , key , value ) {
key = _toPropertyKey ( key ) ;
if ( key in obj ) {
Object . defineProperty ( obj , key , {
value ,
enumerable : true ,
configurable : true ,
writable : true
} ) ;
} else {
obj [ key ] = value ;
}
return obj ;
}
function _toPrimitive ( input , hint ) {
if ( typeof input !== "object" || input === null )
return input ;
var prim = input [ Symbol . toPrimitive ] ;
if ( prim !== void 0 ) {
var res = prim . call ( input , hint || "default" ) ;
if ( typeof res !== "object" )
return res ;
throw new TypeError ( "@@toPrimitive must return a primitive value." ) ;
}
return ( hint === "string" ? String : Number ) ( input ) ;
}
function _toPropertyKey ( arg ) {
var key = _toPrimitive ( arg , "string" ) ;
return typeof key === "symbol" ? key : String ( key ) ;
}
var activeFocusTraps = {
activateTrap : function activateTrap ( trapStack , trap ) {
if ( trapStack . length > 0 ) {
var activeTrap = trapStack [ trapStack . length - 1 ] ;
if ( activeTrap !== trap ) {
activeTrap . pause ( ) ;
}
}
var trapIndex = trapStack . indexOf ( trap ) ;
if ( trapIndex === - 1 ) {
trapStack . push ( trap ) ;
} else {
trapStack . splice ( trapIndex , 1 ) ;
trapStack . push ( trap ) ;
}
} ,
deactivateTrap : function deactivateTrap ( trapStack , trap ) {
var trapIndex = trapStack . indexOf ( trap ) ;
if ( trapIndex !== - 1 ) {
trapStack . splice ( trapIndex , 1 ) ;
}
if ( trapStack . length > 0 ) {
trapStack [ trapStack . length - 1 ] . unpause ( ) ;
}
}
} ;
var isSelectableInput = function isSelectableInput2 ( node ) {
return node . tagName && node . tagName . toLowerCase ( ) === "input" && typeof node . select === "function" ;
} ;
var isEscapeEvent = function isEscapeEvent2 ( e ) {
return ( e === null || e === void 0 ? void 0 : e . key ) === "Escape" || ( e === null || e === void 0 ? void 0 : e . key ) === "Esc" || ( e === null || e === void 0 ? void 0 : e . keyCode ) === 27 ;
} ;
var isTabEvent = function isTabEvent2 ( e ) {
return ( e === null || e === void 0 ? void 0 : e . key ) === "Tab" || ( e === null || e === void 0 ? void 0 : e . keyCode ) === 9 ;
} ;
var isKeyForward = function isKeyForward2 ( e ) {
return isTabEvent ( e ) && ! e . shiftKey ;
} ;
var isKeyBackward = function isKeyBackward2 ( e ) {
return isTabEvent ( e ) && e . shiftKey ;
} ;
var delay = function delay2 ( fn ) {
return setTimeout ( fn , 0 ) ;
} ;
var findIndex = function findIndex2 ( arr , fn ) {
var idx = - 1 ;
arr . every ( function ( value , i ) {
if ( fn ( value ) ) {
idx = i ;
return false ;
}
return true ;
} ) ;
return idx ;
} ;
var valueOrHandler = function valueOrHandler2 ( value ) {
for ( var _len = arguments . length , params = new Array ( _len > 1 ? _len - 1 : 0 ) , _key = 1 ; _key < _len ; _key ++ ) {
params [ _key - 1 ] = arguments [ _key ] ;
}
return typeof value === "function" ? value . apply ( void 0 , params ) : value ;
} ;
var getActualTarget = function getActualTarget2 ( event ) {
return event . target . shadowRoot && typeof event . composedPath === "function" ? event . composedPath ( ) [ 0 ] : event . target ;
} ;
var internalTrapStack = [ ] ;
var createFocusTrap = function createFocusTrap2 ( elements , userOptions ) {
var doc = ( userOptions === null || userOptions === void 0 ? void 0 : userOptions . document ) || document ;
var trapStack = ( userOptions === null || userOptions === void 0 ? void 0 : userOptions . trapStack ) || internalTrapStack ;
var config = _objectSpread2 ( {
returnFocusOnDeactivate : true ,
escapeDeactivates : true ,
delayInitialFocus : true ,
isKeyForward ,
isKeyBackward
} , userOptions ) ;
var state = {
// containers given to createFocusTrap()
// @type {Array<HTMLElement>}
containers : [ ] ,
// list of objects identifying tabbable nodes in `containers` in the trap
// NOTE: it's possible that a group has no tabbable nodes if nodes get removed while the trap
// is active, but the trap should never get to a state where there isn't at least one group
// with at least one tabbable node in it (that would lead to an error condition that would
// result in an error being thrown)
// @type {Array<{
// container: HTMLElement,
// tabbableNodes: Array<HTMLElement>, // empty if none
// focusableNodes: Array<HTMLElement>, // empty if none
// posTabIndexesFound: boolean,
// firstTabbableNode: HTMLElement|undefined,
// lastTabbableNode: HTMLElement|undefined,
// firstDomTabbableNode: HTMLElement|undefined,
// lastDomTabbableNode: HTMLElement|undefined,
// nextTabbableNode: (node: HTMLElement, forward: boolean) => HTMLElement|undefined
// }>}
containerGroups : [ ] ,
// same order/length as `containers` list
// references to objects in `containerGroups`, but only those that actually have
// tabbable nodes in them
// NOTE: same order as `containers` and `containerGroups`, but __not necessarily__
// the same length
tabbableGroups : [ ] ,
nodeFocusedBeforeActivation : null ,
mostRecentlyFocusedNode : null ,
active : false ,
paused : false ,
// timer ID for when delayInitialFocus is true and initial focus in this trap
// has been delayed during activation
delayInitialFocusTimer : void 0 ,
// the most recent KeyboardEvent for the configured nav key (typically [SHIFT+]TAB), if any
recentNavEvent : void 0
} ;
var trap ;
var getOption = function getOption2 ( configOverrideOptions , optionName , configOptionName ) {
return configOverrideOptions && configOverrideOptions [ optionName ] !== void 0 ? configOverrideOptions [ optionName ] : config [ configOptionName || optionName ] ;
} ;
var findContainerIndex = function findContainerIndex2 ( element , event ) {
var composedPath = typeof ( event === null || event === void 0 ? void 0 : event . composedPath ) === "function" ? event . composedPath ( ) : void 0 ;
return state . containerGroups . findIndex ( function ( _ref ) {
var container = _ref . container , tabbableNodes = _ref . tabbableNodes ;
return container . contains ( element ) || // fall back to explicit tabbable search which will take into consideration any
// web components if the `tabbableOptions.getShadowRoot` option was used for
// the trap, enabling shadow DOM support in tabbable (`Node.contains()` doesn't
// look inside web components even if open)
( composedPath === null || composedPath === void 0 ? void 0 : composedPath . includes ( container ) ) || tabbableNodes . find ( function ( node ) {
return node === element ;
} ) ;
} ) ;
} ;
var getNodeForOption = function getNodeForOption2 ( optionName ) {
var optionValue = config [ optionName ] ;
if ( typeof optionValue === "function" ) {
for ( var _len2 = arguments . length , params = new Array ( _len2 > 1 ? _len2 - 1 : 0 ) , _key2 = 1 ; _key2 < _len2 ; _key2 ++ ) {
params [ _key2 - 1 ] = arguments [ _key2 ] ;
}
optionValue = optionValue . apply ( void 0 , params ) ;
}
if ( optionValue === true ) {
optionValue = void 0 ;
}
if ( ! optionValue ) {
if ( optionValue === void 0 || optionValue === false ) {
return optionValue ;
}
throw new Error ( "`" . concat ( optionName , "` was specified but was not a node, or did not return a node" ) ) ;
}
var node = optionValue ;
if ( typeof optionValue === "string" ) {
node = doc . querySelector ( optionValue ) ;
if ( ! node ) {
throw new Error ( "`" . concat ( optionName , "` as selector refers to no known node" ) ) ;
}
}
return node ;
} ;
var getInitialFocusNode = function getInitialFocusNode2 ( ) {
var node = getNodeForOption ( "initialFocus" ) ;
if ( node === false ) {
return false ;
}
if ( node === void 0 || ! isFocusable ( node , config . tabbableOptions ) ) {
if ( findContainerIndex ( doc . activeElement ) >= 0 ) {
node = doc . activeElement ;
} else {
var firstTabbableGroup = state . tabbableGroups [ 0 ] ;
var firstTabbableNode = firstTabbableGroup && firstTabbableGroup . firstTabbableNode ;
node = firstTabbableNode || getNodeForOption ( "fallbackFocus" ) ;
}
}
if ( ! node ) {
throw new Error ( "Your focus-trap needs to have at least one focusable element" ) ;
}
return node ;
} ;
var updateTabbableNodes = function updateTabbableNodes2 ( ) {
state . containerGroups = state . containers . map ( function ( container ) {
var tabbableNodes = tabbable ( container , config . tabbableOptions ) ;
var focusableNodes = focusable ( container , config . tabbableOptions ) ;
var firstTabbableNode = tabbableNodes . length > 0 ? tabbableNodes [ 0 ] : void 0 ;
var lastTabbableNode = tabbableNodes . length > 0 ? tabbableNodes [ tabbableNodes . length - 1 ] : void 0 ;
var firstDomTabbableNode = focusableNodes . find ( function ( node ) {
return isTabbable ( node ) ;
} ) ;
var lastDomTabbableNode = focusableNodes . slice ( ) . reverse ( ) . find ( function ( node ) {
return isTabbable ( node ) ;
} ) ;
var posTabIndexesFound = ! ! tabbableNodes . find ( function ( node ) {
return getTabIndex ( node ) > 0 ;
} ) ;
return {
container ,
tabbableNodes ,
focusableNodes ,
/** True if at least one node with positive `tabindex` was found in this container. */
posTabIndexesFound ,
/** First tabbable node in container, __tabindex__ order; `undefined` if none. */
firstTabbableNode ,
/** Last tabbable node in container, __tabindex__ order; `undefined` if none. */
lastTabbableNode ,
// NOTE: DOM order is NOT NECESSARILY "document position" order, but figuring that out
// would require more than just https://developer.mozilla.org/en-US/docs/Web/API/Node/compareDocumentPosition
// because that API doesn't work with Shadow DOM as well as it should (@see
// https://github.com/whatwg/dom/issues/320) and since this first/last is only needed, so far,
// to address an edge case related to positive tabindex support, this seems like a much easier,
// "close enough most of the time" alternative for positive tabindexes which should generally
// be avoided anyway...
/** First tabbable node in container, __DOM__ order; `undefined` if none. */
firstDomTabbableNode ,
/** Last tabbable node in container, __DOM__ order; `undefined` if none. */
lastDomTabbableNode ,
/ * *
* Finds the _ _tabbable _ _ node that follows the given node in the specified direction ,
* in this container , if any .
* @ param { HTMLElement } node
* @ param { boolean } [ forward ] True if going in forward tab order ; false if going
* in reverse .
* @ returns { HTMLElement | undefined } The next tabbable node , if any .
* /
nextTabbableNode : function nextTabbableNode ( node ) {
var forward = arguments . length > 1 && arguments [ 1 ] !== void 0 ? arguments [ 1 ] : true ;
var nodeIdx = tabbableNodes . indexOf ( node ) ;
if ( nodeIdx < 0 ) {
if ( forward ) {
return focusableNodes . slice ( focusableNodes . indexOf ( node ) + 1 ) . find ( function ( el ) {
return isTabbable ( el ) ;
} ) ;
}
return focusableNodes . slice ( 0 , focusableNodes . indexOf ( node ) ) . reverse ( ) . find ( function ( el ) {
return isTabbable ( el ) ;
} ) ;
}
return tabbableNodes [ nodeIdx + ( forward ? 1 : - 1 ) ] ;
}
} ;
} ) ;
state . tabbableGroups = state . containerGroups . filter ( function ( group ) {
return group . tabbableNodes . length > 0 ;
} ) ;
if ( state . tabbableGroups . length <= 0 && ! getNodeForOption ( "fallbackFocus" ) ) {
throw new Error ( "Your focus-trap must have at least one container with at least one tabbable node in it at all times" ) ;
}
if ( state . containerGroups . find ( function ( g ) {
return g . posTabIndexesFound ;
} ) && state . containerGroups . length > 1 ) {
throw new Error ( "At least one node with a positive tabindex was found in one of your focus-trap's multiple containers. Positive tabindexes are only supported in single-container focus-traps." ) ;
}
} ;
var getActiveElement = function getActiveElement2 ( el ) {
var activeElement = el . activeElement ;
if ( ! activeElement ) {
return ;
}
if ( activeElement . shadowRoot && activeElement . shadowRoot . activeElement !== null ) {
return getActiveElement2 ( activeElement . shadowRoot ) ;
}
return activeElement ;
} ;
var tryFocus = function tryFocus2 ( node ) {
if ( node === false ) {
return ;
}
if ( node === getActiveElement ( document ) ) {
return ;
}
if ( ! node || ! node . focus ) {
tryFocus2 ( getInitialFocusNode ( ) ) ;
return ;
}
node . focus ( {
preventScroll : ! ! config . preventScroll
} ) ;
state . mostRecentlyFocusedNode = node ;
if ( isSelectableInput ( node ) ) {
node . select ( ) ;
}
} ;
var getReturnFocusNode = function getReturnFocusNode2 ( previousActiveElement ) {
var node = getNodeForOption ( "setReturnFocus" , previousActiveElement ) ;
return node ? node : node === false ? false : previousActiveElement ;
} ;
var findNextNavNode = function findNextNavNode2 ( _ref2 ) {
var target = _ref2 . target , event = _ref2 . event , _ref2$isBackward = _ref2 . isBackward , isBackward = _ref2$isBackward === void 0 ? false : _ref2$isBackward ;
target = target || getActualTarget ( event ) ;
updateTabbableNodes ( ) ;
var destinationNode = null ;
if ( state . tabbableGroups . length > 0 ) {
var containerIndex = findContainerIndex ( target , event ) ;
var containerGroup = containerIndex >= 0 ? state . containerGroups [ containerIndex ] : void 0 ;
if ( containerIndex < 0 ) {
if ( isBackward ) {
destinationNode = state . tabbableGroups [ state . tabbableGroups . length - 1 ] . lastTabbableNode ;
} else {
destinationNode = state . tabbableGroups [ 0 ] . firstTabbableNode ;
}
} else if ( isBackward ) {
var startOfGroupIndex = findIndex ( state . tabbableGroups , function ( _ref3 ) {
var firstTabbableNode = _ref3 . firstTabbableNode ;
return target === firstTabbableNode ;
} ) ;
if ( startOfGroupIndex < 0 && ( containerGroup . container === target || isFocusable ( target , config . tabbableOptions ) && ! isTabbable ( target , config . tabbableOptions ) && ! containerGroup . nextTabbableNode ( target , false ) ) ) {
startOfGroupIndex = containerIndex ;
}
if ( startOfGroupIndex >= 0 ) {
var destinationGroupIndex = startOfGroupIndex === 0 ? state . tabbableGroups . length - 1 : startOfGroupIndex - 1 ;
var destinationGroup = state . tabbableGroups [ destinationGroupIndex ] ;
destinationNode = getTabIndex ( target ) >= 0 ? destinationGroup . lastTabbableNode : destinationGroup . lastDomTabbableNode ;
} else if ( ! isTabEvent ( event ) ) {
destinationNode = containerGroup . nextTabbableNode ( target , false ) ;
}
} else {
var lastOfGroupIndex = findIndex ( state . tabbableGroups , function ( _ref4 ) {
var lastTabbableNode = _ref4 . lastTabbableNode ;
return target === lastTabbableNode ;
} ) ;
if ( lastOfGroupIndex < 0 && ( containerGroup . container === target || isFocusable ( target , config . tabbableOptions ) && ! isTabbable ( target , config . tabbableOptions ) && ! containerGroup . nextTabbableNode ( target ) ) ) {
lastOfGroupIndex = containerIndex ;
}
if ( lastOfGroupIndex >= 0 ) {
var _destinationGroupIndex = lastOfGroupIndex === state . tabbableGroups . length - 1 ? 0 : lastOfGroupIndex + 1 ;
var _destinationGroup = state . tabbableGroups [ _destinationGroupIndex ] ;
destinationNode = getTabIndex ( target ) >= 0 ? _destinationGroup . firstTabbableNode : _destinationGroup . firstDomTabbableNode ;
} else if ( ! isTabEvent ( event ) ) {
destinationNode = containerGroup . nextTabbableNode ( target ) ;
}
}
} else {
destinationNode = getNodeForOption ( "fallbackFocus" ) ;
}
return destinationNode ;
} ;
var checkPointerDown = function checkPointerDown2 ( e ) {
var target = getActualTarget ( e ) ;
if ( findContainerIndex ( target , e ) >= 0 ) {
return ;
}
if ( valueOrHandler ( config . clickOutsideDeactivates , e ) ) {
trap . deactivate ( {
// NOTE: by setting `returnFocus: false`, deactivate() will do nothing,
// which will result in the outside click setting focus to the node
// that was clicked (and if not focusable, to "nothing"); by setting
// `returnFocus: true`, we'll attempt to re-focus the node originally-focused
// on activation (or the configured `setReturnFocus` node), whether the
// outside click was on a focusable node or not
returnFocus : config . returnFocusOnDeactivate
} ) ;
return ;
}
if ( valueOrHandler ( config . allowOutsideClick , e ) ) {
return ;
}
e . preventDefault ( ) ;
} ;
var checkFocusIn = function checkFocusIn2 ( event ) {
var target = getActualTarget ( event ) ;
var targetContained = findContainerIndex ( target , event ) >= 0 ;
if ( targetContained || target instanceof Document ) {
if ( targetContained ) {
state . mostRecentlyFocusedNode = target ;
}
} else {
event . stopImmediatePropagation ( ) ;
var nextNode ;
var navAcrossContainers = true ;
if ( state . mostRecentlyFocusedNode ) {
if ( getTabIndex ( state . mostRecentlyFocusedNode ) > 0 ) {
var mruContainerIdx = findContainerIndex ( state . mostRecentlyFocusedNode ) ;
var tabbableNodes = state . containerGroups [ mruContainerIdx ] . tabbableNodes ;
if ( tabbableNodes . length > 0 ) {
var mruTabIdx = tabbableNodes . findIndex ( function ( node ) {
return node === state . mostRecentlyFocusedNode ;
} ) ;
if ( mruTabIdx >= 0 ) {
if ( config . isKeyForward ( state . recentNavEvent ) ) {
if ( mruTabIdx + 1 < tabbableNodes . length ) {
nextNode = tabbableNodes [ mruTabIdx + 1 ] ;
navAcrossContainers = false ;
}
} else {
if ( mruTabIdx - 1 >= 0 ) {
nextNode = tabbableNodes [ mruTabIdx - 1 ] ;
navAcrossContainers = false ;
}
}
}
}
} else {
if ( ! state . containerGroups . some ( function ( g ) {
return g . tabbableNodes . some ( function ( n ) {
return getTabIndex ( n ) > 0 ;
} ) ;
} ) ) {
navAcrossContainers = false ;
}
}
} else {
navAcrossContainers = false ;
}
if ( navAcrossContainers ) {
nextNode = findNextNavNode ( {
// move FROM the MRU node, not event-related node (which will be the node that is
// outside the trap causing the focus escape we're trying to fix)
target : state . mostRecentlyFocusedNode ,
isBackward : config . isKeyBackward ( state . recentNavEvent )
} ) ;
}
if ( nextNode ) {
tryFocus ( nextNode ) ;
} else {
tryFocus ( state . mostRecentlyFocusedNode || getInitialFocusNode ( ) ) ;
}
}
state . recentNavEvent = void 0 ;
} ;
var checkKeyNav = function checkKeyNav2 ( event ) {
var isBackward = arguments . length > 1 && arguments [ 1 ] !== void 0 ? arguments [ 1 ] : false ;
state . recentNavEvent = event ;
var destinationNode = findNextNavNode ( {
event ,
isBackward
} ) ;
if ( destinationNode ) {
if ( isTabEvent ( event ) ) {
event . preventDefault ( ) ;
}
tryFocus ( destinationNode ) ;
}
} ;
var checkKey = function checkKey2 ( event ) {
if ( isEscapeEvent ( event ) && valueOrHandler ( config . escapeDeactivates , event ) !== false ) {
event . preventDefault ( ) ;
trap . deactivate ( ) ;
return ;
}
if ( config . isKeyForward ( event ) || config . isKeyBackward ( event ) ) {
checkKeyNav ( event , config . isKeyBackward ( event ) ) ;
}
} ;
var checkClick = function checkClick2 ( e ) {
var target = getActualTarget ( e ) ;
if ( findContainerIndex ( target , e ) >= 0 ) {
return ;
}
if ( valueOrHandler ( config . clickOutsideDeactivates , e ) ) {
return ;
}
if ( valueOrHandler ( config . allowOutsideClick , e ) ) {
return ;
}
e . preventDefault ( ) ;
e . stopImmediatePropagation ( ) ;
} ;
var addListeners = function addListeners2 ( ) {
if ( ! state . active ) {
return ;
}
activeFocusTraps . activateTrap ( trapStack , trap ) ;
state . delayInitialFocusTimer = config . delayInitialFocus ? delay ( function ( ) {
tryFocus ( getInitialFocusNode ( ) ) ;
} ) : tryFocus ( getInitialFocusNode ( ) ) ;
doc . addEventListener ( "focusin" , checkFocusIn , true ) ;
doc . addEventListener ( "mousedown" , checkPointerDown , {
capture : true ,
passive : false
} ) ;
doc . addEventListener ( "touchstart" , checkPointerDown , {
capture : true ,
passive : false
} ) ;
doc . addEventListener ( "click" , checkClick , {
capture : true ,
passive : false
} ) ;
doc . addEventListener ( "keydown" , checkKey , {
capture : true ,
passive : false
} ) ;
return trap ;
} ;
var removeListeners = function removeListeners2 ( ) {
if ( ! state . active ) {
return ;
}
doc . removeEventListener ( "focusin" , checkFocusIn , true ) ;
doc . removeEventListener ( "mousedown" , checkPointerDown , true ) ;
doc . removeEventListener ( "touchstart" , checkPointerDown , true ) ;
doc . removeEventListener ( "click" , checkClick , true ) ;
doc . removeEventListener ( "keydown" , checkKey , true ) ;
return trap ;
} ;
var checkDomRemoval = function checkDomRemoval2 ( mutations ) {
var isFocusedNodeRemoved = mutations . some ( function ( mutation ) {
var removedNodes = Array . from ( mutation . removedNodes ) ;
return removedNodes . some ( function ( node ) {
return node === state . mostRecentlyFocusedNode ;
} ) ;
} ) ;
if ( isFocusedNodeRemoved ) {
tryFocus ( getInitialFocusNode ( ) ) ;
}
} ;
var mutationObserver = typeof window !== "undefined" && "MutationObserver" in window ? new MutationObserver ( checkDomRemoval ) : void 0 ;
var updateObservedNodes = function updateObservedNodes2 ( ) {
if ( ! mutationObserver ) {
return ;
}
mutationObserver . disconnect ( ) ;
if ( state . active && ! state . paused ) {
state . containers . map ( function ( container ) {
mutationObserver . observe ( container , {
subtree : true ,
childList : true
} ) ;
} ) ;
}
} ;
trap = {
get active ( ) {
return state . active ;
} ,
get paused ( ) {
return state . paused ;
} ,
activate : function activate ( activateOptions ) {
if ( state . active ) {
return this ;
}
var onActivate = getOption ( activateOptions , "onActivate" ) ;
var onPostActivate = getOption ( activateOptions , "onPostActivate" ) ;
var checkCanFocusTrap = getOption ( activateOptions , "checkCanFocusTrap" ) ;
if ( ! checkCanFocusTrap ) {
updateTabbableNodes ( ) ;
}
state . active = true ;
state . paused = false ;
state . nodeFocusedBeforeActivation = doc . activeElement ;
onActivate === null || onActivate === void 0 || onActivate ( ) ;
var finishActivation = function finishActivation2 ( ) {
if ( checkCanFocusTrap ) {
updateTabbableNodes ( ) ;
}
addListeners ( ) ;
updateObservedNodes ( ) ;
onPostActivate === null || onPostActivate === void 0 || onPostActivate ( ) ;
} ;
if ( checkCanFocusTrap ) {
checkCanFocusTrap ( state . containers . concat ( ) ) . then ( finishActivation , finishActivation ) ;
return this ;
}
finishActivation ( ) ;
return this ;
} ,
deactivate : function deactivate ( deactivateOptions ) {
if ( ! state . active ) {
return this ;
}
var options = _objectSpread2 ( {
onDeactivate : config . onDeactivate ,
onPostDeactivate : config . onPostDeactivate ,
checkCanReturnFocus : config . checkCanReturnFocus
} , deactivateOptions ) ;
clearTimeout ( state . delayInitialFocusTimer ) ;
state . delayInitialFocusTimer = void 0 ;
removeListeners ( ) ;
state . active = false ;
state . paused = false ;
updateObservedNodes ( ) ;
activeFocusTraps . deactivateTrap ( trapStack , trap ) ;
var onDeactivate = getOption ( options , "onDeactivate" ) ;
var onPostDeactivate = getOption ( options , "onPostDeactivate" ) ;
var checkCanReturnFocus = getOption ( options , "checkCanReturnFocus" ) ;
var returnFocus = getOption ( options , "returnFocus" , "returnFocusOnDeactivate" ) ;
onDeactivate === null || onDeactivate === void 0 || onDeactivate ( ) ;
var finishDeactivation = function finishDeactivation2 ( ) {
delay ( function ( ) {
if ( returnFocus ) {
tryFocus ( getReturnFocusNode ( state . nodeFocusedBeforeActivation ) ) ;
}
onPostDeactivate === null || onPostDeactivate === void 0 || onPostDeactivate ( ) ;
} ) ;
} ;
if ( returnFocus && checkCanReturnFocus ) {
checkCanReturnFocus ( getReturnFocusNode ( state . nodeFocusedBeforeActivation ) ) . then ( finishDeactivation , finishDeactivation ) ;
return this ;
}
finishDeactivation ( ) ;
return this ;
} ,
pause : function pause ( pauseOptions ) {
if ( state . paused || ! state . active ) {
return this ;
}
var onPause = getOption ( pauseOptions , "onPause" ) ;
var onPostPause = getOption ( pauseOptions , "onPostPause" ) ;
state . paused = true ;
onPause === null || onPause === void 0 || onPause ( ) ;
removeListeners ( ) ;
updateObservedNodes ( ) ;
onPostPause === null || onPostPause === void 0 || onPostPause ( ) ;
return this ;
} ,
unpause : function unpause ( unpauseOptions ) {
if ( ! state . paused || ! state . active ) {
return this ;
}
var onUnpause = getOption ( unpauseOptions , "onUnpause" ) ;
var onPostUnpause = getOption ( unpauseOptions , "onPostUnpause" ) ;
state . paused = false ;
onUnpause === null || onUnpause === void 0 || onUnpause ( ) ;
updateTabbableNodes ( ) ;
addListeners ( ) ;
updateObservedNodes ( ) ;
onPostUnpause === null || onPostUnpause === void 0 || onPostUnpause ( ) ;
return this ;
} ,
updateContainerElements : function updateContainerElements ( containerElements ) {
var elementsAsArray = [ ] . concat ( containerElements ) . filter ( Boolean ) ;
state . containers = elementsAsArray . map ( function ( element ) {
return typeof element === "string" ? doc . querySelector ( element ) : element ;
} ) ;
if ( state . active ) {
updateTabbableNodes ( ) ;
}
updateObservedNodes ( ) ;
return this ;
}
} ;
trap . updateContainerElements ( elements ) ;
return trap ;
} ;
function useFocusTrap ( target , options = { } ) {
let trap ;
const { immediate , ... focusTrapOptions } = options ;
const hasFocus = ref ( false ) ;
const isPaused = ref ( false ) ;
const activate = ( opts ) => trap && trap . activate ( opts ) ;
const deactivate = ( opts ) => trap && trap . deactivate ( opts ) ;
const pause = ( ) => {
if ( trap ) {
trap . pause ( ) ;
isPaused . value = true ;
}
} ;
const unpause = ( ) => {
if ( trap ) {
trap . unpause ( ) ;
isPaused . value = false ;
}
} ;
watch (
( ) => unrefElement ( target ) ,
( el ) => {
if ( ! el )
return ;
trap = createFocusTrap ( el , {
... focusTrapOptions ,
onActivate ( ) {
hasFocus . value = true ;
if ( options . onActivate )
options . onActivate ( ) ;
} ,
onDeactivate ( ) {
hasFocus . value = false ;
if ( options . onDeactivate )
options . onDeactivate ( ) ;
}
} ) ;
if ( immediate )
activate ( ) ;
} ,
{ flush : "post" }
) ;
tryOnScopeDispose ( ( ) => deactivate ( ) ) ;
return {
hasFocus ,
isPaused ,
activate ,
deactivate ,
pause ,
unpause
} ;
}
class DOMIterator {
/ * *
* @ param { HTMLElement | HTMLElement [ ] | NodeList | string } ctx - The context DOM
* element , an array of DOM elements , a NodeList or a selector
* @ param { boolean } [ iframes = true ] - A boolean indicating if iframes should
* be handled
* @ param { string [ ] } [ exclude = [ ] ] - An array containing exclusion selectors
* for iframes
* @ param { number } [ iframesTimeout = 5000 ] - A number indicating the ms to
* wait before an iframe should be skipped , in case the load event isn ' t
* fired . This also applies if the user is offline and the resource of the
* iframe is online ( either by the browsers "offline" mode or because
* there ' s no internet connection )
* /
constructor ( ctx , iframes = true , exclude = [ ] , iframesTimeout = 5e3 ) {
this . ctx = ctx ;
this . iframes = iframes ;
this . exclude = exclude ;
this . iframesTimeout = iframesTimeout ;
}
/ * *
* Checks if the specified DOM element matches the selector
* @ param { HTMLElement } element - The DOM element
* @ param { string | string [ ] } selector - The selector or an array with
* selectors
* @ return { boolean }
* @ access public
* /
static matches ( element , selector ) {
const selectors = typeof selector === "string" ? [ selector ] : selector , fn = element . matches || element . matchesSelector || element . msMatchesSelector || element . mozMatchesSelector || element . oMatchesSelector || element . webkitMatchesSelector ;
if ( fn ) {
let match = false ;
selectors . every ( ( sel ) => {
if ( fn . call ( element , sel ) ) {
match = true ;
return false ;
}
return true ;
} ) ;
return match ;
} else {
return false ;
}
}
/ * *
* Returns all contexts filtered by duplicates ( even nested )
* @ return { HTMLElement [ ] } - An array containing DOM contexts
* @ access protected
* /
getContexts ( ) {
let ctx , filteredCtx = [ ] ;
if ( typeof this . ctx === "undefined" || ! this . ctx ) {
ctx = [ ] ;
} else if ( NodeList . prototype . isPrototypeOf ( this . ctx ) ) {
ctx = Array . prototype . slice . call ( this . ctx ) ;
} else if ( Array . isArray ( this . ctx ) ) {
ctx = this . ctx ;
} else if ( typeof this . ctx === "string" ) {
ctx = Array . prototype . slice . call (
document . querySelectorAll ( this . ctx )
) ;
} else {
ctx = [ this . ctx ] ;
}
ctx . forEach ( ( ctx2 ) => {
const isDescendant = filteredCtx . filter ( ( contexts ) => {
return contexts . contains ( ctx2 ) ;
} ) . length > 0 ;
if ( filteredCtx . indexOf ( ctx2 ) === - 1 && ! isDescendant ) {
filteredCtx . push ( ctx2 ) ;
}
} ) ;
return filteredCtx ;
}
/ * *
* @ callback DOMIterator ~ getIframeContentsSuccessCallback
* @ param { HTMLDocument } contents - The contentDocument of the iframe
* /
/ * *
* Calls the success callback function with the iframe document . If it can ' t
* be accessed it calls the error callback function
* @ param { HTMLElement } ifr - The iframe DOM element
* @ param { DOMIterator ~ getIframeContentsSuccessCallback } successFn
* @ param { function } [ errorFn ]
* @ access protected
* /
getIframeContents ( ifr , successFn , errorFn = ( ) => {
} ) {
let doc ;
try {
const ifrWin = ifr . contentWindow ;
doc = ifrWin . document ;
if ( ! ifrWin || ! doc ) {
throw new Error ( "iframe inaccessible" ) ;
}
} catch ( e ) {
errorFn ( ) ;
}
if ( doc ) {
successFn ( doc ) ;
}
}
/ * *
* Checks if an iframe is empty ( if about : blank is the shown page )
* @ param { HTMLElement } ifr - The iframe DOM element
* @ return { boolean }
* @ access protected
* /
isIframeBlank ( ifr ) {
const bl = "about:blank" , src = ifr . getAttribute ( "src" ) . trim ( ) , href = ifr . contentWindow . location . href ;
return href === bl && src !== bl && src ;
}
/ * *
* Observes the onload event of an iframe and calls the success callback or
* the error callback if the iframe is inaccessible . If the event isn ' t
* fired within the specified { @ link DOMIterator # iframesTimeout } , then it ' ll
* call the error callback too
* @ param { HTMLElement } ifr - The iframe DOM element
* @ param { DOMIterator ~ getIframeContentsSuccessCallback } successFn
* @ param { function } errorFn
* @ access protected
* /
observeIframeLoad ( ifr , successFn , errorFn ) {
let called = false , tout = null ;
const listener = ( ) => {
if ( called ) {
return ;
}
called = true ;
clearTimeout ( tout ) ;
try {
if ( ! this . isIframeBlank ( ifr ) ) {
ifr . removeEventListener ( "load" , listener ) ;
this . getIframeContents ( ifr , successFn , errorFn ) ;
}
} catch ( e ) {
errorFn ( ) ;
}
} ;
ifr . addEventListener ( "load" , listener ) ;
tout = setTimeout ( listener , this . iframesTimeout ) ;
}
/ * *
* Callback when the iframe is ready
* @ callback DOMIterator ~ onIframeReadySuccessCallback
* @ param { HTMLDocument } contents - The contentDocument of the iframe
* /
/ * *
* Callback if the iframe can ' t be accessed
* @ callback DOMIterator ~ onIframeReadyErrorCallback
* /
/ * *
* Calls the callback if the specified iframe is ready for DOM access
* @ param { HTMLElement } ifr - The iframe DOM element
* @ param { DOMIterator ~ onIframeReadySuccessCallback } successFn - Success
* callback
* @ param { DOMIterator ~ onIframeReadyErrorCallback } errorFn - Error callback
* @ see { @ link http : //stackoverflow.com/a/36155560/3894981} for
* background information
* @ access protected
* /
onIframeReady ( ifr , successFn , errorFn ) {
try {
if ( ifr . contentWindow . document . readyState === "complete" ) {
if ( this . isIframeBlank ( ifr ) ) {
this . observeIframeLoad ( ifr , successFn , errorFn ) ;
} else {
this . getIframeContents ( ifr , successFn , errorFn ) ;
}
} else {
this . observeIframeLoad ( ifr , successFn , errorFn ) ;
}
} catch ( e ) {
errorFn ( ) ;
}
}
/ * *
* Callback when all iframes are ready for DOM access
* @ callback DOMIterator ~ waitForIframesDoneCallback
* /
/ * *
* Iterates over all iframes and calls the done callback when all of them
* are ready for DOM access ( including nested ones )
* @ param { HTMLElement } ctx - The context DOM element
* @ param { DOMIterator ~ waitForIframesDoneCallback } done - Done callback
* /
waitForIframes ( ctx , done ) {
let eachCalled = 0 ;
this . forEachIframe ( ctx , ( ) => true , ( ifr ) => {
eachCalled ++ ;
this . waitForIframes ( ifr . querySelector ( "html" ) , ( ) => {
if ( ! -- eachCalled ) {
done ( ) ;
}
} ) ;
} , ( handled ) => {
if ( ! handled ) {
done ( ) ;
}
} ) ;
}
/ * *
* Callback allowing to filter an iframe . Must return true when the element
* should remain , otherwise false
* @ callback DOMIterator ~ forEachIframeFilterCallback
* @ param { HTMLElement } iframe - The iframe DOM element
* /
/ * *
* Callback for each iframe content
* @ callback DOMIterator ~ forEachIframeEachCallback
* @ param { HTMLElement } content - The iframe document
* /
/ * *
* Callback if all iframes inside the context were handled
* @ callback DOMIterator ~ forEachIframeEndCallback
* @ param { number } handled - The number of handled iframes ( those who
* wheren ' t filtered )
* /
/ * *
* Iterates over all iframes inside the specified context and calls the
* callbacks when they ' re ready . Filters iframes based on the instance
* exclusion selectors
* @ param { HTMLElement } ctx - The context DOM element
* @ param { DOMIterator ~ forEachIframeFilterCallback } filter - Filter callback
* @ param { DOMIterator ~ forEachIframeEachCallback } each - Each callback
* @ param { DOMIterator ~ forEachIframeEndCallback } [ end ] - End callback
* @ access protected
* /
forEachIframe ( ctx , filter , each , end = ( ) => {
} ) {
let ifr = ctx . querySelectorAll ( "iframe" ) , open = ifr . length , handled = 0 ;
ifr = Array . prototype . slice . call ( ifr ) ;
const checkEnd = ( ) => {
if ( -- open <= 0 ) {
end ( handled ) ;
}
} ;
if ( ! open ) {
checkEnd ( ) ;
}
ifr . forEach ( ( ifr2 ) => {
if ( DOMIterator . matches ( ifr2 , this . exclude ) ) {
checkEnd ( ) ;
} else {
this . onIframeReady ( ifr2 , ( con ) => {
if ( filter ( ifr2 ) ) {
handled ++ ;
each ( con ) ;
}
checkEnd ( ) ;
} , checkEnd ) ;
}
} ) ;
}
/ * *
* Creates a NodeIterator on the specified context
* @ see { @ link https : //developer.mozilla.org/en/docs/Web/API/NodeIterator}
* @ param { HTMLElement } ctx - The context DOM element
* @ param { DOMIterator ~ whatToShow } whatToShow
* @ param { DOMIterator ~ filterCb } filter
* @ return { NodeIterator }
* @ access protected
* /
createIterator ( ctx , whatToShow , filter ) {
return document . createNodeIterator ( ctx , whatToShow , filter , false ) ;
}
/ * *
* Creates an instance of DOMIterator in an iframe
* @ param { HTMLDocument } contents - Iframe document
* @ return { DOMIterator }
* @ access protected
* /
createInstanceOnIframe ( contents ) {
return new DOMIterator ( contents . querySelector ( "html" ) , this . iframes ) ;
}
/ * *
* Checks if an iframe occurs between two nodes , more specifically if an
* iframe occurs before the specified node and after the specified prevNode
* @ param { HTMLElement } node - The node that should occur after the iframe
* @ param { HTMLElement } prevNode - The node that should occur before the
* iframe
* @ param { HTMLElement } ifr - The iframe to check against
* @ return { boolean }
* @ access protected
* /
compareNodeIframe ( node , prevNode , ifr ) {
const compCurr = node . compareDocumentPosition ( ifr ) , prev = Node . DOCUMENT _POSITION _PRECEDING ;
if ( compCurr & prev ) {
if ( prevNode !== null ) {
const compPrev = prevNode . compareDocumentPosition ( ifr ) , after = Node . DOCUMENT _POSITION _FOLLOWING ;
if ( compPrev & after ) {
return true ;
}
} else {
return true ;
}
}
return false ;
}
/ * *
* @ typedef { DOMIterator ~ getIteratorNodeReturn }
* @ type { object . < string > }
* @ property { HTMLElement } prevNode - The previous node or null if there is
* no
* @ property { HTMLElement } node - The current node
* /
/ * *
* Returns the previous and current node of the specified iterator
* @ param { NodeIterator } itr - The iterator
* @ return { DOMIterator ~ getIteratorNodeReturn }
* @ access protected
* /
getIteratorNode ( itr ) {
const prevNode = itr . previousNode ( ) ;
let node ;
if ( prevNode === null ) {
node = itr . nextNode ( ) ;
} else {
node = itr . nextNode ( ) && itr . nextNode ( ) ;
}
return {
prevNode ,
node
} ;
}
/ * *
* An array containing objects . The object key "val" contains an iframe
* DOM element . The object key "handled" contains a boolean indicating if
* the iframe was handled already .
* It wouldn ' t be enough to save all open or all already handled iframes .
* The information of open iframes is necessary because they may occur after
* all other text nodes ( and compareNodeIframe would never be true ) . The
* information of already handled iframes is necessary as otherwise they may
* be handled multiple times
* @ typedef DOMIterator ~ checkIframeFilterIfr
* @ type { object [ ] }
* /
/ * *
* Checks if an iframe wasn ' t handled already and if so , calls
* { @ link DOMIterator # compareNodeIframe } to check if it should be handled .
* Information wheter an iframe was or wasn ' t handled is given within the
* < code > ifr < / c o d e > d i c t i o n a r y
* @ param { HTMLElement } node - The node that should occur after the iframe
* @ param { HTMLElement } prevNode - The node that should occur before the
* iframe
* @ param { HTMLElement } currIfr - The iframe to check
* @ param { DOMIterator ~ checkIframeFilterIfr } ifr - The iframe dictionary .
* Will be manipulated ( by reference )
* @ return { boolean } Returns true when it should be handled , otherwise false
* @ access protected
* /
checkIframeFilter ( node , prevNode , currIfr , ifr ) {
let key = false , handled = false ;
ifr . forEach ( ( ifrDict , i ) => {
if ( ifrDict . val === currIfr ) {
key = i ;
handled = ifrDict . handled ;
}
} ) ;
if ( this . compareNodeIframe ( node , prevNode , currIfr ) ) {
if ( key === false && ! handled ) {
ifr . push ( {
val : currIfr ,
handled : true
} ) ;
} else if ( key !== false && ! handled ) {
ifr [ key ] . handled = true ;
}
return true ;
}
if ( key === false ) {
ifr . push ( {
val : currIfr ,
handled : false
} ) ;
}
return false ;
}
/ * *
* Creates an iterator on all open iframes in the specified array and calls
* the end callback when finished
* @ param { DOMIterator ~ checkIframeFilterIfr } ifr
* @ param { DOMIterator ~ whatToShow } whatToShow
* @ param { DOMIterator ~ forEachNodeCallback } eCb - Each callback
* @ param { DOMIterator ~ filterCb } fCb
* @ access protected
* /
handleOpenIframes ( ifr , whatToShow , eCb , fCb ) {
ifr . forEach ( ( ifrDict ) => {
if ( ! ifrDict . handled ) {
this . getIframeContents ( ifrDict . val , ( con ) => {
this . createInstanceOnIframe ( con ) . forEachNode (
whatToShow ,
eCb ,
fCb
) ;
} ) ;
}
} ) ;
}
/ * *
* Iterates through all nodes in the specified context and handles iframe
* nodes at the correct position
* @ param { DOMIterator ~ whatToShow } whatToShow
* @ param { HTMLElement } ctx - The context
* @ param { DOMIterator ~ forEachNodeCallback } eachCb - Each callback
* @ param { DOMIterator ~ filterCb } filterCb - Filter callback
* @ param { DOMIterator ~ forEachNodeEndCallback } doneCb - End callback
* @ access protected
* /
iterateThroughNodes ( whatToShow , ctx , eachCb , filterCb , doneCb ) {
const itr = this . createIterator ( ctx , whatToShow , filterCb ) ;
let ifr = [ ] , elements = [ ] , node , prevNode , retrieveNodes = ( ) => {
( {
prevNode ,
node
} = this . getIteratorNode ( itr ) ) ;
return node ;
} ;
while ( retrieveNodes ( ) ) {
if ( this . iframes ) {
this . forEachIframe ( ctx , ( currIfr ) => {
return this . checkIframeFilter ( node , prevNode , currIfr , ifr ) ;
} , ( con ) => {
this . createInstanceOnIframe ( con ) . forEachNode (
whatToShow ,
( ifrNode ) => elements . push ( ifrNode ) ,
filterCb
) ;
} ) ;
}
elements . push ( node ) ;
}
elements . forEach ( ( node2 ) => {
eachCb ( node2 ) ;
} ) ;
if ( this . iframes ) {
this . handleOpenIframes ( ifr , whatToShow , eachCb , filterCb ) ;
}
doneCb ( ) ;
}
/ * *
* Callback for each node
* @ callback DOMIterator ~ forEachNodeCallback
* @ param { HTMLElement } node - The DOM text node element
* /
/ * *
* Callback if all contexts were handled
* @ callback DOMIterator ~ forEachNodeEndCallback
* /
/ * *
* Iterates over all contexts and initializes
* { @ link DOMIterator # iterateThroughNodes iterateThroughNodes } on them
* @ param { DOMIterator ~ whatToShow } whatToShow
* @ param { DOMIterator ~ forEachNodeCallback } each - Each callback
* @ param { DOMIterator ~ filterCb } filter - Filter callback
* @ param { DOMIterator ~ forEachNodeEndCallback } done - End callback
* @ access public
* /
forEachNode ( whatToShow , each , filter , done = ( ) => {
} ) {
const contexts = this . getContexts ( ) ;
let open = contexts . length ;
if ( ! open ) {
done ( ) ;
}
contexts . forEach ( ( ctx ) => {
const ready = ( ) => {
this . iterateThroughNodes ( whatToShow , ctx , each , filter , ( ) => {
if ( -- open <= 0 ) {
done ( ) ;
}
} ) ;
} ;
if ( this . iframes ) {
this . waitForIframes ( ctx , ready ) ;
} else {
ready ( ) ;
}
} ) ;
}
/ * *
* Callback to filter nodes . Can return e . g . NodeFilter . FILTER _ACCEPT or
* NodeFilter . FILTER _REJECT
* @ see { @ link http : //tinyurl.com/zdczmm2}
* @ callback DOMIterator ~ filterCb
* @ param { HTMLElement } node - The node to filter
* /
/ * *
* @ typedef DOMIterator ~ whatToShow
* @ see { @ link http : //tinyurl.com/zfqqkx2}
* @ type { number }
* /
}
let Mark$1 = class Mark {
// eslint-disable-line no-unused-vars
/ * *
* @ param { HTMLElement | HTMLElement [ ] | NodeList | string } ctx - The context DOM
* element , an array of DOM elements , a NodeList or a selector
* /
constructor ( ctx ) {
this . ctx = ctx ;
this . ie = false ;
const ua = window . navigator . userAgent ;
if ( ua . indexOf ( "MSIE" ) > - 1 || ua . indexOf ( "Trident" ) > - 1 ) {
this . ie = true ;
}
}
/ * *
* Options defined by the user . They will be initialized from one of the
* public methods . See { @ link Mark # mark } , { @ link Mark # markRegExp } ,
* { @ link Mark # markRanges } and { @ link Mark # unmark } for option properties .
* @ type { object }
* @ param { object } [ val ] - An object that will be merged with defaults
* @ access protected
* /
set opt ( val ) {
this . _opt = Object . assign ( { } , {
"element" : "" ,
"className" : "" ,
"exclude" : [ ] ,
"iframes" : false ,
"iframesTimeout" : 5e3 ,
"separateWordSearch" : true ,
"diacritics" : true ,
"synonyms" : { } ,
"accuracy" : "partially" ,
"acrossElements" : false ,
"caseSensitive" : false ,
"ignoreJoiners" : false ,
"ignoreGroups" : 0 ,
"ignorePunctuation" : [ ] ,
"wildcards" : "disabled" ,
"each" : ( ) => {
} ,
"noMatch" : ( ) => {
} ,
"filter" : ( ) => true ,
"done" : ( ) => {
} ,
"debug" : false ,
"log" : window . console
} , val ) ;
}
get opt ( ) {
return this . _opt ;
}
/ * *
* An instance of DOMIterator
* @ type { DOMIterator }
* @ access protected
* /
get iterator ( ) {
return new DOMIterator (
this . ctx ,
this . opt . iframes ,
this . opt . exclude ,
this . opt . iframesTimeout
) ;
}
/ * *
* Logs a message if log is enabled
* @ param { string } msg - The message to log
* @ param { string } [ level = "debug" ] - The log level , e . g . < code > warn < / c o d e >
* < code > error < / c o d e > , < c o d e > d e b u g < / c o d e >
* @ access protected
* /
log ( msg , level = "debug" ) {
const log = this . opt . log ;
if ( ! this . opt . debug ) {
return ;
}
if ( typeof log === "object" && typeof log [ level ] === "function" ) {
log [ level ] ( ` mark.js: ${ msg } ` ) ;
}
}
/ * *
* Escapes a string for usage within a regular expression
* @ param { string } str - The string to escape
* @ return { string }
* @ access protected
* /
escapeStr ( str ) {
return str . replace ( /[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g , "\\$&" ) ;
}
/ * *
* Creates a regular expression string to match the specified search
* term including synonyms , diacritics and accuracy if defined
* @ param { string } str - The search term to be used
* @ return { string }
* @ access protected
* /
createRegExp ( str ) {
if ( this . opt . wildcards !== "disabled" ) {
str = this . setupWildcardsRegExp ( str ) ;
}
str = this . escapeStr ( str ) ;
if ( Object . keys ( this . opt . synonyms ) . length ) {
str = this . createSynonymsRegExp ( str ) ;
}
if ( this . opt . ignoreJoiners || this . opt . ignorePunctuation . length ) {
str = this . setupIgnoreJoinersRegExp ( str ) ;
}
if ( this . opt . diacritics ) {
str = this . createDiacriticsRegExp ( str ) ;
}
str = this . createMergedBlanksRegExp ( str ) ;
if ( this . opt . ignoreJoiners || this . opt . ignorePunctuation . length ) {
str = this . createJoinersRegExp ( str ) ;
}
if ( this . opt . wildcards !== "disabled" ) {
str = this . createWildcardsRegExp ( str ) ;
}
str = this . createAccuracyRegExp ( str ) ;
return str ;
}
/ * *
* Creates a regular expression string to match the defined synonyms
* @ param { string } str - The search term to be used
* @ return { string }
* @ access protected
* /
createSynonymsRegExp ( str ) {
const syn = this . opt . synonyms , sens = this . opt . caseSensitive ? "" : "i" , joinerPlaceholder = this . opt . ignoreJoiners || this . opt . ignorePunctuation . length ? "\0" : "" ;
for ( let index in syn ) {
if ( syn . hasOwnProperty ( index ) ) {
const value = syn [ index ] , k1 = this . opt . wildcards !== "disabled" ? this . setupWildcardsRegExp ( index ) : this . escapeStr ( index ) , k2 = this . opt . wildcards !== "disabled" ? this . setupWildcardsRegExp ( value ) : this . escapeStr ( value ) ;
if ( k1 !== "" && k2 !== "" ) {
str = str . replace (
new RegExp (
` ( ${ this . escapeStr ( k1 ) } | ${ this . escapeStr ( k2 ) } ) ` ,
` gm ${ sens } `
) ,
joinerPlaceholder + ` ( ${ this . processSynomyms ( k1 ) } | ${ this . processSynomyms ( k2 ) } ) ` + joinerPlaceholder
) ;
}
}
}
return str ;
}
/ * *
* Setup synonyms to work with ignoreJoiners and or ignorePunctuation
* @ param { string } str - synonym key or value to process
* @ return { string } - processed synonym string
* /
processSynomyms ( str ) {
if ( this . opt . ignoreJoiners || this . opt . ignorePunctuation . length ) {
str = this . setupIgnoreJoinersRegExp ( str ) ;
}
return str ;
}
/ * *
* Sets up the regular expression string to allow later insertion of
* wildcard regular expression matches
* @ param { string } str - The search term to be used
* @ return { string }
* @ access protected
* /
setupWildcardsRegExp ( str ) {
str = str . replace ( /(?:\\)*\?/g , ( val ) => {
return val . charAt ( 0 ) === "\\" ? "?" : " " ;
} ) ;
return str . replace ( /(?:\\)*\*/g , ( val ) => {
return val . charAt ( 0 ) === "\\" ? "*" : " " ;
} ) ;
}
/ * *
* Sets up the regular expression string to allow later insertion of
* wildcard regular expression matches
* @ param { string } str - The search term to be used
* @ return { string }
* @ access protected
* /
createWildcardsRegExp ( str ) {
let spaces = this . opt . wildcards === "withSpaces" ;
return str . replace ( /\u0001/g , spaces ? "[\\S\\s]?" : "\\S?" ) . replace ( /\u0002/g , spaces ? "[\\S\\s]*?" : "\\S*" ) ;
}
/ * *
* Sets up the regular expression string to allow later insertion of
* designated characters ( soft hyphens & zero width characters )
* @ param { string } str - The search term to be used
* @ return { string }
* @ access protected
* /
setupIgnoreJoinersRegExp ( str ) {
return str . replace ( /[^(|)\\]/g , ( val , indx , original ) => {
let nextChar = original . charAt ( indx + 1 ) ;
if ( /[(|)\\]/ . test ( nextChar ) || nextChar === "" ) {
return val ;
} else {
return val + "\0" ;
}
} ) ;
}
/ * *
* Creates a regular expression string to allow ignoring of designated
* characters ( soft hyphens , zero width characters & punctuation ) based on
* the specified option values of < code > ignorePunctuation < / c o d e > a n d
* < code > ignoreJoiners < / c o d e >
* @ param { string } str - The search term to be used
* @ return { string }
* @ access protected
* /
createJoinersRegExp ( str ) {
let joiner = [ ] ;
const ignorePunctuation = this . opt . ignorePunctuation ;
if ( Array . isArray ( ignorePunctuation ) && ignorePunctuation . length ) {
joiner . push ( this . escapeStr ( ignorePunctuation . join ( "" ) ) ) ;
}
if ( this . opt . ignoreJoiners ) {
joiner . push ( "\\u00ad\\u200b\\u200c\\u200d" ) ;
}
return joiner . length ? str . split ( /\u0000+/ ) . join ( ` [ ${ joiner . join ( "" ) } ]* ` ) : str ;
}
/ * *
* Creates a regular expression string to match diacritics
* @ param { string } str - The search term to be used
* @ return { string }
* @ access protected
* /
createDiacriticsRegExp ( str ) {
const sens = this . opt . caseSensitive ? "" : "i" , dct = this . opt . caseSensitive ? [
"aàáảãạăằắẳẵặâầấẩẫậäåāą" ,
"AÀÁẢÃẠĂẰẮẲẴẶÂẦẤẨẪẬÄÅĀĄ" ,
"cçćč" ,
"CÇĆČ" ,
"dđď" ,
"DĐĎ" ,
"eèéẻẽẹêềếểễệëěēę" ,
"EÈÉẺẼẸÊỀẾỂỄỆËĚĒĘ" ,
"iìíỉĩịîïī" ,
"IÌÍỈĨỊÎÏĪ" ,
"lł" ,
"LŁ" ,
"nñňń" ,
"NÑŇŃ" ,
"oòóỏõọôồốổỗộơởỡớờợöøō" ,
"OÒÓỎÕỌÔỒỐỔỖỘƠỞỠỚỜỢÖØŌ" ,
"rř" ,
"RŘ" ,
"sšśșş" ,
"SŠŚȘŞ" ,
"tťțţ" ,
"TŤȚŢ" ,
"uùúủũụưừứửữựûüůū" ,
"UÙÚỦŨỤƯỪỨỬỮỰÛÜŮŪ" ,
"yýỳỷỹỵÿ" ,
"YÝỲỶỸỴŸ" ,
"zžżź" ,
"ZŽŻŹ"
] : [
"aàáảãạăằắẳẵặâầấẩẫậäåāąAÀÁẢÃẠĂẰẮẲẴẶÂẦẤẨẪẬÄÅĀĄ" ,
"cçćčCÇĆČ" ,
"dđďDĐĎ" ,
"eèéẻẽẹêềếểễệëěēęEÈÉẺẼẸÊỀẾỂỄỆËĚĒĘ" ,
"iìíỉĩịîïīIÌÍỈĨỊÎÏĪ" ,
"lłLŁ" ,
"nñňńNÑŇŃ" ,
"oòóỏõọôồốổỗộơởỡớờợöøōOÒÓỎÕỌÔỒỐỔỖỘƠỞỠỚỜỢÖØŌ" ,
"rřRŘ" ,
"sšśșşSŠŚȘŞ" ,
"tťțţTŤȚŢ" ,
"uùúủũụưừứửữựûüůūUÙÚỦŨỤƯỪỨỬỮỰÛÜŮŪ" ,
"yýỳỷỹỵÿYÝỲỶỸỴŸ" ,
"zžżźZŽŻŹ"
] ;
let handled = [ ] ;
str . split ( "" ) . forEach ( ( ch ) => {
dct . every ( ( dct2 ) => {
if ( dct2 . indexOf ( ch ) !== - 1 ) {
if ( handled . indexOf ( dct2 ) > - 1 ) {
return false ;
}
str = str . replace (
new RegExp ( ` [ ${ dct2 } ] ` , ` gm ${ sens } ` ) ,
` [ ${ dct2 } ] `
) ;
handled . push ( dct2 ) ;
}
return true ;
} ) ;
} ) ;
return str ;
}
/ * *
* Creates a regular expression string that merges whitespace characters
* including subsequent ones into a single pattern , one or multiple
* whitespaces
* @ param { string } str - The search term to be used
* @ return { string }
* @ access protected
* /
createMergedBlanksRegExp ( str ) {
return str . replace ( /[\s]+/gmi , "[\\s]+" ) ;
}
/ * *
* Creates a regular expression string to match the specified string with
* the defined accuracy . As in the regular expression of "exactly" can be
* a group containing a blank at the beginning , all regular expressions will
* be created with two groups . The first group can be ignored ( may contain
* the said blank ) , the second contains the actual match
* @ param { string } str - The searm term to be used
* @ return { str }
* @ access protected
* /
createAccuracyRegExp ( str ) {
const chars = "!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~¡¿" ;
let acc = this . opt . accuracy , val = typeof acc === "string" ? acc : acc . value , ls = typeof acc === "string" ? [ ] : acc . limiters , lsJoin = "" ;
ls . forEach ( ( limiter ) => {
lsJoin += ` | ${ this . escapeStr ( limiter ) } ` ;
} ) ;
switch ( val ) {
case "partially" :
default :
return ` ()( ${ str } ) ` ;
case "complementary" :
lsJoin = "\\s" + ( lsJoin ? lsJoin : this . escapeStr ( chars ) ) ;
return ` ()([^ ${ lsJoin } ]* ${ str } [^ ${ lsJoin } ]*) ` ;
case "exactly" :
return ` (^| \\ s ${ lsJoin } )( ${ str } )(?= $ | \\ s ${ lsJoin } ) ` ;
}
}
/ * *
* @ typedef Mark ~ separatedKeywords
* @ type { object . < string > }
* @ property { array . < string > } keywords - The list of keywords
* @ property { number } length - The length
* /
/ * *
* Returns a list of keywords dependent on whether separate word search
* was defined . Also it filters empty keywords
* @ param { array } sv - The array of keywords
* @ return { Mark ~ separatedKeywords }
* @ access protected
* /
getSeparatedKeywords ( sv ) {
let stack = [ ] ;
sv . forEach ( ( kw ) => {
if ( ! this . opt . separateWordSearch ) {
if ( kw . trim ( ) && stack . indexOf ( kw ) === - 1 ) {
stack . push ( kw ) ;
}
} else {
kw . split ( " " ) . forEach ( ( kwSplitted ) => {
if ( kwSplitted . trim ( ) && stack . indexOf ( kwSplitted ) === - 1 ) {
stack . push ( kwSplitted ) ;
}
} ) ;
}
} ) ;
return {
// sort because of https://git.io/v6USg
"keywords" : stack . sort ( ( a , b ) => {
return b . length - a . length ;
} ) ,
"length" : stack . length
} ;
}
/ * *
* Check if a value is a number
* @ param { number | string } value - the value to check ;
* numeric strings allowed
* @ return { boolean }
* @ access protected
* /
isNumeric ( value ) {
return Number ( parseFloat ( value ) ) == value ;
}
/ * *
* @ typedef Mark ~ rangeObject
* @ type { object }
* @ property { number } start - The start position within the composite value
* @ property { number } length - The length of the string to mark within the
* composite value .
* /
/ * *
* @ typedef Mark ~ setOfRanges
* @ type { object [ ] }
* @ property { Mark ~ rangeObject }
* /
/ * *
* Returns a processed list of integer offset indexes that do not overlap
* each other , and remove any string values or additional elements
* @ param { Mark ~ setOfRanges } array - unprocessed raw array
* @ return { Mark ~ setOfRanges } - processed array with any invalid entries
* removed
* @ throws Will throw an error if an array of objects is not passed
* @ access protected
* /
checkRanges ( array ) {
if ( ! Array . isArray ( array ) || Object . prototype . toString . call ( array [ 0 ] ) !== "[object Object]" ) {
this . log ( "markRanges() will only accept an array of objects" ) ;
this . opt . noMatch ( array ) ;
return [ ] ;
}
const stack = [ ] ;
let last2 = 0 ;
array . sort ( ( a , b ) => {
return a . start - b . start ;
} ) . forEach ( ( item ) => {
let { start , end , valid } = this . callNoMatchOnInvalidRanges ( item , last2 ) ;
if ( valid ) {
item . start = start ;
item . length = end - start ;
stack . push ( item ) ;
last2 = end ;
}
} ) ;
return stack ;
}
/ * *
* @ typedef Mark ~ validObject
* @ type { object }
* @ property { number } start - The start position within the composite value
* @ property { number } end - The calculated end position within the composite
* value .
* @ property { boolean } valid - boolean value indicating that the start and
* calculated end range is valid
* /
/ * *
* Initial validation of ranges for markRanges . Preliminary checks are done
* to ensure the start and length values exist and are not zero or non -
* numeric
* @ param { Mark ~ rangeObject } range - the current range object
* @ param { number } last - last index of range
* @ return { Mark ~ validObject }
* @ access protected
* /
callNoMatchOnInvalidRanges ( range , last2 ) {
let start , end , valid = false ;
if ( range && typeof range . start !== "undefined" ) {
start = parseInt ( range . start , 10 ) ;
end = start + parseInt ( range . length , 10 ) ;
if ( this . isNumeric ( range . start ) && this . isNumeric ( range . length ) && end - last2 > 0 && end - start > 0 ) {
valid = true ;
} else {
this . log (
` Ignoring invalid or overlapping range: ${ JSON . stringify ( range ) } `
) ;
this . opt . noMatch ( range ) ;
}
} else {
this . log ( ` Ignoring invalid range: ${ JSON . stringify ( range ) } ` ) ;
this . opt . noMatch ( range ) ;
}
return {
start ,
end ,
valid
} ;
}
/ * *
* Check valid range for markRanges . Check ranges with access to the context
* string . Range values are double checked , lengths that extend the mark
* beyond the string length are limitied and ranges containing only
* whitespace are ignored
* @ param { Mark ~ rangeObject } range - the current range object
* @ param { number } originalLength - original length of the context string
* @ param { string } string - current content string
* @ return { Mark ~ validObject }
* @ access protected
* /
checkWhitespaceRanges ( range , originalLength , string ) {
let end , valid = true , max = string . length , offset = originalLength - max , start = parseInt ( range . start , 10 ) - offset ;
start = start > max ? max : start ;
end = start + parseInt ( range . length , 10 ) ;
if ( end > max ) {
end = max ;
this . log ( ` End range automatically set to the max value of ${ max } ` ) ;
}
if ( start < 0 || end - start < 0 || start > max || end > max ) {
valid = false ;
this . log ( ` Invalid range: ${ JSON . stringify ( range ) } ` ) ;
this . opt . noMatch ( range ) ;
} else if ( string . substring ( start , end ) . replace ( /\s+/g , "" ) === "" ) {
valid = false ;
this . log ( "Skipping whitespace only range: " + JSON . stringify ( range ) ) ;
this . opt . noMatch ( range ) ;
}
return {
start ,
end ,
valid
} ;
}
/ * *
* @ typedef Mark ~ getTextNodesDict
* @ type { object . < string > }
* @ property { string } value - The composite value of all text nodes
* @ property { object [ ] } nodes - An array of objects
* @ property { number } nodes . start - The start position within the composite
* value
* @ property { number } nodes . end - The end position within the composite
* value
* @ property { HTMLElement } nodes . node - The DOM text node element
* /
/ * *
* Callback
* @ callback Mark ~ getTextNodesCallback
* @ param { Mark ~ getTextNodesDict }
* /
/ * *
* Calls the callback with an object containing all text nodes ( including
* iframe text nodes ) with start and end positions and the composite value
* of them ( string )
* @ param { Mark ~ getTextNodesCallback } cb - Callback
* @ access protected
* /
getTextNodes ( cb ) {
let val = "" , nodes = [ ] ;
this . iterator . forEachNode ( NodeFilter . SHOW _TEXT , ( node ) => {
nodes . push ( {
start : val . length ,
end : ( val += node . textContent ) . length ,
node
} ) ;
} , ( node ) => {
if ( this . matchesExclude ( node . parentNode ) ) {
return NodeFilter . FILTER _REJECT ;
} else {
return NodeFilter . FILTER _ACCEPT ;
}
} , ( ) => {
cb ( {
value : val ,
nodes
} ) ;
} ) ;
}
/ * *
* Checks if an element matches any of the specified exclude selectors . Also
* it checks for elements in which no marks should be performed ( e . g .
* script and style tags ) and optionally already marked elements
* @ param { HTMLElement } el - The element to check
* @ return { boolean }
* @ access protected
* /
matchesExclude ( el ) {
return DOMIterator . matches ( el , this . opt . exclude . concat ( [
// ignores the elements itself, not their childrens (selector *)
"script" ,
"style" ,
"title" ,
"head" ,
"html"
] ) ) ;
}
/ * *
* Wraps the instance element and class around matches that fit the start
* and end positions within the node
* @ param { HTMLElement } node - The DOM text node
* @ param { number } start - The position where to start wrapping
* @ param { number } end - The position where to end wrapping
* @ return { HTMLElement } Returns the splitted text node that will appear
* after the wrapped text node
* @ access protected
* /
wrapRangeInTextNode ( node , start , end ) {
const hEl = ! this . opt . element ? "mark" : this . opt . element , startNode = node . splitText ( start ) , ret = startNode . splitText ( end - start ) ;
let repl = document . createElement ( hEl ) ;
repl . setAttribute ( "data-markjs" , "true" ) ;
if ( this . opt . className ) {
repl . setAttribute ( "class" , this . opt . className ) ;
}
repl . textContent = startNode . textContent ;
startNode . parentNode . replaceChild ( repl , startNode ) ;
return ret ;
}
/ * *
* @ typedef Mark ~ wrapRangeInMappedTextNodeDict
* @ type { object . < string > }
* @ property { string } value - The composite value of all text nodes
* @ property { object [ ] } nodes - An array of objects
* @ property { number } nodes . start - The start position within the composite
* value
* @ property { number } nodes . end - The end position within the composite
* value
* @ property { HTMLElement } nodes . node - The DOM text node element
* /
/ * *
* Each callback
* @ callback Mark ~ wrapMatchesEachCallback
* @ param { HTMLElement } node - The wrapped DOM element
* @ param { number } lastIndex - The last matching position within the
* composite value of text nodes
* /
/ * *
* Filter callback
* @ callback Mark ~ wrapMatchesFilterCallback
* @ param { HTMLElement } node - The matching text node DOM element
* /
/ * *
* Determines matches by start and end positions using the text node
* dictionary even across text nodes and calls
* { @ link Mark # wrapRangeInTextNode } to wrap them
* @ param { Mark ~ wrapRangeInMappedTextNodeDict } dict - The dictionary
* @ param { number } start - The start position of the match
* @ param { number } end - The end position of the match
* @ param { Mark ~ wrapMatchesFilterCallback } filterCb - Filter callback
* @ param { Mark ~ wrapMatchesEachCallback } eachCb - Each callback
* @ access protected
* /
wrapRangeInMappedTextNode ( dict , start , end , filterCb , eachCb ) {
dict . nodes . every ( ( n , i ) => {
const sibl = dict . nodes [ i + 1 ] ;
if ( typeof sibl === "undefined" || sibl . start > start ) {
if ( ! filterCb ( n . node ) ) {
return false ;
}
const s = start - n . start , e = ( end > n . end ? n . end : end ) - n . start , startStr = dict . value . substr ( 0 , n . start ) , endStr = dict . value . substr ( e + n . start ) ;
n . node = this . wrapRangeInTextNode ( n . node , s , e ) ;
dict . value = startStr + endStr ;
dict . nodes . forEach ( ( k , j ) => {
if ( j >= i ) {
if ( dict . nodes [ j ] . start > 0 && j !== i ) {
dict . nodes [ j ] . start -= e ;
}
dict . nodes [ j ] . end -= e ;
}
} ) ;
end -= e ;
eachCb ( n . node . previousSibling , n . start ) ;
if ( end > n . end ) {
start = n . end ;
} else {
return false ;
}
}
return true ;
} ) ;
}
/ * *
* Filter callback before each wrapping
* @ callback Mark ~ wrapMatchesFilterCallback
* @ param { string } match - The matching string
* @ param { HTMLElement } node - The text node where the match occurs
* /
/ * *
* Callback for each wrapped element
* @ callback Mark ~ wrapMatchesEachCallback
* @ param { HTMLElement } element - The marked DOM element
* /
/ * *
* Callback on end
* @ callback Mark ~ wrapMatchesEndCallback
* /
/ * *
* Wraps the instance element and class around matches within single HTML
* elements in all contexts
* @ param { RegExp } regex - The regular expression to be searched for
* @ param { number } ignoreGroups - A number indicating the amount of RegExp
* matching groups to ignore
* @ param { Mark ~ wrapMatchesFilterCallback } filterCb
* @ param { Mark ~ wrapMatchesEachCallback } eachCb
* @ param { Mark ~ wrapMatchesEndCallback } endCb
* @ access protected
* /
wrapMatches ( regex , ignoreGroups , filterCb , eachCb , endCb ) {
const matchIdx = ignoreGroups === 0 ? 0 : ignoreGroups + 1 ;
this . getTextNodes ( ( dict ) => {
dict . nodes . forEach ( ( node ) => {
node = node . node ;
let match ;
while ( ( match = regex . exec ( node . textContent ) ) !== null && match [ matchIdx ] !== "" ) {
if ( ! filterCb ( match [ matchIdx ] , node ) ) {
continue ;
}
let pos = match . index ;
if ( matchIdx !== 0 ) {
for ( let i = 1 ; i < matchIdx ; i ++ ) {
pos += match [ i ] . length ;
}
}
node = this . wrapRangeInTextNode (
node ,
pos ,
pos + match [ matchIdx ] . length
) ;
eachCb ( node . previousSibling ) ;
regex . lastIndex = 0 ;
}
} ) ;
endCb ( ) ;
} ) ;
}
/ * *
* Callback for each wrapped element
* @ callback Mark ~ wrapMatchesAcrossElementsEachCallback
* @ param { HTMLElement } element - The marked DOM element
* /
/ * *
* Filter callback before each wrapping
* @ callback Mark ~ wrapMatchesAcrossElementsFilterCallback
* @ param { string } match - The matching string
* @ param { HTMLElement } node - The text node where the match occurs
* /
/ * *
* Callback on end
* @ callback Mark ~ wrapMatchesAcrossElementsEndCallback
* /
/ * *
* Wraps the instance element and class around matches across all HTML
* elements in all contexts
* @ param { RegExp } regex - The regular expression to be searched for
* @ param { number } ignoreGroups - A number indicating the amount of RegExp
* matching groups to ignore
* @ param { Mark ~ wrapMatchesAcrossElementsFilterCallback } filterCb
* @ param { Mark ~ wrapMatchesAcrossElementsEachCallback } eachCb
* @ param { Mark ~ wrapMatchesAcrossElementsEndCallback } endCb
* @ access protected
* /
wrapMatchesAcrossElements ( regex , ignoreGroups , filterCb , eachCb , endCb ) {
const matchIdx = ignoreGroups === 0 ? 0 : ignoreGroups + 1 ;
this . getTextNodes ( ( dict ) => {
let match ;
while ( ( match = regex . exec ( dict . value ) ) !== null && match [ matchIdx ] !== "" ) {
let start = match . index ;
if ( matchIdx !== 0 ) {
for ( let i = 1 ; i < matchIdx ; i ++ ) {
start += match [ i ] . length ;
}
}
const end = start + match [ matchIdx ] . length ;
this . wrapRangeInMappedTextNode ( dict , start , end , ( node ) => {
return filterCb ( match [ matchIdx ] , node ) ;
} , ( node , lastIndex ) => {
regex . lastIndex = lastIndex ;
eachCb ( node ) ;
} ) ;
}
endCb ( ) ;
} ) ;
}
/ * *
* Callback for each wrapped element
* @ callback Mark ~ wrapRangeFromIndexEachCallback
* @ param { HTMLElement } element - The marked DOM element
* @ param { Mark ~ rangeObject } range - the current range object ; provided
* start and length values will be numeric integers modified from the
* provided original ranges .
* /
/ * *
* Filter callback before each wrapping
* @ callback Mark ~ wrapRangeFromIndexFilterCallback
* @ param { HTMLElement } node - The text node which includes the range
* @ param { Mark ~ rangeObject } range - the current range object
* @ param { string } match - string extracted from the matching range
* @ param { number } counter - A counter indicating the number of all marks
* /
/ * *
* Callback on end
* @ callback Mark ~ wrapRangeFromIndexEndCallback
* /
/ * *
* Wraps the indicated ranges across all HTML elements in all contexts
* @ param { Mark ~ setOfRanges } ranges
* @ param { Mark ~ wrapRangeFromIndexFilterCallback } filterCb
* @ param { Mark ~ wrapRangeFromIndexEachCallback } eachCb
* @ param { Mark ~ wrapRangeFromIndexEndCallback } endCb
* @ access protected
* /
wrapRangeFromIndex ( ranges , filterCb , eachCb , endCb ) {
this . getTextNodes ( ( dict ) => {
const originalLength = dict . value . length ;
ranges . forEach ( ( range , counter ) => {
let { start , end , valid } = this . checkWhitespaceRanges (
range ,
originalLength ,
dict . value
) ;
if ( valid ) {
this . wrapRangeInMappedTextNode ( dict , start , end , ( node ) => {
return filterCb (
node ,
range ,
dict . value . substring ( start , end ) ,
counter
) ;
} , ( node ) => {
eachCb ( node , range ) ;
} ) ;
}
} ) ;
endCb ( ) ;
} ) ;
}
/ * *
* Unwraps the specified DOM node with its content ( text nodes or HTML )
* without destroying possibly present events ( using innerHTML ) and
* normalizes the parent at the end ( merge splitted text nodes )
* @ param { HTMLElement } node - The DOM node to unwrap
* @ access protected
* /
unwrapMatches ( node ) {
const parent = node . parentNode ;
let docFrag = document . createDocumentFragment ( ) ;
while ( node . firstChild ) {
docFrag . appendChild ( node . removeChild ( node . firstChild ) ) ;
}
parent . replaceChild ( docFrag , node ) ;
if ( ! this . ie ) {
parent . normalize ( ) ;
} else {
this . normalizeTextNode ( parent ) ;
}
}
/ * *
* Normalizes text nodes . It ' s a workaround for the native normalize method
* that has a bug in IE ( see attached link ) . Should only be used in IE
* browsers as it ' s slower than the native method .
* @ see { @ link http : //tinyurl.com/z5asa8c}
* @ param { HTMLElement } node - The DOM node to normalize
* @ access protected
* /
normalizeTextNode ( node ) {
if ( ! node ) {
return ;
}
if ( node . nodeType === 3 ) {
while ( node . nextSibling && node . nextSibling . nodeType === 3 ) {
node . nodeValue += node . nextSibling . nodeValue ;
node . parentNode . removeChild ( node . nextSibling ) ;
}
} else {
this . normalizeTextNode ( node . firstChild ) ;
}
this . normalizeTextNode ( node . nextSibling ) ;
}
/ * *
* Callback when finished
* @ callback Mark ~ commonDoneCallback
* @ param { number } totalMatches - The number of marked elements
* /
/ * *
* @ typedef Mark ~ commonOptions
* @ type { object . < string > }
* @ property { string } [ element = "mark" ] - HTML element tag name
* @ property { string } [ className ] - An optional class name
* @ property { string [ ] } [ exclude ] - An array with exclusion selectors .
* Elements matching those selectors will be ignored
* @ property { boolean } [ iframes = false ] - Whether to search inside iframes
* @ property { Mark ~ commonDoneCallback } [ done ]
* @ property { boolean } [ debug = false ] - Wheter to log messages
* @ property { object } [ log = window . console ] - Where to log messages ( only if
* debug is true )
* /
/ * *
* Callback for each marked element
* @ callback Mark ~ markRegExpEachCallback
* @ param { HTMLElement } element - The marked DOM element
* /
/ * *
* Callback if there were no matches
* @ callback Mark ~ markRegExpNoMatchCallback
* @ param { RegExp } regexp - The regular expression
* /
/ * *
* Callback to filter matches
* @ callback Mark ~ markRegExpFilterCallback
* @ param { HTMLElement } textNode - The text node which includes the match
* @ param { string } match - The matching string for the RegExp
* @ param { number } counter - A counter indicating the number of all marks
* /
/ * *
* These options also include the common options from
* { @ link Mark ~ commonOptions }
* @ typedef Mark ~ markRegExpOptions
* @ type { object . < string > }
* @ property { Mark ~ markRegExpEachCallback } [ each ]
* @ property { Mark ~ markRegExpNoMatchCallback } [ noMatch ]
* @ property { Mark ~ markRegExpFilterCallback } [ filter ]
* /
/ * *
* Marks a custom regular expression
* @ param { RegExp } regexp - The regular expression
* @ param { Mark ~ markRegExpOptions } [ opt ] - Optional options object
* @ access public
* /
markRegExp ( regexp , opt ) {
this . opt = opt ;
this . log ( ` Searching with expression " ${ regexp } " ` ) ;
let totalMatches = 0 , fn = "wrapMatches" ;
const eachCb = ( element ) => {
totalMatches ++ ;
this . opt . each ( element ) ;
} ;
if ( this . opt . acrossElements ) {
fn = "wrapMatchesAcrossElements" ;
}
this [ fn ] ( regexp , this . opt . ignoreGroups , ( match , node ) => {
return this . opt . filter ( node , match , totalMatches ) ;
} , eachCb , ( ) => {
if ( totalMatches === 0 ) {
this . opt . noMatch ( regexp ) ;
}
this . opt . done ( totalMatches ) ;
} ) ;
}
/ * *
* Callback for each marked element
* @ callback Mark ~ markEachCallback
* @ param { HTMLElement } element - The marked DOM element
* /
/ * *
* Callback if there were no matches
* @ callback Mark ~ markNoMatchCallback
* @ param { RegExp } term - The search term that was not found
* /
/ * *
* Callback to filter matches
* @ callback Mark ~ markFilterCallback
* @ param { HTMLElement } textNode - The text node which includes the match
* @ param { string } match - The matching term
* @ param { number } totalCounter - A counter indicating the number of all
* marks
* @ param { number } termCounter - A counter indicating the number of marks
* for the specific match
* /
/ * *
* @ typedef Mark ~ markAccuracyObject
* @ type { object . < string > }
* @ property { string } value - A accuracy string value
* @ property { string [ ] } limiters - A custom array of limiters . For example
* < code > [ "-" , "," ] < / c o d e >
* /
/ * *
* @ typedef Mark ~ markAccuracySetting
* @ type { string }
* @ property { "partially" | "complementary" | "exactly" | Mark ~ markAccuracyObject }
* [ accuracy = "partially" ] - Either one of the following string values :
* < ul >
* < li > < i > partially < / i > : W h e n s e a r c h i n g f o r " l o r " o n l y " l o r " i n s i d e
* "lorem" will be marked < / l i >
* < li > < i > complementary < / i > : W h e n s e a r c h i n g f o r " l o r " t h e w h o l e w o r d
* "lorem" will be marked < / l i >
* < li > < i > exactly < / i > : W h e n s e a r c h i n g f o r " l o r " o n l y t h o s e e x a c t w o r d s
* will be marked . In this example nothing inside "lorem" . This value
* is equivalent to the previous option < i > wordBoundary < / i > < / l i >
* < / u l >
* Or an object containing two properties :
* < ul >
* < li > < i > value < / i > : O n e o f t h e a b o v e n a m e d s t r i n g v a l u e s < / l i >
* < li > < i > limiters < / i > : A c u s t o m a r r a y o f s t r i n g l i m i t e r s f o r a c c u r a c y
* "exactly" or "complementary" < / l i >
* < / u l >
* /
/ * *
* @ typedef Mark ~ markWildcardsSetting
* @ type { string }
* @ property { "disabled" | "enabled" | "withSpaces" }
* [ wildcards = "disabled" ] - Set to any of the following string values :
* < ul >
* < li > < i > disabled < / i > : D i s a b l e w i l d c a r d u s a g e < / l i >
* < li > < i > enabled < / i > : W h e n s e a r c h i n g f o r " l o r ? m " , t h e " ? " w i l l m a t c h z e r o
* or one non - space character ( e . g . "lorm" , "loram" , "lor3m" , etc ) . When
* searching for "lor*m" , the "*" will match zero or more non - space
* characters ( e . g . "lorm" , "loram" , "lor123m" , etc ) . < / l i >
* < li > < i > withSpaces < / i > : W h e n s e a r c h i n g f o r " l o r ? m " , t h e " ? " w i l l
* match zero or one space or non - space character ( e . g . "lor m" , "loram" ,
* etc ) . When searching for "lor*m" , the "*" will match zero or more space
* or non - space characters ( e . g . "lorm" , "lore et dolor ipsum" , "lor: m" ,
* etc ) . < / l i >
* < / u l >
* /
/ * *
* @ typedef Mark ~ markIgnorePunctuationSetting
* @ type { string [ ] }
* @ property { string } The strings in this setting will contain punctuation
* marks that will be ignored :
* < ul >
* < li > These punctuation marks can be between any characters , e . g . setting
* this option to < code > [ "'" ] < / c o d e > w o u l d m a t c h " W o r l d s " , " W o r l d ' s " a n d
* "Wo'rlds" < / l i >
* < li > One or more apostrophes between the letters would still produce a
* match ( e . g . "W'o''r'l'd's" ) . < / l i >
* < li > A typical setting for this option could be as follows :
* < pre > ignorePunctuation : ":;.,-– —‒ _(){}[]!'\"+=" . split ( "" ) , < / p r e > T h i s
* setting includes common punctuation as well as a minus , en - dash ,
* em - dash and figure - dash
* ( { @ link https : //en.wikipedia.org/wiki/Dash#Figure_dash ref}), as well
* as an underscore . < / l i >
* < / u l >
* /
/ * *
* These options also include the common options from
* { @ link Mark ~ commonOptions }
* @ typedef Mark ~ markOptions
* @ type { object . < string > }
* @ property { boolean } [ separateWordSearch = true ] - Whether to search for
* each word separated by a blank instead of the complete term
* @ property { boolean } [ diacritics = true ] - If diacritic characters should be
* matched . ( { @ link https : //en.wikipedia.org/wiki/Diacritic Diacritics})
* @ property { object } [ synonyms ] - An object with synonyms . The key will be
* a synonym for the value and the value for the key
* @ property { Mark ~ markAccuracySetting } [ accuracy ]
* @ property { Mark ~ markWildcardsSetting } [ wildcards ]
* @ property { boolean } [ acrossElements = false ] - Whether to find matches
* across HTML elements . By default , only matches within single HTML
* elements will be found
* @ property { boolean } [ ignoreJoiners = false ] - Whether to ignore word
* joiners inside of key words . These include soft - hyphens , zero - width
* space , zero - width non - joiners and zero - width joiners .
* @ property { Mark ~ markIgnorePunctuationSetting } [ ignorePunctuation ]
* @ property { Mark ~ markEachCallback } [ each ]
* @ property { Mark ~ markNoMatchCallback } [ noMatch ]
* @ property { Mark ~ markFilterCallback } [ filter ]
* /
/ * *
* Marks the specified search terms
* @ param { string | string [ ] } [ sv ] - Search value , either a search string or
* an array containing multiple search strings
* @ param { Mark ~ markOptions } [ opt ] - Optional options object
* @ access public
* /
mark ( sv , opt ) {
this . opt = opt ;
let totalMatches = 0 , fn = "wrapMatches" ;
const {
keywords : kwArr ,
length : kwArrLen
} = this . getSeparatedKeywords ( typeof sv === "string" ? [ sv ] : sv ) , sens = this . opt . caseSensitive ? "" : "i" , handler = ( kw ) => {
let regex = new RegExp ( this . createRegExp ( kw ) , ` gm ${ sens } ` ) , matches2 = 0 ;
this . log ( ` Searching with expression " ${ regex } " ` ) ;
this [ fn ] ( regex , 1 , ( term , node ) => {
return this . opt . filter ( node , kw , totalMatches , matches2 ) ;
} , ( element ) => {
matches2 ++ ;
totalMatches ++ ;
this . opt . each ( element ) ;
} , ( ) => {
if ( matches2 === 0 ) {
this . opt . noMatch ( kw ) ;
}
if ( kwArr [ kwArrLen - 1 ] === kw ) {
this . opt . done ( totalMatches ) ;
} else {
handler ( kwArr [ kwArr . indexOf ( kw ) + 1 ] ) ;
}
} ) ;
} ;
if ( this . opt . acrossElements ) {
fn = "wrapMatchesAcrossElements" ;
}
if ( kwArrLen === 0 ) {
this . opt . done ( totalMatches ) ;
} else {
handler ( kwArr [ 0 ] ) ;
}
}
/ * *
* Callback for each marked element
* @ callback Mark ~ markRangesEachCallback
* @ param { HTMLElement } element - The marked DOM element
* @ param { array } range - array of range start and end points
* /
/ * *
* Callback if a processed range is invalid , out - of - bounds , overlaps another
* range , or only matches whitespace
* @ callback Mark ~ markRangesNoMatchCallback
* @ param { Mark ~ rangeObject } range - a range object
* /
/ * *
* Callback to filter matches
* @ callback Mark ~ markRangesFilterCallback
* @ param { HTMLElement } node - The text node which includes the range
* @ param { array } range - array of range start and end points
* @ param { string } match - string extracted from the matching range
* @ param { number } counter - A counter indicating the number of all marks
* /
/ * *
* These options also include the common options from
* { @ link Mark ~ commonOptions }
* @ typedef Mark ~ markRangesOptions
* @ type { object . < string > }
* @ property { Mark ~ markRangesEachCallback } [ each ]
* @ property { Mark ~ markRangesNoMatchCallback } [ noMatch ]
* @ property { Mark ~ markRangesFilterCallback } [ filter ]
* /
/ * *
* Marks an array of objects containing a start with an end or length of the
* string to mark
* @ param { Mark ~ setOfRanges } rawRanges - The original ( preprocessed )
* array of objects
* @ param { Mark ~ markRangesOptions } [ opt ] - Optional options object
* @ access public
* /
markRanges ( rawRanges , opt ) {
this . opt = opt ;
let totalMatches = 0 , ranges = this . checkRanges ( rawRanges ) ;
if ( ranges && ranges . length ) {
this . log (
"Starting to mark with the following ranges: " + JSON . stringify ( ranges )
) ;
this . wrapRangeFromIndex (
ranges ,
( node , range , match , counter ) => {
return this . opt . filter ( node , range , match , counter ) ;
} ,
( element , range ) => {
totalMatches ++ ;
this . opt . each ( element , range ) ;
} ,
( ) => {
this . opt . done ( totalMatches ) ;
}
) ;
} else {
this . opt . done ( totalMatches ) ;
}
}
/ * *
* Removes all marked elements inside the context with their HTML and
* normalizes the parent at the end
* @ param { Mark ~ commonOptions } [ opt ] - Optional options object
* @ access public
* /
unmark ( opt ) {
this . opt = opt ;
let sel = this . opt . element ? this . opt . element : "*" ;
sel += "[data-markjs]" ;
if ( this . opt . className ) {
sel += ` . ${ this . opt . className } ` ;
}
this . log ( ` Removal selector " ${ sel } " ` ) ;
this . iterator . forEachNode ( NodeFilter . SHOW _ELEMENT , ( node ) => {
this . unwrapMatches ( node ) ;
} , ( node ) => {
const matchesSel = DOMIterator . matches ( node , sel ) , matchesExclude = this . matchesExclude ( node ) ;
if ( ! matchesSel || matchesExclude ) {
return NodeFilter . FILTER _REJECT ;
} else {
return NodeFilter . FILTER _ACCEPT ;
}
} , this . opt . done ) ;
}
} ;
function Mark2 ( ctx ) {
const instance = new Mark$1 ( ctx ) ;
this . mark = ( sv , opt ) => {
instance . mark ( sv , opt ) ;
return this ;
} ;
this . markRegExp = ( sv , opt ) => {
instance . markRegExp ( sv , opt ) ;
return this ;
} ;
this . markRanges = ( sv , opt ) => {
instance . markRanges ( sv , opt ) ;
return this ;
} ;
this . unmark = ( opt ) => {
instance . unmark ( opt ) ;
return this ;
} ;
return this ;
}
var _ _assign = function ( ) {
_ _assign = Object . assign || function _ _assign2 ( t ) {
for ( var s , i = 1 , n = arguments . length ; i < n ; i ++ ) {
s = arguments [ i ] ;
for ( var p in s )
if ( Object . prototype . hasOwnProperty . call ( s , p ) )
t [ p ] = s [ p ] ;
}
return t ;
} ;
return _ _assign . apply ( this , arguments ) ;
} ;
function _ _awaiter ( thisArg , _arguments , P , generator ) {
function adopt ( value ) {
return value instanceof P ? value : new P ( function ( resolve ) {
resolve ( value ) ;
} ) ;
}
return new ( P || ( P = Promise ) ) ( function ( resolve , reject ) {
function fulfilled ( value ) {
try {
step ( generator . next ( value ) ) ;
} catch ( e ) {
reject ( e ) ;
}
}
function rejected ( value ) {
try {
step ( generator [ "throw" ] ( value ) ) ;
} catch ( e ) {
reject ( e ) ;
}
}
function step ( result ) {
result . done ? resolve ( result . value ) : adopt ( result . value ) . then ( fulfilled , rejected ) ;
}
2024-09-24 08:56:37 +00:00
step ( ( generator = generator . apply ( thisArg , [ ] ) ) . next ( ) ) ;
2024-05-30 02:02:10 +00:00
} ) ;
}
function _ _generator ( thisArg , body ) {
var _ = { label : 0 , sent : function ( ) {
if ( t [ 0 ] & 1 )
throw t [ 1 ] ;
return t [ 1 ] ;
} , trys : [ ] , ops : [ ] } , f , y , t , g ;
return g = { next : verb ( 0 ) , "throw" : verb ( 1 ) , "return" : verb ( 2 ) } , typeof Symbol === "function" && ( g [ Symbol . iterator ] = function ( ) {
return this ;
} ) , g ;
function verb ( n ) {
return function ( v ) {
return step ( [ n , v ] ) ;
} ;
}
function step ( op ) {
if ( f )
throw new TypeError ( "Generator is already executing." ) ;
while ( g && ( g = 0 , op [ 0 ] && ( _ = 0 ) ) , _ )
try {
if ( f = 1 , y && ( t = op [ 0 ] & 2 ? y [ "return" ] : op [ 0 ] ? y [ "throw" ] || ( ( t = y [ "return" ] ) && t . call ( y ) , 0 ) : y . next ) && ! ( t = t . call ( y , op [ 1 ] ) ) . done )
return t ;
if ( y = 0 , t )
op = [ op [ 0 ] & 2 , t . value ] ;
switch ( op [ 0 ] ) {
case 0 :
case 1 :
t = op ;
break ;
case 4 :
_ . label ++ ;
return { value : op [ 1 ] , done : false } ;
case 5 :
_ . label ++ ;
y = op [ 1 ] ;
op = [ 0 ] ;
continue ;
case 7 :
op = _ . ops . pop ( ) ;
_ . trys . pop ( ) ;
continue ;
default :
if ( ! ( t = _ . trys , t = t . length > 0 && t [ t . length - 1 ] ) && ( op [ 0 ] === 6 || op [ 0 ] === 2 ) ) {
_ = 0 ;
continue ;
}
if ( op [ 0 ] === 3 && ( ! t || op [ 1 ] > t [ 0 ] && op [ 1 ] < t [ 3 ] ) ) {
_ . label = op [ 1 ] ;
break ;
}
if ( op [ 0 ] === 6 && _ . label < t [ 1 ] ) {
_ . label = t [ 1 ] ;
t = op ;
break ;
}
if ( t && _ . label < t [ 2 ] ) {
_ . label = t [ 2 ] ;
_ . ops . push ( op ) ;
break ;
}
if ( t [ 2 ] )
_ . ops . pop ( ) ;
_ . trys . pop ( ) ;
continue ;
}
op = body . call ( thisArg , _ ) ;
} catch ( e ) {
op = [ 6 , e ] ;
y = 0 ;
} finally {
f = t = 0 ;
}
if ( op [ 0 ] & 5 )
throw op [ 1 ] ;
return { value : op [ 0 ] ? op [ 1 ] : void 0 , done : true } ;
}
}
function _ _values ( o ) {
var s = typeof Symbol === "function" && Symbol . iterator , m = s && o [ s ] , i = 0 ;
if ( m )
return m . call ( o ) ;
if ( o && typeof o . length === "number" )
return {
next : function ( ) {
if ( o && i >= o . length )
o = void 0 ;
return { value : o && o [ i ++ ] , done : ! o } ;
}
} ;
throw new TypeError ( s ? "Object is not iterable." : "Symbol.iterator is not defined." ) ;
}
function _ _read ( o , n ) {
var m = typeof Symbol === "function" && o [ Symbol . iterator ] ;
if ( ! m )
return o ;
var i = m . call ( o ) , r , ar = [ ] , e ;
try {
while ( ( n === void 0 || n -- > 0 ) && ! ( r = i . next ( ) ) . done )
ar . push ( r . value ) ;
} catch ( error ) {
e = { error } ;
} finally {
try {
if ( r && ! r . done && ( m = i [ "return" ] ) )
m . call ( i ) ;
} finally {
if ( e )
throw e . error ;
}
}
return ar ;
}
typeof SuppressedError === "function" ? SuppressedError : function ( error , suppressed , message ) {
var e = new Error ( message ) ;
return e . name = "SuppressedError" , e . error = error , e . suppressed = suppressed , e ;
} ;
var ENTRIES = "ENTRIES" ;
var KEYS = "KEYS" ;
var VALUES = "VALUES" ;
var LEAF = "" ;
var TreeIterator = (
/** @class */
function ( ) {
function TreeIterator2 ( set , type ) {
var node = set . _tree ;
var keys = Array . from ( node . keys ( ) ) ;
this . set = set ;
this . _type = type ;
this . _path = keys . length > 0 ? [ { node , keys } ] : [ ] ;
}
TreeIterator2 . prototype . next = function ( ) {
var value = this . dive ( ) ;
this . backtrack ( ) ;
return value ;
} ;
TreeIterator2 . prototype . dive = function ( ) {
if ( this . _path . length === 0 ) {
return { done : true , value : void 0 } ;
}
var _a2 = last$1 ( this . _path ) , node = _a2 . node , keys = _a2 . keys ;
if ( last$1 ( keys ) === LEAF ) {
return { done : false , value : this . result ( ) } ;
}
var child = node . get ( last$1 ( keys ) ) ;
this . _path . push ( { node : child , keys : Array . from ( child . keys ( ) ) } ) ;
return this . dive ( ) ;
} ;
TreeIterator2 . prototype . backtrack = function ( ) {
if ( this . _path . length === 0 ) {
return ;
}
var keys = last$1 ( this . _path ) . keys ;
keys . pop ( ) ;
if ( keys . length > 0 ) {
return ;
}
this . _path . pop ( ) ;
this . backtrack ( ) ;
} ;
TreeIterator2 . prototype . key = function ( ) {
return this . set . _prefix + this . _path . map ( function ( _a2 ) {
var keys = _a2 . keys ;
return last$1 ( keys ) ;
} ) . filter ( function ( key ) {
return key !== LEAF ;
} ) . join ( "" ) ;
} ;
TreeIterator2 . prototype . value = function ( ) {
return last$1 ( this . _path ) . node . get ( LEAF ) ;
} ;
TreeIterator2 . prototype . result = function ( ) {
switch ( this . _type ) {
case VALUES :
return this . value ( ) ;
case KEYS :
return this . key ( ) ;
default :
return [ this . key ( ) , this . value ( ) ] ;
}
} ;
TreeIterator2 . prototype [ Symbol . iterator ] = function ( ) {
return this ;
} ;
return TreeIterator2 ;
} ( )
) ;
var last$1 = function ( array ) {
return array [ array . length - 1 ] ;
} ;
var fuzzySearch = function ( node , query , maxDistance ) {
var results = /* @__PURE__ */ new Map ( ) ;
if ( query === void 0 )
return results ;
var n = query . length + 1 ;
var m = n + maxDistance ;
var matrix = new Uint8Array ( m * n ) . fill ( maxDistance + 1 ) ;
for ( var j = 0 ; j < n ; ++ j )
matrix [ j ] = j ;
for ( var i = 1 ; i < m ; ++ i )
matrix [ i * n ] = i ;
recurse ( node , query , maxDistance , results , matrix , 1 , n , "" ) ;
return results ;
} ;
var recurse = function ( node , query , maxDistance , results , matrix , m , n , prefix ) {
var e _1 , _a2 ;
var offset = m * n ;
try {
key :
for ( var _b = _ _values ( node . keys ( ) ) , _c = _b . next ( ) ; ! _c . done ; _c = _b . next ( ) ) {
var key = _c . value ;
if ( key === LEAF ) {
var distance = matrix [ offset - 1 ] ;
if ( distance <= maxDistance ) {
results . set ( prefix , [ node . get ( key ) , distance ] ) ;
}
} else {
var i = m ;
for ( var pos = 0 ; pos < key . length ; ++ pos , ++ i ) {
var char = key [ pos ] ;
var thisRowOffset = n * i ;
var prevRowOffset = thisRowOffset - n ;
var minDistance = matrix [ thisRowOffset ] ;
var jmin = Math . max ( 0 , i - maxDistance - 1 ) ;
var jmax = Math . min ( n - 1 , i + maxDistance ) ;
for ( var j = jmin ; j < jmax ; ++ j ) {
var different = char !== query [ j ] ;
var rpl = matrix [ prevRowOffset + j ] + + different ;
var del = matrix [ prevRowOffset + j + 1 ] + 1 ;
var ins = matrix [ thisRowOffset + j ] + 1 ;
var dist = matrix [ thisRowOffset + j + 1 ] = Math . min ( rpl , del , ins ) ;
if ( dist < minDistance )
minDistance = dist ;
}
if ( minDistance > maxDistance ) {
continue key ;
}
}
recurse ( node . get ( key ) , query , maxDistance , results , matrix , i , n , prefix + key ) ;
}
}
} catch ( e _1 _1 ) {
e _1 = { error : e _1 _1 } ;
} finally {
try {
if ( _c && ! _c . done && ( _a2 = _b . return ) )
_a2 . call ( _b ) ;
} finally {
if ( e _1 )
throw e _1 . error ;
}
}
} ;
var SearchableMap = (
/** @class */
function ( ) {
function SearchableMap2 ( tree , prefix ) {
if ( tree === void 0 ) {
tree = /* @__PURE__ */ new Map ( ) ;
}
if ( prefix === void 0 ) {
prefix = "" ;
}
this . _size = void 0 ;
this . _tree = tree ;
this . _prefix = prefix ;
}
SearchableMap2 . prototype . atPrefix = function ( prefix ) {
var e _1 , _a2 ;
if ( ! prefix . startsWith ( this . _prefix ) ) {
throw new Error ( "Mismatched prefix" ) ;
}
var _b = _ _read ( trackDown ( this . _tree , prefix . slice ( this . _prefix . length ) ) , 2 ) , node = _b [ 0 ] , path = _b [ 1 ] ;
if ( node === void 0 ) {
var _c = _ _read ( last ( path ) , 2 ) , parentNode = _c [ 0 ] , key = _c [ 1 ] ;
try {
for ( var _d = _ _values ( parentNode . keys ( ) ) , _e = _d . next ( ) ; ! _e . done ; _e = _d . next ( ) ) {
var k = _e . value ;
if ( k !== LEAF && k . startsWith ( key ) ) {
var node _1 = /* @__PURE__ */ new Map ( ) ;
node _1 . set ( k . slice ( key . length ) , parentNode . get ( k ) ) ;
return new SearchableMap2 ( node _1 , prefix ) ;
}
}
} catch ( e _1 _1 ) {
e _1 = { error : e _1 _1 } ;
} finally {
try {
if ( _e && ! _e . done && ( _a2 = _d . return ) )
_a2 . call ( _d ) ;
} finally {
if ( e _1 )
throw e _1 . error ;
}
}
}
return new SearchableMap2 ( node , prefix ) ;
} ;
SearchableMap2 . prototype . clear = function ( ) {
this . _size = void 0 ;
this . _tree . clear ( ) ;
} ;
SearchableMap2 . prototype . delete = function ( key ) {
this . _size = void 0 ;
return remove ( this . _tree , key ) ;
} ;
SearchableMap2 . prototype . entries = function ( ) {
return new TreeIterator ( this , ENTRIES ) ;
} ;
SearchableMap2 . prototype . forEach = function ( fn ) {
var e _2 , _a2 ;
try {
for ( var _b = _ _values ( this ) , _c = _b . next ( ) ; ! _c . done ; _c = _b . next ( ) ) {
var _d = _ _read ( _c . value , 2 ) , key = _d [ 0 ] , value = _d [ 1 ] ;
fn ( key , value , this ) ;
}
} catch ( e _2 _1 ) {
e _2 = { error : e _2 _1 } ;
} finally {
try {
if ( _c && ! _c . done && ( _a2 = _b . return ) )
_a2 . call ( _b ) ;
} finally {
if ( e _2 )
throw e _2 . error ;
}
}
} ;
SearchableMap2 . prototype . fuzzyGet = function ( key , maxEditDistance ) {
return fuzzySearch ( this . _tree , key , maxEditDistance ) ;
} ;
SearchableMap2 . prototype . get = function ( key ) {
var node = lookup ( this . _tree , key ) ;
return node !== void 0 ? node . get ( LEAF ) : void 0 ;
} ;
SearchableMap2 . prototype . has = function ( key ) {
var node = lookup ( this . _tree , key ) ;
return node !== void 0 && node . has ( LEAF ) ;
} ;
SearchableMap2 . prototype . keys = function ( ) {
return new TreeIterator ( this , KEYS ) ;
} ;
SearchableMap2 . prototype . set = function ( key , value ) {
if ( typeof key !== "string" ) {
throw new Error ( "key must be a string" ) ;
}
this . _size = void 0 ;
var node = createPath ( this . _tree , key ) ;
node . set ( LEAF , value ) ;
return this ;
} ;
Object . defineProperty ( SearchableMap2 . prototype , "size" , {
/ * *
* @ see https : //developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/size
* /
get : function ( ) {
if ( this . _size ) {
return this . _size ;
}
this . _size = 0 ;
var iter = this . entries ( ) ;
while ( ! iter . next ( ) . done )
this . _size += 1 ;
return this . _size ;
} ,
enumerable : false ,
configurable : true
} ) ;
SearchableMap2 . prototype . update = function ( key , fn ) {
if ( typeof key !== "string" ) {
throw new Error ( "key must be a string" ) ;
}
this . _size = void 0 ;
var node = createPath ( this . _tree , key ) ;
node . set ( LEAF , fn ( node . get ( LEAF ) ) ) ;
return this ;
} ;
SearchableMap2 . prototype . fetch = function ( key , initial ) {
if ( typeof key !== "string" ) {
throw new Error ( "key must be a string" ) ;
}
this . _size = void 0 ;
var node = createPath ( this . _tree , key ) ;
var value = node . get ( LEAF ) ;
if ( value === void 0 ) {
node . set ( LEAF , value = initial ( ) ) ;
}
return value ;
} ;
SearchableMap2 . prototype . values = function ( ) {
return new TreeIterator ( this , VALUES ) ;
} ;
SearchableMap2 . prototype [ Symbol . iterator ] = function ( ) {
return this . entries ( ) ;
} ;
SearchableMap2 . from = function ( entries ) {
var e _3 , _a2 ;
var tree = new SearchableMap2 ( ) ;
try {
for ( var entries _1 = _ _values ( entries ) , entries _1 _1 = entries _1 . next ( ) ; ! entries _1 _1 . done ; entries _1 _1 = entries _1 . next ( ) ) {
var _b = _ _read ( entries _1 _1 . value , 2 ) , key = _b [ 0 ] , value = _b [ 1 ] ;
tree . set ( key , value ) ;
}
} catch ( e _3 _1 ) {
e _3 = { error : e _3 _1 } ;
} finally {
try {
if ( entries _1 _1 && ! entries _1 _1 . done && ( _a2 = entries _1 . return ) )
_a2 . call ( entries _1 ) ;
} finally {
if ( e _3 )
throw e _3 . error ;
}
}
return tree ;
} ;
SearchableMap2 . fromObject = function ( object ) {
return SearchableMap2 . from ( Object . entries ( object ) ) ;
} ;
return SearchableMap2 ;
} ( )
) ;
var trackDown = function ( tree , key , path ) {
var e _4 , _a2 ;
if ( path === void 0 ) {
path = [ ] ;
}
if ( key . length === 0 || tree == null ) {
return [ tree , path ] ;
}
try {
for ( var _b = _ _values ( tree . keys ( ) ) , _c = _b . next ( ) ; ! _c . done ; _c = _b . next ( ) ) {
var k = _c . value ;
if ( k !== LEAF && key . startsWith ( k ) ) {
path . push ( [ tree , k ] ) ;
return trackDown ( tree . get ( k ) , key . slice ( k . length ) , path ) ;
}
}
} catch ( e _4 _1 ) {
e _4 = { error : e _4 _1 } ;
} finally {
try {
if ( _c && ! _c . done && ( _a2 = _b . return ) )
_a2 . call ( _b ) ;
} finally {
if ( e _4 )
throw e _4 . error ;
}
}
path . push ( [ tree , key ] ) ;
return trackDown ( void 0 , "" , path ) ;
} ;
var lookup = function ( tree , key ) {
var e _5 , _a2 ;
if ( key . length === 0 || tree == null ) {
return tree ;
}
try {
for ( var _b = _ _values ( tree . keys ( ) ) , _c = _b . next ( ) ; ! _c . done ; _c = _b . next ( ) ) {
var k = _c . value ;
if ( k !== LEAF && key . startsWith ( k ) ) {
return lookup ( tree . get ( k ) , key . slice ( k . length ) ) ;
}
}
} catch ( e _5 _1 ) {
e _5 = { error : e _5 _1 } ;
} finally {
try {
if ( _c && ! _c . done && ( _a2 = _b . return ) )
_a2 . call ( _b ) ;
} finally {
if ( e _5 )
throw e _5 . error ;
}
}
} ;
var createPath = function ( node , key ) {
var e _6 , _a2 ;
var keyLength = key . length ;
outer :
for ( var pos = 0 ; node && pos < keyLength ; ) {
try {
for ( var _b = ( e _6 = void 0 , _ _values ( node . keys ( ) ) ) , _c = _b . next ( ) ; ! _c . done ; _c = _b . next ( ) ) {
var k = _c . value ;
if ( k !== LEAF && key [ pos ] === k [ 0 ] ) {
var len = Math . min ( keyLength - pos , k . length ) ;
var offset = 1 ;
while ( offset < len && key [ pos + offset ] === k [ offset ] )
++ offset ;
var child _1 = node . get ( k ) ;
if ( offset === k . length ) {
node = child _1 ;
} else {
var intermediate = /* @__PURE__ */ new Map ( ) ;
intermediate . set ( k . slice ( offset ) , child _1 ) ;
node . set ( key . slice ( pos , pos + offset ) , intermediate ) ;
node . delete ( k ) ;
node = intermediate ;
}
pos += offset ;
continue outer ;
}
}
} catch ( e _6 _1 ) {
e _6 = { error : e _6 _1 } ;
} finally {
try {
if ( _c && ! _c . done && ( _a2 = _b . return ) )
_a2 . call ( _b ) ;
} finally {
if ( e _6 )
throw e _6 . error ;
}
}
var child = /* @__PURE__ */ new Map ( ) ;
node . set ( key . slice ( pos ) , child ) ;
return child ;
}
return node ;
} ;
var remove = function ( tree , key ) {
var _a2 = _ _read ( trackDown ( tree , key ) , 2 ) , node = _a2 [ 0 ] , path = _a2 [ 1 ] ;
if ( node === void 0 ) {
return ;
}
node . delete ( LEAF ) ;
if ( node . size === 0 ) {
cleanup ( path ) ;
} else if ( node . size === 1 ) {
var _b = _ _read ( node . entries ( ) . next ( ) . value , 2 ) , key _1 = _b [ 0 ] , value = _b [ 1 ] ;
merge ( path , key _1 , value ) ;
}
} ;
var cleanup = function ( path ) {
if ( path . length === 0 ) {
return ;
}
var _a2 = _ _read ( last ( path ) , 2 ) , node = _a2 [ 0 ] , key = _a2 [ 1 ] ;
node . delete ( key ) ;
if ( node . size === 0 ) {
cleanup ( path . slice ( 0 , - 1 ) ) ;
} else if ( node . size === 1 ) {
var _b = _ _read ( node . entries ( ) . next ( ) . value , 2 ) , key _2 = _b [ 0 ] , value = _b [ 1 ] ;
if ( key _2 !== LEAF ) {
merge ( path . slice ( 0 , - 1 ) , key _2 , value ) ;
}
}
} ;
var merge = function ( path , key , value ) {
if ( path . length === 0 ) {
return ;
}
var _a2 = _ _read ( last ( path ) , 2 ) , node = _a2 [ 0 ] , nodeKey = _a2 [ 1 ] ;
node . set ( nodeKey + key , value ) ;
node . delete ( nodeKey ) ;
} ;
var last = function ( array ) {
return array [ array . length - 1 ] ;
} ;
var _a ;
var OR = "or" ;
var AND = "and" ;
var AND _NOT = "and_not" ;
var MiniSearch = (
/** @class */
function ( ) {
function MiniSearch2 ( options ) {
if ( ( options === null || options === void 0 ? void 0 : options . fields ) == null ) {
throw new Error ( 'MiniSearch: option "fields" must be provided' ) ;
}
var autoVacuum = options . autoVacuum == null || options . autoVacuum === true ? defaultAutoVacuumOptions : options . autoVacuum ;
this . _options = _ _assign ( _ _assign ( _ _assign ( { } , defaultOptions ) , options ) , { autoVacuum , searchOptions : _ _assign ( _ _assign ( { } , defaultSearchOptions ) , options . searchOptions || { } ) , autoSuggestOptions : _ _assign ( _ _assign ( { } , defaultAutoSuggestOptions ) , options . autoSuggestOptions || { } ) } ) ;
this . _index = new SearchableMap ( ) ;
this . _documentCount = 0 ;
this . _documentIds = /* @__PURE__ */ new Map ( ) ;
this . _idToShortId = /* @__PURE__ */ new Map ( ) ;
this . _fieldIds = { } ;
this . _fieldLength = /* @__PURE__ */ new Map ( ) ;
this . _avgFieldLength = [ ] ;
this . _nextId = 0 ;
this . _storedFields = /* @__PURE__ */ new Map ( ) ;
this . _dirtCount = 0 ;
this . _currentVacuum = null ;
this . _enqueuedVacuum = null ;
this . _enqueuedVacuumConditions = defaultVacuumConditions ;
this . addFields ( this . _options . fields ) ;
}
MiniSearch2 . prototype . add = function ( document2 ) {
var e _1 , _a2 , e _2 , _b , e _3 , _c ;
var _d = this . _options , extractField = _d . extractField , tokenize = _d . tokenize , processTerm = _d . processTerm , fields = _d . fields , idField = _d . idField ;
var id = extractField ( document2 , idField ) ;
if ( id == null ) {
throw new Error ( 'MiniSearch: document does not have ID field "' . concat ( idField , '"' ) ) ;
}
if ( this . _idToShortId . has ( id ) ) {
throw new Error ( "MiniSearch: duplicate ID " . concat ( id ) ) ;
}
var shortDocumentId = this . addDocumentId ( id ) ;
this . saveStoredFields ( shortDocumentId , document2 ) ;
try {
for ( var fields _1 = _ _values ( fields ) , fields _1 _1 = fields _1 . next ( ) ; ! fields _1 _1 . done ; fields _1 _1 = fields _1 . next ( ) ) {
var field = fields _1 _1 . value ;
var fieldValue = extractField ( document2 , field ) ;
if ( fieldValue == null )
continue ;
var tokens = tokenize ( fieldValue . toString ( ) , field ) ;
var fieldId = this . _fieldIds [ field ] ;
var uniqueTerms = new Set ( tokens ) . size ;
this . addFieldLength ( shortDocumentId , fieldId , this . _documentCount - 1 , uniqueTerms ) ;
try {
for ( var tokens _1 = ( e _2 = void 0 , _ _values ( tokens ) ) , tokens _1 _1 = tokens _1 . next ( ) ; ! tokens _1 _1 . done ; tokens _1 _1 = tokens _1 . next ( ) ) {
var term = tokens _1 _1 . value ;
var processedTerm = processTerm ( term , field ) ;
if ( Array . isArray ( processedTerm ) ) {
try {
for ( var processedTerm _1 = ( e _3 = void 0 , _ _values ( processedTerm ) ) , processedTerm _1 _1 = processedTerm _1 . next ( ) ; ! processedTerm _1 _1 . done ; processedTerm _1 _1 = processedTerm _1 . next ( ) ) {
var t = processedTerm _1 _1 . value ;
this . addTerm ( fieldId , shortDocumentId , t ) ;
}
} catch ( e _3 _1 ) {
e _3 = { error : e _3 _1 } ;
} finally {
try {
if ( processedTerm _1 _1 && ! processedTerm _1 _1 . done && ( _c = processedTerm _1 . return ) )
_c . call ( processedTerm _1 ) ;
} finally {
if ( e _3 )
throw e _3 . error ;
}
}
} else if ( processedTerm ) {
this . addTerm ( fieldId , shortDocumentId , processedTerm ) ;
}
}
} catch ( e _2 _1 ) {
e _2 = { error : e _2 _1 } ;
} finally {
try {
if ( tokens _1 _1 && ! tokens _1 _1 . done && ( _b = tokens _1 . return ) )
_b . call ( tokens _1 ) ;
} finally {
if ( e _2 )
throw e _2 . error ;
}
}
}
} catch ( e _1 _1 ) {
e _1 = { error : e _1 _1 } ;
} finally {
try {
if ( fields _1 _1 && ! fields _1 _1 . done && ( _a2 = fields _1 . return ) )
_a2 . call ( fields _1 ) ;
} finally {
if ( e _1 )
throw e _1 . error ;
}
}
} ;
MiniSearch2 . prototype . addAll = function ( documents ) {
var e _4 , _a2 ;
try {
for ( var documents _1 = _ _values ( documents ) , documents _1 _1 = documents _1 . next ( ) ; ! documents _1 _1 . done ; documents _1 _1 = documents _1 . next ( ) ) {
var document _1 = documents _1 _1 . value ;
this . add ( document _1 ) ;
}
} catch ( e _4 _1 ) {
e _4 = { error : e _4 _1 } ;
} finally {
try {
if ( documents _1 _1 && ! documents _1 _1 . done && ( _a2 = documents _1 . return ) )
_a2 . call ( documents _1 ) ;
} finally {
if ( e _4 )
throw e _4 . error ;
}
}
} ;
MiniSearch2 . prototype . addAllAsync = function ( documents , options ) {
var _this = this ;
if ( options === void 0 ) {
options = { } ;
}
var _a2 = options . chunkSize , chunkSize = _a2 === void 0 ? 10 : _a2 ;
var acc = { chunk : [ ] , promise : Promise . resolve ( ) } ;
var _b = documents . reduce ( function ( _a3 , document2 , i ) {
var chunk2 = _a3 . chunk , promise2 = _a3 . promise ;
chunk2 . push ( document2 ) ;
if ( ( i + 1 ) % chunkSize === 0 ) {
return {
chunk : [ ] ,
promise : promise2 . then ( function ( ) {
return new Promise ( function ( resolve ) {
return setTimeout ( resolve , 0 ) ;
} ) ;
} ) . then ( function ( ) {
return _this . addAll ( chunk2 ) ;
} )
} ;
} else {
return { chunk : chunk2 , promise : promise2 } ;
}
} , acc ) , chunk = _b . chunk , promise = _b . promise ;
return promise . then ( function ( ) {
return _this . addAll ( chunk ) ;
} ) ;
} ;
MiniSearch2 . prototype . remove = function ( document2 ) {
var e _5 , _a2 , e _6 , _b , e _7 , _c ;
var _d = this . _options , tokenize = _d . tokenize , processTerm = _d . processTerm , extractField = _d . extractField , fields = _d . fields , idField = _d . idField ;
var id = extractField ( document2 , idField ) ;
if ( id == null ) {
throw new Error ( 'MiniSearch: document does not have ID field "' . concat ( idField , '"' ) ) ;
}
var shortId = this . _idToShortId . get ( id ) ;
if ( shortId == null ) {
throw new Error ( "MiniSearch: cannot remove document with ID " . concat ( id , ": it is not in the index" ) ) ;
}
try {
for ( var fields _2 = _ _values ( fields ) , fields _2 _1 = fields _2 . next ( ) ; ! fields _2 _1 . done ; fields _2 _1 = fields _2 . next ( ) ) {
var field = fields _2 _1 . value ;
var fieldValue = extractField ( document2 , field ) ;
if ( fieldValue == null )
continue ;
var tokens = tokenize ( fieldValue . toString ( ) , field ) ;
var fieldId = this . _fieldIds [ field ] ;
var uniqueTerms = new Set ( tokens ) . size ;
this . removeFieldLength ( shortId , fieldId , this . _documentCount , uniqueTerms ) ;
try {
for ( var tokens _2 = ( e _6 = void 0 , _ _values ( tokens ) ) , tokens _2 _1 = tokens _2 . next ( ) ; ! tokens _2 _1 . done ; tokens _2 _1 = tokens _2 . next ( ) ) {
var term = tokens _2 _1 . value ;
var processedTerm = processTerm ( term , field ) ;
if ( Array . isArray ( processedTerm ) ) {
try {
for ( var processedTerm _2 = ( e _7 = void 0 , _ _values ( processedTerm ) ) , processedTerm _2 _1 = processedTerm _2 . next ( ) ; ! processedTerm _2 _1 . done ; processedTerm _2 _1 = processedTerm _2 . next ( ) ) {
var t = processedTerm _2 _1 . value ;
this . removeTerm ( fieldId , shortId , t ) ;
}
} catch ( e _7 _1 ) {
e _7 = { error : e _7 _1 } ;
} finally {
try {
if ( processedTerm _2 _1 && ! processedTerm _2 _1 . done && ( _c = processedTerm _2 . return ) )
_c . call ( processedTerm _2 ) ;
} finally {
if ( e _7 )
throw e _7 . error ;
}
}
} else if ( processedTerm ) {
this . removeTerm ( fieldId , shortId , processedTerm ) ;
}
}
} catch ( e _6 _1 ) {
e _6 = { error : e _6 _1 } ;
} finally {
try {
if ( tokens _2 _1 && ! tokens _2 _1 . done && ( _b = tokens _2 . return ) )
_b . call ( tokens _2 ) ;
} finally {
if ( e _6 )
throw e _6 . error ;
}
}
}
} catch ( e _5 _1 ) {
e _5 = { error : e _5 _1 } ;
} finally {
try {
if ( fields _2 _1 && ! fields _2 _1 . done && ( _a2 = fields _2 . return ) )
_a2 . call ( fields _2 ) ;
} finally {
if ( e _5 )
throw e _5 . error ;
}
}
this . _storedFields . delete ( shortId ) ;
this . _documentIds . delete ( shortId ) ;
this . _idToShortId . delete ( id ) ;
this . _fieldLength . delete ( shortId ) ;
this . _documentCount -= 1 ;
} ;
MiniSearch2 . prototype . removeAll = function ( documents ) {
var e _8 , _a2 ;
if ( documents ) {
try {
for ( var documents _2 = _ _values ( documents ) , documents _2 _1 = documents _2 . next ( ) ; ! documents _2 _1 . done ; documents _2 _1 = documents _2 . next ( ) ) {
var document _2 = documents _2 _1 . value ;
this . remove ( document _2 ) ;
}
} catch ( e _8 _1 ) {
e _8 = { error : e _8 _1 } ;
} finally {
try {
if ( documents _2 _1 && ! documents _2 _1 . done && ( _a2 = documents _2 . return ) )
_a2 . call ( documents _2 ) ;
} finally {
if ( e _8 )
throw e _8 . error ;
}
}
} else if ( arguments . length > 0 ) {
throw new Error ( "Expected documents to be present. Omit the argument to remove all documents." ) ;
} else {
this . _index = new SearchableMap ( ) ;
this . _documentCount = 0 ;
this . _documentIds = /* @__PURE__ */ new Map ( ) ;
this . _idToShortId = /* @__PURE__ */ new Map ( ) ;
this . _fieldLength = /* @__PURE__ */ new Map ( ) ;
this . _avgFieldLength = [ ] ;
this . _storedFields = /* @__PURE__ */ new Map ( ) ;
this . _nextId = 0 ;
}
} ;
MiniSearch2 . prototype . discard = function ( id ) {
var _this = this ;
var shortId = this . _idToShortId . get ( id ) ;
if ( shortId == null ) {
throw new Error ( "MiniSearch: cannot discard document with ID " . concat ( id , ": it is not in the index" ) ) ;
}
this . _idToShortId . delete ( id ) ;
this . _documentIds . delete ( shortId ) ;
this . _storedFields . delete ( shortId ) ;
( this . _fieldLength . get ( shortId ) || [ ] ) . forEach ( function ( fieldLength , fieldId ) {
_this . removeFieldLength ( shortId , fieldId , _this . _documentCount , fieldLength ) ;
} ) ;
this . _fieldLength . delete ( shortId ) ;
this . _documentCount -= 1 ;
this . _dirtCount += 1 ;
this . maybeAutoVacuum ( ) ;
} ;
MiniSearch2 . prototype . maybeAutoVacuum = function ( ) {
if ( this . _options . autoVacuum === false ) {
return ;
}
var _a2 = this . _options . autoVacuum , minDirtFactor = _a2 . minDirtFactor , minDirtCount = _a2 . minDirtCount , batchSize = _a2 . batchSize , batchWait = _a2 . batchWait ;
this . conditionalVacuum ( { batchSize , batchWait } , { minDirtCount , minDirtFactor } ) ;
} ;
MiniSearch2 . prototype . discardAll = function ( ids ) {
var e _9 , _a2 ;
var autoVacuum = this . _options . autoVacuum ;
try {
this . _options . autoVacuum = false ;
try {
for ( var ids _1 = _ _values ( ids ) , ids _1 _1 = ids _1 . next ( ) ; ! ids _1 _1 . done ; ids _1 _1 = ids _1 . next ( ) ) {
var id = ids _1 _1 . value ;
this . discard ( id ) ;
}
} catch ( e _9 _1 ) {
e _9 = { error : e _9 _1 } ;
} finally {
try {
if ( ids _1 _1 && ! ids _1 _1 . done && ( _a2 = ids _1 . return ) )
_a2 . call ( ids _1 ) ;
} finally {
if ( e _9 )
throw e _9 . error ;
}
}
} finally {
this . _options . autoVacuum = autoVacuum ;
}
this . maybeAutoVacuum ( ) ;
} ;
MiniSearch2 . prototype . replace = function ( updatedDocument ) {
var _a2 = this . _options , idField = _a2 . idField , extractField = _a2 . extractField ;
var id = extractField ( updatedDocument , idField ) ;
this . discard ( id ) ;
this . add ( updatedDocument ) ;
} ;
MiniSearch2 . prototype . vacuum = function ( options ) {
if ( options === void 0 ) {
options = { } ;
}
return this . conditionalVacuum ( options ) ;
} ;
MiniSearch2 . prototype . conditionalVacuum = function ( options , conditions ) {
var _this = this ;
if ( this . _currentVacuum ) {
this . _enqueuedVacuumConditions = this . _enqueuedVacuumConditions && conditions ;
if ( this . _enqueuedVacuum != null ) {
return this . _enqueuedVacuum ;
}
this . _enqueuedVacuum = this . _currentVacuum . then ( function ( ) {
var conditions2 = _this . _enqueuedVacuumConditions ;
_this . _enqueuedVacuumConditions = defaultVacuumConditions ;
return _this . performVacuuming ( options , conditions2 ) ;
} ) ;
return this . _enqueuedVacuum ;
}
if ( this . vacuumConditionsMet ( conditions ) === false ) {
return Promise . resolve ( ) ;
}
this . _currentVacuum = this . performVacuuming ( options ) ;
return this . _currentVacuum ;
} ;
MiniSearch2 . prototype . performVacuuming = function ( options , conditions ) {
return _ _awaiter ( this , void 0 , void 0 , function ( ) {
var initialDirtCount , batchSize , batchWait _1 , i , _a2 , _b , _c , term , fieldsData , fieldsData _1 , fieldsData _1 _1 , _d , fieldId , fieldIndex , fieldIndex _1 , fieldIndex _1 _1 , _e , shortId , e _10 _1 ;
var e _10 , _f , e _11 , _g , e _12 , _h ;
return _ _generator ( this , function ( _j ) {
switch ( _j . label ) {
case 0 :
initialDirtCount = this . _dirtCount ;
if ( ! this . vacuumConditionsMet ( conditions ) )
return [ 3 , 10 ] ;
batchSize = options . batchSize || defaultVacuumOptions . batchSize ;
batchWait _1 = options . batchWait || defaultVacuumOptions . batchWait ;
i = 1 ;
_j . label = 1 ;
case 1 :
_j . trys . push ( [ 1 , 7 , 8 , 9 ] ) ;
_a2 = _ _values ( this . _index ) , _b = _a2 . next ( ) ;
_j . label = 2 ;
case 2 :
if ( ! ! _b . done )
return [ 3 , 6 ] ;
_c = _ _read ( _b . value , 2 ) , term = _c [ 0 ] , fieldsData = _c [ 1 ] ;
try {
for ( fieldsData _1 = ( e _11 = void 0 , _ _values ( fieldsData ) ) , fieldsData _1 _1 = fieldsData _1 . next ( ) ; ! fieldsData _1 _1 . done ; fieldsData _1 _1 = fieldsData _1 . next ( ) ) {
_d = _ _read ( fieldsData _1 _1 . value , 2 ) , fieldId = _d [ 0 ] , fieldIndex = _d [ 1 ] ;
try {
for ( fieldIndex _1 = ( e _12 = void 0 , _ _values ( fieldIndex ) ) , fieldIndex _1 _1 = fieldIndex _1 . next ( ) ; ! fieldIndex _1 _1 . done ; fieldIndex _1 _1 = fieldIndex _1 . next ( ) ) {
_e = _ _read ( fieldIndex _1 _1 . value , 1 ) , shortId = _e [ 0 ] ;
if ( this . _documentIds . has ( shortId ) ) {
continue ;
}
if ( fieldIndex . size <= 1 ) {
fieldsData . delete ( fieldId ) ;
} else {
fieldIndex . delete ( shortId ) ;
}
}
} catch ( e _12 _1 ) {
e _12 = { error : e _12 _1 } ;
} finally {
try {
if ( fieldIndex _1 _1 && ! fieldIndex _1 _1 . done && ( _h = fieldIndex _1 . return ) )
_h . call ( fieldIndex _1 ) ;
} finally {
if ( e _12 )
throw e _12 . error ;
}
}
}
} catch ( e _11 _1 ) {
e _11 = { error : e _11 _1 } ;
} finally {
try {
if ( fieldsData _1 _1 && ! fieldsData _1 _1 . done && ( _g = fieldsData _1 . return ) )
_g . call ( fieldsData _1 ) ;
} finally {
if ( e _11 )
throw e _11 . error ;
}
}
if ( this . _index . get ( term ) . size === 0 ) {
this . _index . delete ( term ) ;
}
if ( ! ( i % batchSize === 0 ) )
return [ 3 , 4 ] ;
return [ 4 , new Promise ( function ( resolve ) {
return setTimeout ( resolve , batchWait _1 ) ;
} ) ] ;
case 3 :
_j . sent ( ) ;
_j . label = 4 ;
case 4 :
i += 1 ;
_j . label = 5 ;
case 5 :
_b = _a2 . next ( ) ;
return [ 3 , 2 ] ;
case 6 :
return [ 3 , 9 ] ;
case 7 :
e _10 _1 = _j . sent ( ) ;
e _10 = { error : e _10 _1 } ;
return [ 3 , 9 ] ;
case 8 :
try {
if ( _b && ! _b . done && ( _f = _a2 . return ) )
_f . call ( _a2 ) ;
} finally {
if ( e _10 )
throw e _10 . error ;
}
return [
7
/*endfinally*/
] ;
case 9 :
this . _dirtCount -= initialDirtCount ;
_j . label = 10 ;
case 10 :
return [ 4 , null ] ;
case 11 :
_j . sent ( ) ;
this . _currentVacuum = this . _enqueuedVacuum ;
this . _enqueuedVacuum = null ;
return [
2
/*return*/
] ;
}
} ) ;
} ) ;
} ;
MiniSearch2 . prototype . vacuumConditionsMet = function ( conditions ) {
if ( conditions == null ) {
return true ;
}
var minDirtCount = conditions . minDirtCount , minDirtFactor = conditions . minDirtFactor ;
minDirtCount = minDirtCount || defaultAutoVacuumOptions . minDirtCount ;
minDirtFactor = minDirtFactor || defaultAutoVacuumOptions . minDirtFactor ;
return this . dirtCount >= minDirtCount && this . dirtFactor >= minDirtFactor ;
} ;
Object . defineProperty ( MiniSearch2 . prototype , "isVacuuming" , {
/ * *
* Is ` true ` if a vacuuming operation is ongoing , ` false ` otherwise
* /
get : function ( ) {
return this . _currentVacuum != null ;
} ,
enumerable : false ,
configurable : true
} ) ;
Object . defineProperty ( MiniSearch2 . prototype , "dirtCount" , {
/ * *
* The number of documents discarded since the most recent vacuuming
* /
get : function ( ) {
return this . _dirtCount ;
} ,
enumerable : false ,
configurable : true
} ) ;
Object . defineProperty ( MiniSearch2 . prototype , "dirtFactor" , {
/ * *
* A number between 0 and 1 giving an indication about the proportion of
* documents that are discarded , and can therefore be cleaned up by vacuuming .
* A value close to 0 means that the index is relatively clean , while a higher
* value means that the index is relatively dirty , and vacuuming could release
* memory .
* /
get : function ( ) {
return this . _dirtCount / ( 1 + this . _documentCount + this . _dirtCount ) ;
} ,
enumerable : false ,
configurable : true
} ) ;
MiniSearch2 . prototype . has = function ( id ) {
return this . _idToShortId . has ( id ) ;
} ;
MiniSearch2 . prototype . getStoredFields = function ( id ) {
var shortId = this . _idToShortId . get ( id ) ;
if ( shortId == null ) {
return void 0 ;
}
return this . _storedFields . get ( shortId ) ;
} ;
MiniSearch2 . prototype . search = function ( query , searchOptions ) {
var e _13 , _a2 ;
if ( searchOptions === void 0 ) {
searchOptions = { } ;
}
var rawResults = this . executeQuery ( query , searchOptions ) ;
var results = [ ] ;
try {
for ( var rawResults _1 = _ _values ( rawResults ) , rawResults _1 _1 = rawResults _1 . next ( ) ; ! rawResults _1 _1 . done ; rawResults _1 _1 = rawResults _1 . next ( ) ) {
var _b = _ _read ( rawResults _1 _1 . value , 2 ) , docId = _b [ 0 ] , _c = _b [ 1 ] , score = _c . score , terms = _c . terms , match = _c . match ;
var quality = terms . length || 1 ;
var result = {
id : this . _documentIds . get ( docId ) ,
score : score * quality ,
terms : Object . keys ( match ) ,
queryTerms : terms ,
match
} ;
Object . assign ( result , this . _storedFields . get ( docId ) ) ;
if ( searchOptions . filter == null || searchOptions . filter ( result ) ) {
results . push ( result ) ;
}
}
} catch ( e _13 _1 ) {
e _13 = { error : e _13 _1 } ;
} finally {
try {
if ( rawResults _1 _1 && ! rawResults _1 _1 . done && ( _a2 = rawResults _1 . return ) )
_a2 . call ( rawResults _1 ) ;
} finally {
if ( e _13 )
throw e _13 . error ;
}
}
if ( query === MiniSearch2 . wildcard && searchOptions . boostDocument == null && this . _options . searchOptions . boostDocument == null ) {
return results ;
}
results . sort ( byScore ) ;
return results ;
} ;
MiniSearch2 . prototype . autoSuggest = function ( queryString , options ) {
var e _14 , _a2 , e _15 , _b ;
if ( options === void 0 ) {
options = { } ;
}
options = _ _assign ( _ _assign ( { } , this . _options . autoSuggestOptions ) , options ) ;
var suggestions = /* @__PURE__ */ new Map ( ) ;
try {
for ( var _c = _ _values ( this . search ( queryString , options ) ) , _d = _c . next ( ) ; ! _d . done ; _d = _c . next ( ) ) {
var _e = _d . value , score = _e . score , terms = _e . terms ;
var phrase = terms . join ( " " ) ;
var suggestion = suggestions . get ( phrase ) ;
if ( suggestion != null ) {
suggestion . score += score ;
suggestion . count += 1 ;
} else {
suggestions . set ( phrase , { score , terms , count : 1 } ) ;
}
}
} catch ( e _14 _1 ) {
e _14 = { error : e _14 _1 } ;
} finally {
try {
if ( _d && ! _d . done && ( _a2 = _c . return ) )
_a2 . call ( _c ) ;
} finally {
if ( e _14 )
throw e _14 . error ;
}
}
var results = [ ] ;
try {
for ( var suggestions _1 = _ _values ( suggestions ) , suggestions _1 _1 = suggestions _1 . next ( ) ; ! suggestions _1 _1 . done ; suggestions _1 _1 = suggestions _1 . next ( ) ) {
var _f = _ _read ( suggestions _1 _1 . value , 2 ) , suggestion = _f [ 0 ] , _g = _f [ 1 ] , score = _g . score , terms = _g . terms , count = _g . count ;
results . push ( { suggestion , terms , score : score / count } ) ;
}
} catch ( e _15 _1 ) {
e _15 = { error : e _15 _1 } ;
} finally {
try {
if ( suggestions _1 _1 && ! suggestions _1 _1 . done && ( _b = suggestions _1 . return ) )
_b . call ( suggestions _1 ) ;
} finally {
if ( e _15 )
throw e _15 . error ;
}
}
results . sort ( byScore ) ;
return results ;
} ;
Object . defineProperty ( MiniSearch2 . prototype , "documentCount" , {
/ * *
* Total number of documents available to search
* /
get : function ( ) {
return this . _documentCount ;
} ,
enumerable : false ,
configurable : true
} ) ;
Object . defineProperty ( MiniSearch2 . prototype , "termCount" , {
/ * *
* Number of terms in the index
* /
get : function ( ) {
return this . _index . size ;
} ,
enumerable : false ,
configurable : true
} ) ;
MiniSearch2 . loadJSON = function ( json , options ) {
if ( options == null ) {
throw new Error ( "MiniSearch: loadJSON should be given the same options used when serializing the index" ) ;
}
return this . loadJS ( JSON . parse ( json ) , options ) ;
} ;
MiniSearch2 . getDefault = function ( optionName ) {
if ( defaultOptions . hasOwnProperty ( optionName ) ) {
return getOwnProperty ( defaultOptions , optionName ) ;
} else {
throw new Error ( 'MiniSearch: unknown option "' . concat ( optionName , '"' ) ) ;
}
} ;
MiniSearch2 . loadJS = function ( js , options ) {
var e _16 , _a2 , e _17 , _b , e _18 , _c ;
var index = js . index , documentCount = js . documentCount , nextId = js . nextId , documentIds = js . documentIds , fieldIds = js . fieldIds , fieldLength = js . fieldLength , averageFieldLength = js . averageFieldLength , storedFields = js . storedFields , dirtCount = js . dirtCount , serializationVersion = js . serializationVersion ;
if ( serializationVersion !== 1 && serializationVersion !== 2 ) {
throw new Error ( "MiniSearch: cannot deserialize an index created with an incompatible version" ) ;
}
var miniSearch = new MiniSearch2 ( options ) ;
miniSearch . _documentCount = documentCount ;
miniSearch . _nextId = nextId ;
miniSearch . _documentIds = objectToNumericMap ( documentIds ) ;
miniSearch . _idToShortId = /* @__PURE__ */ new Map ( ) ;
miniSearch . _fieldIds = fieldIds ;
miniSearch . _fieldLength = objectToNumericMap ( fieldLength ) ;
miniSearch . _avgFieldLength = averageFieldLength ;
miniSearch . _storedFields = objectToNumericMap ( storedFields ) ;
miniSearch . _dirtCount = dirtCount || 0 ;
miniSearch . _index = new SearchableMap ( ) ;
try {
for ( var _d = _ _values ( miniSearch . _documentIds ) , _e = _d . next ( ) ; ! _e . done ; _e = _d . next ( ) ) {
var _f = _ _read ( _e . value , 2 ) , shortId = _f [ 0 ] , id = _f [ 1 ] ;
miniSearch . _idToShortId . set ( id , shortId ) ;
}
} catch ( e _16 _1 ) {
e _16 = { error : e _16 _1 } ;
} finally {
try {
if ( _e && ! _e . done && ( _a2 = _d . return ) )
_a2 . call ( _d ) ;
} finally {
if ( e _16 )
throw e _16 . error ;
}
}
try {
for ( var index _1 = _ _values ( index ) , index _1 _1 = index _1 . next ( ) ; ! index _1 _1 . done ; index _1 _1 = index _1 . next ( ) ) {
var _g = _ _read ( index _1 _1 . value , 2 ) , term = _g [ 0 ] , data = _g [ 1 ] ;
var dataMap = /* @__PURE__ */ new Map ( ) ;
try {
for ( var _h = ( e _18 = void 0 , _ _values ( Object . keys ( data ) ) ) , _j = _h . next ( ) ; ! _j . done ; _j = _h . next ( ) ) {
var fieldId = _j . value ;
var indexEntry = data [ fieldId ] ;
if ( serializationVersion === 1 ) {
indexEntry = indexEntry . ds ;
}
dataMap . set ( parseInt ( fieldId , 10 ) , objectToNumericMap ( indexEntry ) ) ;
}
} catch ( e _18 _1 ) {
e _18 = { error : e _18 _1 } ;
} finally {
try {
if ( _j && ! _j . done && ( _c = _h . return ) )
_c . call ( _h ) ;
} finally {
if ( e _18 )
throw e _18 . error ;
}
}
miniSearch . _index . set ( term , dataMap ) ;
}
} catch ( e _17 _1 ) {
e _17 = { error : e _17 _1 } ;
} finally {
try {
if ( index _1 _1 && ! index _1 _1 . done && ( _b = index _1 . return ) )
_b . call ( index _1 ) ;
} finally {
if ( e _17 )
throw e _17 . error ;
}
}
return miniSearch ;
} ;
MiniSearch2 . prototype . executeQuery = function ( query , searchOptions ) {
var _this = this ;
if ( searchOptions === void 0 ) {
searchOptions = { } ;
}
if ( query === MiniSearch2 . wildcard ) {
return this . executeWildcardQuery ( searchOptions ) ;
}
if ( typeof query !== "string" ) {
var options _1 = _ _assign ( _ _assign ( _ _assign ( { } , searchOptions ) , query ) , { queries : void 0 } ) ;
var results _1 = query . queries . map ( function ( subquery ) {
return _this . executeQuery ( subquery , options _1 ) ;
} ) ;
return this . combineResults ( results _1 , options _1 . combineWith ) ;
}
var _a2 = this . _options , tokenize = _a2 . tokenize , processTerm = _a2 . processTerm , globalSearchOptions = _a2 . searchOptions ;
var options = _ _assign ( _ _assign ( { tokenize , processTerm } , globalSearchOptions ) , searchOptions ) ;
var searchTokenize = options . tokenize , searchProcessTerm = options . processTerm ;
var terms = searchTokenize ( query ) . flatMap ( function ( term ) {
return searchProcessTerm ( term ) ;
} ) . filter ( function ( term ) {
return ! ! term ;
} ) ;
var queries = terms . map ( termToQuerySpec ( options ) ) ;
var results = queries . map ( function ( query2 ) {
return _this . executeQuerySpec ( query2 , options ) ;
} ) ;
return this . combineResults ( results , options . combineWith ) ;
} ;
MiniSearch2 . prototype . executeQuerySpec = function ( query , searchOptions ) {
var e _19 , _a2 , e _20 , _b ;
var options = _ _assign ( _ _assign ( { } , this . _options . searchOptions ) , searchOptions ) ;
var boosts = ( options . fields || this . _options . fields ) . reduce ( function ( boosts2 , field ) {
var _a3 ;
return _ _assign ( _ _assign ( { } , boosts2 ) , ( _a3 = { } , _a3 [ field ] = getOwnProperty ( options . boost , field ) || 1 , _a3 ) ) ;
} , { } ) ;
var boostDocument = options . boostDocument , weights = options . weights , maxFuzzy = options . maxFuzzy , bm25params = options . bm25 ;
var _c = _ _assign ( _ _assign ( { } , defaultSearchOptions . weights ) , weights ) , fuzzyWeight = _c . fuzzy , prefixWeight = _c . prefix ;
var data = this . _index . get ( query . term ) ;
var results = this . termResults ( query . term , query . term , 1 , data , boosts , boostDocument , bm25params ) ;
var prefixMatches ;
var fuzzyMatches ;
if ( query . prefix ) {
prefixMatches = this . _index . atPrefix ( query . term ) ;
}
if ( query . fuzzy ) {
var fuzzy = query . fuzzy === true ? 0.2 : query . fuzzy ;
var maxDistance = fuzzy < 1 ? Math . min ( maxFuzzy , Math . round ( query . term . length * fuzzy ) ) : fuzzy ;
if ( maxDistance )
fuzzyMatches = this . _index . fuzzyGet ( query . term , maxDistance ) ;
}
if ( prefixMatches ) {
try {
for ( var prefixMatches _1 = _ _values ( prefixMatches ) , prefixMatches _1 _1 = prefixMatches _1 . next ( ) ; ! prefixMatches _1 _1 . done ; prefixMatches _1 _1 = prefixMatches _1 . next ( ) ) {
var _d = _ _read ( prefixMatches _1 _1 . value , 2 ) , term = _d [ 0 ] , data _1 = _d [ 1 ] ;
var distance = term . length - query . term . length ;
if ( ! distance ) {
continue ;
}
fuzzyMatches === null || fuzzyMatches === void 0 ? void 0 : fuzzyMatches . delete ( term ) ;
var weight = prefixWeight * term . length / ( term . length + 0.3 * distance ) ;
this . termResults ( query . term , term , weight , data _1 , boosts , boostDocument , bm25params , results ) ;
}
} catch ( e _19 _1 ) {
e _19 = { error : e _19 _1 } ;
} finally {
try {
if ( prefixMatches _1 _1 && ! prefixMatches _1 _1 . done && ( _a2 = prefixMatches _1 . return ) )
_a2 . call ( prefixMatches _1 ) ;
} finally {
if ( e _19 )
throw e _19 . error ;
}
}
}
if ( fuzzyMatches ) {
try {
for ( var _e = _ _values ( fuzzyMatches . keys ( ) ) , _f = _e . next ( ) ; ! _f . done ; _f = _e . next ( ) ) {
var term = _f . value ;
var _g = _ _read ( fuzzyMatches . get ( term ) , 2 ) , data _2 = _g [ 0 ] , distance = _g [ 1 ] ;
if ( ! distance ) {
continue ;
}
var weight = fuzzyWeight * term . length / ( term . length + distance ) ;
this . termResults ( query . term , term , weight , data _2 , boosts , boostDocument , bm25params , results ) ;
}
} catch ( e _20 _1 ) {
e _20 = { error : e _20 _1 } ;
} finally {
try {
if ( _f && ! _f . done && ( _b = _e . return ) )
_b . call ( _e ) ;
} finally {
if ( e _20 )
throw e _20 . error ;
}
}
}
return results ;
} ;
MiniSearch2 . prototype . executeWildcardQuery = function ( searchOptions ) {
var e _21 , _a2 ;
var results = /* @__PURE__ */ new Map ( ) ;
var options = _ _assign ( _ _assign ( { } , this . _options . searchOptions ) , searchOptions ) ;
try {
for ( var _b = _ _values ( this . _documentIds ) , _c = _b . next ( ) ; ! _c . done ; _c = _b . next ( ) ) {
var _d = _ _read ( _c . value , 2 ) , shortId = _d [ 0 ] , id = _d [ 1 ] ;
var score = options . boostDocument ? options . boostDocument ( id , "" , this . _storedFields . get ( shortId ) ) : 1 ;
results . set ( shortId , {
score ,
terms : [ ] ,
match : { }
} ) ;
}
} catch ( e _21 _1 ) {
e _21 = { error : e _21 _1 } ;
} finally {
try {
if ( _c && ! _c . done && ( _a2 = _b . return ) )
_a2 . call ( _b ) ;
} finally {
if ( e _21 )
throw e _21 . error ;
}
}
return results ;
} ;
MiniSearch2 . prototype . combineResults = function ( results , combineWith ) {
if ( combineWith === void 0 ) {
combineWith = OR ;
}
if ( results . length === 0 ) {
return /* @__PURE__ */ new Map ( ) ;
}
var operator = combineWith . toLowerCase ( ) ;
return results . reduce ( combinators [ operator ] ) || /* @__PURE__ */ new Map ( ) ;
} ;
MiniSearch2 . prototype . toJSON = function ( ) {
var e _22 , _a2 , e _23 , _b ;
var index = [ ] ;
try {
for ( var _c = _ _values ( this . _index ) , _d = _c . next ( ) ; ! _d . done ; _d = _c . next ( ) ) {
var _e = _ _read ( _d . value , 2 ) , term = _e [ 0 ] , fieldIndex = _e [ 1 ] ;
var data = { } ;
try {
for ( var fieldIndex _2 = ( e _23 = void 0 , _ _values ( fieldIndex ) ) , fieldIndex _2 _1 = fieldIndex _2 . next ( ) ; ! fieldIndex _2 _1 . done ; fieldIndex _2 _1 = fieldIndex _2 . next ( ) ) {
var _f = _ _read ( fieldIndex _2 _1 . value , 2 ) , fieldId = _f [ 0 ] , freqs = _f [ 1 ] ;
data [ fieldId ] = Object . fromEntries ( freqs ) ;
}
} catch ( e _23 _1 ) {
e _23 = { error : e _23 _1 } ;
} finally {
try {
if ( fieldIndex _2 _1 && ! fieldIndex _2 _1 . done && ( _b = fieldIndex _2 . return ) )
_b . call ( fieldIndex _2 ) ;
} finally {
if ( e _23 )
throw e _23 . error ;
}
}
index . push ( [ term , data ] ) ;
}
} catch ( e _22 _1 ) {
e _22 = { error : e _22 _1 } ;
} finally {
try {
if ( _d && ! _d . done && ( _a2 = _c . return ) )
_a2 . call ( _c ) ;
} finally {
if ( e _22 )
throw e _22 . error ;
}
}
return {
documentCount : this . _documentCount ,
nextId : this . _nextId ,
documentIds : Object . fromEntries ( this . _documentIds ) ,
fieldIds : this . _fieldIds ,
fieldLength : Object . fromEntries ( this . _fieldLength ) ,
averageFieldLength : this . _avgFieldLength ,
storedFields : Object . fromEntries ( this . _storedFields ) ,
dirtCount : this . _dirtCount ,
index ,
serializationVersion : 2
} ;
} ;
MiniSearch2 . prototype . termResults = function ( sourceTerm , derivedTerm , termWeight , fieldTermData , fieldBoosts , boostDocumentFn , bm25params , results ) {
var e _24 , _a2 , e _25 , _b , _c ;
if ( results === void 0 ) {
results = /* @__PURE__ */ new Map ( ) ;
}
if ( fieldTermData == null )
return results ;
try {
for ( var _d = _ _values ( Object . keys ( fieldBoosts ) ) , _e = _d . next ( ) ; ! _e . done ; _e = _d . next ( ) ) {
var field = _e . value ;
var fieldBoost = fieldBoosts [ field ] ;
var fieldId = this . _fieldIds [ field ] ;
var fieldTermFreqs = fieldTermData . get ( fieldId ) ;
if ( fieldTermFreqs == null )
continue ;
var matchingFields = fieldTermFreqs . size ;
var avgFieldLength = this . _avgFieldLength [ fieldId ] ;
try {
for ( var _f = ( e _25 = void 0 , _ _values ( fieldTermFreqs . keys ( ) ) ) , _g = _f . next ( ) ; ! _g . done ; _g = _f . next ( ) ) {
var docId = _g . value ;
if ( ! this . _documentIds . has ( docId ) ) {
this . removeTerm ( fieldId , docId , derivedTerm ) ;
matchingFields -= 1 ;
continue ;
}
var docBoost = boostDocumentFn ? boostDocumentFn ( this . _documentIds . get ( docId ) , derivedTerm , this . _storedFields . get ( docId ) ) : 1 ;
if ( ! docBoost )
continue ;
var termFreq = fieldTermFreqs . get ( docId ) ;
var fieldLength = this . _fieldLength . get ( docId ) [ fieldId ] ;
var rawScore = calcBM25Score ( termFreq , matchingFields , this . _documentCount , fieldLength , avgFieldLength , bm25params ) ;
var weightedScore = termWeight * fieldBoost * docBoost * rawScore ;
var result = results . get ( docId ) ;
if ( result ) {
result . score += weightedScore ;
assignUniqueTerm ( result . terms , sourceTerm ) ;
var match = getOwnProperty ( result . match , derivedTerm ) ;
if ( match ) {
match . push ( field ) ;
} else {
result . match [ derivedTerm ] = [ field ] ;
}
} else {
results . set ( docId , {
score : weightedScore ,
terms : [ sourceTerm ] ,
match : ( _c = { } , _c [ derivedTerm ] = [ field ] , _c )
} ) ;
}
}
} catch ( e _25 _1 ) {
e _25 = { error : e _25 _1 } ;
} finally {
try {
if ( _g && ! _g . done && ( _b = _f . return ) )
_b . call ( _f ) ;
} finally {
if ( e _25 )
throw e _25 . error ;
}
}
}
} catch ( e _24 _1 ) {
e _24 = { error : e _24 _1 } ;
} finally {
try {
if ( _e && ! _e . done && ( _a2 = _d . return ) )
_a2 . call ( _d ) ;
} finally {
if ( e _24 )
throw e _24 . error ;
}
}
return results ;
} ;
MiniSearch2 . prototype . addTerm = function ( fieldId , documentId , term ) {
var indexData = this . _index . fetch ( term , createMap ) ;
var fieldIndex = indexData . get ( fieldId ) ;
if ( fieldIndex == null ) {
fieldIndex = /* @__PURE__ */ new Map ( ) ;
fieldIndex . set ( documentId , 1 ) ;
indexData . set ( fieldId , fieldIndex ) ;
} else {
var docs = fieldIndex . get ( documentId ) ;
fieldIndex . set ( documentId , ( docs || 0 ) + 1 ) ;
}
} ;
MiniSearch2 . prototype . removeTerm = function ( fieldId , documentId , term ) {
if ( ! this . _index . has ( term ) ) {
this . warnDocumentChanged ( documentId , fieldId , term ) ;
return ;
}
var indexData = this . _index . fetch ( term , createMap ) ;
var fieldIndex = indexData . get ( fieldId ) ;
if ( fieldIndex == null || fieldIndex . get ( documentId ) == null ) {
this . warnDocumentChanged ( documentId , fieldId , term ) ;
} else if ( fieldIndex . get ( documentId ) <= 1 ) {
if ( fieldIndex . size <= 1 ) {
indexData . delete ( fieldId ) ;
} else {
fieldIndex . delete ( documentId ) ;
}
} else {
fieldIndex . set ( documentId , fieldIndex . get ( documentId ) - 1 ) ;
}
if ( this . _index . get ( term ) . size === 0 ) {
this . _index . delete ( term ) ;
}
} ;
MiniSearch2 . prototype . warnDocumentChanged = function ( shortDocumentId , fieldId , term ) {
var e _26 , _a2 ;
try {
for ( var _b = _ _values ( Object . keys ( this . _fieldIds ) ) , _c = _b . next ( ) ; ! _c . done ; _c = _b . next ( ) ) {
var fieldName = _c . value ;
if ( this . _fieldIds [ fieldName ] === fieldId ) {
this . _options . logger ( "warn" , "MiniSearch: document with ID " . concat ( this . _documentIds . get ( shortDocumentId ) , ' has changed before removal: term "' ) . concat ( term , '" was not present in field "' ) . concat ( fieldName , '". Removing a document after it has changed can corrupt the index!' ) , "version_conflict" ) ;
return ;
}
}
} catch ( e _26 _1 ) {
e _26 = { error : e _26 _1 } ;
} finally {
try {
if ( _c && ! _c . done && ( _a2 = _b . return ) )
_a2 . call ( _b ) ;
} finally {
if ( e _26 )
throw e _26 . error ;
}
}
} ;
MiniSearch2 . prototype . addDocumentId = function ( documentId ) {
var shortDocumentId = this . _nextId ;
this . _idToShortId . set ( documentId , shortDocumentId ) ;
this . _documentIds . set ( shortDocumentId , documentId ) ;
this . _documentCount += 1 ;
this . _nextId += 1 ;
return shortDocumentId ;
} ;
MiniSearch2 . prototype . addFields = function ( fields ) {
for ( var i = 0 ; i < fields . length ; i ++ ) {
this . _fieldIds [ fields [ i ] ] = i ;
}
} ;
MiniSearch2 . prototype . addFieldLength = function ( documentId , fieldId , count , length ) {
var fieldLengths = this . _fieldLength . get ( documentId ) ;
if ( fieldLengths == null )
this . _fieldLength . set ( documentId , fieldLengths = [ ] ) ;
fieldLengths [ fieldId ] = length ;
var averageFieldLength = this . _avgFieldLength [ fieldId ] || 0 ;
var totalFieldLength = averageFieldLength * count + length ;
this . _avgFieldLength [ fieldId ] = totalFieldLength / ( count + 1 ) ;
} ;
MiniSearch2 . prototype . removeFieldLength = function ( documentId , fieldId , count , length ) {
if ( count === 1 ) {
this . _avgFieldLength [ fieldId ] = 0 ;
return ;
}
var totalFieldLength = this . _avgFieldLength [ fieldId ] * count - length ;
this . _avgFieldLength [ fieldId ] = totalFieldLength / ( count - 1 ) ;
} ;
MiniSearch2 . prototype . saveStoredFields = function ( documentId , doc ) {
var e _27 , _a2 ;
var _b = this . _options , storeFields = _b . storeFields , extractField = _b . extractField ;
if ( storeFields == null || storeFields . length === 0 ) {
return ;
}
var documentFields = this . _storedFields . get ( documentId ) ;
if ( documentFields == null )
this . _storedFields . set ( documentId , documentFields = { } ) ;
try {
for ( var storeFields _1 = _ _values ( storeFields ) , storeFields _1 _1 = storeFields _1 . next ( ) ; ! storeFields _1 _1 . done ; storeFields _1 _1 = storeFields _1 . next ( ) ) {
var fieldName = storeFields _1 _1 . value ;
var fieldValue = extractField ( doc , fieldName ) ;
if ( fieldValue !== void 0 )
documentFields [ fieldName ] = fieldValue ;
}
} catch ( e _27 _1 ) {
e _27 = { error : e _27 _1 } ;
} finally {
try {
if ( storeFields _1 _1 && ! storeFields _1 _1 . done && ( _a2 = storeFields _1 . return ) )
_a2 . call ( storeFields _1 ) ;
} finally {
if ( e _27 )
throw e _27 . error ;
}
}
} ;
MiniSearch2 . wildcard = Symbol ( "*" ) ;
return MiniSearch2 ;
} ( )
) ;
var getOwnProperty = function ( object , property ) {
return Object . prototype . hasOwnProperty . call ( object , property ) ? object [ property ] : void 0 ;
} ;
var combinators = ( _a = { } , _a [ OR ] = function ( a , b ) {
var e _28 , _a2 ;
try {
for ( var _b = _ _values ( b . keys ( ) ) , _c = _b . next ( ) ; ! _c . done ; _c = _b . next ( ) ) {
var docId = _c . value ;
var existing = a . get ( docId ) ;
if ( existing == null ) {
a . set ( docId , b . get ( docId ) ) ;
} else {
var _d = b . get ( docId ) , score = _d . score , terms = _d . terms , match = _d . match ;
existing . score = existing . score + score ;
existing . match = Object . assign ( existing . match , match ) ;
assignUniqueTerms ( existing . terms , terms ) ;
}
}
} catch ( e _28 _1 ) {
e _28 = { error : e _28 _1 } ;
} finally {
try {
if ( _c && ! _c . done && ( _a2 = _b . return ) )
_a2 . call ( _b ) ;
} finally {
if ( e _28 )
throw e _28 . error ;
}
}
return a ;
} , _a [ AND ] = function ( a , b ) {
var e _29 , _a2 ;
var combined = /* @__PURE__ */ new Map ( ) ;
try {
for ( var _b = _ _values ( b . keys ( ) ) , _c = _b . next ( ) ; ! _c . done ; _c = _b . next ( ) ) {
var docId = _c . value ;
var existing = a . get ( docId ) ;
if ( existing == null )
continue ;
var _d = b . get ( docId ) , score = _d . score , terms = _d . terms , match = _d . match ;
assignUniqueTerms ( existing . terms , terms ) ;
combined . set ( docId , {
score : existing . score + score ,
terms : existing . terms ,
match : Object . assign ( existing . match , match )
} ) ;
}
} catch ( e _29 _1 ) {
e _29 = { error : e _29 _1 } ;
} finally {
try {
if ( _c && ! _c . done && ( _a2 = _b . return ) )
_a2 . call ( _b ) ;
} finally {
if ( e _29 )
throw e _29 . error ;
}
}
return combined ;
} , _a [ AND _NOT ] = function ( a , b ) {
var e _30 , _a2 ;
try {
for ( var _b = _ _values ( b . keys ( ) ) , _c = _b . next ( ) ; ! _c . done ; _c = _b . next ( ) ) {
var docId = _c . value ;
a . delete ( docId ) ;
}
} catch ( e _30 _1 ) {
e _30 = { error : e _30 _1 } ;
} finally {
try {
if ( _c && ! _c . done && ( _a2 = _b . return ) )
_a2 . call ( _b ) ;
} finally {
if ( e _30 )
throw e _30 . error ;
}
}
return a ;
} , _a ) ;
var defaultBM25params = { k : 1.2 , b : 0.7 , d : 0.5 } ;
var calcBM25Score = function ( termFreq , matchingCount , totalCount , fieldLength , avgFieldLength , bm25params ) {
var k = bm25params . k , b = bm25params . b , d = bm25params . d ;
var invDocFreq = Math . log ( 1 + ( totalCount - matchingCount + 0.5 ) / ( matchingCount + 0.5 ) ) ;
return invDocFreq * ( d + termFreq * ( k + 1 ) / ( termFreq + k * ( 1 - b + b * fieldLength / avgFieldLength ) ) ) ;
} ;
var termToQuerySpec = function ( options ) {
return function ( term , i , terms ) {
var fuzzy = typeof options . fuzzy === "function" ? options . fuzzy ( term , i , terms ) : options . fuzzy || false ;
var prefix = typeof options . prefix === "function" ? options . prefix ( term , i , terms ) : options . prefix === true ;
return { term , fuzzy , prefix } ;
} ;
} ;
var defaultOptions = {
idField : "id" ,
extractField : function ( document2 , fieldName ) {
return document2 [ fieldName ] ;
} ,
tokenize : function ( text ) {
return text . split ( SPACE _OR _PUNCTUATION ) ;
} ,
processTerm : function ( term ) {
return term . toLowerCase ( ) ;
} ,
fields : void 0 ,
searchOptions : void 0 ,
storeFields : [ ] ,
logger : function ( level , message ) {
if ( typeof ( console === null || console === void 0 ? void 0 : console [ level ] ) === "function" )
console [ level ] ( message ) ;
} ,
autoVacuum : true
} ;
var defaultSearchOptions = {
combineWith : OR ,
prefix : false ,
fuzzy : false ,
maxFuzzy : 6 ,
boost : { } ,
weights : { fuzzy : 0.45 , prefix : 0.375 } ,
bm25 : defaultBM25params
} ;
var defaultAutoSuggestOptions = {
combineWith : AND ,
prefix : function ( term , i , terms ) {
return i === terms . length - 1 ;
}
} ;
var defaultVacuumOptions = { batchSize : 1e3 , batchWait : 10 } ;
var defaultVacuumConditions = { minDirtFactor : 0.1 , minDirtCount : 20 } ;
var defaultAutoVacuumOptions = _ _assign ( _ _assign ( { } , defaultVacuumOptions ) , defaultVacuumConditions ) ;
var assignUniqueTerm = function ( target , term ) {
if ( ! target . includes ( term ) )
target . push ( term ) ;
} ;
var assignUniqueTerms = function ( target , source ) {
var e _31 , _a2 ;
try {
for ( var source _1 = _ _values ( source ) , source _1 _1 = source _1 . next ( ) ; ! source _1 _1 . done ; source _1 _1 = source _1 . next ( ) ) {
var term = source _1 _1 . value ;
if ( ! target . includes ( term ) )
target . push ( term ) ;
}
} catch ( e _31 _1 ) {
e _31 = { error : e _31 _1 } ;
} finally {
try {
if ( source _1 _1 && ! source _1 _1 . done && ( _a2 = source _1 . return ) )
_a2 . call ( source _1 ) ;
} finally {
if ( e _31 )
throw e _31 . error ;
}
}
} ;
var byScore = function ( _a2 , _b ) {
var a = _a2 . score ;
var b = _b . score ;
return b - a ;
} ;
var createMap = function ( ) {
return /* @__PURE__ */ new Map ( ) ;
} ;
var objectToNumericMap = function ( object ) {
var e _32 , _a2 ;
var map = /* @__PURE__ */ new Map ( ) ;
try {
for ( var _b = _ _values ( Object . keys ( object ) ) , _c = _b . next ( ) ; ! _c . done ; _c = _b . next ( ) ) {
var key = _c . value ;
map . set ( parseInt ( key , 10 ) , object [ key ] ) ;
}
} catch ( e _32 _1 ) {
e _32 = { error : e _32 _1 } ;
} finally {
try {
if ( _c && ! _c . done && ( _a2 = _b . return ) )
_a2 . call ( _b ) ;
} finally {
if ( e _32 )
throw e _32 . error ;
}
}
return map ;
} ;
var SPACE _OR _PUNCTUATION = /[\n\r -#%-*,-/:;?@[-\]_{}\u00A0\u00A1\u00A7\u00AB\u00B6\u00B7\u00BB\u00BF\u037E\u0387\u055A-\u055F\u0589\u058A\u05BE\u05C0\u05C3\u05C6\u05F3\u05F4\u0609\u060A\u060C\u060D\u061B\u061E\u061F\u066A-\u066D\u06D4\u0700-\u070D\u07F7-\u07F9\u0830-\u083E\u085E\u0964\u0965\u0970\u09FD\u0A76\u0AF0\u0C77\u0C84\u0DF4\u0E4F\u0E5A\u0E5B\u0F04-\u0F12\u0F14\u0F3A-\u0F3D\u0F85\u0FD0-\u0FD4\u0FD9\u0FDA\u104A-\u104F\u10FB\u1360-\u1368\u1400\u166E\u1680\u169B\u169C\u16EB-\u16ED\u1735\u1736\u17D4-\u17D6\u17D8-\u17DA\u1800-\u180A\u1944\u1945\u1A1E\u1A1F\u1AA0-\u1AA6\u1AA8-\u1AAD\u1B5A-\u1B60\u1BFC-\u1BFF\u1C3B-\u1C3F\u1C7E\u1C7F\u1CC0-\u1CC7\u1CD3\u2000-\u200A\u2010-\u2029\u202F-\u2043\u2045-\u2051\u2053-\u205F\u207D\u207E\u208D\u208E\u2308-\u230B\u2329\u232A\u2768-\u2775\u27C5\u27C6\u27E6-\u27EF\u2983-\u2998\u29D8-\u29DB\u29FC\u29FD\u2CF9-\u2CFC\u2CFE\u2CFF\u2D70\u2E00-\u2E2E\u2E30-\u2E4F\u3000-\u3003\u3008-\u3011\u3014-\u301F\u3030\u303D\u30A0\u30FB\uA4FE\uA4FF\uA60D-\uA60F\uA673\uA67E\uA6F2-\uA6F7\uA874-\uA877\uA8CE\uA8CF\uA8F8-\uA8FA\uA8FC\uA92E\uA92F\uA95F\uA9C1-\uA9CD\uA9DE\uA9DF\uAA5C-\uAA5F\uAADE\uAADF\uAAF0\uAAF1\uABEB\uFD3E\uFD3F\uFE10-\uFE19\uFE30-\uFE52\uFE54-\uFE61\uFE63\uFE68\uFE6A\uFE6B\uFF01-\uFF03\uFF05-\uFF0A\uFF0C-\uFF0F\uFF1A\uFF1B\uFF1F\uFF20\uFF3B-\uFF3D\uFF3F\uFF5B\uFF5D\uFF5F-\uFF65]+/u ;
class LRUCache {
constructor ( max = 10 ) {
_ _publicField ( this , "max" ) ;
_ _publicField ( this , "cache" ) ;
this . max = max ;
this . cache = /* @__PURE__ */ new Map ( ) ;
}
get ( key ) {
let item = this . cache . get ( key ) ;
if ( item !== void 0 ) {
this . cache . delete ( key ) ;
this . cache . set ( key , item ) ;
}
return item ;
}
set ( key , val ) {
if ( this . cache . has ( key ) )
this . cache . delete ( key ) ;
else if ( this . cache . size === this . max )
this . cache . delete ( this . first ( ) ) ;
this . cache . set ( key , val ) ;
}
first ( ) {
return this . cache . keys ( ) . next ( ) . value ;
}
clear ( ) {
this . cache . clear ( ) ;
}
}
const _withScopeId = ( n ) => ( pushScopeId ( "data-v-43c4f204" ) , n = n ( ) , popScopeId ( ) , n ) ;
const _hoisted _1 = [ "aria-owns" ] ;
const _hoisted _2 = { class : "shell" } ;
const _hoisted _3 = [ "title" ] ;
const _hoisted _4 = /* @__PURE__ */ _withScopeId ( ( ) => /* @__PURE__ */ createBaseVNode ( "span" , {
"aria-hidden" : "true" ,
class : "vpi-search search-icon local-search-icon"
} , null , - 1 ) ) ;
const _hoisted _5 = [
_hoisted _4
] ;
const _hoisted _6 = { class : "search-actions before" } ;
const _hoisted _7 = [ "title" ] ;
const _hoisted _8 = /* @__PURE__ */ _withScopeId ( ( ) => /* @__PURE__ */ createBaseVNode ( "span" , { class : "vpi-arrow-left local-search-icon" } , null , - 1 ) ) ;
const _hoisted _9 = [
_hoisted _8
] ;
const _hoisted _10 = [ "placeholder" ] ;
const _hoisted _11 = { class : "search-actions" } ;
const _hoisted _12 = [ "title" ] ;
const _hoisted _13 = /* @__PURE__ */ _withScopeId ( ( ) => /* @__PURE__ */ createBaseVNode ( "span" , { class : "vpi-layout-list local-search-icon" } , null , - 1 ) ) ;
const _hoisted _14 = [
_hoisted _13
] ;
const _hoisted _15 = [ "disabled" , "title" ] ;
const _hoisted _16 = /* @__PURE__ */ _withScopeId ( ( ) => /* @__PURE__ */ createBaseVNode ( "span" , { class : "vpi-delete local-search-icon" } , null , - 1 ) ) ;
const _hoisted _17 = [
_hoisted _16
] ;
const _hoisted _18 = [ "id" , "role" , "aria-labelledby" ] ;
const _hoisted _19 = [ "aria-selected" ] ;
const _hoisted _20 = [ "href" , "aria-label" , "onMouseenter" , "onFocusin" ] ;
const _hoisted _21 = { class : "titles" } ;
const _hoisted _22 = /* @__PURE__ */ _withScopeId ( ( ) => /* @__PURE__ */ createBaseVNode ( "span" , { class : "title-icon" } , "#" , - 1 ) ) ;
const _hoisted _23 = [ "innerHTML" ] ;
const _hoisted _24 = /* @__PURE__ */ _withScopeId ( ( ) => /* @__PURE__ */ createBaseVNode ( "span" , { class : "vpi-chevron-right local-search-icon" } , null , - 1 ) ) ;
const _hoisted _25 = { class : "title main" } ;
const _hoisted _26 = [ "innerHTML" ] ;
const _hoisted _27 = {
key : 0 ,
class : "excerpt-wrapper"
} ;
const _hoisted _28 = {
key : 0 ,
class : "excerpt" ,
inert : ""
} ;
const _hoisted _29 = [ "innerHTML" ] ;
const _hoisted _30 = /* @__PURE__ */ _withScopeId ( ( ) => /* @__PURE__ */ createBaseVNode ( "div" , { class : "excerpt-gradient-bottom" } , null , - 1 ) ) ;
const _hoisted _31 = /* @__PURE__ */ _withScopeId ( ( ) => /* @__PURE__ */ createBaseVNode ( "div" , { class : "excerpt-gradient-top" } , null , - 1 ) ) ;
const _hoisted _32 = {
key : 0 ,
class : "no-results"
} ;
const _hoisted _33 = { class : "search-keyboard-shortcuts" } ;
const _hoisted _34 = [ "aria-label" ] ;
const _hoisted _35 = /* @__PURE__ */ _withScopeId ( ( ) => /* @__PURE__ */ createBaseVNode ( "span" , { class : "vpi-arrow-up navigate-icon" } , null , - 1 ) ) ;
const _hoisted _36 = [
_hoisted _35
] ;
const _hoisted _37 = [ "aria-label" ] ;
const _hoisted _38 = /* @__PURE__ */ _withScopeId ( ( ) => /* @__PURE__ */ createBaseVNode ( "span" , { class : "vpi-arrow-down navigate-icon" } , null , - 1 ) ) ;
const _hoisted _39 = [
_hoisted _38
] ;
const _hoisted _40 = [ "aria-label" ] ;
const _hoisted _41 = /* @__PURE__ */ _withScopeId ( ( ) => /* @__PURE__ */ createBaseVNode ( "span" , { class : "vpi-corner-down-left navigate-icon" } , null , - 1 ) ) ;
const _hoisted _42 = [
_hoisted _41
] ;
const _hoisted _43 = [ "aria-label" ] ;
const _sfc _main = /* @__PURE__ */ defineComponent ( {
_ _name : "VPLocalSearchBox" ,
emits : [ "close" ] ,
setup ( _ _props , { emit : _ _emit } ) {
var _a2 , _b ;
const emit = _ _emit ;
const el = shallowRef ( ) ;
const resultsEl = shallowRef ( ) ;
const searchIndexData = shallowRef ( localSearchIndex ) ;
const vitePressData = useData ( ) ;
const { activate } = useFocusTrap ( el , {
immediate : true ,
allowOutsideClick : true ,
clickOutsideDeactivates : true ,
escapeDeactivates : true
} ) ;
const { localeIndex , theme } = vitePressData ;
const searchIndex = computedAsync (
async ( ) => {
var _a3 , _b2 , _c , _d , _e , _f , _g , _h , _i ;
return markRaw (
MiniSearch . loadJSON (
( _c = await ( ( _b2 = ( _a3 = searchIndexData . value ) [ localeIndex . value ] ) == null ? void 0 : _b2 . call ( _a3 ) ) ) == null ? void 0 : _c . default ,
{
fields : [ "title" , "titles" , "text" ] ,
storeFields : [ "title" , "titles" ] ,
searchOptions : {
fuzzy : 0.2 ,
prefix : true ,
boost : { title : 4 , text : 2 , titles : 1 } ,
... ( ( _d = theme . value . search ) == null ? void 0 : _d . provider ) === "local" && ( ( _f = ( _e = theme . value . search . options ) == null ? void 0 : _e . miniSearch ) == null ? void 0 : _f . searchOptions )
} ,
... ( ( _g = theme . value . search ) == null ? void 0 : _g . provider ) === "local" && ( ( _i = ( _h = theme . value . search . options ) == null ? void 0 : _h . miniSearch ) == null ? void 0 : _i . options )
}
)
) ;
}
) ;
const disableQueryPersistence = computed ( ( ) => {
var _a3 , _b2 ;
return ( ( _a3 = theme . value . search ) == null ? void 0 : _a3 . provider ) === "local" && ( ( _b2 = theme . value . search . options ) == null ? void 0 : _b2 . disableQueryPersistence ) === true ;
} ) ;
const filterText = disableQueryPersistence . value ? ref ( "" ) : useSessionStorage ( "vitepress:local-search-filter" , "" ) ;
const showDetailedList = useLocalStorage (
"vitepress:local-search-detailed-list" ,
( ( _a2 = theme . value . search ) == null ? void 0 : _a2 . provider ) === "local" && ( ( _b = theme . value . search . options ) == null ? void 0 : _b . detailedView ) === true
) ;
const disableDetailedView = computed ( ( ) => {
var _a3 , _b2 , _c ;
return ( ( _a3 = theme . value . search ) == null ? void 0 : _a3 . provider ) === "local" && ( ( ( _b2 = theme . value . search . options ) == null ? void 0 : _b2 . disableDetailedView ) === true || ( ( _c = theme . value . search . options ) == null ? void 0 : _c . detailedView ) === false ) ;
} ) ;
const buttonText = computed ( ( ) => {
var _a3 , _b2 , _c , _d , _e , _f , _g ;
const options = ( ( _a3 = theme . value . search ) == null ? void 0 : _a3 . options ) ? ? theme . value . algolia ;
return ( ( _e = ( _d = ( _c = ( _b2 = options == null ? void 0 : options . locales ) == null ? void 0 : _b2 [ localeIndex . value ] ) == null ? void 0 : _c . translations ) == null ? void 0 : _d . button ) == null ? void 0 : _e . buttonText ) || ( ( _g = ( _f = options == null ? void 0 : options . translations ) == null ? void 0 : _f . button ) == null ? void 0 : _g . buttonText ) || "Search" ;
} ) ;
watchEffect ( ( ) => {
if ( disableDetailedView . value ) {
showDetailedList . value = false ;
}
} ) ;
const results = shallowRef ( [ ] ) ;
const enableNoResults = ref ( false ) ;
watch ( filterText , ( ) => {
enableNoResults . value = false ;
} ) ;
const mark = computedAsync ( async ( ) => {
if ( ! resultsEl . value )
return ;
return markRaw ( new Mark2 ( resultsEl . value ) ) ;
} , null ) ;
const cache = new LRUCache ( 16 ) ;
watchDebounced (
( ) => [ searchIndex . value , filterText . value , showDetailedList . value ] ,
async ( [ index , filterTextValue , showDetailedListValue ] , old , onCleanup ) => {
var _a3 , _b2 , _c , _d ;
if ( ( old == null ? void 0 : old [ 0 ] ) !== index ) {
cache . clear ( ) ;
}
let canceled = false ;
onCleanup ( ( ) => {
canceled = true ;
} ) ;
if ( ! index )
return ;
results . value = index . search ( filterTextValue ) . slice ( 0 , 16 ) ;
enableNoResults . value = true ;
const mods = showDetailedListValue ? await Promise . all ( results . value . map ( ( r ) => fetchExcerpt ( r . id ) ) ) : [ ] ;
if ( canceled )
return ;
for ( const { id , mod } of mods ) {
const mapId = id . slice ( 0 , id . indexOf ( "#" ) ) ;
let map = cache . get ( mapId ) ;
if ( map )
continue ;
map = /* @__PURE__ */ new Map ( ) ;
cache . set ( mapId , map ) ;
const comp = mod . default ? ? mod ;
if ( ( comp == null ? void 0 : comp . render ) || ( comp == null ? void 0 : comp . setup ) ) {
const app = createApp ( comp ) ;
app . config . warnHandler = ( ) => {
} ;
app . provide ( dataSymbol , vitePressData ) ;
Object . defineProperties ( app . config . globalProperties , {
$frontmatter : {
get ( ) {
return vitePressData . frontmatter . value ;
}
} ,
$params : {
get ( ) {
return vitePressData . page . value . params ;
}
}
} ) ;
const div = document . createElement ( "div" ) ;
app . mount ( div ) ;
const headings = div . querySelectorAll ( "h1, h2, h3, h4, h5, h6" ) ;
headings . forEach ( ( el2 ) => {
var _a4 ;
const href = ( _a4 = el2 . querySelector ( "a" ) ) == null ? void 0 : _a4 . getAttribute ( "href" ) ;
const anchor = ( href == null ? void 0 : href . startsWith ( "#" ) ) && href . slice ( 1 ) ;
if ( ! anchor )
return ;
let html = "" ;
while ( ( el2 = el2 . nextElementSibling ) && ! /^h[1-6]$/i . test ( el2 . tagName ) )
html += el2 . outerHTML ;
map . set ( anchor , html ) ;
} ) ;
app . unmount ( ) ;
}
if ( canceled )
return ;
}
const terms = /* @__PURE__ */ new Set ( ) ;
results . value = results . value . map ( ( r ) => {
const [ id , anchor ] = r . id . split ( "#" ) ;
const map = cache . get ( id ) ;
const text = ( map == null ? void 0 : map . get ( anchor ) ) ? ? "" ;
for ( const term in r . match ) {
terms . add ( term ) ;
}
return { ... r , text } ;
} ) ;
await nextTick ( ) ;
if ( canceled )
return ;
await new Promise ( ( r ) => {
var _a4 ;
( _a4 = mark . value ) == null ? void 0 : _a4 . unmark ( {
done : ( ) => {
var _a5 ;
( _a5 = mark . value ) == null ? void 0 : _a5 . markRegExp ( formMarkRegex ( terms ) , { done : r } ) ;
}
} ) ;
} ) ;
const excerpts = ( ( _a3 = el . value ) == null ? void 0 : _a3 . querySelectorAll ( ".result .excerpt" ) ) ? ? [ ] ;
for ( const excerpt of excerpts ) {
( _b2 = excerpt . querySelector ( 'mark[data-markjs="true"]' ) ) == null ? void 0 : _b2 . scrollIntoView ( { block : "center" } ) ;
}
( _d = ( _c = resultsEl . value ) == null ? void 0 : _c . firstElementChild ) == null ? void 0 : _d . scrollIntoView ( { block : "start" } ) ;
} ,
{ debounce : 200 , immediate : true }
) ;
async function fetchExcerpt ( id ) {
const file = pathToFile ( id . slice ( 0 , id . indexOf ( "#" ) ) ) ;
try {
if ( ! file )
throw new Error ( ` Cannot find file for id: ${ id } ` ) ;
2024-09-18 08:58:07 +00:00
return { id , mod : await import (
2024-05-30 02:02:10 +00:00
/*@vite-ignore*/
file
2024-09-18 08:58:07 +00:00
) } ;
2024-05-30 02:02:10 +00:00
} catch ( e ) {
console . error ( e ) ;
return { id , mod : { } } ;
}
}
const searchInput = ref ( ) ;
const disableReset = computed ( ( ) => {
var _a3 ;
return ( ( _a3 = filterText . value ) == null ? void 0 : _a3 . length ) <= 0 ;
} ) ;
function focusSearchInput ( select = true ) {
var _a3 , _b2 ;
( _a3 = searchInput . value ) == null ? void 0 : _a3 . focus ( ) ;
select && ( ( _b2 = searchInput . value ) == null ? void 0 : _b2 . select ( ) ) ;
}
onMounted ( ( ) => {
focusSearchInput ( ) ;
} ) ;
function onSearchBarClick ( event ) {
if ( event . pointerType === "mouse" ) {
focusSearchInput ( ) ;
}
}
const selectedIndex = ref ( - 1 ) ;
const disableMouseOver = ref ( false ) ;
watch ( results , ( r ) => {
selectedIndex . value = r . length ? 0 : - 1 ;
scrollToSelectedResult ( ) ;
} ) ;
function scrollToSelectedResult ( ) {
nextTick ( ( ) => {
const selectedEl = document . querySelector ( ".result.selected" ) ;
if ( selectedEl ) {
selectedEl . scrollIntoView ( {
block : "nearest"
} ) ;
}
} ) ;
}
onKeyStroke ( "ArrowUp" , ( event ) => {
event . preventDefault ( ) ;
selectedIndex . value -- ;
if ( selectedIndex . value < 0 ) {
selectedIndex . value = results . value . length - 1 ;
}
disableMouseOver . value = true ;
scrollToSelectedResult ( ) ;
} ) ;
onKeyStroke ( "ArrowDown" , ( event ) => {
event . preventDefault ( ) ;
selectedIndex . value ++ ;
if ( selectedIndex . value >= results . value . length ) {
selectedIndex . value = 0 ;
}
disableMouseOver . value = true ;
scrollToSelectedResult ( ) ;
} ) ;
const router = useRouter ( ) ;
onKeyStroke ( "Enter" , ( e ) => {
if ( e . isComposing )
return ;
if ( e . target instanceof HTMLButtonElement && e . target . type !== "submit" )
return ;
const selectedPackage = results . value [ selectedIndex . value ] ;
if ( e . target instanceof HTMLInputElement && ! selectedPackage ) {
e . preventDefault ( ) ;
return ;
}
if ( selectedPackage ) {
router . go ( selectedPackage . id ) ;
emit ( "close" ) ;
}
} ) ;
onKeyStroke ( "Escape" , ( ) => {
emit ( "close" ) ;
} ) ;
const defaultTranslations = {
modal : {
displayDetails : "Display detailed list" ,
resetButtonTitle : "Reset search" ,
backButtonTitle : "Close search" ,
noResultsText : "No results for" ,
footer : {
selectText : "to select" ,
selectKeyAriaLabel : "enter" ,
navigateText : "to navigate" ,
navigateUpKeyAriaLabel : "up arrow" ,
navigateDownKeyAriaLabel : "down arrow" ,
closeText : "to close" ,
closeKeyAriaLabel : "escape"
}
}
} ;
const translate = createSearchTranslate ( defaultTranslations ) ;
onMounted ( ( ) => {
window . history . pushState ( null , "" , null ) ;
} ) ;
useEventListener ( "popstate" , ( event ) => {
event . preventDefault ( ) ;
emit ( "close" ) ;
} ) ;
const isLocked = useScrollLock ( inBrowser ? document . body : null ) ;
onMounted ( ( ) => {
nextTick ( ( ) => {
isLocked . value = true ;
nextTick ( ) . then ( ( ) => activate ( ) ) ;
} ) ;
} ) ;
onBeforeUnmount ( ( ) => {
isLocked . value = false ;
} ) ;
function resetSearch ( ) {
filterText . value = "" ;
nextTick ( ) . then ( ( ) => focusSearchInput ( false ) ) ;
}
function formMarkRegex ( terms ) {
return new RegExp (
[ ... terms ] . sort ( ( a , b ) => b . length - a . length ) . map ( ( term ) => ` ( ${ escapeRegExp ( term ) } ) ` ) . join ( "|" ) ,
"gi"
) ;
}
return ( _ctx , _cache ) => {
var _a3 , _b2 , _c , _d ;
return openBlock ( ) , createBlock ( Teleport , { to : "body" } , [
createBaseVNode ( "div" , {
ref _key : "el" ,
ref : el ,
role : "button" ,
"aria-owns" : ( ( _a3 = results . value ) == null ? void 0 : _a3 . length ) ? "localsearch-list" : void 0 ,
"aria-expanded" : "true" ,
"aria-haspopup" : "listbox" ,
"aria-labelledby" : "localsearch-label" ,
class : "VPLocalSearchBox"
} , [
createBaseVNode ( "div" , {
class : "backdrop" ,
onClick : _cache [ 0 ] || ( _cache [ 0 ] = ( $event ) => _ctx . $emit ( "close" ) )
} ) ,
createBaseVNode ( "div" , _hoisted _2 , [
createBaseVNode ( "form" , {
class : "search-bar" ,
onPointerup : _cache [ 4 ] || ( _cache [ 4 ] = ( $event ) => onSearchBarClick ( $event ) ) ,
onSubmit : _cache [ 5 ] || ( _cache [ 5 ] = withModifiers ( ( ) => {
} , [ "prevent" ] ) )
} , [
createBaseVNode ( "label" , {
title : buttonText . value ,
id : "localsearch-label" ,
for : "localsearch-input"
} , _hoisted _5 , 8 , _hoisted _3 ) ,
createBaseVNode ( "div" , _hoisted _6 , [
createBaseVNode ( "button" , {
class : "back-button" ,
title : unref ( translate ) ( "modal.backButtonTitle" ) ,
onClick : _cache [ 1 ] || ( _cache [ 1 ] = ( $event ) => _ctx . $emit ( "close" ) )
} , _hoisted _9 , 8 , _hoisted _7 )
] ) ,
withDirectives ( createBaseVNode ( "input" , {
ref _key : "searchInput" ,
ref : searchInput ,
"onUpdate:modelValue" : _cache [ 2 ] || ( _cache [ 2 ] = ( $event ) => isRef ( filterText ) ? filterText . value = $event : null ) ,
placeholder : buttonText . value ,
id : "localsearch-input" ,
"aria-labelledby" : "localsearch-label" ,
class : "search-input"
} , null , 8 , _hoisted _10 ) , [
[ vModelText , unref ( filterText ) ]
] ) ,
createBaseVNode ( "div" , _hoisted _11 , [
! disableDetailedView . value ? ( openBlock ( ) , createElementBlock ( "button" , {
key : 0 ,
class : normalizeClass ( [ "toggle-layout-button" , { "detailed-list" : unref ( showDetailedList ) } ] ) ,
type : "button" ,
title : unref ( translate ) ( "modal.displayDetails" ) ,
onClick : _cache [ 3 ] || ( _cache [ 3 ] = ( $event ) => selectedIndex . value > - 1 && ( showDetailedList . value = ! unref ( showDetailedList ) ) )
} , _hoisted _14 , 10 , _hoisted _12 ) ) : createCommentVNode ( "" , true ) ,
createBaseVNode ( "button" , {
class : "clear-button" ,
type : "reset" ,
disabled : disableReset . value ,
title : unref ( translate ) ( "modal.resetButtonTitle" ) ,
onClick : resetSearch
} , _hoisted _17 , 8 , _hoisted _15 )
] )
] , 32 ) ,
createBaseVNode ( "ul" , {
ref _key : "resultsEl" ,
ref : resultsEl ,
id : ( ( _b2 = results . value ) == null ? void 0 : _b2 . length ) ? "localsearch-list" : void 0 ,
role : ( ( _c = results . value ) == null ? void 0 : _c . length ) ? "listbox" : void 0 ,
"aria-labelledby" : ( ( _d = results . value ) == null ? void 0 : _d . length ) ? "localsearch-label" : void 0 ,
class : "results" ,
onMousemove : _cache [ 7 ] || ( _cache [ 7 ] = ( $event ) => disableMouseOver . value = false )
} , [
( openBlock ( true ) , createElementBlock ( Fragment , null , renderList ( results . value , ( p , index ) => {
return openBlock ( ) , createElementBlock ( "li" , {
key : p . id ,
role : "option" ,
"aria-selected" : selectedIndex . value === index ? "true" : "false"
} , [
createBaseVNode ( "a" , {
href : p . id ,
class : normalizeClass ( [ "result" , {
selected : selectedIndex . value === index
} ] ) ,
"aria-label" : [ ... p . titles , p . title ] . join ( " > " ) ,
onMouseenter : ( $event ) => ! disableMouseOver . value && ( selectedIndex . value = index ) ,
onFocusin : ( $event ) => selectedIndex . value = index ,
onClick : _cache [ 6 ] || ( _cache [ 6 ] = ( $event ) => _ctx . $emit ( "close" ) )
} , [
createBaseVNode ( "div" , null , [
createBaseVNode ( "div" , _hoisted _21 , [
_hoisted _22 ,
( openBlock ( true ) , createElementBlock ( Fragment , null , renderList ( p . titles , ( t , index2 ) => {
return openBlock ( ) , createElementBlock ( "span" , {
key : index2 ,
class : "title"
} , [
createBaseVNode ( "span" , {
class : "text" ,
innerHTML : t
} , null , 8 , _hoisted _23 ) ,
_hoisted _24
] ) ;
} ) , 128 ) ) ,
createBaseVNode ( "span" , _hoisted _25 , [
createBaseVNode ( "span" , {
class : "text" ,
innerHTML : p . title
} , null , 8 , _hoisted _26 )
] )
] ) ,
unref ( showDetailedList ) ? ( openBlock ( ) , createElementBlock ( "div" , _hoisted _27 , [
p . text ? ( openBlock ( ) , createElementBlock ( "div" , _hoisted _28 , [
createBaseVNode ( "div" , {
class : "vp-doc" ,
innerHTML : p . text
} , null , 8 , _hoisted _29 )
] ) ) : createCommentVNode ( "" , true ) ,
_hoisted _30 ,
_hoisted _31
] ) ) : createCommentVNode ( "" , true )
] )
] , 42 , _hoisted _20 )
] , 8 , _hoisted _19 ) ;
} ) , 128 ) ) ,
unref ( filterText ) && ! results . value . length && enableNoResults . value ? ( openBlock ( ) , createElementBlock ( "li" , _hoisted _32 , [
createTextVNode ( toDisplayString ( unref ( translate ) ( "modal.noResultsText" ) ) + ' "' , 1 ) ,
createBaseVNode ( "strong" , null , toDisplayString ( unref ( filterText ) ) , 1 ) ,
createTextVNode ( '" ' )
] ) ) : createCommentVNode ( "" , true )
] , 40 , _hoisted _18 ) ,
createBaseVNode ( "div" , _hoisted _33 , [
createBaseVNode ( "span" , null , [
createBaseVNode ( "kbd" , {
"aria-label" : unref ( translate ) ( "modal.footer.navigateUpKeyAriaLabel" )
} , _hoisted _36 , 8 , _hoisted _34 ) ,
createBaseVNode ( "kbd" , {
"aria-label" : unref ( translate ) ( "modal.footer.navigateDownKeyAriaLabel" )
} , _hoisted _39 , 8 , _hoisted _37 ) ,
createTextVNode ( " " + toDisplayString ( unref ( translate ) ( "modal.footer.navigateText" ) ) , 1 )
] ) ,
createBaseVNode ( "span" , null , [
createBaseVNode ( "kbd" , {
"aria-label" : unref ( translate ) ( "modal.footer.selectKeyAriaLabel" )
} , _hoisted _42 , 8 , _hoisted _40 ) ,
createTextVNode ( " " + toDisplayString ( unref ( translate ) ( "modal.footer.selectText" ) ) , 1 )
] ) ,
createBaseVNode ( "span" , null , [
createBaseVNode ( "kbd" , {
"aria-label" : unref ( translate ) ( "modal.footer.closeKeyAriaLabel" )
} , "esc" , 8 , _hoisted _43 ) ,
createTextVNode ( " " + toDisplayString ( unref ( translate ) ( "modal.footer.closeText" ) ) , 1 )
] )
] )
] )
] , 8 , _hoisted _1 )
] ) ;
} ;
}
} ) ;
const VPLocalSearchBox = /* @__PURE__ */ _export _sfc ( _sfc _main , [ [ "__scopeId" , "data-v-43c4f204" ] ] ) ;
export {
VPLocalSearchBox as default
} ;