@embedpdf/plugin-search 1.4.1 → 2.0.0-next.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +324 -199
- package/dist/index.js.map +1 -1
- package/dist/lib/actions.d.ts +58 -22
- package/dist/lib/index.d.ts +2 -2
- package/dist/lib/reducer.d.ts +2 -1
- package/dist/lib/search-plugin.d.ts +8 -8
- package/dist/lib/types.d.ts +76 -63
- package/dist/preact/adapter.d.ts +1 -1
- package/dist/preact/index.cjs +1 -1
- package/dist/preact/index.cjs.map +1 -1
- package/dist/preact/index.js +49 -18
- package/dist/preact/index.js.map +1 -1
- package/dist/react/adapter.d.ts +1 -1
- package/dist/react/index.cjs +1 -1
- package/dist/react/index.cjs.map +1 -1
- package/dist/react/index.js +49 -18
- package/dist/react/index.js.map +1 -1
- package/dist/shared/components/search-layer.d.ts +3 -2
- package/dist/shared/hooks/use-search.d.ts +4 -4
- package/dist/shared-preact/components/search-layer.d.ts +3 -2
- package/dist/shared-preact/hooks/use-search.d.ts +4 -4
- package/dist/shared-react/components/search-layer.d.ts +3 -2
- package/dist/shared-react/hooks/use-search.d.ts +4 -4
- package/dist/svelte/components/SearchLayer.svelte.d.ts +4 -3
- package/dist/svelte/hooks/use-search.svelte.d.ts +11 -5
- package/dist/svelte/index.cjs +1 -1
- package/dist/svelte/index.cjs.map +1 -1
- package/dist/svelte/index.js +69 -35
- package/dist/svelte/index.js.map +1 -1
- package/dist/vue/components/search-layer.vue.d.ts +4 -2
- package/dist/vue/hooks/use-search.d.ts +9 -64
- package/dist/vue/index.cjs +1 -1
- package/dist/vue/index.cjs.map +1 -1
- package/dist/vue/index.js +77 -32
- package/dist/vue/index.js.map +1 -1
- package/package.json +5 -7
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../src/lib/actions.ts","../src/lib/search-plugin.ts","../src/lib/manifest.ts","../src/lib/reducer.ts","../src/lib/index.ts"],"sourcesContent":["import { Action } from '@embedpdf/core';\nimport { MatchFlag, SearchResult } from '@embedpdf/models';\n\n// Action Types\nexport const START_SEARCH_SESSION = 'START_SEARCH_SESSION';\nexport const STOP_SEARCH_SESSION = 'STOP_SEARCH_SESSION';\nexport const SET_SEARCH_FLAGS = 'SET_SEARCH_FLAGS';\nexport const SET_SHOW_ALL_RESULTS = 'SET_SHOW_ALL_RESULTS';\nexport const START_SEARCH = 'START_SEARCH';\nexport const SET_SEARCH_RESULTS = 'SET_SEARCH_RESULTS';\nexport const APPEND_SEARCH_RESULTS = 'APPEND_SEARCH_RESULTS';\nexport const SET_ACTIVE_RESULT_INDEX = 'SET_ACTIVE_RESULT_INDEX';\n\n// Action Interfaces\nexport interface StartSearchSessionAction extends Action {\n type: typeof START_SEARCH_SESSION;\n}\n\nexport interface StopSearchSessionAction extends Action {\n type: typeof STOP_SEARCH_SESSION;\n}\n\nexport interface SetSearchFlagsAction extends Action {\n type: typeof SET_SEARCH_FLAGS;\n payload: MatchFlag[];\n}\n\nexport interface SetShowAllResultsAction extends Action {\n type: typeof SET_SHOW_ALL_RESULTS;\n payload: boolean;\n}\n\nexport interface StartSearchAction extends Action {\n type: typeof START_SEARCH;\n payload: string;\n}\n\nexport interface SetSearchResultsAction extends Action {\n type: typeof SET_SEARCH_RESULTS;\n payload: {\n results: SearchResult[];\n total: number;\n activeResultIndex: number;\n };\n}\n\nexport interface AppendSearchResultsAction extends Action {\n type: typeof APPEND_SEARCH_RESULTS;\n payload: {\n results: SearchResult[];\n };\n}\n\nexport interface SetActiveResultIndexAction extends Action {\n type: typeof SET_ACTIVE_RESULT_INDEX;\n payload: number;\n}\n\n// Union Type for All Actions\nexport type SearchAction =\n | StartSearchSessionAction\n | StopSearchSessionAction\n | SetSearchFlagsAction\n | SetShowAllResultsAction\n | StartSearchAction\n | SetSearchResultsAction\n | AppendSearchResultsAction\n | SetActiveResultIndexAction;\n\n// Action Creators\nexport function startSearchSession(): StartSearchSessionAction {\n return { type: START_SEARCH_SESSION };\n}\n\nexport function stopSearchSession(): StopSearchSessionAction {\n return { type: STOP_SEARCH_SESSION };\n}\n\nexport function setSearchFlags(flags: MatchFlag[]): SetSearchFlagsAction {\n return { type: SET_SEARCH_FLAGS, payload: flags };\n}\n\nexport function setShowAllResults(showAll: boolean): SetShowAllResultsAction {\n return { type: SET_SHOW_ALL_RESULTS, payload: showAll };\n}\n\nexport function startSearch(query: string): StartSearchAction {\n return { type: START_SEARCH, payload: query };\n}\n\nexport function setSearchResults(\n results: SearchResult[],\n total: number,\n activeResultIndex: number,\n): SetSearchResultsAction {\n return { type: SET_SEARCH_RESULTS, payload: { results, total, activeResultIndex } };\n}\n\nexport function appendSearchResults(results: SearchResult[]): AppendSearchResultsAction {\n return { type: APPEND_SEARCH_RESULTS, payload: { results } };\n}\n\nexport function setActiveResultIndex(index: number): SetActiveResultIndexAction {\n return { type: SET_ACTIVE_RESULT_INDEX, payload: index };\n}\n","import { BasePlugin, createBehaviorEmitter, PluginRegistry } from '@embedpdf/core';\nimport {\n MatchFlag,\n PdfDocumentObject,\n SearchAllPagesResult,\n PdfEngine,\n PdfTask,\n PdfPageSearchProgress,\n PdfTaskHelper,\n} from '@embedpdf/models';\nimport { SearchPluginConfig, SearchCapability, SearchState, SearchResultState } from './types';\nimport { LoaderCapability, LoaderEvent, LoaderPlugin } from '@embedpdf/plugin-loader';\nimport {\n startSearchSession,\n stopSearchSession,\n setSearchFlags,\n setShowAllResults,\n startSearch,\n setSearchResults,\n setActiveResultIndex,\n appendSearchResults,\n SearchAction,\n} from './actions';\n\nexport class SearchPlugin extends BasePlugin<\n SearchPluginConfig,\n SearchCapability,\n SearchState,\n SearchAction\n> {\n static readonly id = 'search' as const;\n private loader: LoaderCapability;\n private currentDocument?: PdfDocumentObject;\n\n private readonly searchStop$ = createBehaviorEmitter();\n private readonly searchStart$ = createBehaviorEmitter();\n private readonly searchResult$ = createBehaviorEmitter<SearchAllPagesResult>();\n private readonly searchActiveResultChange$ = createBehaviorEmitter<number>();\n private readonly searchResultState$ = createBehaviorEmitter<SearchResultState>();\n private readonly searchState$ = createBehaviorEmitter<SearchState>();\n\n // keep reference to current running task (optional abort handling if your PdfTask supports it)\n private currentTask?: ReturnType<PdfEngine['searchAllPages']>;\n\n constructor(id: string, registry: PluginRegistry) {\n super(id, registry);\n this.loader = this.registry.getPlugin<LoaderPlugin>('loader')!.provides();\n\n this.loader.onDocumentLoaded(this.handleDocumentLoaded.bind(this));\n this.loader.onLoaderEvent(this.handleLoaderEvent.bind(this));\n }\n\n private handleDocumentLoaded(doc: PdfDocumentObject): void {\n this.currentDocument = doc;\n if (this.state.active) {\n this.startSearchSession();\n }\n }\n\n private handleLoaderEvent(event: LoaderEvent): void {\n if (event.type === 'error' || (event.type === 'start' && this.currentDocument)) {\n if (this.state.active) {\n this.stopSearchSession();\n }\n this.currentDocument = undefined;\n }\n }\n\n async initialize(config: SearchPluginConfig): Promise<void> {\n this.dispatch(setSearchFlags(config.flags || []));\n this.dispatch(\n setShowAllResults(config.showAllResults !== undefined ? config.showAllResults : true),\n );\n }\n\n override onStoreUpdated(_prevState: SearchState, newState: SearchState): void {\n this.searchResultState$.emit({\n results: newState.results,\n activeResultIndex: newState.activeResultIndex,\n showAllResults: newState.showAllResults,\n active: newState.active,\n });\n this.searchState$.emit(newState);\n }\n\n protected buildCapability(): SearchCapability {\n return {\n startSearch: this.startSearchSession.bind(this),\n stopSearch: this.stopSearchSession.bind(this),\n searchAllPages: this.searchAllPages.bind(this),\n nextResult: this.nextResult.bind(this),\n previousResult: this.previousResult.bind(this),\n goToResult: this.goToResult.bind(this),\n setShowAllResults: (showAll) => this.dispatch(setShowAllResults(showAll)),\n getShowAllResults: () => this.state.showAllResults,\n onSearchResult: this.searchResult$.on,\n onSearchStart: this.searchStart$.on,\n onSearchStop: this.searchStop$.on,\n onActiveResultChange: this.searchActiveResultChange$.on,\n onSearchResultStateChange: this.searchResultState$.on,\n onStateChange: this.searchState$.on,\n getFlags: () => this.state.flags,\n setFlags: (flags) => this.setFlags(flags),\n getState: () => this.state,\n };\n }\n\n private setFlags(flags: MatchFlag[]): void {\n this.dispatch(setSearchFlags(flags));\n if (this.state.active) {\n this.searchAllPages(this.state.query, true);\n }\n }\n\n private notifySearchStart(): void {\n this.searchStart$.emit();\n }\n\n private notifySearchStop(): void {\n this.searchStop$.emit();\n }\n\n private notifyActiveResultChange(index: number): void {\n this.searchActiveResultChange$.emit(index);\n }\n\n private startSearchSession(): void {\n if (!this.currentDocument) return;\n this.dispatch(startSearchSession());\n this.notifySearchStart();\n }\n\n private stopSearchSession(): void {\n if (!this.currentDocument || !this.state.active) return;\n // optional: abort current task if PdfTask supports it\n try {\n // @ts-expect-error: optional abort if available\n this.currentTask?.abort?.({ type: 'abort', code: 'cancelled', message: 'search stopped' });\n } catch {}\n this.currentTask = undefined;\n\n this.dispatch(stopSearchSession());\n this.notifySearchStop();\n }\n\n private searchAllPages(\n keyword: string,\n force: boolean = false,\n ): PdfTask<SearchAllPagesResult, PdfPageSearchProgress> {\n const trimmedKeyword = keyword.trim();\n\n if (this.state.query === trimmedKeyword && !force) {\n return PdfTaskHelper.resolve<SearchAllPagesResult, PdfPageSearchProgress>({\n results: this.state.results,\n total: this.state.total,\n });\n }\n\n // stop previous task if still running\n if (this.currentTask) {\n try {\n // @ts-expect-error: optional abort if available\n this.currentTask.abort?.({ type: 'abort', code: 'superseded', message: 'new search' });\n } catch {}\n this.currentTask = undefined;\n }\n\n this.dispatch(startSearch(trimmedKeyword));\n\n if (!trimmedKeyword || !this.currentDocument) {\n this.dispatch(setSearchResults([], 0, -1));\n return PdfTaskHelper.resolve<SearchAllPagesResult, PdfPageSearchProgress>({\n results: [],\n total: 0,\n });\n }\n\n if (!this.state.active) {\n this.startSearchSession();\n }\n\n const task = (this.currentTask = this.engine.searchAllPages(\n this.currentDocument!,\n trimmedKeyword,\n { flags: this.state.flags },\n ));\n\n task.onProgress((p) => {\n if (p?.results?.length) {\n this.dispatch(appendSearchResults(p.results));\n // set first active result as soon as we have something\n if (this.state.activeResultIndex === -1) {\n this.dispatch(setActiveResultIndex(0));\n this.notifyActiveResultChange(0);\n }\n }\n });\n\n task.wait(\n (results) => {\n this.currentTask = undefined;\n const activeResultIndex = results.total > 0 ? 0 : -1;\n this.dispatch(setSearchResults(results.results, results.total, activeResultIndex));\n this.searchResult$.emit(results);\n if (results.total > 0) {\n this.notifyActiveResultChange(0);\n }\n },\n (error) => {\n this.currentTask = undefined;\n console.error('Error during search:', error);\n this.dispatch(setSearchResults([], 0, -1));\n },\n );\n\n return task;\n }\n\n private nextResult(): number {\n if (this.state.results.length === 0) return -1;\n const nextIndex =\n this.state.activeResultIndex >= this.state.results.length - 1\n ? 0\n : this.state.activeResultIndex + 1;\n return this.goToResult(nextIndex);\n }\n\n private previousResult(): number {\n if (this.state.results.length === 0) return -1;\n const prevIndex =\n this.state.activeResultIndex <= 0\n ? this.state.results.length - 1\n : this.state.activeResultIndex - 1;\n return this.goToResult(prevIndex);\n }\n\n private goToResult(index: number): number {\n if (this.state.results.length === 0 || index < 0 || index >= this.state.results.length) {\n return -1;\n }\n this.dispatch(setActiveResultIndex(index));\n this.notifyActiveResultChange(index);\n return index;\n }\n\n async destroy(): Promise<void> {\n if (this.state.active && this.currentDocument) {\n this.stopSearchSession();\n }\n this.searchResult$.clear();\n this.searchStart$.clear();\n this.searchStop$.clear();\n this.searchActiveResultChange$.clear();\n this.searchResultState$.clear();\n this.searchState$.clear();\n }\n}\n","import { PluginManifest } from '@embedpdf/core';\nimport { SearchPluginConfig } from './types';\n\nexport const SEARCH_PLUGIN_ID = 'search';\n\nexport const manifest: PluginManifest<SearchPluginConfig> = {\n id: SEARCH_PLUGIN_ID,\n name: 'Search Plugin',\n version: '1.0.0',\n provides: ['search'],\n requires: ['loader'],\n optional: [],\n defaultConfig: {\n enabled: true,\n flags: [],\n },\n};\n","import { Reducer } from '@embedpdf/core';\nimport { SearchState } from './types';\nimport {\n START_SEARCH_SESSION,\n STOP_SEARCH_SESSION,\n SET_SEARCH_FLAGS,\n SET_SHOW_ALL_RESULTS,\n START_SEARCH,\n SET_SEARCH_RESULTS,\n APPEND_SEARCH_RESULTS,\n SET_ACTIVE_RESULT_INDEX,\n SearchAction,\n} from './actions';\n\nexport const initialState: SearchState = {\n flags: [],\n results: [],\n total: 0,\n activeResultIndex: -1,\n showAllResults: true,\n query: '',\n loading: false,\n active: false,\n};\n\nexport const searchReducer: Reducer<SearchState, SearchAction> = (state = initialState, action) => {\n switch (action.type) {\n case START_SEARCH_SESSION:\n return { ...state, active: true };\n\n case STOP_SEARCH_SESSION:\n return {\n ...state,\n results: [],\n total: 0,\n activeResultIndex: -1,\n query: '',\n loading: false,\n active: false,\n };\n\n case SET_SEARCH_FLAGS:\n return { ...state, flags: action.payload };\n\n case SET_SHOW_ALL_RESULTS:\n return { ...state, showAllResults: action.payload };\n\n case START_SEARCH:\n return {\n ...state,\n loading: true,\n query: action.payload,\n // clear old results on new search start\n results: [],\n total: 0,\n activeResultIndex: -1,\n };\n\n case APPEND_SEARCH_RESULTS: {\n const newResults = [...state.results, ...action.payload.results];\n const firstHitIndex =\n state.activeResultIndex === -1 && newResults.length > 0 ? 0 : state.activeResultIndex;\n return {\n ...state,\n results: newResults,\n total: newResults.length, // total-so-far\n activeResultIndex: firstHitIndex,\n // keep loading true until final SET_SEARCH_RESULTS\n loading: true,\n };\n }\n\n case SET_SEARCH_RESULTS:\n return {\n ...state,\n results: action.payload.results,\n total: action.payload.total,\n activeResultIndex: action.payload.activeResultIndex,\n loading: false,\n };\n\n case SET_ACTIVE_RESULT_INDEX:\n return { ...state, activeResultIndex: action.payload };\n\n default:\n return state;\n }\n};\n","import { PluginPackage } from '@embedpdf/core';\nimport { SearchPlugin } from './search-plugin';\nimport { manifest, SEARCH_PLUGIN_ID } from './manifest';\nimport { SearchPluginConfig, SearchState } from './types';\nimport { searchReducer, initialState } from './reducer';\nimport { SearchAction } from './actions';\n\nexport const SearchPluginPackage: PluginPackage<\n SearchPlugin,\n SearchPluginConfig,\n SearchState,\n SearchAction\n> = {\n manifest,\n create: (registry) => new SearchPlugin(SEARCH_PLUGIN_ID, registry),\n reducer: searchReducer,\n initialState,\n};\n\nexport * from './search-plugin';\nexport * from './types';\nexport * from './manifest';\nexport { initialState };\n"],"names":["_a"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../src/lib/actions.ts","../src/lib/reducer.ts","../src/lib/search-plugin.ts","../src/lib/manifest.ts","../src/lib/index.ts"],"sourcesContent":["import { Action } from '@embedpdf/core';\nimport { MatchFlag, SearchResult } from '@embedpdf/models';\nimport { SearchDocumentState } from './types';\n\n// Action Types\nexport const INIT_SEARCH_STATE = 'SEARCH/INIT_STATE';\nexport const CLEANUP_SEARCH_STATE = 'SEARCH/CLEANUP_STATE';\nexport const START_SEARCH_SESSION = 'SEARCH/START_SEARCH_SESSION';\nexport const STOP_SEARCH_SESSION = 'SEARCH/STOP_SEARCH_SESSION';\nexport const SET_SEARCH_FLAGS = 'SEARCH/SET_SEARCH_FLAGS';\nexport const SET_SHOW_ALL_RESULTS = 'SEARCH/SET_SHOW_ALL_RESULTS';\nexport const START_SEARCH = 'SEARCH/START_SEARCH';\nexport const SET_SEARCH_RESULTS = 'SEARCH/SET_SEARCH_RESULTS';\nexport const APPEND_SEARCH_RESULTS = 'SEARCH/APPEND_SEARCH_RESULTS';\nexport const SET_ACTIVE_RESULT_INDEX = 'SEARCH/SET_ACTIVE_RESULT_INDEX';\n\n// Action Interfaces\nexport interface InitSearchStateAction extends Action {\n type: typeof INIT_SEARCH_STATE;\n payload: { documentId: string; state: SearchDocumentState };\n}\n\nexport interface CleanupSearchStateAction extends Action {\n type: typeof CLEANUP_SEARCH_STATE;\n payload: string; // documentId\n}\n\nexport interface StartSearchSessionAction extends Action {\n type: typeof START_SEARCH_SESSION;\n payload: { documentId: string };\n}\n\nexport interface StopSearchSessionAction extends Action {\n type: typeof STOP_SEARCH_SESSION;\n payload: { documentId: string };\n}\n\nexport interface SetSearchFlagsAction extends Action {\n type: typeof SET_SEARCH_FLAGS;\n payload: { documentId: string; flags: MatchFlag[] };\n}\n\nexport interface SetShowAllResultsAction extends Action {\n type: typeof SET_SHOW_ALL_RESULTS;\n payload: { documentId: string; showAll: boolean };\n}\n\nexport interface StartSearchAction extends Action {\n type: typeof START_SEARCH;\n payload: { documentId: string; query: string };\n}\n\nexport interface SetSearchResultsAction extends Action {\n type: typeof SET_SEARCH_RESULTS;\n payload: {\n documentId: string;\n results: SearchResult[];\n total: number;\n activeResultIndex: number;\n };\n}\n\nexport interface AppendSearchResultsAction extends Action {\n type: typeof APPEND_SEARCH_RESULTS;\n payload: {\n documentId: string;\n results: SearchResult[];\n };\n}\n\nexport interface SetActiveResultIndexAction extends Action {\n type: typeof SET_ACTIVE_RESULT_INDEX;\n payload: { documentId: string; index: number };\n}\n\n// Union Type for All Actions\nexport type SearchAction =\n | InitSearchStateAction\n | CleanupSearchStateAction\n | StartSearchSessionAction\n | StopSearchSessionAction\n | SetSearchFlagsAction\n | SetShowAllResultsAction\n | StartSearchAction\n | SetSearchResultsAction\n | AppendSearchResultsAction\n | SetActiveResultIndexAction;\n\n// Action Creators\nexport function initSearchState(\n documentId: string,\n state: SearchDocumentState,\n): InitSearchStateAction {\n return { type: INIT_SEARCH_STATE, payload: { documentId, state } };\n}\n\nexport function cleanupSearchState(documentId: string): CleanupSearchStateAction {\n return { type: CLEANUP_SEARCH_STATE, payload: documentId };\n}\n\nexport function startSearchSession(documentId: string): StartSearchSessionAction {\n return { type: START_SEARCH_SESSION, payload: { documentId } };\n}\n\nexport function stopSearchSession(documentId: string): StopSearchSessionAction {\n return { type: STOP_SEARCH_SESSION, payload: { documentId } };\n}\n\nexport function setSearchFlags(documentId: string, flags: MatchFlag[]): SetSearchFlagsAction {\n return { type: SET_SEARCH_FLAGS, payload: { documentId, flags } };\n}\n\nexport function setShowAllResults(documentId: string, showAll: boolean): SetShowAllResultsAction {\n return { type: SET_SHOW_ALL_RESULTS, payload: { documentId, showAll } };\n}\n\nexport function startSearch(documentId: string, query: string): StartSearchAction {\n return { type: START_SEARCH, payload: { documentId, query } };\n}\n\nexport function setSearchResults(\n documentId: string,\n results: SearchResult[],\n total: number,\n activeResultIndex: number,\n): SetSearchResultsAction {\n return { type: SET_SEARCH_RESULTS, payload: { documentId, results, total, activeResultIndex } };\n}\n\nexport function appendSearchResults(\n documentId: string,\n results: SearchResult[],\n): AppendSearchResultsAction {\n return { type: APPEND_SEARCH_RESULTS, payload: { documentId, results } };\n}\n\nexport function setActiveResultIndex(\n documentId: string,\n index: number,\n): SetActiveResultIndexAction {\n return { type: SET_ACTIVE_RESULT_INDEX, payload: { documentId, index } };\n}\n","import { Reducer } from '@embedpdf/core';\nimport { SearchDocumentState, SearchState } from './types';\nimport {\n START_SEARCH_SESSION,\n STOP_SEARCH_SESSION,\n SET_SEARCH_FLAGS,\n SET_SHOW_ALL_RESULTS,\n START_SEARCH,\n SET_SEARCH_RESULTS,\n APPEND_SEARCH_RESULTS,\n SET_ACTIVE_RESULT_INDEX,\n SearchAction,\n INIT_SEARCH_STATE,\n CLEANUP_SEARCH_STATE,\n} from './actions';\nimport { MatchFlag } from '@embedpdf/models';\n\nexport const initialSearchDocumentState: SearchDocumentState = {\n flags: [] as MatchFlag[],\n results: [],\n total: 0,\n activeResultIndex: -1,\n showAllResults: true,\n query: '',\n loading: false,\n active: false,\n};\n\nexport const initialState: SearchState = {\n documents: {},\n};\n\nconst updateDocState = (\n state: SearchState,\n documentId: string,\n newDocState: Partial<SearchDocumentState>,\n): SearchState => {\n const oldDocState = state.documents[documentId] || initialSearchDocumentState;\n return {\n ...state,\n documents: {\n ...state.documents,\n [documentId]: {\n ...oldDocState,\n ...newDocState,\n },\n },\n };\n};\n\nexport const searchReducer: Reducer<SearchState, SearchAction> = (state = initialState, action) => {\n switch (action.type) {\n case INIT_SEARCH_STATE:\n return {\n ...state,\n documents: {\n ...state.documents,\n [action.payload.documentId]: action.payload.state,\n },\n };\n\n case CLEANUP_SEARCH_STATE: {\n const documentId = action.payload;\n const { [documentId]: removed, ...remaining } = state.documents;\n return {\n ...state,\n documents: remaining,\n };\n }\n\n case START_SEARCH_SESSION:\n return updateDocState(state, action.payload.documentId, { active: true });\n\n case STOP_SEARCH_SESSION:\n return updateDocState(state, action.payload.documentId, {\n results: [],\n total: 0,\n activeResultIndex: -1,\n query: '',\n loading: false,\n active: false,\n });\n\n case SET_SEARCH_FLAGS:\n return updateDocState(state, action.payload.documentId, { flags: action.payload.flags });\n\n case SET_SHOW_ALL_RESULTS:\n return updateDocState(state, action.payload.documentId, {\n showAllResults: action.payload.showAll,\n });\n\n case START_SEARCH:\n return updateDocState(state, action.payload.documentId, {\n loading: true,\n query: action.payload.query,\n // clear old results on new search start\n results: [],\n total: 0,\n activeResultIndex: -1,\n });\n\n case APPEND_SEARCH_RESULTS: {\n const { documentId, results } = action.payload;\n const docState = state.documents[documentId];\n if (!docState) return state;\n\n const newResults = [...docState.results, ...results];\n const firstHitIndex =\n docState.activeResultIndex === -1 && newResults.length > 0 ? 0 : docState.activeResultIndex;\n return updateDocState(state, documentId, {\n results: newResults,\n total: newResults.length, // total-so-far\n activeResultIndex: firstHitIndex,\n // keep loading true until final SET_SEARCH_RESULTS\n loading: true,\n });\n }\n\n case SET_SEARCH_RESULTS: {\n const { documentId, results, total, activeResultIndex } = action.payload;\n return updateDocState(state, documentId, {\n results,\n total,\n activeResultIndex,\n loading: false,\n });\n }\n\n case SET_ACTIVE_RESULT_INDEX:\n return updateDocState(state, action.payload.documentId, {\n activeResultIndex: action.payload.index,\n });\n\n default:\n return state;\n }\n};\n","import { BasePlugin, createBehaviorEmitter, Listener, PluginRegistry } from '@embedpdf/core';\nimport {\n MatchFlag,\n SearchAllPagesResult,\n PdfEngine,\n PdfTask,\n PdfPageSearchProgress,\n PdfTaskHelper,\n PdfErrorCode,\n} from '@embedpdf/models';\nimport {\n SearchPluginConfig,\n SearchCapability,\n SearchState,\n SearchResultState,\n SearchScope,\n SearchResultEvent,\n SearchStartEvent,\n SearchStopEvent,\n ActiveResultChangeEvent,\n SearchResultStateEvent,\n SearchStateEvent,\n SearchDocumentState,\n} from './types';\nimport {\n startSearchSession,\n stopSearchSession,\n setSearchFlags,\n setShowAllResults,\n startSearch,\n setSearchResults,\n setActiveResultIndex,\n appendSearchResults,\n SearchAction,\n initSearchState,\n cleanupSearchState,\n} from './actions';\nimport { initialSearchDocumentState } from './reducer';\n\nexport class SearchPlugin extends BasePlugin<\n SearchPluginConfig,\n SearchCapability,\n SearchState,\n SearchAction\n> {\n static readonly id = 'search' as const;\n\n // Event emitters are now global and include documentId\n private readonly searchStop$ = createBehaviorEmitter<SearchStopEvent>();\n private readonly searchStart$ = createBehaviorEmitter<SearchStartEvent>();\n private readonly searchResult$ = createBehaviorEmitter<SearchResultEvent>();\n private readonly searchActiveResultChange$ = createBehaviorEmitter<ActiveResultChangeEvent>();\n private readonly searchResultState$ = createBehaviorEmitter<SearchResultStateEvent>();\n private readonly searchState$ = createBehaviorEmitter<SearchStateEvent>();\n\n // Keep reference to current running tasks per document\n private currentTask = new Map<string, ReturnType<PdfEngine['searchAllPages']>>();\n private pluginConfig: SearchPluginConfig;\n\n constructor(id: string, registry: PluginRegistry, config: SearchPluginConfig) {\n super(id, registry);\n this.pluginConfig = config;\n // We no longer need to listen to the loader.\n // Document lifecycle is handled by BasePlugin hooks.\n }\n\n protected override onDocumentLoadingStarted(documentId: string): void {\n const initialState = {\n ...initialSearchDocumentState,\n flags: this.pluginConfig.flags || [],\n showAllResults: this.pluginConfig.showAllResults ?? true,\n };\n this.dispatch(initSearchState(documentId, initialState));\n }\n\n protected override onDocumentClosed(documentId: string): void {\n this.stopSearchSession(documentId); // Ensure any running search is stopped\n this.dispatch(cleanupSearchState(documentId));\n this.currentTask.delete(documentId);\n }\n\n async initialize(): Promise<void> {\n // Config is now handled in onDocumentLoadingStarted\n }\n\n override onStoreUpdated(prevState: SearchState, newState: SearchState): void {\n for (const documentId in newState.documents) {\n const prevDocState = prevState.documents[documentId];\n const newDocState = newState.documents[documentId];\n\n if (prevDocState !== newDocState) {\n // Emit per-document state\n this.searchState$.emit({ documentId, state: newDocState });\n\n // Emit reactive result state\n if (\n !prevDocState ||\n prevDocState.results !== newDocState.results ||\n prevDocState.activeResultIndex !== newDocState.activeResultIndex ||\n prevDocState.showAllResults !== newDocState.showAllResults ||\n prevDocState.active !== newDocState.active\n ) {\n this.searchResultState$.emit({\n documentId,\n state: {\n results: newDocState.results,\n activeResultIndex: newDocState.activeResultIndex,\n showAllResults: newDocState.showAllResults,\n active: newDocState.active,\n },\n });\n }\n }\n }\n }\n\n protected buildCapability(): SearchCapability {\n const getDocId = (documentId?: string) => documentId ?? this.getActiveDocumentId();\n const getDocState = (docId?: string) => {\n const id = getDocId(docId);\n const state = this.state.documents[id];\n if (!state) throw new Error(`Search state not found for document ${id}`);\n return state;\n };\n\n return {\n startSearch: (docId) => this.startSearchSession(getDocId(docId)),\n stopSearch: (docId) => this.stopSearchSession(getDocId(docId)),\n searchAllPages: (keyword, docId) => this.searchAllPages(keyword, getDocId(docId)),\n nextResult: (docId) => this.nextResult(getDocId(docId)),\n previousResult: (docId) => this.previousResult(getDocId(docId)),\n goToResult: (index, docId) => this.goToResult(index, getDocId(docId)),\n setShowAllResults: (showAll, docId) =>\n this.dispatch(setShowAllResults(getDocId(docId), showAll)),\n getShowAllResults: (docId) => getDocState(docId).showAllResults,\n getFlags: (docId) => getDocState(docId).flags,\n setFlags: (flags, docId) => this.setFlags(flags, getDocId(docId)),\n getState: (docId) => getDocState(docId),\n forDocument: this.createSearchScope.bind(this),\n onSearchResult: this.searchResult$.on,\n onSearchStart: this.searchStart$.on,\n onSearchStop: this.searchStop$.on,\n onActiveResultChange: this.searchActiveResultChange$.on,\n onSearchResultStateChange: this.searchResultState$.on,\n onStateChange: this.searchState$.on,\n };\n }\n\n private createSearchScope(documentId: string): SearchScope {\n const getDocState = () => {\n const state = this.state.documents[documentId];\n if (!state) throw new Error(`Search state not found for document ${documentId}`);\n return state;\n };\n\n return {\n startSearch: () => this.startSearchSession(documentId),\n stopSearch: () => this.stopSearchSession(documentId),\n searchAllPages: (keyword) => this.searchAllPages(keyword, documentId),\n nextResult: () => this.nextResult(documentId),\n previousResult: () => this.previousResult(documentId),\n goToResult: (index) => this.goToResult(index, documentId),\n setShowAllResults: (showAll) => this.dispatch(setShowAllResults(documentId, showAll)),\n getShowAllResults: () => getDocState().showAllResults,\n getFlags: () => getDocState().flags,\n setFlags: (flags) => this.setFlags(flags, documentId),\n getState: getDocState,\n onSearchResult: (listener: Listener<SearchAllPagesResult>) =>\n this.searchResult$.on((event) => {\n if (event.documentId === documentId) listener(event.results);\n }),\n onSearchStart: (listener: Listener<void>) =>\n this.searchStart$.on((event) => {\n if (event.documentId === documentId) listener();\n }),\n onSearchStop: (listener: Listener<void>) =>\n this.searchStop$.on((event) => {\n if (event.documentId === documentId) listener();\n }),\n onActiveResultChange: (listener: Listener<number>) =>\n this.searchActiveResultChange$.on((event) => {\n if (event.documentId === documentId) listener(event.index);\n }),\n onSearchResultStateChange: (listener: Listener<SearchResultState>) =>\n this.searchResultState$.on((event) => {\n if (event.documentId === documentId) listener(event.state);\n }),\n onStateChange: (listener: Listener<SearchDocumentState>) =>\n this.searchState$.on((event) => {\n if (event.documentId === documentId) listener(event.state);\n }),\n };\n }\n\n private setFlags(flags: MatchFlag[], documentId: string): void {\n this.dispatch(setSearchFlags(documentId, flags));\n const docState = this.state.documents[documentId];\n if (docState?.active) {\n this.searchAllPages(docState.query, documentId, true);\n }\n }\n\n private notifySearchStart(documentId: string): void {\n this.searchStart$.emit({ documentId });\n }\n\n private notifySearchStop(documentId: string): void {\n this.searchStop$.emit({ documentId });\n }\n\n private notifyActiveResultChange(documentId: string, index: number): void {\n this.searchActiveResultChange$.emit({ documentId, index });\n }\n\n private startSearchSession(documentId: string): void {\n const coreDoc = this.getCoreDocument(documentId);\n if (!coreDoc) return;\n this.dispatch(startSearchSession(documentId));\n this.notifySearchStart(documentId);\n }\n\n private stopSearchSession(documentId: string): void {\n const docState = this.state.documents[documentId];\n if (!docState?.active) return;\n\n const task = this.currentTask.get(documentId);\n if (task) {\n try {\n task.abort?.({ code: PdfErrorCode.Cancelled, message: 'search stopped' });\n } catch {}\n this.currentTask.delete(documentId);\n }\n\n this.dispatch(stopSearchSession(documentId));\n this.notifySearchStop(documentId);\n }\n\n private searchAllPages(\n keyword: string,\n documentId: string,\n force: boolean = false,\n ): PdfTask<SearchAllPagesResult, PdfPageSearchProgress> {\n const docState = this.state.documents[documentId];\n if (!docState) {\n return PdfTaskHelper.reject({\n code: PdfErrorCode.NotFound,\n message: 'Search state not initialized',\n });\n }\n const coreDoc = this.getCoreDocument(documentId);\n if (!coreDoc?.document) {\n return PdfTaskHelper.reject({ code: PdfErrorCode.NotFound, message: 'Document not loaded' });\n }\n\n const trimmedKeyword = keyword.trim();\n\n if (docState.query === trimmedKeyword && !force) {\n return PdfTaskHelper.resolve<SearchAllPagesResult, PdfPageSearchProgress>({\n results: docState.results,\n total: docState.total,\n });\n }\n\n // stop previous task if still running\n const oldTask = this.currentTask.get(documentId);\n if (oldTask) {\n try {\n oldTask.abort?.({ code: PdfErrorCode.Cancelled, message: 'new search' });\n } catch {}\n this.currentTask.delete(documentId);\n }\n\n this.dispatch(startSearch(documentId, trimmedKeyword));\n\n if (!trimmedKeyword) {\n this.dispatch(setSearchResults(documentId, [], 0, -1));\n return PdfTaskHelper.resolve<SearchAllPagesResult, PdfPageSearchProgress>({\n results: [],\n total: 0,\n });\n }\n\n if (!docState.active) {\n this.startSearchSession(documentId);\n }\n\n const task = this.engine.searchAllPages(coreDoc.document, trimmedKeyword, {\n flags: docState.flags,\n });\n this.currentTask.set(documentId, task);\n\n task.onProgress((p) => {\n if (p?.results?.length) {\n // Check if the task is still the current one before dispatching\n if (this.currentTask.get(documentId) === task) {\n this.dispatch(appendSearchResults(documentId, p.results));\n // set first active result as soon as we have something\n if (this.state.documents[documentId].activeResultIndex === -1) {\n this.dispatch(setActiveResultIndex(documentId, 0));\n this.notifyActiveResultChange(documentId, 0);\n }\n }\n }\n });\n\n task.wait(\n (results) => {\n this.currentTask.delete(documentId);\n const activeResultIndex = results.total > 0 ? 0 : -1;\n this.dispatch(\n setSearchResults(documentId, results.results, results.total, activeResultIndex),\n );\n this.searchResult$.emit({ documentId, results });\n if (results.total > 0) {\n this.notifyActiveResultChange(documentId, 0);\n }\n },\n (error) => {\n // Only clear results if the error wasn't an abort\n if (error?.reason?.code !== PdfErrorCode.Cancelled) {\n console.error('Error during search:', error);\n this.dispatch(setSearchResults(documentId, [], 0, -1));\n }\n this.currentTask.delete(documentId);\n },\n );\n\n return task;\n }\n\n private nextResult(documentId: string): number {\n const docState = this.state.documents[documentId];\n if (!docState || docState.results.length === 0) return -1;\n const nextIndex =\n docState.activeResultIndex >= docState.results.length - 1\n ? 0\n : docState.activeResultIndex + 1;\n return this.goToResult(nextIndex, documentId);\n }\n\n private previousResult(documentId: string): number {\n const docState = this.state.documents[documentId];\n if (!docState || docState.results.length === 0) return -1;\n const prevIndex =\n docState.activeResultIndex <= 0\n ? docState.results.length - 1\n : docState.activeResultIndex - 1;\n return this.goToResult(prevIndex, documentId);\n }\n\n private goToResult(index: number, documentId: string): number {\n const docState = this.state.documents[documentId];\n if (\n !docState ||\n docState.results.length === 0 ||\n index < 0 ||\n index >= docState.results.length\n ) {\n return -1;\n }\n this.dispatch(setActiveResultIndex(documentId, index));\n this.notifyActiveResultChange(documentId, index);\n return index;\n }\n\n async destroy(): Promise<void> {\n for (const documentId of Object.keys(this.state.documents)) {\n this.stopSearchSession(documentId);\n }\n this.searchResult$.clear();\n this.searchStart$.clear();\n this.searchStop$.clear();\n this.searchActiveResultChange$.clear();\n this.searchResultState$.clear();\n this.searchState$.clear();\n super.destroy();\n }\n}\n","import { PluginManifest } from '@embedpdf/core';\nimport { SearchPluginConfig } from './types';\n\nexport const SEARCH_PLUGIN_ID = 'search';\n\nexport const manifest: PluginManifest<SearchPluginConfig> = {\n id: SEARCH_PLUGIN_ID,\n name: 'Search Plugin',\n version: '1.0.0',\n provides: ['search'],\n requires: [],\n optional: [],\n defaultConfig: {\n enabled: true,\n flags: [],\n },\n};\n","import { PluginPackage } from '@embedpdf/core';\nimport { SearchPlugin } from './search-plugin';\nimport { manifest, SEARCH_PLUGIN_ID } from './manifest';\nimport { SearchPluginConfig, SearchState } from './types';\nimport { searchReducer, initialState, initialSearchDocumentState } from './reducer';\nimport { SearchAction } from './actions';\n\nexport const SearchPluginPackage: PluginPackage<\n SearchPlugin,\n SearchPluginConfig,\n SearchState,\n SearchAction\n> = {\n manifest,\n create: (registry, config) => new SearchPlugin(SEARCH_PLUGIN_ID, registry, config),\n reducer: searchReducer,\n initialState,\n};\n\nexport * from './search-plugin';\nexport * from './types';\nexport * from './manifest';\nexport { initialState, initialSearchDocumentState };\n"],"names":["initialState","_a"],"mappings":"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"}
|
package/dist/lib/actions.d.ts
CHANGED
|
@@ -1,34 +1,64 @@
|
|
|
1
1
|
import { Action } from '@embedpdf/core';
|
|
2
2
|
import { MatchFlag, SearchResult } from '@embedpdf/models';
|
|
3
|
-
|
|
4
|
-
export declare const
|
|
5
|
-
export declare const
|
|
6
|
-
export declare const
|
|
7
|
-
export declare const
|
|
8
|
-
export declare const
|
|
9
|
-
export declare const
|
|
10
|
-
export declare const
|
|
3
|
+
import { SearchDocumentState } from './types';
|
|
4
|
+
export declare const INIT_SEARCH_STATE = "SEARCH/INIT_STATE";
|
|
5
|
+
export declare const CLEANUP_SEARCH_STATE = "SEARCH/CLEANUP_STATE";
|
|
6
|
+
export declare const START_SEARCH_SESSION = "SEARCH/START_SEARCH_SESSION";
|
|
7
|
+
export declare const STOP_SEARCH_SESSION = "SEARCH/STOP_SEARCH_SESSION";
|
|
8
|
+
export declare const SET_SEARCH_FLAGS = "SEARCH/SET_SEARCH_FLAGS";
|
|
9
|
+
export declare const SET_SHOW_ALL_RESULTS = "SEARCH/SET_SHOW_ALL_RESULTS";
|
|
10
|
+
export declare const START_SEARCH = "SEARCH/START_SEARCH";
|
|
11
|
+
export declare const SET_SEARCH_RESULTS = "SEARCH/SET_SEARCH_RESULTS";
|
|
12
|
+
export declare const APPEND_SEARCH_RESULTS = "SEARCH/APPEND_SEARCH_RESULTS";
|
|
13
|
+
export declare const SET_ACTIVE_RESULT_INDEX = "SEARCH/SET_ACTIVE_RESULT_INDEX";
|
|
14
|
+
export interface InitSearchStateAction extends Action {
|
|
15
|
+
type: typeof INIT_SEARCH_STATE;
|
|
16
|
+
payload: {
|
|
17
|
+
documentId: string;
|
|
18
|
+
state: SearchDocumentState;
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
export interface CleanupSearchStateAction extends Action {
|
|
22
|
+
type: typeof CLEANUP_SEARCH_STATE;
|
|
23
|
+
payload: string;
|
|
24
|
+
}
|
|
11
25
|
export interface StartSearchSessionAction extends Action {
|
|
12
26
|
type: typeof START_SEARCH_SESSION;
|
|
27
|
+
payload: {
|
|
28
|
+
documentId: string;
|
|
29
|
+
};
|
|
13
30
|
}
|
|
14
31
|
export interface StopSearchSessionAction extends Action {
|
|
15
32
|
type: typeof STOP_SEARCH_SESSION;
|
|
33
|
+
payload: {
|
|
34
|
+
documentId: string;
|
|
35
|
+
};
|
|
16
36
|
}
|
|
17
37
|
export interface SetSearchFlagsAction extends Action {
|
|
18
38
|
type: typeof SET_SEARCH_FLAGS;
|
|
19
|
-
payload:
|
|
39
|
+
payload: {
|
|
40
|
+
documentId: string;
|
|
41
|
+
flags: MatchFlag[];
|
|
42
|
+
};
|
|
20
43
|
}
|
|
21
44
|
export interface SetShowAllResultsAction extends Action {
|
|
22
45
|
type: typeof SET_SHOW_ALL_RESULTS;
|
|
23
|
-
payload:
|
|
46
|
+
payload: {
|
|
47
|
+
documentId: string;
|
|
48
|
+
showAll: boolean;
|
|
49
|
+
};
|
|
24
50
|
}
|
|
25
51
|
export interface StartSearchAction extends Action {
|
|
26
52
|
type: typeof START_SEARCH;
|
|
27
|
-
payload:
|
|
53
|
+
payload: {
|
|
54
|
+
documentId: string;
|
|
55
|
+
query: string;
|
|
56
|
+
};
|
|
28
57
|
}
|
|
29
58
|
export interface SetSearchResultsAction extends Action {
|
|
30
59
|
type: typeof SET_SEARCH_RESULTS;
|
|
31
60
|
payload: {
|
|
61
|
+
documentId: string;
|
|
32
62
|
results: SearchResult[];
|
|
33
63
|
total: number;
|
|
34
64
|
activeResultIndex: number;
|
|
@@ -37,19 +67,25 @@ export interface SetSearchResultsAction extends Action {
|
|
|
37
67
|
export interface AppendSearchResultsAction extends Action {
|
|
38
68
|
type: typeof APPEND_SEARCH_RESULTS;
|
|
39
69
|
payload: {
|
|
70
|
+
documentId: string;
|
|
40
71
|
results: SearchResult[];
|
|
41
72
|
};
|
|
42
73
|
}
|
|
43
74
|
export interface SetActiveResultIndexAction extends Action {
|
|
44
75
|
type: typeof SET_ACTIVE_RESULT_INDEX;
|
|
45
|
-
payload:
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
export
|
|
51
|
-
export declare function
|
|
52
|
-
export declare function
|
|
53
|
-
export declare function
|
|
54
|
-
export declare function
|
|
55
|
-
export declare function
|
|
76
|
+
payload: {
|
|
77
|
+
documentId: string;
|
|
78
|
+
index: number;
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
export type SearchAction = InitSearchStateAction | CleanupSearchStateAction | StartSearchSessionAction | StopSearchSessionAction | SetSearchFlagsAction | SetShowAllResultsAction | StartSearchAction | SetSearchResultsAction | AppendSearchResultsAction | SetActiveResultIndexAction;
|
|
82
|
+
export declare function initSearchState(documentId: string, state: SearchDocumentState): InitSearchStateAction;
|
|
83
|
+
export declare function cleanupSearchState(documentId: string): CleanupSearchStateAction;
|
|
84
|
+
export declare function startSearchSession(documentId: string): StartSearchSessionAction;
|
|
85
|
+
export declare function stopSearchSession(documentId: string): StopSearchSessionAction;
|
|
86
|
+
export declare function setSearchFlags(documentId: string, flags: MatchFlag[]): SetSearchFlagsAction;
|
|
87
|
+
export declare function setShowAllResults(documentId: string, showAll: boolean): SetShowAllResultsAction;
|
|
88
|
+
export declare function startSearch(documentId: string, query: string): StartSearchAction;
|
|
89
|
+
export declare function setSearchResults(documentId: string, results: SearchResult[], total: number, activeResultIndex: number): SetSearchResultsAction;
|
|
90
|
+
export declare function appendSearchResults(documentId: string, results: SearchResult[]): AppendSearchResultsAction;
|
|
91
|
+
export declare function setActiveResultIndex(documentId: string, index: number): SetActiveResultIndexAction;
|
package/dist/lib/index.d.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { PluginPackage } from '@embedpdf/core';
|
|
2
2
|
import { SearchPlugin } from './search-plugin';
|
|
3
3
|
import { SearchPluginConfig, SearchState } from './types';
|
|
4
|
-
import { initialState } from './reducer';
|
|
4
|
+
import { initialState, initialSearchDocumentState } from './reducer';
|
|
5
5
|
import { SearchAction } from './actions';
|
|
6
6
|
export declare const SearchPluginPackage: PluginPackage<SearchPlugin, SearchPluginConfig, SearchState, SearchAction>;
|
|
7
7
|
export * from './search-plugin';
|
|
8
8
|
export * from './types';
|
|
9
9
|
export * from './manifest';
|
|
10
|
-
export { initialState };
|
|
10
|
+
export { initialState, initialSearchDocumentState };
|
package/dist/lib/reducer.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { Reducer } from '@embedpdf/core';
|
|
2
|
-
import { SearchState } from './types';
|
|
2
|
+
import { SearchDocumentState, SearchState } from './types';
|
|
3
3
|
import { SearchAction } from './actions';
|
|
4
|
+
export declare const initialSearchDocumentState: SearchDocumentState;
|
|
4
5
|
export declare const initialState: SearchState;
|
|
5
6
|
export declare const searchReducer: Reducer<SearchState, SearchAction>;
|
|
@@ -3,21 +3,21 @@ import { SearchPluginConfig, SearchCapability, SearchState } from './types';
|
|
|
3
3
|
import { SearchAction } from './actions';
|
|
4
4
|
export declare class SearchPlugin extends BasePlugin<SearchPluginConfig, SearchCapability, SearchState, SearchAction> {
|
|
5
5
|
static readonly id: "search";
|
|
6
|
-
private loader;
|
|
7
|
-
private currentDocument?;
|
|
8
6
|
private readonly searchStop$;
|
|
9
7
|
private readonly searchStart$;
|
|
10
8
|
private readonly searchResult$;
|
|
11
9
|
private readonly searchActiveResultChange$;
|
|
12
10
|
private readonly searchResultState$;
|
|
13
11
|
private readonly searchState$;
|
|
14
|
-
private currentTask
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
12
|
+
private currentTask;
|
|
13
|
+
private pluginConfig;
|
|
14
|
+
constructor(id: string, registry: PluginRegistry, config: SearchPluginConfig);
|
|
15
|
+
protected onDocumentLoadingStarted(documentId: string): void;
|
|
16
|
+
protected onDocumentClosed(documentId: string): void;
|
|
17
|
+
initialize(): Promise<void>;
|
|
18
|
+
onStoreUpdated(prevState: SearchState, newState: SearchState): void;
|
|
20
19
|
protected buildCapability(): SearchCapability;
|
|
20
|
+
private createSearchScope;
|
|
21
21
|
private setFlags;
|
|
22
22
|
private notifySearchStart;
|
|
23
23
|
private notifySearchStop;
|
package/dist/lib/types.d.ts
CHANGED
|
@@ -8,11 +8,19 @@ export interface SearchPluginConfig extends BasePluginConfig {
|
|
|
8
8
|
*/
|
|
9
9
|
showAllResults?: boolean;
|
|
10
10
|
}
|
|
11
|
-
|
|
11
|
+
/**
|
|
12
|
+
* This is the state for a *single* document
|
|
13
|
+
*/
|
|
14
|
+
export interface SearchDocumentState {
|
|
15
|
+
flags: MatchFlag[];
|
|
12
16
|
/**
|
|
13
17
|
* Current search results from last search operation
|
|
14
18
|
*/
|
|
15
19
|
results: SearchResult[];
|
|
20
|
+
/**
|
|
21
|
+
* Total number of search results
|
|
22
|
+
*/
|
|
23
|
+
total: number;
|
|
16
24
|
/**
|
|
17
25
|
* Current active result index (0-based)
|
|
18
26
|
*/
|
|
@@ -21,21 +29,33 @@ export interface SearchResultState {
|
|
|
21
29
|
* Whether to show all search results or only the active one
|
|
22
30
|
*/
|
|
23
31
|
showAllResults: boolean;
|
|
32
|
+
/**
|
|
33
|
+
* Current search query
|
|
34
|
+
*/
|
|
35
|
+
query: string;
|
|
36
|
+
/**
|
|
37
|
+
* Whether a search operation is in progress
|
|
38
|
+
*/
|
|
39
|
+
loading: boolean;
|
|
24
40
|
/**
|
|
25
41
|
* Whether search is currently active
|
|
26
42
|
*/
|
|
27
43
|
active: boolean;
|
|
28
44
|
}
|
|
45
|
+
/**
|
|
46
|
+
* This is the combined state for the plugin
|
|
47
|
+
*/
|
|
29
48
|
export interface SearchState {
|
|
30
|
-
|
|
49
|
+
documents: Record<string, SearchDocumentState>;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* This is the payload for the reactive result state
|
|
53
|
+
*/
|
|
54
|
+
export interface SearchResultState {
|
|
31
55
|
/**
|
|
32
56
|
* Current search results from last search operation
|
|
33
57
|
*/
|
|
34
58
|
results: SearchResult[];
|
|
35
|
-
/**
|
|
36
|
-
* Total number of search results
|
|
37
|
-
*/
|
|
38
|
-
total: number;
|
|
39
59
|
/**
|
|
40
60
|
* Current active result index (0-based)
|
|
41
61
|
*/
|
|
@@ -44,20 +64,34 @@ export interface SearchState {
|
|
|
44
64
|
* Whether to show all search results or only the active one
|
|
45
65
|
*/
|
|
46
66
|
showAllResults: boolean;
|
|
47
|
-
/**
|
|
48
|
-
* Current search query
|
|
49
|
-
*/
|
|
50
|
-
query: string;
|
|
51
|
-
/**
|
|
52
|
-
* Whether a search operation is in progress
|
|
53
|
-
*/
|
|
54
|
-
loading: boolean;
|
|
55
67
|
/**
|
|
56
68
|
* Whether search is currently active
|
|
57
69
|
*/
|
|
58
70
|
active: boolean;
|
|
59
71
|
}
|
|
60
|
-
export interface
|
|
72
|
+
export interface SearchResultEvent {
|
|
73
|
+
documentId: string;
|
|
74
|
+
results: SearchAllPagesResult;
|
|
75
|
+
}
|
|
76
|
+
export interface SearchStartEvent {
|
|
77
|
+
documentId: string;
|
|
78
|
+
}
|
|
79
|
+
export interface SearchStopEvent {
|
|
80
|
+
documentId: string;
|
|
81
|
+
}
|
|
82
|
+
export interface ActiveResultChangeEvent {
|
|
83
|
+
documentId: string;
|
|
84
|
+
index: number;
|
|
85
|
+
}
|
|
86
|
+
export interface SearchResultStateEvent {
|
|
87
|
+
documentId: string;
|
|
88
|
+
state: SearchResultState;
|
|
89
|
+
}
|
|
90
|
+
export interface SearchStateEvent {
|
|
91
|
+
documentId: string;
|
|
92
|
+
state: SearchDocumentState;
|
|
93
|
+
}
|
|
94
|
+
export interface SearchScope {
|
|
61
95
|
/**
|
|
62
96
|
* Start a search session
|
|
63
97
|
*/
|
|
@@ -68,85 +102,64 @@ export interface SearchCapability {
|
|
|
68
102
|
stopSearch: () => void;
|
|
69
103
|
/**
|
|
70
104
|
* Search for all occurrences of the keyword throughout the document
|
|
71
|
-
* @param keyword - Text to search for
|
|
72
|
-
* @returns Promise that resolves to all search results or empty result if none found
|
|
73
105
|
*/
|
|
74
106
|
searchAllPages: (keyword: string) => PdfTask<SearchAllPagesResult, PdfPageSearchProgress>;
|
|
75
107
|
/**
|
|
76
108
|
* Navigate to the next search result
|
|
77
|
-
* @returns The new active result index
|
|
78
109
|
*/
|
|
79
110
|
nextResult: () => number;
|
|
80
111
|
/**
|
|
81
112
|
* Navigate to the previous search result
|
|
82
|
-
* @returns The new active result index
|
|
83
113
|
*/
|
|
84
114
|
previousResult: () => number;
|
|
85
115
|
/**
|
|
86
116
|
* Go to a specific search result by index
|
|
87
|
-
* @param index - The index of the result to go to
|
|
88
|
-
* @returns The new active result index
|
|
89
117
|
*/
|
|
90
118
|
goToResult: (index: number) => number;
|
|
91
119
|
/**
|
|
92
120
|
* Toggle visibility of all search results
|
|
93
|
-
* @param showAll - Whether to show all results or only the active one
|
|
94
121
|
*/
|
|
95
122
|
setShowAllResults: (showAll: boolean) => void;
|
|
96
123
|
/**
|
|
97
124
|
* Get current state of search results visibility
|
|
98
|
-
* @returns Whether all results are visible
|
|
99
125
|
*/
|
|
100
126
|
getShowAllResults: () => boolean;
|
|
101
|
-
/**
|
|
102
|
-
* Subscribe to search results
|
|
103
|
-
* @param handler - Handler function to receive search results
|
|
104
|
-
* @returns Function to unsubscribe the handler
|
|
105
|
-
*/
|
|
106
|
-
onSearchResult: EventHook<SearchAllPagesResult>;
|
|
107
|
-
/**
|
|
108
|
-
* Subscribe to search session start events
|
|
109
|
-
* @param handler - Handler function called when search session starts
|
|
110
|
-
* @returns Function to unsubscribe the handler
|
|
111
|
-
*/
|
|
112
|
-
onSearchStart: EventHook;
|
|
113
|
-
/**
|
|
114
|
-
* Subscribe to search session stop events
|
|
115
|
-
* @param handler - Handler function called when search session stops
|
|
116
|
-
* @returns Function to unsubscribe the handler
|
|
117
|
-
*/
|
|
118
|
-
onSearchStop: EventHook;
|
|
119
|
-
/**
|
|
120
|
-
* Subscribe to active result change events
|
|
121
|
-
* @param handler - Handler function called when active result changes
|
|
122
|
-
* @returns Function to unsubscribe the handler
|
|
123
|
-
*/
|
|
124
|
-
onActiveResultChange: EventHook<number>;
|
|
125
|
-
/**
|
|
126
|
-
* Subscribe to search result state change events
|
|
127
|
-
* @param handler - Handler function called when search state changes
|
|
128
|
-
* @returns Function to unsubscribe the handler
|
|
129
|
-
*/
|
|
130
|
-
onSearchResultStateChange: EventHook<SearchResultState>;
|
|
131
127
|
/**
|
|
132
128
|
* Get the current search flags
|
|
133
|
-
* @returns Array of active search flags
|
|
134
129
|
*/
|
|
135
130
|
getFlags: () => MatchFlag[];
|
|
136
131
|
/**
|
|
137
132
|
* Set the search flags
|
|
138
|
-
* @param flags - Array of search flags to use
|
|
139
133
|
*/
|
|
140
134
|
setFlags: (flags: MatchFlag[]) => void;
|
|
141
|
-
/**
|
|
142
|
-
* Subscribe to state change events
|
|
143
|
-
* @param handler - Handler function called when state changes
|
|
144
|
-
* @returns Function to unsubscribe the handler
|
|
145
|
-
*/
|
|
146
|
-
onStateChange: EventHook<SearchState>;
|
|
147
135
|
/**
|
|
148
136
|
* Get the current search state
|
|
149
|
-
* @returns The current search state
|
|
150
137
|
*/
|
|
151
|
-
getState: () =>
|
|
138
|
+
getState: () => SearchDocumentState;
|
|
139
|
+
onSearchResult: EventHook<SearchAllPagesResult>;
|
|
140
|
+
onSearchStart: EventHook<void>;
|
|
141
|
+
onSearchStop: EventHook<void>;
|
|
142
|
+
onActiveResultChange: EventHook<number>;
|
|
143
|
+
onSearchResultStateChange: EventHook<SearchResultState>;
|
|
144
|
+
onStateChange: EventHook<SearchDocumentState>;
|
|
145
|
+
}
|
|
146
|
+
export interface SearchCapability {
|
|
147
|
+
startSearch: (documentId?: string) => void;
|
|
148
|
+
stopSearch: (documentId?: string) => void;
|
|
149
|
+
searchAllPages: (keyword: string, documentId?: string) => PdfTask<SearchAllPagesResult, PdfPageSearchProgress>;
|
|
150
|
+
nextResult: (documentId?: string) => number;
|
|
151
|
+
previousResult: (documentId?: string) => number;
|
|
152
|
+
goToResult: (index: number, documentId?: string) => number;
|
|
153
|
+
setShowAllResults: (showAll: boolean, documentId?: string) => void;
|
|
154
|
+
getShowAllResults: (documentId?: string) => boolean;
|
|
155
|
+
getFlags: (documentId?: string) => MatchFlag[];
|
|
156
|
+
setFlags: (flags: MatchFlag[], documentId?: string) => void;
|
|
157
|
+
getState: (documentId?: string) => SearchDocumentState;
|
|
158
|
+
forDocument(documentId: string): SearchScope;
|
|
159
|
+
onSearchResult: EventHook<SearchResultEvent>;
|
|
160
|
+
onSearchStart: EventHook<SearchStartEvent>;
|
|
161
|
+
onSearchStop: EventHook<SearchStopEvent>;
|
|
162
|
+
onActiveResultChange: EventHook<ActiveResultChangeEvent>;
|
|
163
|
+
onSearchResultStateChange: EventHook<SearchResultStateEvent>;
|
|
164
|
+
onStateChange: EventHook<SearchStateEvent>;
|
|
152
165
|
}
|
package/dist/preact/adapter.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export { Fragment } from 'preact';
|
|
2
|
-
export { useEffect, useRef, useState } from 'preact/hooks';
|
|
2
|
+
export { useEffect, useRef, useState, useMemo } from 'preact/hooks';
|
|
3
3
|
export type { ComponentChildren as ReactNode } from 'preact';
|
|
4
4
|
export type CSSProperties = import('preact').JSX.CSSProperties;
|
|
5
5
|
export type HTMLAttributes<T = any> = import('preact').JSX.HTMLAttributes<T extends EventTarget ? T : never>;
|
package/dist/preact/index.cjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("@embedpdf/core/preact"),t=require("@embedpdf/plugin-search");require("preact");const r=require("preact/hooks"),i=require("preact/jsx-runtime"),s=()=>e.useCapability(t.SearchPlugin.id);exports.SearchLayer=function({pageIndex:
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("@embedpdf/core/preact"),t=require("@embedpdf/plugin-search");require("preact");const r=require("preact/hooks"),i=require("preact/jsx-runtime"),s=()=>e.useCapability(t.SearchPlugin.id);exports.SearchLayer=function({documentId:t,pageIndex:o,scale:l,style:n,highlightColor:a="#FFFF00",activeHighlightColor:u="#FFBF00",...c}){const{provides:d}=s(),[p,h]=r.useState(null),g=e.useDocumentState(t),f=r.useMemo(()=>null==d?void 0:d.forDocument(t),[d,t]),m=r.useMemo(()=>void 0!==l?l:(null==g?void 0:g.scale)??1,[l,null==g?void 0:g.scale]);if(r.useEffect(()=>{if(!f)return void h(null);const e=f.getState();return h({results:e.results,activeResultIndex:e.activeResultIndex,showAllResults:e.showAllResults,active:e.active}),f.onSearchResultStateChange(e=>{h(e)})},[f]),!p||!p.active)return null;const v=p.results.map((e,t)=>({result:e,originalIndex:t})).filter(({result:e})=>e.pageIndex===o).filter(({originalIndex:e})=>p.showAllResults||e===p.activeResultIndex);return i.jsx("div",{style:{...n,pointerEvents:"none"},...c,children:v.map(({result:e,originalIndex:t})=>e.rects.map((e,r)=>i.jsx("div",{style:{position:"absolute",top:e.origin.y*m,left:e.origin.x*m,width:e.size.width*m,height:e.size.height*m,backgroundColor:t===p.activeResultIndex?u:a,mixBlendMode:"multiply",transform:"scale(1.02)",transformOrigin:"center",transition:"opacity .3s ease-in-out",opacity:1}},`${t}-${r}`)))})},exports.useSearch=e=>{const{provides:i}=s(),[o,l]=r.useState(t.initialSearchDocumentState),n=r.useMemo(()=>null==i?void 0:i.forDocument(e),[i,e]);return r.useEffect(()=>{if(n)return l(n.getState()),n.onStateChange(e=>l(e));l(t.initialSearchDocumentState)},[n]),{state:o,provides:n??null}},exports.useSearchCapability=s,exports.useSearchPlugin=()=>e.usePlugin(t.SearchPlugin.id),Object.keys(t).forEach(e=>{"default"===e||Object.prototype.hasOwnProperty.call(exports,e)||Object.defineProperty(exports,e,{enumerable:!0,get:()=>t[e]})});
|
|
2
2
|
//# sourceMappingURL=index.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","sources":["../../src/shared/hooks/use-search.ts","../../src/shared/components/search-layer.tsx"],"sourcesContent":["import { useCapability, usePlugin } from '@embedpdf/core/@framework';\nimport {
|
|
1
|
+
{"version":3,"file":"index.cjs","sources":["../../src/shared/hooks/use-search.ts","../../src/shared/components/search-layer.tsx"],"sourcesContent":["import { useCapability, usePlugin } from '@embedpdf/core/@framework';\nimport {\n SearchPlugin,\n SearchDocumentState,\n SearchScope,\n initialSearchDocumentState,\n} from '@embedpdf/plugin-search';\nimport { useEffect, useMemo, useState } from '@framework';\n\nexport const useSearchPlugin = () => usePlugin<SearchPlugin>(SearchPlugin.id);\nexport const useSearchCapability = () => useCapability<SearchPlugin>(SearchPlugin.id);\n\nexport const useSearch = (\n documentId: string,\n): {\n state: SearchDocumentState;\n provides: SearchScope | null;\n} => {\n const { provides } = useSearchCapability();\n const [searchState, setSearchState] = useState<SearchDocumentState>(initialSearchDocumentState);\n\n const scope = useMemo(() => provides?.forDocument(documentId), [provides, documentId]);\n\n useEffect(() => {\n if (!scope) {\n setSearchState(initialSearchDocumentState);\n return;\n }\n // Set initial state\n setSearchState(scope.getState());\n // Subscribe to changes\n return scope.onStateChange((state) => setSearchState(state));\n }, [scope]);\n\n return {\n state: searchState,\n provides: scope ?? null,\n };\n};\n","import { useEffect, useMemo, useState, HTMLAttributes, CSSProperties } from '@framework';\nimport { useDocumentState } from '@embedpdf/core/@framework';\nimport { SearchResultState } from '@embedpdf/plugin-search';\n\nimport { useSearchCapability } from '../hooks';\n\ntype SearchLayoutProps = Omit<HTMLAttributes<HTMLDivElement>, 'style'> & {\n documentId: string;\n pageIndex: number;\n scale?: number;\n highlightColor?: string;\n activeHighlightColor?: string;\n style?: CSSProperties;\n};\n\nexport function SearchLayer({\n documentId,\n pageIndex,\n scale: scaleOverride,\n style,\n highlightColor = '#FFFF00',\n activeHighlightColor = '#FFBF00',\n ...props\n}: SearchLayoutProps) {\n const { provides: searchProvides } = useSearchCapability();\n const [searchResultState, setSearchResultState] = useState<SearchResultState | null>(null);\n const documentState = useDocumentState(documentId);\n\n const scope = useMemo(\n () => searchProvides?.forDocument(documentId),\n [searchProvides, documentId],\n );\n\n const actualScale = useMemo(() => {\n if (scaleOverride !== undefined) return scaleOverride;\n return documentState?.scale ?? 1;\n }, [scaleOverride, documentState?.scale]);\n\n useEffect(() => {\n if (!scope) {\n setSearchResultState(null);\n return;\n }\n // Set initial state\n const currentState = scope.getState();\n setSearchResultState({\n results: currentState.results,\n activeResultIndex: currentState.activeResultIndex,\n showAllResults: currentState.showAllResults,\n active: currentState.active,\n });\n // Subscribe to changes\n return scope.onSearchResultStateChange((state) => {\n setSearchResultState(state);\n });\n }, [scope]);\n\n if (!searchResultState || !searchResultState.active) {\n return null;\n }\n\n // Filter results for current page while preserving original indices\n const pageResults = searchResultState.results\n .map((result, originalIndex) => ({ result, originalIndex }))\n .filter(({ result }) => result.pageIndex === pageIndex);\n\n // Decide which results to show\n const resultsToShow = pageResults.filter(\n ({ originalIndex }) =>\n searchResultState.showAllResults || originalIndex === searchResultState.activeResultIndex,\n );\n\n return (\n <div\n style={{\n ...style,\n pointerEvents: 'none',\n }}\n {...props}\n >\n {resultsToShow.map(({ result, originalIndex }) =>\n result.rects.map((rect, rectIndex) => (\n <div\n key={`${originalIndex}-${rectIndex}`}\n style={{\n position: 'absolute',\n top: rect.origin.y * actualScale,\n left: rect.origin.x * actualScale,\n width: rect.size.width * actualScale,\n height: rect.size.height * actualScale,\n backgroundColor:\n originalIndex === searchResultState.activeResultIndex\n ? activeHighlightColor\n : highlightColor,\n mixBlendMode: 'multiply',\n transform: 'scale(1.02)',\n transformOrigin: 'center',\n transition: 'opacity .3s ease-in-out',\n opacity: 1,\n }}\n ></div>\n )),\n )}\n </div>\n );\n}\n"],"names":["useSearchCapability","useCapability","SearchPlugin","id","documentId","pageIndex","scale","scaleOverride","style","highlightColor","activeHighlightColor","props","provides","searchProvides","searchResultState","setSearchResultState","useState","documentState","useDocumentState","scope","useMemo","forDocument","actualScale","useEffect","currentState","getState","results","activeResultIndex","showAllResults","active","onSearchResultStateChange","state","resultsToShow","map","result","originalIndex","filter","jsx","pointerEvents","children","rects","rect","rectIndex","position","top","origin","y","left","x","width","size","height","backgroundColor","mixBlendMode","transform","transformOrigin","transition","opacity","searchState","setSearchState","initialSearchDocumentState","onStateChange","usePlugin"],"mappings":"gPAUaA,EAAsB,IAAMC,gBAA4BC,EAAAA,aAAaC,wBCK3E,UAAqBC,WAC1BA,EAAAC,UACAA,EACAC,MAAOC,EAAAC,MACPA,EAAAC,eACAA,EAAiB,UAAAC,qBACjBA,EAAuB,aACpBC,IAEH,MAAQC,SAAUC,GAAmBb,KAC9Bc,EAAmBC,GAAwBC,EAAAA,SAAmC,MAC/EC,EAAgBC,EAAAA,iBAAiBd,GAEjCe,EAAQC,EAAAA,QACZ,UAAMP,WAAgBQ,YAAYjB,GAClC,CAACS,EAAgBT,IAGbkB,EAAcF,EAAAA,QAAQ,SACJ,IAAlBb,EAAoCA,SACjCU,WAAeX,QAAS,EAC9B,CAACC,EAAe,MAAAU,OAAA,EAAAA,EAAeX,QAqBlC,GAnBAiB,EAAAA,UAAU,KACR,IAAKJ,EAEH,YADAJ,EAAqB,MAIvB,MAAMS,EAAeL,EAAMM,WAQ3B,OAPAV,EAAqB,CACnBW,QAASF,EAAaE,QACtBC,kBAAmBH,EAAaG,kBAChCC,eAAgBJ,EAAaI,eAC7BC,OAAQL,EAAaK,SAGhBV,EAAMW,0BAA2BC,IACtChB,EAAqBgB,MAEtB,CAACZ,KAECL,IAAsBA,EAAkBe,OAC3C,OAAO,KAIT,MAKMG,EALclB,EAAkBY,QACnCO,IAAI,CAACC,EAAQC,MAAqBD,SAAQC,mBAC1CC,OAAO,EAAGF,YAAaA,EAAO7B,YAAcA,GAGb+B,OAChC,EAAGD,mBACDrB,EAAkBc,gBAAkBO,IAAkBrB,EAAkBa,mBAG5E,OACEU,EAAAA,IAAC,MAAA,CACC7B,MAAO,IACFA,EACH8B,cAAe,WAEb3B,EAEH4B,SAAAP,EAAcC,IAAI,EAAGC,SAAQC,mBAC5BD,EAAOM,MAAMP,IAAI,CAACQ,EAAMC,IACtBL,EAAAA,IAAC,MAAA,CAEC7B,MAAO,CACLmC,SAAU,WACVC,IAAKH,EAAKI,OAAOC,EAAIxB,EACrByB,KAAMN,EAAKI,OAAOG,EAAI1B,EACtB2B,MAAOR,EAAKS,KAAKD,MAAQ3B,EACzB6B,OAAQV,EAAKS,KAAKC,OAAS7B,EAC3B8B,gBACEjB,IAAkBrB,EAAkBa,kBAChCjB,EACAD,EACN4C,aAAc,WACdC,UAAW,cACXC,gBAAiB,SACjBC,WAAY,0BACZC,QAAS,IAfN,GAAGtB,KAAiBO,QAsBrC,oBD5FEtC,IAKA,MAAMQ,SAAEA,GAAaZ,KACd0D,EAAaC,GAAkB3C,EAAAA,SAA8B4C,EAAAA,4BAE9DzC,EAAQC,UAAQ,IAAM,MAAAR,OAAA,EAAAA,EAAUS,YAAYjB,GAAa,CAACQ,EAAUR,IAa1E,OAXAmB,EAAAA,UAAU,KACR,GAAKJ,EAOL,OAFAwC,EAAexC,EAAMM,YAEdN,EAAM0C,cAAe9B,GAAU4B,EAAe5B,IANnD4B,EAAeC,EAAAA,6BAOhB,CAACzC,IAEG,CACLY,MAAO2B,EACP9C,SAAUO,GAAS,6DA3BQ,IAAM2C,YAAwB5D,EAAAA,aAAaC"}
|