@gradio/core 1.1.3 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +51 -0
- package/dist/src/Blocks.svelte +33 -2
- package/dist/src/_init.js +2 -2
- package/dist/src/api_docs/ApiBanner.svelte +6 -2
- package/dist/src/api_docs/ApiBanner.svelte.d.ts +1 -1
- package/dist/src/api_docs/ApiDocs.svelte +41 -25
- package/dist/src/api_docs/CodeSnippet.svelte +67 -170
- package/dist/src/api_docs/CodeSnippet.svelte.d.ts +2 -6
- package/dist/src/api_docs/CopyMarkdown.svelte +7 -2
- package/dist/src/api_docs/CopyMarkdown.svelte.d.ts +1 -1
- package/dist/src/api_docs/InstallSnippet.svelte +6 -1
- package/dist/src/api_docs/InstallSnippet.svelte.d.ts +1 -1
- package/dist/src/api_docs/ParametersSnippet.svelte +6 -1
- package/dist/src/api_docs/ParametersSnippet.svelte.d.ts +1 -1
- package/dist/src/api_docs/RecordingSnippet.svelte +6 -1
- package/dist/src/api_docs/RecordingSnippet.svelte.d.ts +1 -1
- package/dist/src/api_docs/ResponseSnippet.svelte +6 -1
- package/dist/src/api_docs/ResponseSnippet.svelte.d.ts +1 -1
- package/dist/src/api_docs/Settings.svelte +2 -7
- package/dist/src/api_docs/SettingsBanner.svelte +0 -3
- package/dist/src/api_docs/SkillSnippet.svelte +125 -0
- package/dist/src/api_docs/SkillSnippet.svelte.d.ts +20 -0
- package/dist/src/api_docs/img/skill.svg +10 -0
- package/dist/src/api_docs/utils.d.ts +0 -1
- package/dist/src/api_docs/utils.js +0 -22
- package/dist/src/dependency.d.ts +3 -1
- package/dist/src/dependency.js +39 -1
- package/dist/src/gradio_helper.js +5 -13
- package/dist/src/i18n.d.ts +1 -3
- package/dist/src/i18n.js +6 -53
- package/dist/src/init.svelte.js +81 -82
- package/package.json +49 -49
- package/src/Blocks.svelte +33 -2
- package/src/_init.ts +2 -2
- package/src/api_docs/ApiBanner.svelte +6 -2
- package/src/api_docs/ApiDocs.svelte +41 -25
- package/src/api_docs/CodeSnippet.svelte +67 -170
- package/src/api_docs/CopyMarkdown.svelte +7 -2
- package/src/api_docs/InstallSnippet.svelte +6 -1
- package/src/api_docs/ParametersSnippet.svelte +6 -1
- package/src/api_docs/RecordingSnippet.svelte +6 -1
- package/src/api_docs/ResponseSnippet.svelte +6 -1
- package/src/api_docs/Settings.svelte +2 -7
- package/src/api_docs/SettingsBanner.svelte +0 -3
- package/src/api_docs/SkillSnippet.svelte +125 -0
- package/src/api_docs/img/skill.svg +10 -0
- package/src/api_docs/utils.ts +0 -25
- package/src/dependency.ts +39 -1
- package/src/gradio_helper.ts +5 -17
- package/src/i18n.test.ts +41 -9
- package/src/i18n.ts +9 -62
- package/src/init.svelte.ts +95 -99
|
@@ -5,7 +5,12 @@
|
|
|
5
5
|
export let is_running: boolean;
|
|
6
6
|
export let endpoint_returns: any;
|
|
7
7
|
export let js_returns: any;
|
|
8
|
-
export let current_language:
|
|
8
|
+
export let current_language:
|
|
9
|
+
| "python"
|
|
10
|
+
| "javascript"
|
|
11
|
+
| "bash"
|
|
12
|
+
| "skill"
|
|
13
|
+
| "mcp";
|
|
9
14
|
</script>
|
|
10
15
|
|
|
11
16
|
<h4>
|
|
@@ -15,7 +15,7 @@ declare const ParametersSnippet: $$__sveltets_2_IsomorphicComponent<{
|
|
|
15
15
|
is_running: boolean;
|
|
16
16
|
endpoint_returns: any;
|
|
17
17
|
js_returns: any;
|
|
18
|
-
current_language: "python" | "javascript" | "bash" | "mcp";
|
|
18
|
+
current_language: "python" | "javascript" | "bash" | "skill" | "mcp";
|
|
19
19
|
}, {
|
|
20
20
|
[evt: string]: CustomEvent<any>;
|
|
21
21
|
}, {}, {}, string>;
|
|
@@ -9,7 +9,12 @@
|
|
|
9
9
|
export let short_root: string;
|
|
10
10
|
export let root: string;
|
|
11
11
|
export let api_prefix = "";
|
|
12
|
-
export let current_language:
|
|
12
|
+
export let current_language:
|
|
13
|
+
| "python"
|
|
14
|
+
| "javascript"
|
|
15
|
+
| "bash"
|
|
16
|
+
| "skill"
|
|
17
|
+
| "mcp";
|
|
13
18
|
export let username: string | null;
|
|
14
19
|
|
|
15
20
|
let python_code: HTMLElement;
|
|
@@ -17,7 +17,7 @@ declare const RecordingSnippet: $$__sveltets_2_IsomorphicComponent<{
|
|
|
17
17
|
short_root: string;
|
|
18
18
|
root: string;
|
|
19
19
|
api_prefix?: string;
|
|
20
|
-
current_language: "python" | "javascript" | "bash" | "mcp";
|
|
20
|
+
current_language: "python" | "javascript" | "bash" | "skill" | "mcp";
|
|
21
21
|
username: string | null;
|
|
22
22
|
api_calls?: Payload[];
|
|
23
23
|
}, {
|
|
@@ -4,7 +4,12 @@
|
|
|
4
4
|
export let is_running: boolean;
|
|
5
5
|
export let endpoint_returns: any;
|
|
6
6
|
export let js_returns: any;
|
|
7
|
-
export let current_language:
|
|
7
|
+
export let current_language:
|
|
8
|
+
| "python"
|
|
9
|
+
| "javascript"
|
|
10
|
+
| "bash"
|
|
11
|
+
| "skill"
|
|
12
|
+
| "mcp";
|
|
8
13
|
</script>
|
|
9
14
|
|
|
10
15
|
<h4>
|
|
@@ -15,7 +15,7 @@ declare const ResponseSnippet: $$__sveltets_2_IsomorphicComponent<{
|
|
|
15
15
|
is_running: boolean;
|
|
16
16
|
endpoint_returns: any;
|
|
17
17
|
js_returns: any;
|
|
18
|
-
current_language: "python" | "javascript" | "bash" | "mcp";
|
|
18
|
+
current_language: "python" | "javascript" | "bash" | "skill" | "mcp";
|
|
19
19
|
}, {
|
|
20
20
|
[evt: string]: CustomEvent<any>;
|
|
21
21
|
}, {}, {}, string>;
|
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
import { BaseCheckbox as Checkbox } from "@gradio/checkbox";
|
|
7
7
|
import { language_choices, changeLocale } from "../i18n";
|
|
8
8
|
import { locale, _ } from "svelte-i18n";
|
|
9
|
+
import { get } from "svelte/store";
|
|
9
10
|
import record from "./img/record.svg";
|
|
10
11
|
|
|
11
12
|
let {
|
|
@@ -52,15 +53,9 @@
|
|
|
52
53
|
};
|
|
53
54
|
});
|
|
54
55
|
|
|
55
|
-
let current_locale: string = $state("en");
|
|
56
|
+
let current_locale: string = $state(get(locale) ?? "en");
|
|
56
57
|
let current_theme: "light" | "dark" | "system" = $state("system");
|
|
57
58
|
|
|
58
|
-
locale.subscribe((value) => {
|
|
59
|
-
if (value) {
|
|
60
|
-
current_locale = value;
|
|
61
|
-
}
|
|
62
|
-
});
|
|
63
|
-
|
|
64
59
|
function handleLanguageChange(value: string): void {
|
|
65
60
|
const new_locale = value;
|
|
66
61
|
changeLocale(new_locale);
|
|
@@ -2,11 +2,8 @@
|
|
|
2
2
|
import { _ } from "svelte-i18n";
|
|
3
3
|
import settings_logo from "./img/settings-logo.svg";
|
|
4
4
|
import Clear from "./img/clear.svelte";
|
|
5
|
-
import { setupi18n } from "../i18n";
|
|
6
5
|
|
|
7
6
|
let { root, onclose }: { root: string; onclose?: () => void } = $props();
|
|
8
|
-
|
|
9
|
-
setupi18n();
|
|
10
7
|
</script>
|
|
11
8
|
|
|
12
9
|
<h2>
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { Block } from "@gradio/atoms";
|
|
3
|
+
import CopyButton from "./CopyButton.svelte";
|
|
4
|
+
|
|
5
|
+
export let space_id: string | null;
|
|
6
|
+
|
|
7
|
+
$: effective_space_id = space_id || "";
|
|
8
|
+
$: skill_id = effective_space_id.replace("/", "-");
|
|
9
|
+
$: install_gradio = "pip install --upgrade gradio";
|
|
10
|
+
$: install_cmd_claude = `gradio skills add ${effective_space_id} --claude`;
|
|
11
|
+
$: install_cmd_cursor = `gradio skills add ${effective_space_id} --cursor`;
|
|
12
|
+
$: install_cmd_codex = `gradio skills add ${effective_space_id} --codex`;
|
|
13
|
+
|
|
14
|
+
$: skill_preview = `---
|
|
15
|
+
name: ${skill_id}
|
|
16
|
+
description: Use the ${effective_space_id} Gradio Space via API. Provides Python, JavaScript, and cURL usage examples.
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
# ${effective_space_id}
|
|
20
|
+
|
|
21
|
+
This skill describes how to use the ${effective_space_id} Gradio Space programmatically.
|
|
22
|
+
|
|
23
|
+
## API Endpoints
|
|
24
|
+
...`;
|
|
25
|
+
</script>
|
|
26
|
+
|
|
27
|
+
<div class="skill-content">
|
|
28
|
+
<p class="padded">1. Make sure you are using the latest version of Gradio:</p>
|
|
29
|
+
<Block>
|
|
30
|
+
<code>
|
|
31
|
+
<div class="copy">
|
|
32
|
+
<CopyButton code={install_gradio} />
|
|
33
|
+
</div>
|
|
34
|
+
<div>
|
|
35
|
+
<pre>$ {install_gradio}</pre>
|
|
36
|
+
</div>
|
|
37
|
+
</code>
|
|
38
|
+
</Block>
|
|
39
|
+
|
|
40
|
+
<p class="padded">
|
|
41
|
+
2. Install the usage of this Space as a Skill for your coding agent by
|
|
42
|
+
running this in your terminal:
|
|
43
|
+
</p>
|
|
44
|
+
<Block>
|
|
45
|
+
<code>
|
|
46
|
+
<div class="copy">
|
|
47
|
+
<CopyButton code={install_cmd_claude} />
|
|
48
|
+
</div>
|
|
49
|
+
<div>
|
|
50
|
+
<pre>$ {install_cmd_claude}</pre>
|
|
51
|
+
</div>
|
|
52
|
+
</code>
|
|
53
|
+
</Block>
|
|
54
|
+
<p class="hint">
|
|
55
|
+
Instead of <span class="inline-code">--claude</span>, you can use
|
|
56
|
+
<span class="inline-code">--cursor</span>,
|
|
57
|
+
<span class="inline-code">--codex</span>, or
|
|
58
|
+
<span class="inline-code">--opencode</span>. Combine flags to install for
|
|
59
|
+
multiple agents. Use <span class="inline-code">--global</span> to install user-level
|
|
60
|
+
instead of per-project.
|
|
61
|
+
</p>
|
|
62
|
+
|
|
63
|
+
<p class="padded">
|
|
64
|
+
3. This will add a skill to your coding agent that describes how to use this
|
|
65
|
+
Space via Python, JavaScript, and cURL API. The skill will look like this:
|
|
66
|
+
</p>
|
|
67
|
+
<Block>
|
|
68
|
+
<code>
|
|
69
|
+
<div class="copy">
|
|
70
|
+
<CopyButton code={skill_preview} />
|
|
71
|
+
</div>
|
|
72
|
+
<div>
|
|
73
|
+
<pre>{skill_preview}</pre>
|
|
74
|
+
</div>
|
|
75
|
+
</code>
|
|
76
|
+
</Block>
|
|
77
|
+
</div>
|
|
78
|
+
|
|
79
|
+
<style>
|
|
80
|
+
.skill-content {
|
|
81
|
+
margin-top: var(--size-2);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
p.padded {
|
|
85
|
+
padding: 15px 0px;
|
|
86
|
+
font-size: var(--text-lg);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
.hint {
|
|
90
|
+
margin-top: var(--size-2);
|
|
91
|
+
color: var(--body-text-color);
|
|
92
|
+
opacity: 0.8;
|
|
93
|
+
font-size: var(--text-md);
|
|
94
|
+
line-height: 1.6;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
.inline-code {
|
|
98
|
+
display: inline;
|
|
99
|
+
font-family: var(--font-mono);
|
|
100
|
+
font-size: var(--text-md);
|
|
101
|
+
background: var(--background-fill-secondary);
|
|
102
|
+
padding: 1px 4px;
|
|
103
|
+
border-radius: var(--radius-sm);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
code pre {
|
|
107
|
+
overflow-x: auto;
|
|
108
|
+
color: var(--body-text-color);
|
|
109
|
+
font-family: var(--font-mono);
|
|
110
|
+
tab-size: 2;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
code {
|
|
114
|
+
position: relative;
|
|
115
|
+
display: block;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
.copy {
|
|
119
|
+
position: absolute;
|
|
120
|
+
top: 0;
|
|
121
|
+
right: 0;
|
|
122
|
+
margin-top: -5px;
|
|
123
|
+
margin-right: -5px;
|
|
124
|
+
}
|
|
125
|
+
</style>
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
interface $$__sveltets_2_IsomorphicComponent<Props extends Record<string, any> = any, Events extends Record<string, any> = any, Slots extends Record<string, any> = any, Exports = {}, Bindings = string> {
|
|
2
|
+
new (options: import('svelte').ComponentConstructorOptions<Props>): import('svelte').SvelteComponent<Props, Events, Slots> & {
|
|
3
|
+
$$bindings?: Bindings;
|
|
4
|
+
} & Exports;
|
|
5
|
+
(internal: unknown, props: Props & {
|
|
6
|
+
$$events?: Events;
|
|
7
|
+
$$slots?: Slots;
|
|
8
|
+
}): Exports & {
|
|
9
|
+
$set?: any;
|
|
10
|
+
$on?: any;
|
|
11
|
+
};
|
|
12
|
+
z_$$bindings?: Bindings;
|
|
13
|
+
}
|
|
14
|
+
declare const SkillSnippet: $$__sveltets_2_IsomorphicComponent<{
|
|
15
|
+
space_id: string | null;
|
|
16
|
+
}, {
|
|
17
|
+
[evt: string]: CustomEvent<any>;
|
|
18
|
+
}, {}, {}, string>;
|
|
19
|
+
type SkillSnippet = InstanceType<typeof SkillSnippet>;
|
|
20
|
+
export default SkillSnippet;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="14 22 122 106" style="background-color: #ffffff;">
|
|
2
|
+
<rect x="22" y="28" width="106" height="94" rx="8" fill="none" stroke="#374151" stroke-width="6"/>
|
|
3
|
+
<rect x="22" y="28" width="106" height="20" rx="8" fill="#374151" fill-opacity="0.08"/>
|
|
4
|
+
<circle cx="38" cy="38" r="4" fill="#ff5f57"/>
|
|
5
|
+
<circle cx="52" cy="38" r="4" fill="#febc2e"/>
|
|
6
|
+
<circle cx="66" cy="38" r="4" fill="#28c840"/>
|
|
7
|
+
<text x="38" y="76" fill="#374151" font-family="monospace" font-size="22" font-weight="bold">>_</text>
|
|
8
|
+
<rect x="38" y="88" width="50" height="4" rx="2" fill="#374151" fill-opacity="0.35"/>
|
|
9
|
+
<rect x="38" y="100" width="35" height="4" rx="2" fill="#374151" fill-opacity="0.2"/>
|
|
10
|
+
</svg>
|
|
@@ -1,4 +1,3 @@
|
|
|
1
1
|
export declare function represent_value(value: string, type: string | undefined, lang?: "js" | "py" | "bash" | null): string | null | number | boolean | Record<string, unknown>;
|
|
2
|
-
export declare function is_potentially_nested_file_data(obj: any): boolean;
|
|
3
2
|
export declare function format_latency(val: number): string;
|
|
4
3
|
export declare function get_color_from_success_rate(success_rate: number): string;
|
|
@@ -48,28 +48,6 @@ export function represent_value(value, type, lang = null) {
|
|
|
48
48
|
}
|
|
49
49
|
return stringify_except_file_function(value);
|
|
50
50
|
}
|
|
51
|
-
export function is_potentially_nested_file_data(obj) {
|
|
52
|
-
if (typeof obj === "object" && obj !== null) {
|
|
53
|
-
if (obj.hasOwnProperty("url") && obj.hasOwnProperty("meta")) {
|
|
54
|
-
if (typeof obj.meta === "object" &&
|
|
55
|
-
obj.meta !== null &&
|
|
56
|
-
obj.meta._type === "gradio.FileData") {
|
|
57
|
-
return true;
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
if (typeof obj === "object" && obj !== null) {
|
|
62
|
-
for (let key in obj) {
|
|
63
|
-
if (typeof obj[key] === "object") {
|
|
64
|
-
let result = is_potentially_nested_file_data(obj[key]);
|
|
65
|
-
if (result) {
|
|
66
|
-
return true;
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
return false;
|
|
72
|
-
}
|
|
73
51
|
function simplify_file_data(obj) {
|
|
74
52
|
if (typeof obj === "object" && obj !== null && !Array.isArray(obj)) {
|
|
75
53
|
if ("url" in obj &&
|
package/dist/src/dependency.d.ts
CHANGED
|
@@ -85,8 +85,10 @@ export declare class DependencyManager {
|
|
|
85
85
|
get_state_cb: GetStateCallback;
|
|
86
86
|
rerender_cb: RerenderCallback;
|
|
87
87
|
log_cb: LogCallback;
|
|
88
|
+
on_connection_lost_cb: () => void;
|
|
88
89
|
loading_stati: LoadingStatus;
|
|
89
|
-
|
|
90
|
+
connection_lost: boolean;
|
|
91
|
+
constructor(dependencies: IDependency[], client: Client, update_state_cb: (id: number, state: Record<string, unknown>, check_visibility?: boolean) => Promise<void>, get_state_cb: (id: number) => Promise<Record<string, unknown> | null>, rerender_cb: (components: ComponentMeta[], layout: LayoutNode) => void, log_cb: (title: string, message: string, fn_index: number, type: ToastMessage["type"], duration?: number | null, visible?: boolean) => void, add_to_api_calls: (payload: Payload) => void, on_connection_lost_cb: () => void);
|
|
90
92
|
reload(dependencies: IDependency[], update_state: UpdateStateCallback, get_state: GetStateCallback, rerender: RerenderCallback, client: Client): void;
|
|
91
93
|
register_loading_stati(deps: Map<number, Dependency>): void;
|
|
92
94
|
clear_loading_status(component_id: number): void;
|
package/dist/src/dependency.js
CHANGED
|
@@ -118,13 +118,16 @@ export class DependencyManager {
|
|
|
118
118
|
get_state_cb;
|
|
119
119
|
rerender_cb;
|
|
120
120
|
log_cb;
|
|
121
|
+
on_connection_lost_cb;
|
|
121
122
|
loading_stati = new LoadingStatus();
|
|
122
|
-
|
|
123
|
+
connection_lost = false;
|
|
124
|
+
constructor(dependencies, client, update_state_cb, get_state_cb, rerender_cb, log_cb, add_to_api_calls, on_connection_lost_cb) {
|
|
123
125
|
this.add_to_api_calls = add_to_api_calls;
|
|
124
126
|
this.log_cb = log_cb;
|
|
125
127
|
this.update_state_cb = update_state_cb;
|
|
126
128
|
this.get_state_cb = get_state_cb;
|
|
127
129
|
this.rerender_cb = rerender_cb;
|
|
130
|
+
this.on_connection_lost_cb = on_connection_lost_cb;
|
|
128
131
|
this.client = client;
|
|
129
132
|
this.reload(dependencies, update_state_cb, get_state_cb, rerender_cb, client);
|
|
130
133
|
}
|
|
@@ -180,6 +183,8 @@ export class DependencyManager {
|
|
|
180
183
|
* @returns a value if there is no backend fn, a 'submission' if there is a backend fn, or null if there is no dependency
|
|
181
184
|
*/
|
|
182
185
|
async dispatch(event_meta) {
|
|
186
|
+
if (this.connection_lost)
|
|
187
|
+
return;
|
|
183
188
|
let deps;
|
|
184
189
|
if (event_meta.type === "fn") {
|
|
185
190
|
const dep = this.dependencies_by_fn.get(event_meta.fn_index);
|
|
@@ -314,6 +319,19 @@ export class DependencyManager {
|
|
|
314
319
|
this.update_loading_stati_state();
|
|
315
320
|
}
|
|
316
321
|
else if (result.stage === "error") {
|
|
322
|
+
if (result.broken || result.session_not_found) {
|
|
323
|
+
if (!this.connection_lost) {
|
|
324
|
+
this.connection_lost = true;
|
|
325
|
+
this.on_connection_lost_cb();
|
|
326
|
+
}
|
|
327
|
+
this.loading_stati.update({
|
|
328
|
+
status: "complete",
|
|
329
|
+
fn_index: dep.id,
|
|
330
|
+
stream_state: null
|
|
331
|
+
});
|
|
332
|
+
this.update_loading_stati_state();
|
|
333
|
+
break submit_loop;
|
|
334
|
+
}
|
|
317
335
|
if (Array.isArray(result?.message)) {
|
|
318
336
|
result.message.forEach((m, i) => {
|
|
319
337
|
this.update_state_cb(dep.inputs[i], {
|
|
@@ -567,6 +585,26 @@ export class DependencyManager {
|
|
|
567
585
|
});
|
|
568
586
|
this.update_loading_stati_state();
|
|
569
587
|
this.submissions.delete(id);
|
|
588
|
+
// Need to trigger any dependencies that are waiting for this one to complete
|
|
589
|
+
const { failure, all } = this.dependencies_by_fn
|
|
590
|
+
.get(id)
|
|
591
|
+
?.get_triggers() || { failure: [], all: [] };
|
|
592
|
+
failure.forEach((dep_id) => {
|
|
593
|
+
this.dispatch({
|
|
594
|
+
type: "fn",
|
|
595
|
+
fn_index: dep_id,
|
|
596
|
+
event_data: null,
|
|
597
|
+
target_id: id
|
|
598
|
+
});
|
|
599
|
+
});
|
|
600
|
+
all.forEach((dep_id) => {
|
|
601
|
+
this.dispatch({
|
|
602
|
+
type: "fn",
|
|
603
|
+
fn_index: dep_id,
|
|
604
|
+
event_data: null,
|
|
605
|
+
target_id: id
|
|
606
|
+
});
|
|
607
|
+
});
|
|
570
608
|
}
|
|
571
609
|
}
|
|
572
610
|
}
|
|
@@ -1,28 +1,20 @@
|
|
|
1
|
-
import { all_common_keys } from "./i18n";
|
|
2
1
|
import { _ } from "svelte-i18n";
|
|
3
2
|
import { get, derived } from "svelte/store";
|
|
4
3
|
export { Gradio } from "@gradio/utils";
|
|
4
|
+
import { I18N_MARKER, translate_i18n_marker } from "@gradio/utils";
|
|
5
5
|
export function formatter(value) {
|
|
6
6
|
if (value == null) {
|
|
7
7
|
return "";
|
|
8
8
|
}
|
|
9
9
|
const string_value = String(value);
|
|
10
10
|
const translate = get(_);
|
|
11
|
-
|
|
11
|
+
if (string_value.includes(I18N_MARKER)) {
|
|
12
|
+
return translate_i18n_marker(string_value, translate);
|
|
13
|
+
}
|
|
14
|
+
const direct_translation = translate(string_value);
|
|
12
15
|
if (direct_translation !== string_value) {
|
|
13
16
|
return direct_translation;
|
|
14
17
|
}
|
|
15
|
-
const lower_value = string_value.toLowerCase();
|
|
16
|
-
for (const common_key of all_common_keys) {
|
|
17
|
-
const key_name = common_key.substring(common_key.indexOf(".") + 1);
|
|
18
|
-
if (lower_value === key_name) {
|
|
19
|
-
const translation = translate(common_key);
|
|
20
|
-
if (translation !== common_key) {
|
|
21
|
-
return translation;
|
|
22
|
-
}
|
|
23
|
-
break;
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
18
|
return string_value;
|
|
27
19
|
}
|
|
28
20
|
export const reactive_formatter = derived(_, () => formatter);
|
package/dist/src/i18n.d.ts
CHANGED
|
@@ -15,11 +15,9 @@ export interface LangsRecord {
|
|
|
15
15
|
};
|
|
16
16
|
}
|
|
17
17
|
export declare function is_translation_metadata(obj: any): obj is I18nData;
|
|
18
|
-
export
|
|
19
|
-
export declare function translate_if_needed(value: any): string;
|
|
18
|
+
export { I18N_MARKER as i18n_marker } from "@gradio/utils";
|
|
20
19
|
export declare function process_langs(): LangsRecord;
|
|
21
20
|
export declare const language_choices: [string, string][];
|
|
22
|
-
export declare let all_common_keys: Set<string>;
|
|
23
21
|
export declare function setupi18n(custom_translations?: Record<string, Record<string, string>>, preferred_locale?: string): Promise<void>;
|
|
24
22
|
export declare function changeLocale(new_locale: string): void;
|
|
25
23
|
export declare function get_initial_locale(browser_locale: string | null, available_locales: string[], fallback_locale?: string): string;
|
package/dist/src/i18n.js
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { addMessages, init, getLocaleFromNavigator, locale, register, waitLocale } from "svelte-i18n";
|
|
2
|
-
import { formatter } from "./gradio_helper";
|
|
3
2
|
import { loading } from "./lang/loading";
|
|
4
3
|
const lang_map = {
|
|
5
4
|
ar: "العربية",
|
|
@@ -43,55 +42,7 @@ export function is_translation_metadata(obj) {
|
|
|
43
42
|
typeof obj.key === "string";
|
|
44
43
|
return result;
|
|
45
44
|
}
|
|
46
|
-
export
|
|
47
|
-
// handles strings with embedded JSON metadata of shape "__i18n__{"key": "some.key"}"
|
|
48
|
-
export function translate_if_needed(value) {
|
|
49
|
-
if (typeof value !== "string") {
|
|
50
|
-
return value;
|
|
51
|
-
}
|
|
52
|
-
const marker_index = value.indexOf(i18n_marker);
|
|
53
|
-
if (marker_index === -1) {
|
|
54
|
-
return value;
|
|
55
|
-
}
|
|
56
|
-
try {
|
|
57
|
-
const before_marker = marker_index > 0 ? value.substring(0, marker_index) : "";
|
|
58
|
-
const after_marker_index = marker_index + i18n_marker.length;
|
|
59
|
-
const json_start = value.indexOf("{", after_marker_index);
|
|
60
|
-
let json_end = -1;
|
|
61
|
-
let bracket_count = 0;
|
|
62
|
-
for (let i = json_start; i < value.length; i++) {
|
|
63
|
-
if (value[i] === "{")
|
|
64
|
-
bracket_count++;
|
|
65
|
-
if (value[i] === "}")
|
|
66
|
-
bracket_count--;
|
|
67
|
-
if (bracket_count === 0) {
|
|
68
|
-
json_end = i + 1;
|
|
69
|
-
break;
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
if (json_end === -1) {
|
|
73
|
-
console.error("Could not find end of JSON in i18n string");
|
|
74
|
-
return value;
|
|
75
|
-
}
|
|
76
|
-
const metadata_json = value.substring(json_start, json_end);
|
|
77
|
-
const after_json = json_end < value.length ? value.substring(json_end) : "";
|
|
78
|
-
try {
|
|
79
|
-
const metadata = JSON.parse(metadata_json);
|
|
80
|
-
if (metadata && metadata.key) {
|
|
81
|
-
const translated = formatter(metadata.key);
|
|
82
|
-
return before_marker + translated + after_json;
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
catch (jsonError) {
|
|
86
|
-
console.error("Error parsing i18n JSON:", jsonError);
|
|
87
|
-
}
|
|
88
|
-
return value;
|
|
89
|
-
}
|
|
90
|
-
catch (e) {
|
|
91
|
-
console.error("Error processing translation:", e);
|
|
92
|
-
return value;
|
|
93
|
-
}
|
|
94
|
-
}
|
|
45
|
+
export { I18N_MARKER as i18n_marker } from "@gradio/utils";
|
|
95
46
|
export function process_langs() {
|
|
96
47
|
const lazy_langs = Object.fromEntries(Object.entries(langs).map(([path, mod]) => [
|
|
97
48
|
path.split("/").pop().split(".")[0],
|
|
@@ -105,7 +56,6 @@ export function process_langs() {
|
|
|
105
56
|
const processed_langs = process_langs();
|
|
106
57
|
const available_locales = Object.keys(processed_langs);
|
|
107
58
|
export const language_choices = Object.entries(processed_langs).map(([code]) => [lang_map[code] || code, code]);
|
|
108
|
-
export let all_common_keys = new Set();
|
|
109
59
|
let i18n_initialized = false;
|
|
110
60
|
let previous_translations;
|
|
111
61
|
function get_lang_from_preferred_locale(header) {
|
|
@@ -125,10 +75,13 @@ export async function setupi18n(custom_translations, preferred_locale) {
|
|
|
125
75
|
if (i18n_initialized && !should_reinitialize) {
|
|
126
76
|
return;
|
|
127
77
|
}
|
|
128
|
-
|
|
78
|
+
const translations_to_use = custom_translations ?? previous_translations ?? {};
|
|
79
|
+
if (custom_translations !== undefined) {
|
|
80
|
+
previous_translations = custom_translations;
|
|
81
|
+
}
|
|
129
82
|
load_translations({
|
|
130
83
|
processed_langs,
|
|
131
|
-
custom_translations:
|
|
84
|
+
custom_translations: translations_to_use
|
|
132
85
|
});
|
|
133
86
|
let initial_locale = null;
|
|
134
87
|
const browser_locale = getLocaleFromNavigator();
|