@cloro-dev/response-parser 0.1.6 → 0.3.1

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.
Files changed (76) hide show
  1. package/README.md +148 -117
  2. package/dist/core/parser.d.ts.map +1 -1
  3. package/dist/core/types.d.ts +16 -1
  4. package/dist/core/types.d.ts.map +1 -1
  5. package/dist/index.d.ts +23 -4
  6. package/dist/index.d.ts.map +1 -1
  7. package/dist/index.esm.js +1 -1
  8. package/dist/index.esm.js.map +1 -1
  9. package/dist/index.js +1 -1
  10. package/dist/index.js.map +1 -1
  11. package/dist/providers/ai-mode.d.ts.map +1 -1
  12. package/dist/providers/ai-overview.d.ts.map +1 -1
  13. package/dist/providers/base-provider.d.ts +4 -0
  14. package/dist/providers/base-provider.d.ts.map +1 -1
  15. package/dist/providers/chatgpt.d.ts +4 -0
  16. package/dist/providers/chatgpt.d.ts.map +1 -1
  17. package/dist/providers/copilot.d.ts.map +1 -1
  18. package/dist/providers/gemini.d.ts.map +1 -1
  19. package/dist/providers/grok.d.ts +2 -2
  20. package/dist/providers/grok.d.ts.map +1 -1
  21. package/dist/providers/perplexity.d.ts.map +1 -1
  22. package/package.json +4 -29
  23. package/dist/react/components/AiResponseRenderer.d.ts +0 -24
  24. package/dist/react/components/AiResponseRenderer.d.ts.map +0 -1
  25. package/dist/react/components/IframeRenderer.d.ts +0 -12
  26. package/dist/react/components/IframeRenderer.d.ts.map +0 -1
  27. package/dist/react/components/ResponseRenderer.d.ts +0 -24
  28. package/dist/react/components/ResponseRenderer.d.ts.map +0 -1
  29. package/dist/react/core/detector.d.ts +0 -17
  30. package/dist/react/core/detector.d.ts.map +0 -1
  31. package/dist/react/core/parser.d.ts +0 -40
  32. package/dist/react/core/parser.d.ts.map +0 -1
  33. package/dist/react/core/types.d.ts +0 -34
  34. package/dist/react/core/types.d.ts.map +0 -1
  35. package/dist/react/hooks/useAiResponse.d.ts +0 -19
  36. package/dist/react/hooks/useAiResponse.d.ts.map +0 -1
  37. package/dist/react/hooks/useResponse.d.ts +0 -19
  38. package/dist/react/hooks/useResponse.d.ts.map +0 -1
  39. package/dist/react/index.d.ts +0 -86
  40. package/dist/react/index.d.ts.map +0 -1
  41. package/dist/react/index.esm.js +0 -2
  42. package/dist/react/index.esm.js.map +0 -1
  43. package/dist/react/index.js +0 -2
  44. package/dist/react/index.js.map +0 -1
  45. package/dist/react/providers/ai-mode.d.ts +0 -21
  46. package/dist/react/providers/ai-mode.d.ts.map +0 -1
  47. package/dist/react/providers/ai-overview.d.ts +0 -21
  48. package/dist/react/providers/ai-overview.d.ts.map +0 -1
  49. package/dist/react/providers/base-provider.d.ts +0 -34
  50. package/dist/react/providers/base-provider.d.ts.map +0 -1
  51. package/dist/react/providers/chatgpt.d.ts +0 -22
  52. package/dist/react/providers/chatgpt.d.ts.map +0 -1
  53. package/dist/react/providers/copilot.d.ts +0 -25
  54. package/dist/react/providers/copilot.d.ts.map +0 -1
  55. package/dist/react/providers/gemini.d.ts +0 -21
  56. package/dist/react/providers/gemini.d.ts.map +0 -1
  57. package/dist/react/providers/grok.d.ts +0 -17
  58. package/dist/react/providers/grok.d.ts.map +0 -1
  59. package/dist/react/providers/perplexity.d.ts +0 -17
  60. package/dist/react/providers/perplexity.d.ts.map +0 -1
  61. package/dist/react/react/components/AiResponseRenderer.d.ts +0 -24
  62. package/dist/react/react/components/AiResponseRenderer.d.ts.map +0 -1
  63. package/dist/react/react/components/IframeRenderer.d.ts +0 -12
  64. package/dist/react/react/components/IframeRenderer.d.ts.map +0 -1
  65. package/dist/react/react/components/ResponseRenderer.d.ts +0 -24
  66. package/dist/react/react/components/ResponseRenderer.d.ts.map +0 -1
  67. package/dist/react/react/hooks/useAiResponse.d.ts +0 -19
  68. package/dist/react/react/hooks/useAiResponse.d.ts.map +0 -1
  69. package/dist/react/react/hooks/useResponse.d.ts +0 -19
  70. package/dist/react/react/hooks/useResponse.d.ts.map +0 -1
  71. package/dist/react/react/index.d.ts +0 -7
  72. package/dist/react/react/index.d.ts.map +0 -1
  73. package/dist/react/styles/index.d.ts +0 -1
  74. package/dist/react/styles/index.d.ts.map +0 -1
  75. package/dist/react/utils/helpers.d.ts +0 -28
  76. package/dist/react/utils/helpers.d.ts.map +0 -1
package/README.md CHANGED
@@ -1,14 +1,16 @@
1
1
  # @cloro-dev/response-parser
2
2
 
3
- A powerful TypeScript library for parsing and rendering AI model responses from ChatGPT, Gemini, Perplexity, Copilot, and Google AI Overview/Mode.
3
+ A powerful TypeScript library for parsing AI model responses from ChatGPT, Gemini, Perplexity, Copilot, and Google AI Overview/Mode.
4
+
5
+ > **Framework-Agnostic**: This library returns HTML strings that can be rendered in any framework (React, Vue, Svelte, vanilla JS, etc.).
4
6
 
5
7
  ## Features
6
8
 
7
- - 🤖 **Multi-Provider Support**: ChatGPT, Gemini, Perplexity, Copilot, AI Overview, AI Mode
9
+ - 🤖 **Multi-Provider Support**: ChatGPT, Gemini, Perplexity, Copilot, AI Overview, AI Mode, Grok
8
10
  - 🔍 **Auto-Detection**: Automatically detects the AI provider from response structure
9
- - 🎨 **Built-in Styling**: Provider-specific styling with dark mode support
10
- - ⚡ **React Components**: Ready-to-use React components for rendering
11
- - 🔒 **Secure**: Sandboxed rendering with automatic script sanitization
11
+ - 🎨 **Built-in Styling**: Provider-specific styling
12
+ - 🔧 **Framework-Agnostic**: Pure HTML output for any framework
13
+ - 🔒 **Secure**: Automatic script sanitization
12
14
  - 📦 **TypeScript**: Full TypeScript support with comprehensive types
13
15
  - 🎯 **Lightweight**: No runtime dependencies for core parsing
14
16
 
@@ -24,7 +26,7 @@ pnpm add @cloro-dev/response-parser
24
26
 
25
27
  ## Quick Start
26
28
 
27
- ### Basic Parsing
29
+ This library parses AI responses and returns sanitized HTML strings. You can render the HTML in any framework:
28
30
 
29
31
  ```typescript
30
32
  import { parseAiResponse, detectProvider } from "@cloro-dev/response-parser";
@@ -38,177 +40,205 @@ console.log(parsed.html); // Sanitized HTML ready for rendering
38
40
  console.log(parsed.text); // Plain text version
39
41
  ```
40
42
 
41
- ### React Component
43
+ ## Usage Examples
44
+
45
+ ### React
42
46
 
43
47
  ```tsx
44
- import { ResponseRenderer } from "@cloro-dev/response-parser/react";
48
+ import { parseAiResponse } from "@cloro-dev/response-parser";
45
49
 
46
50
  function MyComponent() {
47
- const [aiResponse, setAiResponse] = useState(null);
51
+ const parsed = parseAiResponse(aiResponse, {
52
+ removeLinks: true
53
+ });
48
54
 
49
55
  return (
50
- <ResponseRenderer
51
- response={aiResponse}
52
- removeLinks={false}
53
- invertColors={false}
54
- autoDetect
55
- className="w-full h-96"
56
- iframeProps={{
57
- sandbox: "allow-popups",
58
- }}
59
- onProviderDetected={(provider) => console.log("Detected:", provider)}
60
- />
56
+ <div dangerouslySetInnerHTML={{ __html: parsed.html }} />
61
57
  );
62
58
  }
63
59
  ```
64
60
 
65
- ## API Reference
61
+ ### Vue
62
+
63
+ ```vue
64
+ <script setup>
65
+ import { parseAiResponse } from "@cloro-dev/response-parser";
66
+
67
+ const parsed = parseAiResponse(aiResponse, {
68
+ removeLinks: true
69
+ });
70
+ </script>
71
+
72
+ <template>
73
+ <div v-html="parsed.html"></div>
74
+ </template>
75
+ ```
76
+
77
+ ### Svelte
78
+
79
+ ```svelte
80
+ <script>
81
+ import { parseAiResponse } from "@cloro-dev/response-parser";
82
+
83
+ const parsed = parseAiResponse(aiResponse, {
84
+ removeLinks: true
85
+ });
86
+ </script>
87
+
88
+ <div>{@html parsed.html}</div>
89
+ ```
90
+
91
+ ### Vanilla JavaScript
92
+
93
+ ```javascript
94
+ import { parseAiResponse } from "@cloro-dev/response-parser";
66
95
 
67
- ### Core Functions
96
+ const parsed = parseAiResponse(aiResponse, {
97
+ removeLinks: true
98
+ });
99
+
100
+ document.getElementById('output').innerHTML = parsed.html;
101
+ ```
68
102
 
69
- #### `parseAiResponse(response, options?)`
103
+ ## API Reference
104
+
105
+ ### `parseAiResponse(response, options?)`
70
106
 
71
107
  Parse an AI response with auto-detected provider.
72
108
 
73
109
  **Options:**
74
110
 
75
111
  - `removeLinks`: `boolean` - Remove all hyperlinks from HTML (default: `false`)
76
- - `invertColors`: `boolean` - Apply color inversion for dark mode (default: `false`)
77
112
  - `removeHeader`: `boolean` - Remove navigation bar/header (default: `false`, Perplexity, Gemini, Copilot, AI Overview & AI Mode)
78
113
  - `removeFooter`: `boolean` - Remove follow-up input box/footer (default: `false`, ChatGPT, Perplexity, Gemini, Copilot, AI Overview & AI Mode)
79
114
  - `removeSidebar`: `boolean` - Remove sidebar (default: `false`, ChatGPT, Gemini & Copilot)
80
115
 
81
116
  **Returns:** `ParsedResponse | null`
82
117
 
83
- #### `detectProvider(response)`
118
+ ```typescript
119
+ interface ParsedResponse {
120
+ provider: AIProvider;
121
+ html: string;
122
+ text: string;
123
+ sources?: Array<{
124
+ title: string;
125
+ url: string;
126
+ snippet?: string;
127
+ }>;
128
+ }
129
+ ```
130
+
131
+ ### `detectProvider(response)`
84
132
 
85
133
  Detect the AI provider from a response.
86
134
 
87
135
  **Returns:** `AIProvider | null`
88
136
 
89
- ### React Components
90
-
91
- #### `<ResponseRenderer />`
92
-
93
- Main React component for rendering AI responses.
94
-
95
- **Props:**
96
-
97
- - `response`: The AI response object
98
- - `autoDetect`: Auto-detect provider (default: `true`)
99
- - `provider`: Explicitly specify provider
100
- - `removeLinks`: Remove all hyperlinks (default: `false`)
101
- - `invertColors`: Apply color inversion (default: `false`)
102
- - `removeHeader`: Remove navigation bar/header (default: `false`, Perplexity, Gemini, Copilot, AI Overview & AI Mode)
103
- - `removeFooter`: Remove follow-up input box/footer (default: `false`, ChatGPT, Perplexity, Gemini, Copilot, AI Overview & AI Mode)
104
- - `removeSidebar`: Remove sidebar (default: `false`, ChatGPT, Gemini & Copilot)
105
- - `className`: CSS class for container
106
- - `iframeProps`: Additional props for iframe
107
- - `loadingComponent`: Custom loading component
108
- - `errorComponent`: Custom error component
109
- - `fallbackComponent`: Custom fallback component
110
- - `onRenderComplete`: Callback when rendering completes
111
- - `onProviderDetected`: Callback when provider is detected
137
+ ```typescript
138
+ type AIProvider =
139
+ | 'CHATGPT'
140
+ | 'GEMINI'
141
+ | 'PERPLEXITY'
142
+ | 'COPILOT'
143
+ | 'AI_OVERVIEW'
144
+ | 'AI_MODE'
145
+ | 'GROK';
146
+ ```
112
147
 
