reneco-advanced-input-module 0.0.1-beta.1 → 0.0.1-beta.2
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/loader/cdn.js +1 -0
- package/loader/index.cjs.js +1 -0
- package/loader/index.d.ts +24 -0
- package/loader/index.es2017.js +1 -0
- package/loader/index.js +2 -0
- package/package.json +6 -2
- package/www/build/index.esm.js +2 -0
- package/www/build/index.esm.js.map +1 -0
- package/www/build/loader.esm.js.map +1 -0
- package/www/build/ocr-file-uploader.voice-input-module.entry.esm.js.map +1 -0
- package/www/build/p-52e59129.entry.js +2 -0
- package/www/build/p-52e59129.entry.js.map +1 -0
- package/www/build/p-DQuL1Twl.js +2 -0
- package/www/build/p-DQuL1Twl.js.map +1 -0
- package/www/build/p-jmc2yzBp.js +3 -0
- package/www/build/p-jmc2yzBp.js.map +1 -0
- package/www/build/voice-input-module.esm.js +2 -0
- package/www/build/voice-input-module.esm.js.map +1 -0
- package/www/build/voice-input-module.js +33 -0
- package/www/host.config.json +15 -0
- package/www/index.html +922 -0
- package/.editorconfig +0 -15
- package/.prettierrc.json +0 -13
- package/api-key-inject.js +0 -46
- package/env-config.js +0 -4
- package/inject-env.js +0 -20
- package/src/components/ocr-file-uploader/ocr-file-uploader.css +0 -26
- package/src/components/ocr-file-uploader/ocr-file-uploader.tsx +0 -100
- package/src/components/ocr-file-uploader/readme.md +0 -31
- package/src/components/voice-input-module/readme.md +0 -114
- package/src/components/voice-input-module/voice-input-module.css +0 -286
- package/src/components/voice-input-module/voice-input-module.tsx +0 -778
- package/src/components.d.ts +0 -158
- package/src/index.html +0 -1015
- package/src/index.ts +0 -12
- package/src/services/audio-recorder.service.ts +0 -74
- package/src/services/llm.service.ts +0 -221
- package/src/services/speech-to-text.service.ts +0 -70
- package/src/types/form-schema.types.ts +0 -78
- package/src/types/service-providers.types.ts +0 -22
- package/src/utils/schema-converter.ts +0 -494
- package/stencil.config.ts +0 -24
- package/tsconfig.json +0 -30
package/.editorconfig
DELETED
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
# http://editorconfig.org
|
|
2
|
-
|
|
3
|
-
root = true
|
|
4
|
-
|
|
5
|
-
[*]
|
|
6
|
-
charset = utf-8
|
|
7
|
-
indent_style = space
|
|
8
|
-
indent_size = 2
|
|
9
|
-
end_of_line = lf
|
|
10
|
-
insert_final_newline = true
|
|
11
|
-
trim_trailing_whitespace = true
|
|
12
|
-
|
|
13
|
-
[*.md]
|
|
14
|
-
insert_final_newline = false
|
|
15
|
-
trim_trailing_whitespace = false
|
package/.prettierrc.json
DELETED
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"arrowParens": "avoid",
|
|
3
|
-
"bracketSpacing": true,
|
|
4
|
-
"jsxBracketSameLine": false,
|
|
5
|
-
"jsxSingleQuote": false,
|
|
6
|
-
"quoteProps": "consistent",
|
|
7
|
-
"printWidth": 180,
|
|
8
|
-
"semi": true,
|
|
9
|
-
"singleQuote": true,
|
|
10
|
-
"tabWidth": 2,
|
|
11
|
-
"trailingComma": "all",
|
|
12
|
-
"useTabs": false
|
|
13
|
-
}
|
package/api-key-inject.js
DELETED
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
// This script injects the API key from server environment into the client
|
|
2
|
-
// This would normally be handled by a server-side framework, but for demo purposes
|
|
3
|
-
// we'll create a simple endpoint to fetch the key
|
|
4
|
-
|
|
5
|
-
async function getApiKey() {
|
|
6
|
-
try {
|
|
7
|
-
// In a real application, you'd have a secure endpoint that provides the API key
|
|
8
|
-
// For this demo, we'll check if it's available in some global scope
|
|
9
|
-
if (typeof process !== 'undefined' && process.env && process.env.OPENAI_API_KEY) {
|
|
10
|
-
return process.env.OPENAI_API_KEY;
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
// Check if Replit has exposed it as a global variable
|
|
14
|
-
if (window.REPLIT_ENV && window.REPLIT_ENV.OPENAI_API_KEY) {
|
|
15
|
-
return window.REPLIT_ENV.OPENAI_API_KEY;
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
// For demo purposes, we'll show a prompt to enter the API key
|
|
19
|
-
return null;
|
|
20
|
-
} catch (error) {
|
|
21
|
-
console.error('Error getting API key:', error);
|
|
22
|
-
return null;
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
// Function to inject API key into components
|
|
27
|
-
async function injectApiKey() {
|
|
28
|
-
const apiKey = await getApiKey();
|
|
29
|
-
|
|
30
|
-
if (apiKey) {
|
|
31
|
-
// Find all voice-input-module components and set their API key
|
|
32
|
-
const components = document.querySelectorAll('voice-input-module');
|
|
33
|
-
components.forEach(component => {
|
|
34
|
-
component.setAttribute('api-key', apiKey);
|
|
35
|
-
});
|
|
36
|
-
} else {
|
|
37
|
-
console.warn('No API key found. Components will show initialization error until API key is provided.');
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
// Run when DOM is loaded
|
|
42
|
-
if (document.readyState === 'loading') {
|
|
43
|
-
document.addEventListener('DOMContentLoaded', injectApiKey);
|
|
44
|
-
} else {
|
|
45
|
-
injectApiKey();
|
|
46
|
-
}
|
package/env-config.js
DELETED
package/inject-env.js
DELETED
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
// Script to inject environment variables into the client config
|
|
4
|
-
const fs = require('fs');
|
|
5
|
-
const path = require('path');
|
|
6
|
-
|
|
7
|
-
const envConfigPath = path.join(__dirname, 'www', 'env-config.js');
|
|
8
|
-
const apiKey = process.env.OPENAI_API_KEY;
|
|
9
|
-
|
|
10
|
-
if (apiKey) {
|
|
11
|
-
const configContent = `// Environment configuration for client-side
|
|
12
|
-
window.ENV_CONFIG = {
|
|
13
|
-
OPENAI_API_KEY: '${apiKey}'
|
|
14
|
-
};`;
|
|
15
|
-
|
|
16
|
-
fs.writeFileSync(envConfigPath, configContent);
|
|
17
|
-
console.log('Environment variables injected successfully');
|
|
18
|
-
} else {
|
|
19
|
-
console.log('No OPENAI_API_KEY found in environment');
|
|
20
|
-
}
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
.upload-container {
|
|
3
|
-
display: inline-block;
|
|
4
|
-
cursor: pointer;
|
|
5
|
-
width: 50px;
|
|
6
|
-
height: 50px;
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
.upload-button {
|
|
10
|
-
display: flex;
|
|
11
|
-
align-items: center;
|
|
12
|
-
justify-content: center;
|
|
13
|
-
transition: transform 0.2s ease, box-shadow 0.2s ease;
|
|
14
|
-
user-select: none;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
.upload-button svg {
|
|
18
|
-
width: 50px;
|
|
19
|
-
height: 50px;
|
|
20
|
-
stroke: #44ee44;
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
.upload-button:hover svg{
|
|
24
|
-
transform: scale(1.05);
|
|
25
|
-
stroke: #33dd33;
|
|
26
|
-
}
|
|
@@ -1,100 +0,0 @@
|
|
|
1
|
-
import { Component, h, Prop } from '@stencil/core';
|
|
2
|
-
|
|
3
|
-
@Component({
|
|
4
|
-
tag: 'ocr-file-uploader',
|
|
5
|
-
styleUrl: 'ocr-file-uploader.css',
|
|
6
|
-
shadow: true
|
|
7
|
-
})
|
|
8
|
-
export class OcrFileUploader {
|
|
9
|
-
@Prop() batch: boolean = false;
|
|
10
|
-
@Prop() callback: Function;
|
|
11
|
-
|
|
12
|
-
private fileInput!: HTMLInputElement;
|
|
13
|
-
|
|
14
|
-
private triggerUpload = () => {
|
|
15
|
-
this.fileInput.click();
|
|
16
|
-
};
|
|
17
|
-
|
|
18
|
-
private handleFileChange = async (event: Event) => {
|
|
19
|
-
const input = event.target as HTMLInputElement;
|
|
20
|
-
if (!input.files || input.files.length === 0) return;
|
|
21
|
-
|
|
22
|
-
const file = input.files[0];
|
|
23
|
-
|
|
24
|
-
// Here you can handle the file upload to your API
|
|
25
|
-
console.log('Selected file:', file);
|
|
26
|
-
|
|
27
|
-
const formData = new FormData();
|
|
28
|
-
formData.append('file', file);
|
|
29
|
-
|
|
30
|
-
if (this.batch) {
|
|
31
|
-
try {
|
|
32
|
-
const response = await fetch('http://127.0.0.1:5001/api/convert-to-xml', {
|
|
33
|
-
method: 'POST',
|
|
34
|
-
body: formData
|
|
35
|
-
});
|
|
36
|
-
|
|
37
|
-
if (!response.ok) {
|
|
38
|
-
console.error("There has been an error!:", response);
|
|
39
|
-
throw new Error(`HTTP error! status: ${response.status}`);
|
|
40
|
-
}
|
|
41
|
-
// get the file as a blob
|
|
42
|
-
const blob = await response.blob();
|
|
43
|
-
// create a download link
|
|
44
|
-
const url = window.URL.createObjectURL(blob);
|
|
45
|
-
const a = document.createElement('a');
|
|
46
|
-
a.href = url;
|
|
47
|
-
a.download = 'result-'+Date.now().toString()+'.xlsx'; // filename
|
|
48
|
-
document.body.appendChild(a);
|
|
49
|
-
a.click();
|
|
50
|
-
a.remove();
|
|
51
|
-
window.URL.revokeObjectURL(url);
|
|
52
|
-
} catch (err) {
|
|
53
|
-
console.error(err);
|
|
54
|
-
alert('Error uploading file');
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
else {
|
|
58
|
-
try {
|
|
59
|
-
const response = await fetch('http://127.0.0.1:5001/api/convert-to-json', {
|
|
60
|
-
method: 'POST',
|
|
61
|
-
body: formData
|
|
62
|
-
});
|
|
63
|
-
|
|
64
|
-
if (!response.ok) {
|
|
65
|
-
console.error("There has been an error!:", response);
|
|
66
|
-
throw new Error(`HTTP error! status: ${response.status}`);
|
|
67
|
-
}
|
|
68
|
-
const data = await response.json();
|
|
69
|
-
console.log('Upload successful:', data);
|
|
70
|
-
|
|
71
|
-
if (this.callback && data[0] && data[0].content){
|
|
72
|
-
this.callback(data[0].content);
|
|
73
|
-
}
|
|
74
|
-
} catch (err) {
|
|
75
|
-
console.error(err);
|
|
76
|
-
alert('Error uploading file');
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
};
|
|
81
|
-
|
|
82
|
-
render() {
|
|
83
|
-
return (
|
|
84
|
-
<div class="upload-container" onClick={this.triggerUpload}>
|
|
85
|
-
<input
|
|
86
|
-
type="file"
|
|
87
|
-
ref={el => (this.fileInput = el!)}
|
|
88
|
-
onChange={this.handleFileChange}
|
|
89
|
-
style={{ display: 'none' }}
|
|
90
|
-
/>
|
|
91
|
-
<div class="upload-button">
|
|
92
|
-
<svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
93
|
-
<path d="M13.5 3H12H8C6.34315 3 5 4.34315 5 6V18C5 19.6569 6.34315 21 8 21H12M13.5 3L19 8.625M13.5 3V7.625C13.5 8.17728 13.9477 8.625 14.5 8.625H19M19 8.625V11.8125" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
|
94
|
-
<path d="M17.5 21L17.5 15M17.5 15L20 17.5M17.5 15L15 17.5" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
|
95
|
-
</svg>
|
|
96
|
-
</div>
|
|
97
|
-
</div>
|
|
98
|
-
);
|
|
99
|
-
}
|
|
100
|
-
}
|
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
# ocr-file-uploader
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
<!-- Auto Generated Below -->
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
## Properties
|
|
9
|
-
|
|
10
|
-
| Property | Attribute | Description | Type | Default |
|
|
11
|
-
| ---------- | ---------- | ----------- | ---------- | ----------- |
|
|
12
|
-
| `batch` | `batch` | | `boolean` | `false` |
|
|
13
|
-
| `callback` | `callback` | | `Function` | `undefined` |
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
## Dependencies
|
|
17
|
-
|
|
18
|
-
### Used by
|
|
19
|
-
|
|
20
|
-
- [voice-input-module](../voice-input-module)
|
|
21
|
-
|
|
22
|
-
### Graph
|
|
23
|
-
```mermaid
|
|
24
|
-
graph TD;
|
|
25
|
-
voice-input-module --> ocr-file-uploader
|
|
26
|
-
style ocr-file-uploader fill:#f9f,stroke:#333,stroke-width:4px
|
|
27
|
-
```
|
|
28
|
-
|
|
29
|
-
----------------------------------------------
|
|
30
|
-
|
|
31
|
-
*Built with [StencilJS](https://stenciljs.com/)*
|
|
@@ -1,114 +0,0 @@
|
|
|
1
|
-
# voice-input-module
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
<!-- Auto Generated Below -->
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
## Properties
|
|
9
|
-
|
|
10
|
-
| Property | Attribute | Description | Type | Default |
|
|
11
|
-
| ----------------------- | ------------------------- | ----------- | ---------------------------------------------- | -------------------- |
|
|
12
|
-
| `apiKey` | `api-key` | | `string` | `undefined` |
|
|
13
|
-
| `classificationRootUrl` | `classification-root-url` | | `string` | `'http://localhost'` |
|
|
14
|
-
| `context` | `context` | | `"ecoll-veto" \| "ecoteka" \| "ng" \| "track"` | `undefined` |
|
|
15
|
-
| `debug` | `debug` | | `boolean` | `false` |
|
|
16
|
-
| `displayStatus` | `display-status` | | `boolean` | `false` |
|
|
17
|
-
| `formJson` | `form-json` | | `string` | `'{}'` |
|
|
18
|
-
| `inputTypes` | `input-types` | | `("audio" \| "voice" \| "ocr")[]` | `[]` |
|
|
19
|
-
| `language` | `language` | | `"en" \| "fr"` | `'en'` |
|
|
20
|
-
| `renderForm` | `render-form` | | `boolean` | `false` |
|
|
21
|
-
| `serviceConfig` | `service-config` | | `string` | `'{}'` |
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
## Events
|
|
25
|
-
|
|
26
|
-
| Event | Description | Type |
|
|
27
|
-
| ----------------------- | ----------- | ------------------------------------------------------- |
|
|
28
|
-
| `formFilled` | | `CustomEvent<VoiceFormRecorderResult>` |
|
|
29
|
-
| `recordingStateChanged` | | `CustomEvent<{ isRecording: boolean; state: string; }>` |
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
## Methods
|
|
33
|
-
|
|
34
|
-
### `convertJsonToXml(jsonForm: FormSchemaFieldsOnlyExtended) => Promise<string>`
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
#### Parameters
|
|
39
|
-
|
|
40
|
-
| Name | Type | Description |
|
|
41
|
-
| ---------- | ------------------------------ | ----------- |
|
|
42
|
-
| `jsonForm` | `FormSchemaFieldsOnlyExtended` | |
|
|
43
|
-
|
|
44
|
-
#### Returns
|
|
45
|
-
|
|
46
|
-
Type: `Promise<string>`
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
### `convertJsonToXmlLegacy(jsonForm: FormSchema) => Promise<string>`
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
#### Parameters
|
|
55
|
-
|
|
56
|
-
| Name | Type | Description |
|
|
57
|
-
| ---------- | ------------ | ----------- |
|
|
58
|
-
| `jsonForm` | `FormSchema` | |
|
|
59
|
-
|
|
60
|
-
#### Returns
|
|
61
|
-
|
|
62
|
-
Type: `Promise<string>`
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
### `convertXmlToJson(xmlForm: string) => Promise<FormSchemaFieldsOnly>`
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
#### Parameters
|
|
71
|
-
|
|
72
|
-
| Name | Type | Description |
|
|
73
|
-
| --------- | -------- | ----------- |
|
|
74
|
-
| `xmlForm` | `string` | |
|
|
75
|
-
|
|
76
|
-
#### Returns
|
|
77
|
-
|
|
78
|
-
Type: `Promise<FormSchemaFieldsOnly>`
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
### `convertXmlToJsonLegacy(xmlForm: string) => Promise<FormSchema>`
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
#### Parameters
|
|
87
|
-
|
|
88
|
-
| Name | Type | Description |
|
|
89
|
-
| --------- | -------- | ----------- |
|
|
90
|
-
| `xmlForm` | `string` | |
|
|
91
|
-
|
|
92
|
-
#### Returns
|
|
93
|
-
|
|
94
|
-
Type: `Promise<FormSchema>`
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
## Dependencies
|
|
100
|
-
|
|
101
|
-
### Depends on
|
|
102
|
-
|
|
103
|
-
- [ocr-file-uploader](../ocr-file-uploader)
|
|
104
|
-
|
|
105
|
-
### Graph
|
|
106
|
-
```mermaid
|
|
107
|
-
graph TD;
|
|
108
|
-
voice-input-module --> ocr-file-uploader
|
|
109
|
-
style voice-input-module fill:#f9f,stroke:#333,stroke-width:4px
|
|
110
|
-
```
|
|
111
|
-
|
|
112
|
-
----------------------------------------------
|
|
113
|
-
|
|
114
|
-
*Built with [StencilJS](https://stenciljs.com/)*
|
|
@@ -1,286 +0,0 @@
|
|
|
1
|
-
:host {
|
|
2
|
-
display: block;
|
|
3
|
-
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
|
4
|
-
}
|
|
5
|
-
|
|
6
|
-
.row-audio-area {
|
|
7
|
-
display: flex;
|
|
8
|
-
flex-direction: row;
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
.voice-recorder-container {
|
|
12
|
-
display: flex;
|
|
13
|
-
flex-direction: column;
|
|
14
|
-
align-items: center;
|
|
15
|
-
gap: 1rem;
|
|
16
|
-
padding: 1rem;
|
|
17
|
-
border: 1px solid #e5e7eb;
|
|
18
|
-
border-radius: 0.5rem;
|
|
19
|
-
background: #ffffff;
|
|
20
|
-
max-width: 100px;
|
|
21
|
-
margin: 0 auto;
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
.voice-recorder-container-debug {
|
|
25
|
-
display: flex;
|
|
26
|
-
flex-direction: column;
|
|
27
|
-
align-items: center;
|
|
28
|
-
gap: 1rem;
|
|
29
|
-
padding: 1rem;
|
|
30
|
-
border: 1px solid #e5e7eb;
|
|
31
|
-
border-radius: 0.5rem;
|
|
32
|
-
background: #ffffff;
|
|
33
|
-
max-width: 800px;
|
|
34
|
-
margin: 0 auto;
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
.upload-record-container {
|
|
38
|
-
display: inline-block;
|
|
39
|
-
cursor: pointer;
|
|
40
|
-
width: 50px;
|
|
41
|
-
height: 50px;
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
.upload-record-button {
|
|
45
|
-
display: flex;
|
|
46
|
-
align-items: center;
|
|
47
|
-
justify-content: center;
|
|
48
|
-
transition: transform 0.2s ease, box-shadow 0.2s ease;
|
|
49
|
-
user-select: none;
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
.upload-record-button svg {
|
|
53
|
-
width: 50px;
|
|
54
|
-
height: 50px;
|
|
55
|
-
stroke: #4444ee;
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
.upload-record-button svg path {
|
|
59
|
-
fill: #4444ee;
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
.upload-record-button:hover svg {
|
|
63
|
-
transform: scale(1.05);
|
|
64
|
-
stroke: #4444ee;
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
.record-button {
|
|
68
|
-
display: flex;
|
|
69
|
-
align-items: center;
|
|
70
|
-
justify-content: center;
|
|
71
|
-
width: 50px;
|
|
72
|
-
height: 50px;
|
|
73
|
-
border: none;
|
|
74
|
-
border-radius: 50%;
|
|
75
|
-
background: #ee4444;
|
|
76
|
-
color: white;
|
|
77
|
-
cursor: pointer;
|
|
78
|
-
transition: all 0.2s ease;
|
|
79
|
-
position: relative;
|
|
80
|
-
overflow: hidden;
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
.record-button:hover:not(:disabled) {
|
|
84
|
-
background: #dd3333;
|
|
85
|
-
transform: scale(1.05);
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
.record-button:disabled {
|
|
89
|
-
opacity: 0.6;
|
|
90
|
-
cursor: not-allowed;
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
.record-button.recording {
|
|
94
|
-
background: #dd3333;
|
|
95
|
-
animation: pulse 1.5s infinite;
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
.record-button.processing {
|
|
99
|
-
background: #3b82f6;
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
@keyframes pulse {
|
|
103
|
-
0% {
|
|
104
|
-
box-shadow: 0 0 0 0 rgba(239, 68, 68, 0.7);
|
|
105
|
-
}
|
|
106
|
-
70% {
|
|
107
|
-
box-shadow: 0 0 0 10px rgba(239, 68, 68, 0);
|
|
108
|
-
}
|
|
109
|
-
100% {
|
|
110
|
-
box-shadow: 0 0 0 0 rgba(239, 68, 68, 0);
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
.record-icon {
|
|
115
|
-
width: 24px;
|
|
116
|
-
height: 24px;
|
|
117
|
-
fill: currentColor;
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
.status-text {
|
|
121
|
-
font-size: 0.875rem;
|
|
122
|
-
color: #6b7280;
|
|
123
|
-
text-align: center;
|
|
124
|
-
min-height: 1.25rem;
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
.status-text.error {
|
|
128
|
-
color: #ee4444;
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
.status-text.success {
|
|
132
|
-
color: #10b981;
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
.debug-panel {
|
|
136
|
-
width: 100%;
|
|
137
|
-
margin-top: 1rem;
|
|
138
|
-
padding: 1rem;
|
|
139
|
-
background: #f9fafb;
|
|
140
|
-
border: 1px solid #e5e7eb;
|
|
141
|
-
border-radius: 0.375rem;
|
|
142
|
-
font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace;
|
|
143
|
-
font-size: 0.75rem;
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
.debug-title {
|
|
147
|
-
font-weight: 600;
|
|
148
|
-
margin-bottom: 0.5rem;
|
|
149
|
-
color: #374151;
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
.debug-content {
|
|
153
|
-
white-space: pre-wrap;
|
|
154
|
-
word-break: break-word;
|
|
155
|
-
color: #6b7280;
|
|
156
|
-
max-height: 200px;
|
|
157
|
-
overflow-y: auto;
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
.permissions-warning {
|
|
161
|
-
padding: 0.75rem;
|
|
162
|
-
background: #fef3c7;
|
|
163
|
-
border: 1px solid #f59e0b;
|
|
164
|
-
border-radius: 0.375rem;
|
|
165
|
-
color: #92400e;
|
|
166
|
-
font-size: 0.875rem;
|
|
167
|
-
text-align: center;
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
.form-preview {
|
|
171
|
-
width: 100%;
|
|
172
|
-
margin-top: 1rem;
|
|
173
|
-
padding: 1rem;
|
|
174
|
-
background: #f8fafc;
|
|
175
|
-
border: 1px solid #e2e8f0;
|
|
176
|
-
border-radius: 0.375rem;
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
.form-preview-title {
|
|
180
|
-
font-weight: 600;
|
|
181
|
-
margin-bottom: 0.5rem;
|
|
182
|
-
color: #1e293b;
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
.form-field {
|
|
186
|
-
margin-bottom: 0.5rem;
|
|
187
|
-
font-size: 0.875rem;
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
.field-name {
|
|
191
|
-
font-weight: 500;
|
|
192
|
-
color: #475569;
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
.field-value {
|
|
196
|
-
color: #64748b;
|
|
197
|
-
margin-left: 0.5rem;
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
.field-value.filled {
|
|
201
|
-
color: #059669;
|
|
202
|
-
font-weight: 500;
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
.voice-filled-form {
|
|
206
|
-
display: flex;
|
|
207
|
-
flex-direction: column;
|
|
208
|
-
gap: 1rem;
|
|
209
|
-
margin-top: 1rem;
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
.form-group {
|
|
213
|
-
display: flex;
|
|
214
|
-
flex-direction: column;
|
|
215
|
-
gap: 0.25rem;
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
.form-label {
|
|
219
|
-
font-weight: 500;
|
|
220
|
-
color: #374151;
|
|
221
|
-
font-size: 0.875rem;
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
.required {
|
|
225
|
-
color: #ee4444;
|
|
226
|
-
margin-left: 0.125rem;
|
|
227
|
-
}
|
|
228
|
-
|
|
229
|
-
.form-input {
|
|
230
|
-
padding: 0.5rem;
|
|
231
|
-
border: 1px solid #d1d5db;
|
|
232
|
-
border-radius: 0.375rem;
|
|
233
|
-
font-size: 0.875rem;
|
|
234
|
-
transition: border-color 0.2s ease;
|
|
235
|
-
}
|
|
236
|
-
|
|
237
|
-
.form-input:focus {
|
|
238
|
-
outline: none;
|
|
239
|
-
border-color: #3b82f6;
|
|
240
|
-
box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.1);
|
|
241
|
-
}
|
|
242
|
-
|
|
243
|
-
.form-checkbox {
|
|
244
|
-
width: auto;
|
|
245
|
-
padding: 0;
|
|
246
|
-
margin: 0;
|
|
247
|
-
}
|
|
248
|
-
|
|
249
|
-
select.form-input {
|
|
250
|
-
background-color: white;
|
|
251
|
-
cursor: pointer;
|
|
252
|
-
}
|
|
253
|
-
|
|
254
|
-
input[type="date"].form-input {
|
|
255
|
-
cursor: pointer;
|
|
256
|
-
}
|
|
257
|
-
|
|
258
|
-
.readonly-select {
|
|
259
|
-
background: #f9fafb;
|
|
260
|
-
border: 1px solid #d1d5db;
|
|
261
|
-
border-radius: 0.375rem;
|
|
262
|
-
padding: 0.5rem;
|
|
263
|
-
}
|
|
264
|
-
|
|
265
|
-
.select-placeholder {
|
|
266
|
-
font-size: 0.875rem;
|
|
267
|
-
color: #6b7280;
|
|
268
|
-
margin-bottom: 0.5rem;
|
|
269
|
-
}
|
|
270
|
-
|
|
271
|
-
.select-options-list {
|
|
272
|
-
list-style: none;
|
|
273
|
-
margin: 0;
|
|
274
|
-
padding: 0;
|
|
275
|
-
display: flex;
|
|
276
|
-
flex-wrap: wrap;
|
|
277
|
-
gap: 0.25rem;
|
|
278
|
-
}
|
|
279
|
-
|
|
280
|
-
.select-option {
|
|
281
|
-
background: #e5e7eb;
|
|
282
|
-
padding: 0.25rem 0.5rem;
|
|
283
|
-
border-radius: 0.25rem;
|
|
284
|
-
font-size: 0.875rem;
|
|
285
|
-
color: #374151;
|
|
286
|
-
}
|