113
- ### Hooks
148
+ ## Supported Providers
114
149
 
115
- #### `useResponse(response, options?)`
150
+ | Provider | Status | Features |
151
+ | ----------- | ------ | ---------------------------------------- |
152
+ | ChatGPT | ✅ | Sidebar hiding |
153
+ | Gemini | ✅ | Navbar removal |
154
+ | Perplexity | ✅ | Link removal, UI element removal |
155
+ | Copilot | ✅ | UI element hiding |
156
+ | AI Overview | ✅ | WIZ data extraction |
157
+ | AI Mode | ✅ | Google UI hiding |
158
+ | Grok | ✅ | UI element removal |
116
159
 
117
- React hook for parsing AI responses.
160
+ ## Common Use Cases
118
161
 
119
- **Options:**
162
+ ### Remove Hyperlinks
120
163
 
121
- - `autoDetect`: Auto-detect provider (default: `true`)
122
- - `provider`: Explicitly specify provider
123
- - `removeLinks`: Remove all hyperlinks (default: `false`)
124
- - `invertColors`: Apply color inversion (default: `false`)
125
- - `removeHeader`: Remove navigation bar/header (default: `false`, Perplexity, Gemini, Copilot, AI Overview & AI Mode)
126
- - `removeFooter`: Remove follow-up input box/footer (default: `false`, ChatGPT, Perplexity, Gemini, Copilot, AI Overview & AI Mode)
127
- - `removeSidebar`: Remove sidebar (default: `false`, ChatGPT, Gemini & Copilot)
128
- - `onProviderDetected`: Callback when provider is detected
129
- - `onError`: Callback when error occurs
130
-
131
- **Returns:**
132
-
133
- - `parsed`: Parsed response object
134
- - `provider`: Detected provider
135
- - `isLoading`: Loading state
136
- - `error`: Error object
137
- - `html`: HTML string
138
- - `text`: Plain text string
139
- - `sources`: Sources array (if available)
140
- - `reparse`: Function to re-parse with new options
164
+ ```typescript
165
+ import { parseAiResponse } from "@cloro-dev/response-parser";
141
166
 
142
- ## Supported Providers
167
+ const parsed = parseAiResponse(response, {
168
+ removeLinks: true, // Removes all <a> tags, keeps text
169
+ });
170
+ ```
143
171
 
144
- | Provider | Status | Features |
145
- | ----------- | ------ | ------------------------------------------------- |
146
- | ChatGPT | ✅ | Dark mode, sidebar hiding |
147
- | Gemini | ✅ | Material Design overrides, navbar removal |
148
- | Perplexity | ✅ | Color inversion, link removal, UI element removal |
149
- | Copilot | ✅ | UI element hiding |
150
- | AI Overview | ✅ | WIZ data extraction |
151
- | AI Mode | ✅ | Google UI hiding |
172
+ ### Clean View (Remove UI Elements)
152
173
 
153
- ## Examples
174
+ ```typescript
175
+ const parsed = parseAiResponse(response, {
176
+ removeHeader: true, // Remove top navigation bar
177
+ removeFooter: true, // Remove follow-up input box
178
+ removeLinks: true, // Remove all hyperlinks
179
+ });
180
+ ```
154
181
 
155
- ### Remove Hyperlinks
182
+ ### Manual Provider Specification
156
183
 
157
184
  ```typescript
158
- import { parseAiResponse } from "@cloro-dev/response-parser";
185
+ import { parseAiResponse, AIProvider } from "@cloro-dev/response-parser";
159
186
 
160
187
  const parsed = parseAiResponse(response, {
161
- removeLinks: true, // Removes all <a> tags, keeps text
188
+ provider: "CHATGPT",
162
189
  });
163
190
  ```
164
191
 
165
- ### Dark Mode
192
+ ### Provider Detection Only
166
193
 
167
- ```tsx
168
- <ResponseRenderer
169
- response={response}
170
- invertColors={true} // Apply CSS filter for dark mode
171
- removeLinks={true} // Optionally remove links
172
- />
194
+ ```typescript
195
+ import { detectProvider } from "@cloro-dev/response-parser";
196
+
197
+ const provider = detectProvider(response);
198
+ console.log(`Detected: ${provider}`); // 'CHATGPT' | 'GEMINI' | etc.
173
199
  ```
174
200
 
175
- ### Clean View (Remove UI Elements)
201
+ ## Migration from v0.1.x
202
+
203
+ If you were using React components from v0.1.x, here's how to migrate:
204
+
205
+ ### Before (v0.1.x with React)
176
206
 
177
207
  ```tsx
208
+ import { ResponseRenderer } from "@cloro-dev/response-parser/react";
209
+
178
210
  <ResponseRenderer
179
211
  response={response}
180
- removeHeader={true} // Remove top navigation bar
181
- removeFooter={true} // Remove follow-up input box
182
- removeLinks={true} // Remove all hyperlinks
183
- invertColors={true} // Dark mode
212
+ removeLinks={true}
213
+ onProviderDetected={(provider) => console.log("Detected:", provider)}
184
214
  />
185
215
  ```
186
216
 
187
- ### Manual Provider Specification
217
+ ### After (v0.2.0 framework-agnostic)
188
218
 
189
- ```typescript
190
- import { parseAiResponse, AIProvider } from "@cloro-dev/response-parser";
219
+ ```tsx
220
+ import { parseAiResponse } from "@cloro-dev/response-parser";
191
221
 
192
222
  const parsed = parseAiResponse(response, {
193
- provider: "CHATGPT",
223
+ removeLinks: true
194
224
  });
195
- ```
196
225
 
197
- ### Error Handling
226
+ console.log("Detected:", parsed.provider);
198
227
 
199
- ```tsx
200
- const ErrorComponent = ({ error, retry }) => (
201
- <div className="error">
202
- <p>Failed to load: {error.message}</p>
203
- <button onClick={retry}>Retry</button>
204
- </div>
205
- );
206
-
207
- <ResponseRenderer response={response} errorComponent={ErrorComponent} />;
228
+ <div dangerouslySetInnerHTML={{ __html: parsed.html }} />
208
229
  ```
209
230
 
231
+ The core parsing logic is identical - you just need to handle the HTML rendering yourself in your framework of choice.
232
+
210
233
  ## What's Changed
211
234
 
235
+ ### v0.2.0
236
+
237
+ - ✅ **Removed** React components and hooks (now framework-agnostic)
238
+ - ✅ **Removed** React peer dependency
239
+ - ✅ **Simplified** API to return pure HTML strings
240
+ - ✅ **Keep** core parsing logic (unchanged)
241
+
212
242
  ### v0.1.4
213
243
 
214
244
  - ✅ **Renamed** `removeNavbar` → `removeHeader` (removes navigation bar/header)
@@ -228,11 +258,6 @@ const ErrorComponent = ({ error, retry }) => (
228
258
  - ❌ **Removed** `includeStyles` option (always enabled)
229
259
  - ❌ **Removed** `baseUrl` option (uses provider default)
230
260
 
231
- ### Component Renaming
232
-
233
- - `AiResponseRenderer` → `ResponseRenderer`
234
- - `useAiResponse` → `useResponse`
235
-
236
261
  ## Development
237
262
 
238
263
  ```bash
@@ -247,6 +272,12 @@ pnpm test
247
272
 
248
273
  # Development mode
249
274
  pnpm dev
275
+
276
+ # Type check
277
+ pnpm type-check
278
+
279
+ # Lint
280
+ pnpm lint
250
281
  ```
251
282
 
252
283
  ## License
@@ -1 +1 @@
1
- {"version":3,"file":"parser.d.ts","sourceRoot":"","sources":["../../src/core/parser.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAUnE,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,SAAS,CAAmC;;IAYpD;;OAEG;IACH,KAAK,CAAC,QAAQ,EAAE,GAAG,EAAE,OAAO,CAAC,EAAE,YAAY,GAAG,cAAc,GAAG,IAAI;IA4BnE;;OAEG;IACH,iBAAiB,CACf,QAAQ,EAAE,GAAG,EACb,QAAQ,EAAE,UAAU,EACpB,OAAO,CAAC,EAAE,YAAY,GACrB,cAAc,GAAG,IAAI;IAcxB;;OAEG;IACH,cAAc,CAAC,QAAQ,EAAE,GAAG,GAAG,UAAU,GAAG,IAAI;IAKhD;;OAEG;IACH,kBAAkB,CAAC,QAAQ,EAAE,GAAG,GAAG,KAAK,CAAC;QAAE,QAAQ,EAAE,UAAU,CAAC;QAAC,UAAU,EAAE,MAAM,CAAA;KAAE,CAAC;IAItF;;OAEG;IACH,OAAO,CAAC,YAAY;IAuDpB;;OAEG;IACH,qBAAqB,IAAI,UAAU,EAAE;IAIrC;;OAEG;IACH,gBAAgB,CAAC,QAAQ,EAAE,UAAU,EAAE,QAAQ,EAAE,GAAG,GAAG,IAAI;CAG5D;AAGD,eAAO,MAAM,MAAM,kBAAyB,CAAC;AAG7C,eAAO,MAAM,eAAe,GAAI,UAAU,GAAG,EAAE,UAAU,YAAY,0BACpC,CAAC;AAElC,eAAO,MAAM,cAAc,GAAI,UAAU,GAAG,sBACX,CAAC"}
1
+ {"version":3,"file":"parser.d.ts","sourceRoot":"","sources":["../../src/core/parser.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,cAAc,EAAE,YAAY,EAAwB,MAAM,SAAS,CAAC;AAUzF,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,SAAS,CAAmC;;IAYpD;;OAEG;IACH,KAAK,CAAC,QAAQ,EAAE,GAAG,EAAE,OAAO,CAAC,EAAE,YAAY,GAAG,cAAc,GAAG,IAAI;IA4BnE;;OAEG;IACH,iBAAiB,CACf,QAAQ,EAAE,GAAG,EACb,QAAQ,EAAE,UAAU,EACpB,OAAO,CAAC,EAAE,YAAY,GACrB,cAAc,GAAG,IAAI;IAcxB;;OAEG;IACH,cAAc,CAAC,QAAQ,EAAE,GAAG,GAAG,UAAU,GAAG,IAAI;IAKhD;;OAEG;IACH,kBAAkB,CAAC,QAAQ,EAAE,GAAG,GAAG,KAAK,CAAC;QAAE,QAAQ,EAAE,UAAU,CAAC;QAAC,UAAU,EAAE,MAAM,CAAA;KAAE,CAAC;IAItF;;OAEG;IACH,OAAO,CAAC,YAAY;IAwBpB;;OAEG;IACH,qBAAqB,IAAI,UAAU,EAAE;IAIrC;;OAEG;IACH,gBAAgB,CAAC,QAAQ,EAAE,UAAU,EAAE,QAAQ,EAAE,GAAG,GAAG,IAAI;CAG5D;AAGD,eAAO,MAAM,MAAM,kBAAyB,CAAC;AAG7C,eAAO,MAAM,eAAe,GAAI,UAAU,GAAG,EAAE,UAAU,YAAY,0BACpC,CAAC;AAElC,eAAO,MAAM,cAAc,GAAI,UAAU,GAAG,sBACX,CAAC"}
@@ -8,7 +8,6 @@ export interface ParsedResponse {
8
8
  }
9
9
  export interface ParseOptions {
10
10
  removeLinks?: boolean;
11
- invertColors?: boolean;
12
11
  removeHeader?: boolean;
13
12
  removeFooter?: boolean;
14
13
  removeSidebar?: boolean;
@@ -31,4 +30,20 @@ export type ContentExtraction = {
31
30
  text?: string;
32
31
  sources?: any[];
33
32
  };
33
+ /**
34
+ * Standardized metadata for provider responses
35
+ */
36
+ export interface ProviderMetadata {
37
+ isFullDocument?: boolean;
38
+ headerRemoved?: boolean;
39
+ footerRemoved?: boolean;
40
+ sidebarRemoved?: boolean;
41
+ linksRemoved?: boolean;
42
+ cookieBannerRemoved?: boolean;
43
+ detectionConfidence?: number;
44
+ }
45
+ /**
46
+ * Common content extraction utility - shared across providers and parser
47
+ */
48
+ export declare function extractContentCommon(response: any): ContentExtraction;
34
49
  //# sourceMappingURL=types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/core/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,UAAU,GAClB,SAAS,GACT,QAAQ,GACR,YAAY,GACZ,SAAS,GACT,YAAY,GACZ,QAAQ,GACR,MAAM,CAAC;AAEX,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,UAAU,CAAC;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,GAAG,EAAE,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;CAChC;AAED,MAAM,WAAW,YAAY;IAC3B,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,UAAU,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,UAAU,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,YAAY;IAC3B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,MAAM,iBAAiB,GAAG;IAC9B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,GAAG,EAAE,CAAC;CACjB,CAAC"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/core/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,UAAU,GAClB,SAAS,GACT,QAAQ,GACR,YAAY,GACZ,SAAS,GACT,YAAY,GACZ,QAAQ,GACR,MAAM,CAAC;AAEX,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,UAAU,CAAC;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,GAAG,EAAE,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;CAChC;AAED,MAAM,WAAW,YAAY;IAC3B,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,UAAU,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,UAAU,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,YAAY;IAC3B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,MAAM,iBAAiB,GAAG;IAC9B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,GAAG,EAAE,CAAC;CACjB,CAAC;AAEF;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,mBAAmB,CAAC,EAAE,MAAM,CAAC;CAC9B;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,GAAG,GAAG,iBAAiB,CAgCrE"}
package/dist/index.d.ts CHANGED
@@ -8,7 +8,6 @@ interface ParsedResponse {
8
8
  }
9
9
  interface ParseOptions {
10
10
  removeLinks?: boolean;
11
- invertColors?: boolean;
12
11
  removeHeader?: boolean;
13
12
  removeFooter?: boolean;
14
13
  removeSidebar?: boolean;
@@ -31,6 +30,18 @@ type ContentExtraction = {
31
30
  text?: string;
32
31
  sources?: any[];
33
32
  };
33
+ /**
34
+ * Standardized metadata for provider responses
35
+ */
36
+ interface ProviderMetadata {
37
+ isFullDocument?: boolean;
38
+ headerRemoved?: boolean;
39
+ footerRemoved?: boolean;
40
+ sidebarRemoved?: boolean;
41
+ linksRemoved?: boolean;
42
+ cookieBannerRemoved?: boolean;
43
+ detectionConfidence?: number;
44
+ }
34
45
 
35
46
  declare class AIResponseParser {
36
47
  private providers;
@@ -98,6 +109,10 @@ declare abstract class BaseProvider {
98
109
  * Extract content from the response object
99
110
  */
100
111
  abstract extractContent(response: any): ContentExtraction;
112
+ /**
113
+ * Common content extraction logic - can be used by providers
114
+ */
115
+ protected extractContentCommon(response: any, includeSources?: boolean): ContentExtraction;
101
116
  /**
102
117
  * Inject provider-specific styles into HTML
103
118
  */
@@ -129,6 +144,10 @@ declare class ChatGPTProvider extends BaseProvider {
129
144
  * Converts <a> tags to <span> while keeping class attributes
130
145
  */
131
146
  removeLinks(html: string): string;
147
+ /**
148
+ * Remove ChatGPT header from HTML
149
+ */
150
+ removeHeader(html: string): string;
132
151
  /**
133
152
  * Remove ChatGPT sidebar from HTML
134
153
  */
@@ -240,15 +259,15 @@ declare class GrokProvider extends BaseProvider {
240
259
  readonly baseUrl = "https://grok.com";
241
260
  extractContent(response: any): ContentExtraction;
242
261
  /**
243
- * Remove Grok header from HTML
262
+ * Remove Grok header from HTML (using CSS-based hiding)
244
263
  */
245
264
  removeHeader(html: string): string;
246
265
  /**
247
- * Remove Grok footer/input area from HTML
266
+ * Remove Grok footer/input area from HTML (using CSS-based hiding)
248
267
  */
249
268
  removeFooter(html: string): string;
250
269
  parse(response: any, options?: ParseOptions): ParsedResponse;
251
270
  }
252
271
 
253
272
  export { AIModeProvider, AIOverviewProvider, AIResponseParser, BaseProvider, ChatGPTProvider, CopilotProvider, GeminiProvider, GrokProvider, PerplexityProvider, ProviderDetector, detectProvider, parseAiResponse, parser };
254
- export type { AIProvider, ContentExtraction, DetectedProvider, ParseOptions, ParsedResponse, ProviderConfig, StyleOptions };
273
+ export type { AIProvider, ContentExtraction, DetectedProvider, ParseOptions, ParsedResponse, ProviderConfig, ProviderMetadata, StyleOptions };
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,gBAAgB,EAAE,MAAM,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAC1F,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAGnD,YAAY,EACV,UAAU,EACV,cAAc,EACd,YAAY,EACZ,cAAc,EACd,gBAAgB,EAChB,YAAY,EACZ,iBAAiB,GAClB,MAAM,cAAc,CAAC;AAGtB,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AACzD,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AACtD,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACpD,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAC5D,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AACtD,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,gBAAgB,EAAE,MAAM,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAC1F,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAGnD,YAAY,EACV,UAAU,EACV,cAAc,EACd,YAAY,EACZ,cAAc,EACd,gBAAgB,EAChB,YAAY,EACZ,iBAAiB,EACjB,gBAAgB,GACjB,MAAM,cAAc,CAAC;AAGtB,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AACzD,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AACtD,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACpD,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAC5D,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AACtD,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC"}
package/dist/index.esm.js CHANGED
@@ -1,2 +1,2 @@
1
- class e{static detect(e){const t={CHATGPT:0,GEMINI:0,PERPLEXITY:0,COPILOT:0,AIOVERVIEW:0,AIMODE:0,GROK:0};for(const[r,n]of Object.entries(this.PROVIDER_PATTERNS))for(const o of n)try{o(e)&&t[r]++}catch(e){}let r=0,n=null;for(const[e,o]of Object.entries(t))o>r&&(r=o,n=e);return 0===r?null:{provider:n,confidence:r/Object.values(t).reduce((e,t)=>Math.max(e,t),1)}}static getAllProviders(e){const t=[];for(const[r,n]of Object.entries(this.PROVIDER_PATTERNS)){let o=0;for(const t of n)try{t(e)&&o++}catch(e){}o>0&&t.push({provider:r,confidence:o/n.length})}return t.sort((e,t)=>t.confidence-e.confidence)}static validate(e,t){const r=this.detect(e);return(null==r?void 0:r.provider)===t&&r.confidence>.5}}e.PROVIDER_PATTERNS={CHATGPT:[e=>{var t;const r=(null===(t=null==e?void 0:e.result)||void 0===t?void 0:t.html)||(null==e?void 0:e.html)||"";return r.includes("bg-token-bg-primary")||r.includes("text-token-text-secondary")},e=>{var t;const r=(null===(t=null==e?void 0:e.result)||void 0===t?void 0:t.html)||(null==e?void 0:e.html)||"";return r.includes("chatgpt.com")||r.includes("openai.com")}],GEMINI:[e=>{var t;const r=(null===(t=null==e?void 0:e.result)||void 0===t?void 0:t.html)||(null==e?void 0:e.html)||"";return r.includes("bard-sidenav")||r.includes("mat-sidenav")},e=>{var t;const r=(null===(t=null==e?void 0:e.result)||void 0===t?void 0:t.html)||(null==e?void 0:e.html)||"";return r.includes("gemini.google.com")||r.includes("gem-sys-color")}],PERPLEXITY:[e=>{var t;const r=(null===(t=null==e?void 0:e.result)||void 0===t?void 0:t.html)||(null==e?void 0:e.html)||"";return r.includes("perplexity.ai")||r.includes("prose")}],COPILOT:[e=>{var t;const r=(null===(t=null==e?void 0:e.result)||void 0===t?void 0:t.html)||(null==e?void 0:e.html)||"";return r.includes("copilot.microsoft.com")||r.includes('data-testid="sidebar-container"')}],AIOVERVIEW:[e=>{var t,r,n,o;if(null===(r=null===(t=null==e?void 0:e.result)||void 0===t?void 0:t.aioverview)||void 0===r?void 0:r.text)return!0;if(null===(n=null==e?void 0:e.aioverview)||void 0===n?void 0:n.text)return!0;const a=(null===(o=null==e?void 0:e.result)||void 0===o?void 0:o.html)||(null==e?void 0:e.html)||"";return a.includes("WIZ_global_data")||a.includes("DnVkpd")}],AIMODE:[e=>{var t;const r=(null===(t=null==e?void 0:e.result)||void 0===t?void 0:t.html)||(null==e?void 0:e.html)||"";return r.includes("DZ13He")||r.includes("wYq63b")||r.includes("AI Mode")}],GROK:[e=>{var t;const r=(null===(t=null==e?void 0:e.result)||void 0===t?void 0:t.html)||(null==e?void 0:e.html)||"";return r.includes("grok.com")||r.includes("x.ai")}]};class t{injectStyles(e,t){let r=e;(null==t?void 0:t.baseUrl)&&!e.includes("<base ")&&(r=r.includes("<head>")?r.replace("<head>",`<head><base href="${t.baseUrl}">`):r.replace(/(<html[^>]*>)/i,`$1<head><base href="${t.baseUrl}"></head>`));const n=(null==t?void 0:t.customCSS)||"";return n&&r.includes("<head>")?r=r.replace("<head>",`<head><style>${n}</style>`):n&&(r=r.replace(/(<html[^>]*>)/i,`$1<head><style>${n}</style></head>`)),r}sanitizeHtml(e){let t=e.replace(/<script\b[^>]*>[\s\S]*?<\/script>/gim,"");return t=t.replace(/<noscript[\s\S]*?<\/noscript>/gi,""),t}isFullDocument(e){return/^\s*(<html|<!DOCTYPE)/i.test(e)}removeLinks(e){return e.replace(/<a\b[^>]*>([\s\S]*?)<\/a>/gim,"$1")}wrapFragment(e){return`<!DOCTYPE html>\n<html>\n<head>\n <meta charset="utf-8">\n <meta http-equiv="Content-Security-Policy" content="default-src 'none'; script-src 'none'; style-src 'unsafe-inline';">\n <style>\n body {\n margin: 0;\n padding: 16px;\n font-family: system-ui, -apple-system, sans-serif;\n white-space: pre-wrap;\n word-wrap: break-word;\n }\n img { max-width: 100%; height: auto; }\n body {\n pointer-events: none;\n user-select: none;\n }\n </style>\n</head>\n<body>\n ${e}\n</body>\n</html>`}}class r extends t{constructor(){super(...arguments),this.name="CHATGPT",this.baseUrl="https://chatgpt.com"}extractContent(e){let t="",r="",n=e;return e.result&&(n=e.result),"string"==typeof n?n.trim().startsWith("<")&&n.includes(">")?t=n:r=n:"object"==typeof n&&null!==n&&(n.html?t=n.html:n.content?n.content.trim().startsWith("<")?t=n.content:r=n.content:n.text&&(r=n.text)),{html:t,text:r}}removeLinks(e){return e.replace(/<a\b([^>]*)>/gi,(e,t)=>{const r=t.replace(/\s+href\s*=\s*["'][^"']*["']/gi,"").replace(/\s+alt\s*=\s*["'][^"']*["']/gi,"").replace(/\s+rel\s*=\s*["'][^"']*["']/gi,"").replace(/\s+target\s*=\s*["'][^"']*["']/gi,"").trim();return`<span${r?" "+r:""}>`}).replace(/<\/a>/gi,"</span>")}removeSidebar(e){let t=e;return t=t.replace(/<nav[^>]*>.*?<\/nav>/gis,""),t=t.replace(/<div[^>]*class="[^"]*sidebar[^"]*"[^>]*>.*?<\/div>/gis,""),t}removeFooter(e){let t=e;return t=t.replace(/<div[^>]*id="thread-bottom-container"[^>]*>.*?<\/div><\/div><\/div>/gis,""),t=t.replace(/<div[^>]*id="thread-bottom"[^>]*>.*?<\/div><\/div><\/div><\/div><\/div>/gis,""),t=t.replace(/<div[^>]*class="[^"]*\[grid-area:leading\][^"]*"[^>]*>.*?<\/div><\/div><\/div>/gis,""),t=t.replace(/<div[^>]*class="[^"]*\[grid-area:footer\][^"]*"[^>]*>.*?<\/div><\/div><\/div><\/div><\/div>/gis,""),t=t.replace(/<div[^>]*class="[^"]*\[grid-area:trailing\][^"]*"[^>]*>.*?<\/div><\/div><\/div>/gis,""),t=t.replace(/<div[^>]*\[view-transition-name:var\(--vt-disclaimer\)\][^>]*>.*?<\/div><\/div>/gis,""),t}parse(e,t){var r;const{html:n,text:o}=this.extractContent(e);if(!n)throw new Error("No HTML content found in ChatGPT response");let a=n;const i=null!==(r=null==t?void 0:t.removeFooter)&&void 0!==r&&r;a=this.sanitizeHtml(a),(null==t?void 0:t.removeSidebar)&&(a=this.removeSidebar(a)),i&&(a=this.removeFooter(a)),(null==t?void 0:t.removeLinks)&&(a=this.removeLinks(a));const s=(null==t?void 0:t.invertColors)?'\n /* Force Light Theme (invert from default dark) - only main background */\n html, body, main {\n background-color: #ffffff !important;\n }\n /* Force all text to dark grey (not pure black for better readability) */\n html, body, main, article, div, span, p, h1, h2, h3, h4, h5, h6, li, a, button, strong, label, textarea {\n color: #1A1A1A !important;\n }\n /* Apply light grey background to user message pills */\n .user-message-bubble-color {\n background-color: #F4F4F4 !important;\n }\n /* Apply light grey background to citation pills - highly specific selector */\n a.flex.rounded-xl.px-2.text-\\[9px\\],\n a[class*="rounded-xl"][class*="px-2"][class*="text-\\[9px\\]"],\n span[class*="webpage-citation-pill"] a {\n background-color: #F4F4F4 !important;\n }\n /* Invert scroll button colors */\n button.rounded-full.w-8.h-8.bg-token-main-surface-primary,\n button[class*="rounded-full"][class*="w-8"][class*="h-8"] {\n background-color: #ffffff !important;\n border-color: #E5E5E5 !important;\n }\n /* Invert composer box */\n div[data-composer-surface="true"],\n div.bg-token-bg-primary.dark\\:bg-\\[\\#303030\\] {\n background-color: #ffffff !important;\n border: 1px solid #E5E5E5 !important;\n }\n /* Invert composer pills */\n button.__composer-pill,\n [class*="__composer-pill"] {\n background-color: #F4F4F4 !important;\n border: 1px solid #E5E5E5 !important;\n }\n ':"";return a=this.injectStyles(a,{baseUrl:this.baseUrl,customCSS:s}),{provider:this.name,html:a,text:o,metadata:{isFullDocument:this.isFullDocument(a),sidebarRemoved:(null==t?void 0:t.removeSidebar)||!1,footerRemoved:i,linksRemoved:(null==t?void 0:t.removeLinks)||!1,colorsInverted:(null==t?void 0:t.invertColors)||!1}}}}class n extends t{constructor(){super(...arguments),this.name="GEMINI",this.baseUrl="https://gemini.google.com"}extractContent(e){let t="",r="",n=[],o=e;return e.result&&(o=e.result),"string"==typeof o?o.trim().startsWith("<")&&o.includes(">")?t=o:r=o:"object"==typeof o&&null!==o&&(o.html?t=o.html:o.content?o.content.trim().startsWith("<")?t=o.content:r=o.content:o.text&&(r=o.text),o.aioverview&&(o.aioverview.text&&(r=o.aioverview.text),o.aioverview.sources&&(n=o.aioverview.sources))),{html:t,text:r,sources:n}}removeHeader(e){let t=e;return t=t.replace(/<div[^>]*class="[^"]*boqOnegoogleliteOgbOneGoogleBar[^"]*"[^>]*>.*?<\/div><\/div><\/div><\/div>/gis,""),t=t.replace(/<div[^>]*class="[^"]*side-nav-menu-button[^"]*"[^>]*>.*?<\/div>/gis,""),t=t.replace(/<top-bar-actions[^>]*>.*?<\/top-bar-actions>/gis,""),t=t.replace(/<div[^>]*class="[^"]*desktop-ogb-buffer[^"]*"[^>]*><\/div>/gis,""),t}removeFooter(e){return e.replace(/<input-container[^>]*>.*?<\/input-container>/gis,"")}removeSidebar(e){return e.replace(/<bard-sidenav[^>]*>.*?<\/bard-sidenav>/gis,"")}parse(e,t){var r,n;const{html:o,text:a,sources:i}=this.extractContent(e);if(!o)throw new Error("No HTML content found in Gemini response");let s=o;const l=null!==(r=null==t?void 0:t.removeHeader)&&void 0!==r&&r,d=null!==(n=null==t?void 0:t.removeFooter)&&void 0!==n&&n;s=this.sanitizeHtml(s),l&&(s=this.removeHeader(s)),d&&(s=this.removeFooter(s)),(null==t?void 0:t.removeSidebar)&&(s=this.removeSidebar(s)),(null==t?void 0:t.removeLinks)&&(s=this.removeLinks(s));const c=(null==t?void 0:t.invertColors)?'\n html {\n color-scheme: light !important;\n }\n /* Force Light Theme (invert from default dark) - only main background */\n html, body, main {\n background-color: #ffffff !important;\n }\n /* Force all text to dark grey (not pure black for better readability) */\n html, body, main, article, div, span, p, h1, h2, h3, h4, h5, h6, li, a, button, strong, label, textarea {\n color: #1A1A1A !important;\n }\n /* User message bubbles - Gemini specific classes */\n .user-query-bubble-with-background,\n .user-query-container,\n .query-text,\n .query-text-line {\n background-color: #F4F4F4 !important;\n color: #1A1A1A !important;\n }\n /* AI response bubbles - Gemini specific classes */\n .model-response-text,\n .response-container,\n .response-container-content,\n .response-content {\n background-color: #ffffff !important;\n color: #1A1A1A !important;\n }\n /* Input/composer area - Gemini specific classes */\n input-area-v2,\n .input-area,\n .input-area-container,\n .text-input-field,\n .text-input-field_textarea-wrapper,\n .text-input-field-main-area,\n .text-input-field_textarea-inner,\n .text-input-field_textarea,\n .ql-editor,\n .textarea,\n .input-buttons-wrapper-bottom {\n background-color: #ffffff !important;\n color: #1A1A1A !important;\n border-color: #E5E5E5 !important;\n }\n /* Input gradient - remove the dark gradient overlay */\n input-container,\n .input-gradient {\n background: transparent !important;\n }\n input-container::before,\n .input-gradient::before {\n background: linear-gradient(transparent, #ffffff) !important;\n content: none !important;\n }\n /* Input placeholder text */\n .ql-editor::before,\n .textarea::placeholder {\n color: #666666 !important;\n }\n /* Buttons */\n button, [role="button"] {\n background-color: #F4F4F4 !important;\n color: #1A1A1A !important;\n border-color: #E5E5E5 !important;\n }\n /* Links */\n a {\n color: #1a73e8 !important;\n }\n /* Code blocks */\n pre, code, [class*="code"] {\n background-color: #f5f5f5 !important;\n color: #1A1A1A !important;\n border-color: #E5E5E5 !important;\n }\n /* Tables */\n table, td, th {\n background-color: #ffffff !important;\n border-color: #E5E5E5 !important;\n color: #1A1A1A !important;\n }\n /* Force borders to be visible */\n [class*="border"], hr {\n border-color: #E5E5E5 !important;\n }\n /* Cards and containers */\n [class*="card"], [class*="container"] {\n background-color: #ffffff !important;\n border-color: #E5E5E5 !important;\n }\n ':"";return s=this.injectStyles(s,{baseUrl:this.baseUrl,customCSS:c}),{provider:this.name,html:s,text:a,sources:i,metadata:{isFullDocument:this.isFullDocument(s),headerRemoved:l,footerRemoved:d,sidebarRemoved:(null==t?void 0:t.removeSidebar)||!1,linksRemoved:(null==t?void 0:t.removeLinks)||!1,colorsInverted:(null==t?void 0:t.invertColors)||!1}}}}class o extends t{constructor(){super(...arguments),this.name="PERPLEXITY",this.baseUrl="https://www.perplexity.ai"}extractContent(e){let t="",r="",n=e;return e.result&&(n=e.result),"string"==typeof n?n.trim().startsWith("<")&&n.includes(">")?t=n:r=n:"object"==typeof n&&null!==n&&(n.html?t=n.html:n.content?n.content.trim().startsWith("<")?t=n.content:r=n.content:n.text&&(r=n.text)),{html:t,text:r}}removeHeader(e){return e.replace(/<div[^>]*class="[^"]*@container\/header[^"]*"[^>]*>.*?<div[^>]*class="[^"]*absolute bottom-0 inset-x-0 border-b[^"]*"[^>]*><\/div>/gis,"")}removeFooter(e){let t=e;return t=t.replace(/<div[^>]*class="[^"]*erp-sidecar:fixed erp-sidecar:w-full bottom-safeAreaInsetBottom p-md pointer-events-none z-10 absolute border-subtlest ring-subtlest divide-subtlest bg-transparent[^"]*"[^>]*>[\s\S]*?(?=<div[^>]*class="[^"]*fixed inset-y-0 right-0[^"]*")/gis,""),t}parse(e,t){var r,n;const{html:o,text:a}=this.extractContent(e);if(!o)throw new Error("No HTML content found in Perplexity response");let i=o;const s=null!==(r=null==t?void 0:t.removeHeader)&&void 0!==r&&r,l=null!==(n=null==t?void 0:t.removeFooter)&&void 0!==n&&n;i=this.sanitizeHtml(i),s&&(i=this.removeHeader(i)),l&&(i=this.removeFooter(i)),(null==t?void 0:t.removeLinks)&&(i=this.removeLinks(i));const d=(null==t?void 0:t.invertColors)?"\n html {\n filter: invert(1) hue-rotate(180deg);\n background-color: white !important;\n }\n ":"";return i=this.injectStyles(i,{baseUrl:this.baseUrl,customCSS:d}),{provider:this.name,html:i,text:a,metadata:{isFullDocument:this.isFullDocument(i),linksRemoved:(null==t?void 0:t.removeLinks)||!1,colorsInverted:(null==t?void 0:t.invertColors)||!1,headerRemoved:s,footerRemoved:l}}}}class a extends t{constructor(){super(...arguments),this.name="COPILOT",this.baseUrl="https://copilot.microsoft.com"}extractContent(e){let t="",r="",n=e;return e.result&&(n=e.result),"string"==typeof n?n.trim().startsWith("<")&&n.includes(">")?t=n:r=n:"object"==typeof n&&null!==n&&(n.html?t=n.html:n.content?n.content.trim().startsWith("<")?t=n.content:r=n.content:n.text&&(r=n.text)),{html:t,text:r}}removeHeader(e){let t=e;return t=t.replace(/<div[^>]*class="[^"]*relative shrink-0 min-h-14[^"]*"[^>]*data-testid="backstage-chats"[^>]*>.*?<\/div>/gis,""),t=t.replace(/<div[^>]*class="[^"]*flex items-center px-6 mx-auto w-full max-w-chat[^"]*"[^>]*>.*?<span[^>]*data-testid="date-divider"[^>]*>.*?<\/span>.*?<div[^>]*class="[^"]*border-t-\[1px\][^"]*"[^>]*>.*?<\/div>.*?<\/div>/gis,""),t=t.replace(/<div[^>]*class="[^"]*absolute flex end-6 origin-top-right flex-col items-end[^"]*"[^>]*data-testid="settings-wrapper"[^>]*>.*?<\/div><\/div>/gis,""),t}removeFooter(e){let t=e;return t=t.replace(/<div[^>]*class="[^"]*absolute bottom-0 w-full[^"]*"[^>]*>.*?<\/div><\/div><\/div><\/div><\/div><\/div><\/div><\/div><\/div><\/div><\/div><\/div>/gis,""),t=t.replace(/<div[^>]*class="[^"]*mt-\[var\(--composer-container-height\)\][^"]*"[^>]*><\/div>/gis,""),t=t.replace(/<div[^>]*class="[^"]*pointer-events-none absolute flex justify-center z-20 inset-x-0 bottom-\[calc\(var\(--composer-container-height\)\+1rem\)\][^"]*"[^>]*>.*?<button[^>]*data-testid="scroll-to-bottom-button"[^>]*>.*?<\/button><\/div>/gis,""),t}removeCookieBanner(e){let t=e;return t=t.replace(/<div[^>]*id="cookie-banner"[^>]*>.*?<\/div>.*?<\/div>.*?<\/div>.*?<\/div>/gis,""),t=t.replace(/<div[^>]*class="[^"]*max-w-cookie-banner[^"]*"[^>]*>.*?<\/div>.*?<\/div>.*?<\/div>.*?<\/div>/gis,""),t}removeSidebar(e){let t=e;return t=t.replace(/<div[^>]*class="[^"]*absolute h-full w-0 will-change-auto max-md:bg-sidebar-light[^"]*"[^>]*style="[^"]*"[^>]*>.*?<main/gis,"<main"),t}parse(e,t){var r,n;const{html:o,text:a}=this.extractContent(e);if(!o)throw new Error("No HTML content found in Copilot response");let i=o;const s=null!==(r=null==t?void 0:t.removeHeader)&&void 0!==r&&r,l=null!==(n=null==t?void 0:t.removeFooter)&&void 0!==n&&n;i=this.sanitizeHtml(i),i=this.removeCookieBanner(i),s&&(i=this.removeHeader(i)),l&&(i=this.removeFooter(i)),(null==t?void 0:t.removeSidebar)&&(i=this.removeSidebar(i)),(null==t?void 0:t.removeLinks)&&(i=this.removeLinks(i));const d=(null==t?void 0:t.invertColors)?'\n html {\n color-scheme: light !important;\n }\n /* Force Light Theme (invert from default dark) - only main background */\n html, body, main {\n background-color: #ffffff !important;\n }\n /* Force all text to dark grey (not pure black for better readability) */\n html, body, main, article, div, span, p, h1, h2, h3, h4, h5, h6, li, a, button, strong, label, textarea {\n color: #1A1A1A !important;\n }\n /* User message bubbles - Copilot uses bg-accent-250/60 */\n .bg-accent-250\\/60,\n [class*="bg-accent-250"] {\n background-color: #F4F4F4 !important;\n color: #1A1A1A !important;\n }\n /* Override dark mode user message background */\n .dark\\:bg-accent-200,\n [class*="dark:bg-accent"] {\n background-color: #F4F4F4 !important;\n }\n /* AI response bubbles */\n [class*="ai-message"] {\n background-color: #ffffff !important;\n color: #1A1A1A !important;\n }\n /* Sidebar */\n .bg-sidebar-dark, [class*="bg-sidebar-dark"] {\n background-color: #ffffff !important;\n }\n /* Composer/input area */\n [class*="composer"], [class*="bottom-0"] {\n background-color: #ffffff !important;\n border-color: #E5E5E5 !important;\n }\n /* Input textarea */\n textarea {\n background-color: #F4F4F4 !important;\n color: #1A1A1A !important;\n }\n textarea::placeholder {\n color: #666666 !important;\n }\n /* Buttons - only override dark mode backgrounds, let transparent buttons stay transparent */\n [class*="dark:bg-background-350\\/60"],\n [class*="dark:bg-black"],\n [class*="dark:bg-muted"] {\n background-color: #F4F4F4 !important;\n }\n /* Don\'t override bg-transparent buttons */\n .bg-transparent {\n background-color: transparent !important;\n }\n /* Override button dark mode backgrounds */\n .dark\\:bg-background-350\\/60,\n [class*="dark:bg-background"] {\n background-color: #F4F4F4 !important;\n }\n /* Override dark mode borders (before:border-black/8) */\n .dark\\:border-black\\/8,\n [class*="dark:border-black"] {\n border-color: #E5E5E5 !important;\n }\n /* Keep transparent borders */\n .after\\:border-transparent,\n [class*="border-transparent"] {\n border-color: transparent !important;\n }\n /* Override dark mode fill colors */\n .dark\\:fill-white,\n [class*="dark:fill"] {\n fill: #1A1A1A !important;\n }\n /* Links */\n a {\n color: #1a73e8 !important;\n }\n /* Override dark mode accent colors */\n .dark\\:text-accent-600,\n [class*="dark:text-accent"] {\n color: #1a73e8 !important;\n }\n /* Code blocks */\n pre, code, [class*="code"] {\n background-color: #f5f5f5 !important;\n color: #1A1A1A !important;\n border-color: #E5E5E5 !important;\n }\n /* Tables - override dark mode background */\n .dark\\:bg-black\\/25,\n [class*="dark:bg-black"] {\n background-color: #ffffff !important;\n }\n table, td, th {\n background-color: #ffffff !important;\n border-color: #E5E5E5 !important;\n color: #1A1A1A !important;\n }\n /* Override dark mode table borders */\n .dark\\:border-stroke-450,\n [class*="dark:border-stroke"] {\n border-color: #E5E5E5 !important;\n }\n /* Force borders to be visible */\n [class*="border"], hr {\n border-color: #E5E5E5 !important;\n }\n /* Foreground colors */\n .text-foreground-800, [class*="text-foreground"] {\n color: #1A1A1A !important;\n }\n /* Override dark mode foreground text */\n .dark\\:fill-white,\n [class*="dark:text-foreground"] {\n color: #1A1A1A !important;\n }\n /* Override dark mode background opacity classes */\n [class*="dark:bg-background-100"],\n [class*="dark:bg-background-150"],\n [class*="dark:bg-background-200"],\n [class*="dark:bg-background-250"],\n [class*="dark:bg-background-350"],\n [class*="dark:bg-background-800"],\n [class*="dark:bg-background-850"],\n [class*="dark:bg-muted-200"],\n [class*="dark:bg-muted-400"],\n [class*="dark:bg-muted-450"] {\n background-color: #F4F4F4 !important;\n }\n /* Override light mode background classes to pure white/gray */\n .bg-background-100,\n .bg-background-150,\n .bg-background-200,\n .bg-background-250,\n [class*="bg-background-1"],\n [class*="bg-background-2"] {\n background-color: #ffffff !important;\n }\n .bg-background-350,\n .bg-background-800,\n .bg-background-850,\n .bg-accent-100,\n .bg-accent-250,\n [class*="bg-accent-1"],\n [class*="bg-accent-2"] {\n background-color: #F4F4F4 !important;\n }\n /* Citation pills - override dark mode */\n .dark\\:bg-white\\/5,\n [class*="dark:bg-white/5"],\n [class*="hover\\:dark\\:bg-accent-250"],\n [class*="focus\\:dark\\:bg-accent-250"] {\n background-color: #F4F4F4 !important;\n }\n /* Citation pills text color */\n .text-foreground-750,\n [class*="text-foreground-750"],\n [class*="dark\\:text-foreground-750"] {\n color: #1A1A1A !important;\n }\n /* Override bg-white/X with dark:bg-background-X pattern */\n .bg-white\\/40,\n .bg-white\\/25,\n .bg-white\\/50,\n .bg-white\\/70,\n .bg-white\\/90,\n [class*="bg-white\\/"] {\n background-color: #ffffff !important;\n }\n /* Pseudo-element overrides - before: gradients */\n [class*="before:from-sidebar-dark"],\n [class*="before:to-sidebar-dark"],\n [class*="dark\\:before:from-sidebar"],\n [class*="dark\\:before:to-sidebar"] {\n background: linear-gradient(transparent, #ffffff) !important;\n }\n /* Override all before: opacity and gradient classes */\n [class*="before:opacity"],\n [class*="before:bg-gradient"],\n [class*="before:from-transparent"],\n [class*="before:to-"] {\n background: linear-gradient(transparent, rgba(255, 255, 255, 0.9)) !important;\n }\n /* Force all before: pseudo-elements to have white/light gradients */\n .before\\:opacity-90\\:before,\n [class*="before:opacity-90"]::before {\n background: linear-gradient(to bottom, transparent, rgba(255, 255, 255, 0.9)) !important;\n }\n /* Pseudo-element overrides - before: borders */\n [class*="before:border-black"],\n [class*="dark\\:before:border-black"] {\n border-color: #E5E5E5 !important;\n }\n /* Pseudo-element overrides - after: borders */\n [class*="after:border-white"],\n [class*="dark\\:after:border-white"] {\n border-color: #E5E5E5 !important;\n }\n /* Pseudo-element overrides - hover states */\n [class*="dark\\:safe-hover:bg-white"],\n [class*="dark\\:active:bg-white"],\n [class*="dark\\:safe-hover\\:before:bg-white"] {\n background-color: #F4F4F4 !important;\n }\n /* Pseudo-element overrides - after:hover */\n [class*="dark\\:after\\:hover:bg-white"],\n [class*="max-md\\:dark\\:after\\:hover"] {\n background-color: rgba(244, 244, 244, 0.5) !important;\n }\n /* Override dark mode marker colors */\n [class*="dark\\:marker:text-foreground"] {\n color: #1A1A1A !important;\n }\n /* Force all before/after pseudo-elements to light colors */\n ::before,\n ::after {\n background-color: transparent !important;\n border-color: #E5E5E5 !important;\n }\n /* Scroll-to-bottom button outer container - force transparent */\n [class*="inset-x-0"][class*="bottom-["],\n .pointer-events-none.absolute.flex.justify-center {\n background-color: transparent !important;\n background: transparent !important;\n }\n [data-testid="scroll-to-bottom-button"] {\n background-color: transparent !important;\n }\n ':"\n /* No color inversion - keep default dark theme */\n ";return i=this.injectStyles(i,{baseUrl:this.baseUrl,customCSS:d}),{provider:this.name,html:i,text:a,metadata:{isFullDocument:this.isFullDocument(i),cookieBannerRemoved:!0,headerRemoved:s,footerRemoved:l,sidebarRemoved:(null==t?void 0:t.removeSidebar)||!1,linksRemoved:(null==t?void 0:t.removeLinks)||!1,colorsInverted:(null==t?void 0:t.invertColors)||!1}}}}class i extends t{constructor(){super(...arguments),this.name="AIOVERVIEW",this.baseUrl="https://www.google.com"}extractContent(e){let t="",r=[],n=e;return e.result&&(n=e.result),n.aioverview&&n.aioverview.sources&&(r=n.aioverview.sources),"string"==typeof n?n.trim().startsWith("<")&&n.includes(">")&&(t=n):"object"==typeof n&&null!==n&&(n.html?t=n.html:n.content&&n.content.trim().startsWith("<")&&(t=n.content)),{html:t,sources:r}}removeHeader(e){return e}removeFooter(e){return e}removeSidebar(e){return e}parse(e,t){var r,n;const{html:o,sources:a}=this.extractContent(e);if(!o)throw new Error("No HTML content found in AI Overview response");let i=o;const s=null===(r=null==t?void 0:t.removeHeader)||void 0===r||r,l=null===(n=null==t?void 0:t.removeFooter)||void 0===n||n;i=this.sanitizeHtml(i),s&&(i=this.removeHeader(i)),l&&(i=this.removeFooter(i)),(null==t?void 0:t.removeSidebar)&&(i=this.removeSidebar(i)),(null==t?void 0:t.removeLinks)&&(i=this.removeLinks(i));let d="";return(null==t?void 0:t.invertColors)?d+="\n /* Dark theme */\n html, body, main, article, footer, form {\n background-color: #131314 !important;\n color: #e3e3e3 !important;\n }\n ":d+='\n /* Light theme - force all backgrounds to white */\n *, div, span, p, a, li, td, th, section, article, main, aside, nav, header, footer {\n background-color: #ffffff !important;\n }\n\n html, body, main, article, footer, form {\n background-color: #ffffff !important;\n }\n\n /* Force dark text color on all text elements */\n *, p, span, div, h1, h2, h3, h4, h5, h6, li, td, th, strong, b, em, i, a {\n color: #1a1a1a !important;\n }\n\n /* Force borders and dividers to be visible */\n hr, [class*="border"], [class*="divider"], [class*="separator"],\n [class*="border-t"], [class*="border-b"], [class*="border-l"], [class*="border-r"],\n table, tr, td, th {\n border-color: #d4d4d4 !important;\n }\n ',s&&(d+='\n /* Header hiding */\n header, #header, #searchform, .sfbg, #appbar,\n div[role="navigation"], #leftnav, #sidetogether,\n [role="banner"], .Fgvgjc, #hdtb, .hdtb-msb,\n .DZ13He, .wYq63b, .eT9Cje, .bNg8Rb, .S6VXfe, .Lu57id {\n display: none !important;\n }\n '),(null==t?void 0:t.removeSidebar)&&(d+="\n /* Sidebar hiding */\n #leftnav, #sidetogether {\n display: none !important;\n }\n "),l&&(d+='\n /* Footer hiding */\n footer, #footer, .fbar,\n .pdp-nav, [aria-label="Main menu"], .gb_Td, .gb_L {\n display: none !important;\n }\n '),i=this.injectStyles(i,{baseUrl:this.baseUrl,customCSS:d}),{provider:this.name,html:i,sources:a,metadata:{isFullDocument:this.isFullDocument(i),headerRemoved:s,footerRemoved:l,sidebarRemoved:(null==t?void 0:t.removeSidebar)||!1,linksRemoved:(null==t?void 0:t.removeLinks)||!1,colorsInverted:(null==t?void 0:t.invertColors)||!1}}}}class s extends t{constructor(){super(...arguments),this.name="AIMODE",this.baseUrl="https://www.google.com"}extractContent(e){let t="",r="",n=e;return e.result&&(n=e.result),"string"==typeof n?n.trim().startsWith("<")&&n.includes(">")?t=n:r=n:"object"==typeof n&&null!==n&&(n.html?t=n.html:n.content?n.content.trim().startsWith("<")?t=n.content:r=n.content:n.text&&(r=n.text)),{html:t,text:r}}removeHeader(e){let t=e;return t=t.replace(/<div[^>]*jsname="oEQ3x"[^>]*class="[^"]*DZ13He[^"]*"[^>]*>.*?<hr class="e9c7U">.*?<\/div><\/div><\/div><\/div><\/div>/gis,""),t}removeFooter(e){let t=e;return t=t.replace(/<div[^>]*data-xid="aim-mars-input-plate"[^>]*>[\s\S]*?<\/div><\/div><\/div><\/div><\/div>/gis,""),t=t.replace(/<div[^>]*jscontroller="P5gZDb"[^>]*>[\s\S]*?<\/div><\/div><\/div>/gis,""),t=t.replace(/<div[^>]*class="[^"]*t0ITR hh3ttd[^"]*"[^>]*>[\s\S]*?<\/div><\/div>/gis,""),t=t.replace(/<div[^>]*class="[^"]*y4VEUd vve6Ce[^"]*"[^>]*>[\s\S]*?<\/div><\/div>/gis,""),t}removeSidebar(e){let t=e;return t=t.replace(/<div[^>]*class="[^"]*ho072b[^"]*"[^>]*aria-label="AI Mode history"[^>]*>[\s\S]*?<\/div><\/div><\/div><\/div><\/div><\/div>/gis,""),t=t.replace(/<div[^>]*jsname="NlVIob"[^>]*class="[^"]*qEn1od[^"]*"[^>]*>[\s\S]*?<\/div><\/div><\/div>/gis,""),t=t.replace(/<div[^>]*class="[^"]*OEwhSe[^"]*"[^>]*>[\s\S]*?<\/div><\/div>/gis,""),t=t.replace(/<button[^>]*aria-label="Start new search"[^>]*>[\s\S]*?<\/button>/gis,""),t=t.replace(/<button[^>]*aria-label="AI Mode history"[^>]*>[\s\S]*?<\/button>/gis,""),t}parse(e,t){var r,n;const{html:o,text:a}=this.extractContent(e);if(!o)throw new Error("No HTML content found in AI Mode response");let i=o;const s=null===(r=null==t?void 0:t.removeHeader)||void 0===r||r,l=null===(n=null==t?void 0:t.removeFooter)||void 0===n||n;i=this.sanitizeHtml(i),s&&(i=this.removeHeader(i)),l&&(i=this.removeFooter(i)),(null==t?void 0:t.removeSidebar)&&(i=this.removeSidebar(i)),(null==t?void 0:t.removeLinks)&&(i=this.removeLinks(i));let d="";return d+="\n .KxvlWc, #CXQnmb {\n display: none !important;\n }\n ",(null==t?void 0:t.invertColors)?d+="\n /* Dark theme */\n html, body, main, article, footer, form {\n background-color: #131314 !important;\n color: #e3e3e3 !important;\n }\n ":d+='\n /* Light theme - force all backgrounds to white */\n *, div, span, p, a, li, td, th, section, article, main, aside, nav, header, footer {\n background-color: #ffffff !important;\n }\n\n html, body, main, article, footer, form {\n background-color: #ffffff !important;\n }\n\n /* Force dark text color on all text elements */\n *, p, span, div, h1, h2, h3, h4, h5, h6, li, td, th, strong, b, em, i, a {\n color: #1a1a1a !important;\n }\n\n /* Force borders and dividers to be visible */\n hr, [class*="border"], [class*="divider"], [class*="separator"],\n [class*="border-t"], [class*="border-b"], [class*="border-l"], [class*="border-r"],\n table, tr, td, th {\n border-color: #d4d4d4 !important;\n }\n ',s&&(d+='\n /* Header hiding */\n header, #header, #searchform, .sfbg, #appbar,\n div[role="navigation"], #leftnav, #sidetogether,\n [role="banner"], .Fgvgjc, #hdtb, .hdtb-msb,\n .DZ13He, .wYq63b, .eT9Cje, .bNg8Rb, .S6VXfe, .Lu57id {\n display: none !important;\n }\n '),(null==t?void 0:t.removeSidebar)&&(d+="\n /* Sidebar hiding */\n #leftnav, #sidetogether {\n display: none !important;\n }\n "),l&&(d+='\n /* Footer hiding */\n footer, #footer, .fbar,\n .pdp-nav, [aria-label="Main menu"], .gb_Td, .gb_L {\n display: none !important;\n }\n '),i=this.injectStyles(i,{baseUrl:this.baseUrl,customCSS:d}),{provider:this.name,html:i,text:a,metadata:{isFullDocument:this.isFullDocument(i),headerRemoved:s,footerRemoved:l,sidebarRemoved:(null==t?void 0:t.removeSidebar)||!1,linksRemoved:(null==t?void 0:t.removeLinks)||!1,colorsInverted:(null==t?void 0:t.invertColors)||!1}}}}class l extends t{constructor(){super(...arguments),this.name="GROK",this.baseUrl="https://grok.com"}extractContent(e){let t="",r="",n=e;return e.result&&(n=e.result),"string"==typeof n?n.trim().startsWith("<")&&n.includes(">")?t=n:r=n:"object"==typeof n&&null!==n&&(n.html?t=n.html:n.content?n.content.trim().startsWith("<")?t=n.content:r=n.content:n.text&&(r=n.text)),{html:t,text:r}}removeHeader(e){let t=e;const r=t.match(/<div[^>]*class="[^"]*h-16\s+top-0\s+@\[80rem\]\/nav:h-0[^"]*"[^>]*>/gi);if(!r)return t;const n=t.indexOf(r[0]);if(-1===n)return t;const o=t.substring(n+r[0].length);let a=1,i=0,s=!1;for(;i<o.length&&!s;){const e=o.indexOf("<div",i),t=o.indexOf("</div>",i);if(-1===e&&-1===t)break;if(-1!==t&&(-1===e||t<e))a--,i=t+6,0===a&&(s=!0);else if(-1!==e){a++;const t=o.indexOf(">",e);if(-1===t)break;i=t+1}}if(s){const e=n+r[0].length+i;t=t.substring(0,n)+t.substring(e)}return t}removeFooter(e){let t=e;const r=t.match(/<div[^>]*class="[^"]*absolute\s+inset-x-0\s+bottom-0\s+mx-auto\s+max-w-breakout\s+z-40\s+print:hidden[^"]*"[^>]*>/gi);if(!r)return t;const n=t.indexOf(r[0]);if(-1===n)return t;const o=t.substring(n),a=o.match(/<\/main>/gi);if(!a)return t;const i=n+o.indexOf(a[0]);return t=t.substring(0,n)+t.substring(i),t}parse(e,t){const{html:r,text:n}=this.extractContent(e);if(!r)throw new Error("No HTML content found in Grok response");let o=r;o=this.sanitizeHtml(o),(null==t?void 0:t.removeHeader)&&(o=this.removeHeader(o)),(null==t?void 0:t.removeFooter)&&(o=this.removeFooter(o)),(null==t?void 0:t.invertColors)&&(o=o.replace(/\s*class\s*=\s*"[^"]*dark[^"]*"/gi,e=>e.replace(/\bdark\b/g,"").replace(/\s+/g," ").replace('class=""','class="light"').replace(/^class=""/,'class="light"').replace(/class="\s+/,'class="').replace(/\s+"/,'"')),o=o.replace(/color-scheme:\s*dark/gi,"color-scheme: light")),(null==t?void 0:t.removeLinks)&&(o=this.removeLinks(o));const a=(null==t?void 0:t.invertColors)?'\n html {\n color-scheme: light !important;\n }\n /* Force light background and dark text for all elements */\n html, body {\n background-color: #ffffff !important;\n color: #1a1a1a !important;\n }\n /* Override Tailwind dark mode classes */\n .dark, [class*="dark"] {\n color-scheme: light !important;\n }\n /* Override common Grok CSS variables and classes */\n [class*="bg-"], [class*="background"] {\n background-color: #ffffff !important;\n }\n [class*="text-"], [class*="fg-"] {\n color: #1a1a1a !important;\n }\n /* Override surface and foreground colors */\n .bg-surface-base, .bg-surface, .surface {\n background-color: #f9f9f9 !important;\n }\n .text-fg-primary, .text-fg, .fg-primary {\n color: #1a1a1a !important;\n }\n /* Force borders to be visible */\n [class*="border"], hr, table, td, th {\n border-color: #d4d4d4 !important;\n }\n /* Code blocks */\n pre, code, [class*="code"] {\n background-color: #f5f5f5 !important;\n color: #1a1a1a !important;\n border-color: #d4d4d4 !important;\n }\n ':"\n /* Force light mode styling for Grok */\n html, body {\n background-color: #ffffff !important;\n color: #1a1a1a !important;\n }\n .bg-surface-base, .bg-surface {\n background-color: #f9f9f9 !important;\n }\n .text-fg-primary, .text-fg {\n color: #1a1a1a !important;\n }\n ";return o=this.injectStyles(o,{baseUrl:this.baseUrl,customCSS:a}),{provider:this.name,html:o,text:n,metadata:{isFullDocument:this.isFullDocument(o),linksRemoved:(null==t?void 0:t.removeLinks)||!1,colorsInverted:(null==t?void 0:t.invertColors)||!1,headerRemoved:(null==t?void 0:t.removeHeader)||!1,footerRemoved:(null==t?void 0:t.removeFooter)||!1}}}}class d{constructor(){this.providers=new Map,this.providers.set("CHATGPT",new r),this.providers.set("GEMINI",new n),this.providers.set("PERPLEXITY",new o),this.providers.set("COPILOT",new a),this.providers.set("AIOVERVIEW",new i),this.providers.set("AIMODE",new s),this.providers.set("GROK",new l)}parse(t,r){const n=e.detect(t);if(!n)return this.parseGeneric(t);const o=this.providers.get(n.provider);if(!o)return null;try{const e=o.parse(t,r);return{...e,metadata:{...e.metadata,detectionConfidence:n.confidence}}}catch(e){return console.error(`Failed to parse response with ${n.provider}:`,e),null}}parseWithProvider(e,t,r){const n=this.providers.get(t);if(!n)throw new Error(`Unknown provider: ${t}`);try{return n.parse(e,r)}catch(e){return console.error(`Failed to parse response with ${t}:`,e),null}}detectProvider(t){const r=e.detect(t);return(null==r?void 0:r.provider)||null}detectAllProviders(t){return e.getAllProviders(t)}parseGeneric(e){let t="",r="";let n=e;var o;return e.result&&(n=e.result),"string"==typeof(o=n)?o.trim().startsWith("<")&&o.includes(">")?t=o:r=o:"object"==typeof o&&null!==o&&(o.html?t=o.html:o.content?o.content.trim().startsWith("<")?t=o.content:r=o.content:o.text&&(r=o.text)),t||r?(t&&(t=t.replace(/<script\b[^>]*>[\s\S]*?<\/script>/gim,""),t=t.replace(/<noscript[\s\S]*?<\/noscript>/gi,"")),{provider:"CHATGPT",html:t,text:r,metadata:{isGeneric:!0}}):null}getSupportedProviders(){return Array.from(this.providers.keys())}registerProvider(e,t){this.providers.set(e,t)}}const c=new d,m=(e,t)=>c.parse(e,t),u=e=>c.detectProvider(e);export{s as AIModeProvider,i as AIOverviewProvider,d as AIResponseParser,t as BaseProvider,r as ChatGPTProvider,a as CopilotProvider,n as GeminiProvider,l as GrokProvider,o as PerplexityProvider,e as ProviderDetector,u as detectProvider,m as parseAiResponse,c as parser};
1
+ function e(e){let t="",r="",i=e;return e.result&&(i=e.result),"string"==typeof i?i.trim().startsWith("<")&&i.includes(">")?t=i:r=i:"object"==typeof i&&null!==i&&(i.html?t=i.html:i.content?i.content.trim().startsWith("<")?t=i.content:r=i.content:i.text&&(r=i.text)),{html:t,text:r}}class t{static detect(e){const t={CHATGPT:0,GEMINI:0,PERPLEXITY:0,COPILOT:0,AIOVERVIEW:0,AIMODE:0,GROK:0};for(const[r,i]of Object.entries(this.PROVIDER_PATTERNS))for(const o of i)try{o(e)&&t[r]++}catch(e){}let r=0,i=null;for(const[e,o]of Object.entries(t))o>r&&(r=o,i=e);return 0===r?null:{provider:i,confidence:r/Object.values(t).reduce((e,t)=>Math.max(e,t),1)}}static getAllProviders(e){const t=[];for(const[r,i]of Object.entries(this.PROVIDER_PATTERNS)){let o=0;for(const t of i)try{t(e)&&o++}catch(e){}o>0&&t.push({provider:r,confidence:o/i.length})}return t.sort((e,t)=>t.confidence-e.confidence)}static validate(e,t){const r=this.detect(e);return(null==r?void 0:r.provider)===t&&r.confidence>.5}}t.PROVIDER_PATTERNS={CHATGPT:[e=>{var t;const r=(null===(t=null==e?void 0:e.result)||void 0===t?void 0:t.html)||(null==e?void 0:e.html)||"";return r.includes("bg-token-bg-primary")||r.includes("text-token-text-secondary")},e=>{var t;const r=(null===(t=null==e?void 0:e.result)||void 0===t?void 0:t.html)||(null==e?void 0:e.html)||"";return r.includes("chatgpt.com")||r.includes("openai.com")}],GEMINI:[e=>{var t;const r=(null===(t=null==e?void 0:e.result)||void 0===t?void 0:t.html)||(null==e?void 0:e.html)||"";return r.includes("bard-sidenav")||r.includes("mat-sidenav")},e=>{var t;const r=(null===(t=null==e?void 0:e.result)||void 0===t?void 0:t.html)||(null==e?void 0:e.html)||"";return r.includes("gemini.google.com")||r.includes("gem-sys-color")}],PERPLEXITY:[e=>{var t;const r=(null===(t=null==e?void 0:e.result)||void 0===t?void 0:t.html)||(null==e?void 0:e.html)||"";return r.includes("perplexity.ai")||r.includes("prose")}],COPILOT:[e=>{var t;const r=(null===(t=null==e?void 0:e.result)||void 0===t?void 0:t.html)||(null==e?void 0:e.html)||"";return r.includes("copilot.microsoft.com")||r.includes('data-testid="sidebar-container"')}],AIOVERVIEW:[e=>{var t,r,i,o;if(null===(r=null===(t=null==e?void 0:e.result)||void 0===t?void 0:t.aioverview)||void 0===r?void 0:r.text)return!0;if(null===(i=null==e?void 0:e.aioverview)||void 0===i?void 0:i.text)return!0;const n=(null===(o=null==e?void 0:e.result)||void 0===o?void 0:o.html)||(null==e?void 0:e.html)||"";return n.includes("WIZ_global_data")||n.includes("DnVkpd")}],AIMODE:[e=>{var t;const r=(null===(t=null==e?void 0:e.result)||void 0===t?void 0:t.html)||(null==e?void 0:e.html)||"";return r.includes("DZ13He")||r.includes("wYq63b")||r.includes("AI Mode")}],GROK:[e=>{var t;const r=(null===(t=null==e?void 0:e.result)||void 0===t?void 0:t.html)||(null==e?void 0:e.html)||"";return r.includes("grok.com")||r.includes("x.ai")}]};class r{extractContentCommon(t,r=!1){var i;const o=e(t);if(r){let e=[];const r=t.result||t;return"object"==typeof r&&null!==r&&((null===(i=r.aioverview)||void 0===i?void 0:i.sources)?e=r.aioverview.sources:r.sources&&(e=r.sources)),{...o,sources:e}}return o}injectStyles(e,t){let r=e;(null==t?void 0:t.baseUrl)&&!e.includes("<base ")&&(r=r.includes("<head>")?r.replace("<head>",`<head><base href="${t.baseUrl}">`):r.replace(/(<html[^>]*>)/i,`$1<head><base href="${t.baseUrl}"></head>`));const i=(null==t?void 0:t.customCSS)||"";return i&&r.includes("<head>")?r=r.replace("<head>",`<head><style>${i}</style>`):i&&(r=r.replace(/(<html[^>]*>)/i,`$1<head><style>${i}</style></head>`)),r}sanitizeHtml(e){let t=e.replace(/<script\b[^>]*>[\s\S]*?<\/script>/gim,"");return t=t.replace(/<noscript[\s\S]*?<\/noscript>/gi,""),t}isFullDocument(e){return/^\s*(<html|<!DOCTYPE)/i.test(e)}removeLinks(e){return e.replace(/<a\b[^>]*>([\s\S]*?)<\/a>/gim,"$1")}wrapFragment(e){return`<!DOCTYPE html>\n<html>\n<head>\n <meta charset="utf-8">\n <meta http-equiv="Content-Security-Policy" content="default-src 'none'; script-src 'none'; style-src 'unsafe-inline';">\n <style>\n body {\n margin: 0;\n padding: 16px;\n font-family: system-ui, -apple-system, sans-serif;\n white-space: pre-wrap;\n word-wrap: break-word;\n }\n img { max-width: 100%; height: auto; }\n body {\n pointer-events: none;\n user-select: none;\n }\n </style>\n</head>\n<body>\n ${e}\n</body>\n</html>`}}class i extends r{constructor(){super(...arguments),this.name="CHATGPT",this.baseUrl="https://chatgpt.com"}extractContent(e){return this.extractContentCommon(e)}removeLinks(e){return e.replace(/<a\b([^>]*)>/gi,(e,t)=>{const r=t.replace(/\s+href\s*=\s*["'][^"']*["']/gi,"").replace(/\s+alt\s*=\s*["'][^"']*["']/gi,"").replace(/\s+rel\s*=\s*["'][^"']*["']/gi,"").replace(/\s+target\s*=\s*["'][^"']*["']/gi,"").trim();return`<span${r?" "+r:""}>`}).replace(/<\/a>/gi,"</span>")}removeHeader(e){let t=e;return t=t.replace(/<header[^>]*id="page-header"[^>]*>.*?<\/header>/gis,""),t}removeSidebar(e){let t=e;return t=t.replace(/<nav[^>]*>.*?<\/nav>/gis,""),t=t.replace(/<div[^>]*class="[^"]*sidebar[^"]*"[^>]*>.*?<\/div>/gis,""),t}removeFooter(e){let t=e;return t=t.replace(/<div[^>]*id="thread-bottom-container"[^>]*>.*?<\/div><\/div><\/div>/gis,""),t=t.replace(/<div[^>]*id="thread-bottom"[^>]*>.*?<\/div><\/div><\/div><\/div><\/div>/gis,""),t=t.replace(/<div[^>]*class="[^"]*\[grid-area:leading\][^"]*"[^>]*>.*?<\/div><\/div><\/div>/gis,""),t=t.replace(/<div[^>]*class="[^"]*\[grid-area:footer\][^"]*"[^>]*>.*?<\/div><\/div><\/div><\/div><\/div>/gis,""),t=t.replace(/<div[^>]*class="[^"]*\[grid-area:trailing\][^"]*"[^>]*>.*?<\/div><\/div><\/div>/gis,""),t=t.replace(/<div[^>]*\[view-transition-name:var\(--vt-disclaimer\)\][^>]*>.*?<\/div><\/div>/gis,""),t}parse(e,t){var r;const{html:i,text:o}=this.extractContent(e);if(!i)throw new Error("No HTML content found in ChatGPT response");let n=i;const s=null!==(r=null==t?void 0:t.removeFooter)&&void 0!==r&&r;return n=this.sanitizeHtml(n),(null==t?void 0:t.removeHeader)&&(n=this.removeHeader(n)),(null==t?void 0:t.removeSidebar)&&(n=this.removeSidebar(n)),s&&(n=this.removeFooter(n)),(null==t?void 0:t.removeLinks)&&(n=this.removeLinks(n)),n=this.injectStyles(n,{baseUrl:this.baseUrl,customCSS:""}),{provider:this.name,html:n,text:o,metadata:{isFullDocument:this.isFullDocument(n),headerRemoved:(null==t?void 0:t.removeHeader)||!1,sidebarRemoved:(null==t?void 0:t.removeSidebar)||!1,footerRemoved:s,linksRemoved:(null==t?void 0:t.removeLinks)||!1}}}}class o extends r{constructor(){super(...arguments),this.name="GEMINI",this.baseUrl="https://gemini.google.com"}extractContent(e){return this.extractContentCommon(e,!0)}removeHeader(e){let t=e;return t=t.replace(/<div[^>]*class="[^"]*boqOnegoogleliteOgbOneGoogleBar[^"]*"[^>]*>.*?<\/div><\/div><\/div><\/div>/gis,""),t=t.replace(/<div[^>]*class="[^"]*side-nav-menu-button[^"]*"[^>]*>.*?<\/div>/gis,""),t=t.replace(/<top-bar-actions[^>]*>.*?<\/top-bar-actions>/gis,""),t=t.replace(/<div[^>]*class="[^"]*desktop-ogb-buffer[^"]*"[^>]*><\/div>/gis,""),t}removeFooter(e){return e.replace(/<input-container[^>]*>.*?<\/input-container>/gis,"")}removeSidebar(e){return e.replace(/<bard-sidenav[^>]*>.*?<\/bard-sidenav>/gis,"")}parse(e,t){var r,i;const{html:o,text:n,sources:s}=this.extractContent(e);if(!o)throw new Error("No HTML content found in Gemini response");let l=o;const d=null!==(r=null==t?void 0:t.removeHeader)&&void 0!==r&&r,a=null!==(i=null==t?void 0:t.removeFooter)&&void 0!==i&&i;return l=this.sanitizeHtml(l),d&&(l=this.removeHeader(l)),a&&(l=this.removeFooter(l)),(null==t?void 0:t.removeSidebar)&&(l=this.removeSidebar(l)),(null==t?void 0:t.removeLinks)&&(l=this.removeLinks(l)),l=this.injectStyles(l,{baseUrl:this.baseUrl,customCSS:""}),{provider:this.name,html:l,text:n,sources:s,metadata:{isFullDocument:this.isFullDocument(l),headerRemoved:d,footerRemoved:a,sidebarRemoved:(null==t?void 0:t.removeSidebar)||!1,linksRemoved:(null==t?void 0:t.removeLinks)||!1}}}}class n extends r{constructor(){super(...arguments),this.name="PERPLEXITY",this.baseUrl="https://www.perplexity.ai"}extractContent(e){return this.extractContentCommon(e)}removeHeader(e){return e.replace(/<div[^>]*class="[^"]*@container\/header[^"]*"[^>]*>.*?<div[^>]*class="[^"]*absolute bottom-0 inset-x-0 border-b[^"]*"[^>]*><\/div>/gis,"")}removeFooter(e){let t=e;return t=t.replace(/<div[^>]*class="[^"]*erp-sidecar:fixed erp-sidecar:w-full bottom-safeAreaInsetBottom p-md pointer-events-none z-10 absolute border-subtlest ring-subtlest divide-subtlest bg-transparent[^"]*"[^>]*>[\s\S]*?(?=<div[^>]*class="[^"]*fixed inset-y-0 right-0[^"]*")/gis,""),t}parse(e,t){var r,i;const{html:o,text:n}=this.extractContent(e);if(!o)throw new Error("No HTML content found in Perplexity response");let s=o;const l=null!==(r=null==t?void 0:t.removeHeader)&&void 0!==r&&r,d=null!==(i=null==t?void 0:t.removeFooter)&&void 0!==i&&i;return s=this.sanitizeHtml(s),l&&(s=this.removeHeader(s)),d&&(s=this.removeFooter(s)),(null==t?void 0:t.removeLinks)&&(s=this.removeLinks(s)),s=this.injectStyles(s,{baseUrl:this.baseUrl,customCSS:""}),{provider:this.name,html:s,text:n,metadata:{isFullDocument:this.isFullDocument(s),linksRemoved:(null==t?void 0:t.removeLinks)||!1,headerRemoved:l,footerRemoved:d}}}}class s extends r{constructor(){super(...arguments),this.name="COPILOT",this.baseUrl="https://copilot.microsoft.com"}extractContent(e){return this.extractContentCommon(e)}removeHeader(e){let t=e;return t=t.replace(/<div[^>]*class="[^"]*relative shrink-0 min-h-14[^"]*"[^>]*data-testid="backstage-chats"[^>]*>.*?<\/div>/gis,""),t=t.replace(/<div[^>]*class="[^"]*flex items-center px-6 mx-auto w-full max-w-chat[^"]*"[^>]*>.*?<span[^>]*data-testid="date-divider"[^>]*>.*?<\/span>.*?<div[^>]*class="[^"]*border-t-\[1px\][^"]*"[^>]*>.*?<\/div>.*?<\/div>/gis,""),t=t.replace(/<div[^>]*class="[^"]*absolute flex end-6 origin-top-right flex-col items-end[^"]*"[^>]*data-testid="settings-wrapper"[^>]*>.*?<\/div><\/div>/gis,""),t}removeFooter(e){let t=e;return t=t.replace(/<div[^>]*class="[^"]*absolute bottom-0 w-full[^"]*"[^>]*>.*?<\/div><\/div><\/div><\/div><\/div><\/div><\/div><\/div><\/div><\/div><\/div><\/div>/gis,""),t=t.replace(/<div[^>]*class="[^"]*mt-\[var\(--composer-container-height\)\][^"]*"[^>]*><\/div>/gis,""),t=t.replace(/<div[^>]*class="[^"]*pointer-events-none absolute flex justify-center z-20 inset-x-0 bottom-\[calc\(var\(--composer-container-height\)\+1rem\)\][^"]*"[^>]*>.*?<button[^>]*data-testid="scroll-to-bottom-button"[^>]*>.*?<\/button><\/div>/gis,""),t}removeCookieBanner(e){let t=e;return t=t.replace(/<div[^>]*id="cookie-banner"[^>]*>.*?<\/div>.*?<\/div>.*?<\/div>.*?<\/div>/gis,""),t=t.replace(/<div[^>]*class="[^"]*max-w-cookie-banner[^"]*"[^>]*>.*?<\/div>.*?<\/div>.*?<\/div>.*?<\/div>/gis,""),t}removeSidebar(e){let t=e;return t=t.replace(/<div[^>]*class="[^"]*absolute h-full w-0 will-change-auto max-md:bg-sidebar-light[^"]*"[^>]*style="[^"]*"[^>]*>.*?<main/gis,"<main"),t}parse(e,t){var r,i;const{html:o,text:n}=this.extractContent(e);if(!o)throw new Error("No HTML content found in Copilot response");let s=o;const l=null!==(r=null==t?void 0:t.removeHeader)&&void 0!==r&&r,d=null!==(i=null==t?void 0:t.removeFooter)&&void 0!==i&&i;return s=this.sanitizeHtml(s),s=this.removeCookieBanner(s),l&&(s=this.removeHeader(s)),d&&(s=this.removeFooter(s)),(null==t?void 0:t.removeSidebar)&&(s=this.removeSidebar(s)),(null==t?void 0:t.removeLinks)&&(s=this.removeLinks(s)),s=this.injectStyles(s,{baseUrl:this.baseUrl,customCSS:""}),{provider:this.name,html:s,text:n,metadata:{isFullDocument:this.isFullDocument(s),cookieBannerRemoved:!0,headerRemoved:l,footerRemoved:d,sidebarRemoved:(null==t?void 0:t.removeSidebar)||!1,linksRemoved:(null==t?void 0:t.removeLinks)||!1}}}}class l extends r{constructor(){super(...arguments),this.name="AIOVERVIEW",this.baseUrl="https://www.google.com"}extractContent(e){return this.extractContentCommon(e,!0)}removeHeader(e){return e}removeFooter(e){return e}removeSidebar(e){return e}parse(e,t){var r,i;const{html:o,sources:n}=this.extractContent(e);if(!o)throw new Error("No HTML content found in AI Overview response");let s=o;const l=null===(r=null==t?void 0:t.removeHeader)||void 0===r||r,d=null===(i=null==t?void 0:t.removeFooter)||void 0===i||i;s=this.sanitizeHtml(s),l&&(s=this.removeHeader(s)),d&&(s=this.removeFooter(s)),(null==t?void 0:t.removeSidebar)&&(s=this.removeSidebar(s)),(null==t?void 0:t.removeLinks)&&(s=this.removeLinks(s));let a="";return l&&(a+='\n /* Header hiding */\n header, #header, #searchform, .sfbg, #appbar,\n div[role="navigation"], #leftnav, #sidetogether,\n [role="banner"], .Fgvgjc, #hdtb, .hdtb-msb,\n .DZ13He, .wYq63b, .eT9Cje, .bNg8Rb, .S6VXfe, .Lu57id {\n display: none !important;\n }\n '),(null==t?void 0:t.removeSidebar)&&(a+="\n /* Sidebar hiding */\n #leftnav, #sidetogether {\n display: none !important;\n }\n "),d&&(a+='\n /* Footer hiding */\n footer, #footer, .fbar,\n .pdp-nav, [aria-label="Main menu"], .gb_Td, .gb_L {\n display: none !important;\n }\n '),s=this.injectStyles(s,{baseUrl:this.baseUrl,customCSS:a}),{provider:this.name,html:s,sources:n,metadata:{isFullDocument:this.isFullDocument(s),headerRemoved:l,footerRemoved:d,sidebarRemoved:(null==t?void 0:t.removeSidebar)||!1,linksRemoved:(null==t?void 0:t.removeLinks)||!1}}}}class d extends r{constructor(){super(...arguments),this.name="AIMODE",this.baseUrl="https://www.google.com"}extractContent(e){return this.extractContentCommon(e)}removeHeader(e){let t=e;return t=t.replace(/<div[^>]*jsname="oEQ3x"[^>]*class="[^"]*DZ13He[^"]*"[^>]*>.*?<hr class="e9c7U">.*?<\/div><\/div><\/div><\/div><\/div>/gis,""),t}removeFooter(e){let t=e;return t=t.replace(/<div[^>]*data-xid="aim-mars-input-plate"[^>]*>[\s\S]*?<\/div><\/div><\/div><\/div><\/div>/gis,""),t=t.replace(/<div[^>]*jscontroller="P5gZDb"[^>]*>[\s\S]*?<\/div><\/div><\/div>/gis,""),t=t.replace(/<div[^>]*class="[^"]*t0ITR hh3ttd[^"]*"[^>]*>[\s\S]*?<\/div><\/div>/gis,""),t=t.replace(/<div[^>]*class="[^"]*y4VEUd vve6Ce[^"]*"[^>]*>[\s\S]*?<\/div><\/div>/gis,""),t}removeSidebar(e){let t=e;return t=t.replace(/<div[^>]*class="[^"]*ho072b[^"]*"[^>]*aria-label="AI Mode history"[^>]*>[\s\S]*?<\/div><\/div><\/div><\/div><\/div><\/div>/gis,""),t=t.replace(/<div[^>]*jsname="NlVIob"[^>]*class="[^"]*qEn1od[^"]*"[^>]*>[\s\S]*?<\/div><\/div><\/div>/gis,""),t=t.replace(/<div[^>]*class="[^"]*OEwhSe[^"]*"[^>]*>[\s\S]*?<\/div><\/div>/gis,""),t=t.replace(/<button[^>]*aria-label="Start new search"[^>]*>[\s\S]*?<\/button>/gis,""),t=t.replace(/<button[^>]*aria-label="AI Mode history"[^>]*>[\s\S]*?<\/button>/gis,""),t}parse(e,t){var r,i;const{html:o,text:n}=this.extractContent(e);if(!o)throw new Error("No HTML content found in AI Mode response");let s=o;const l=null===(r=null==t?void 0:t.removeHeader)||void 0===r||r,d=null===(i=null==t?void 0:t.removeFooter)||void 0===i||i;s=this.sanitizeHtml(s),l&&(s=this.removeHeader(s)),d&&(s=this.removeFooter(s)),(null==t?void 0:t.removeSidebar)&&(s=this.removeSidebar(s)),(null==t?void 0:t.removeLinks)&&(s=this.removeLinks(s));let a="";return a+="\n .KxvlWc, #CXQnmb {\n display: none !important;\n }\n ",l&&(a+='\n /* Header hiding */\n header, #header, #searchform, .sfbg, #appbar,\n div[role="navigation"], #leftnav, #sidetogether,\n [role="banner"], .Fgvgjc, #hdtb, .hdtb-msb,\n .DZ13He, .wYq63b, .eT9Cje, .bNg8Rb, .S6VXfe, .Lu57id {\n display: none !important;\n }\n '),(null==t?void 0:t.removeSidebar)&&(a+="\n /* Sidebar hiding */\n #leftnav, #sidetogether {\n display: none !important;\n }\n "),d&&(a+='\n /* Footer hiding */\n footer, #footer, .fbar,\n .pdp-nav, [aria-label="Main menu"], .gb_Td, .gb_L {\n display: none !important;\n }\n '),s=this.injectStyles(s,{baseUrl:this.baseUrl,customCSS:a}),{provider:this.name,html:s,text:n,metadata:{isFullDocument:this.isFullDocument(s),headerRemoved:l,footerRemoved:d,sidebarRemoved:(null==t?void 0:t.removeSidebar)||!1,linksRemoved:(null==t?void 0:t.removeLinks)||!1}}}}class a extends r{constructor(){super(...arguments),this.name="GROK",this.baseUrl="https://grok.com"}extractContent(e){return this.extractContentCommon(e)}removeHeader(e){return e}removeFooter(e){return e}parse(e,t){const{html:r,text:i}=this.extractContent(e);if(!r)throw new Error("No HTML content found in Grok response");let o=r;o=this.sanitizeHtml(o);let n="";return(null==t?void 0:t.removeHeader)&&(n+='\n /* Header hiding - hide elements with Grok\'s header class pattern */\n div[class*="h-16"][class*="top-0"][class*="z-10"],\n div[class*="absolute"][class*="inset-x-0"][class*="top-0"] {\n display: none !important;\n }\n '),(null==t?void 0:t.removeFooter)&&(n+='\n /* Footer hiding - hide Grok\'s footer/input area */\n div[class*="absolute"][class*="inset-x-0"][class*="bottom-0"][class*="max-w-breakout"],\n div[class*="absolute"][class*="bottom-0"][class*="w-full"] {\n display: none !important;\n }\n '),(null==t?void 0:t.removeLinks)&&(o=this.removeLinks(o)),o=this.injectStyles(o,{baseUrl:this.baseUrl,customCSS:n}),{provider:this.name,html:o,text:i,metadata:{isFullDocument:this.isFullDocument(o),linksRemoved:(null==t?void 0:t.removeLinks)||!1,headerRemoved:(null==t?void 0:t.removeHeader)||!1,footerRemoved:(null==t?void 0:t.removeFooter)||!1}}}}class v{constructor(){this.providers=new Map,this.providers.set("CHATGPT",new i),this.providers.set("GEMINI",new o),this.providers.set("PERPLEXITY",new n),this.providers.set("COPILOT",new s),this.providers.set("AIOVERVIEW",new l),this.providers.set("AIMODE",new d),this.providers.set("GROK",new a)}parse(e,r){const i=t.detect(e);if(!i)return this.parseGeneric(e);const o=this.providers.get(i.provider);if(!o)return null;try{const t=o.parse(e,r);return{...t,metadata:{...t.metadata,detectionConfidence:i.confidence}}}catch(e){return console.error(`Failed to parse response with ${i.provider}:`,e),null}}parseWithProvider(e,t,r){const i=this.providers.get(t);if(!i)throw new Error(`Unknown provider: ${t}`);try{return i.parse(e,r)}catch(e){return console.error(`Failed to parse response with ${t}:`,e),null}}detectProvider(e){const r=t.detect(e);return(null==r?void 0:r.provider)||null}detectAllProviders(e){return t.getAllProviders(e)}parseGeneric(t){const{html:r,text:i}=e(t);if(!r&&!i)return null;let o=r;return o&&(o=o.replace(/<script\b[^>]*>[\s\S]*?<\/script>/gim,""),o=o.replace(/<noscript[\s\S]*?<\/noscript>/gi,"")),{provider:"CHATGPT",html:o||"",text:i||"",metadata:{isGeneric:!0}}}getSupportedProviders(){return Array.from(this.providers.keys())}registerProvider(e,t){this.providers.set(e,t)}}const c=new v,u=(e,t)=>c.parse(e,t),m=e=>c.detectProvider(e);export{d as AIModeProvider,l as AIOverviewProvider,v as AIResponseParser,r as BaseProvider,i as ChatGPTProvider,s as CopilotProvider,o as GeminiProvider,a as GrokProvider,n as PerplexityProvider,t as ProviderDetector,m as detectProvider,u as parseAiResponse,c as parser};
2
2
  //# sourceMappingURL=index.esm.js.map