Spaces:
Running
Running
Update app.py
Browse files
app.py
CHANGED
@@ -1,541 +1,26 @@
|
|
1 |
-
import os, gdown, gc, subprocess
|
2 |
-
import numpy as np
|
3 |
import gradio as gr
|
4 |
-
from
|
5 |
-
import torch
|
6 |
-
from safetensors.torch import save_file, load_file
|
7 |
-
from huggingface_hub import model_info, create_repo, create_branch, upload_folder
|
8 |
-
from huggingface_hub.utils import RepositoryNotFoundError, RevisionNotFoundError
|
9 |
|
10 |
-
def
|
11 |
-
|
12 |
-
gdown.download(url=ckpt_url, output="model.ckpt", quiet=False, fuzzy=True)
|
13 |
-
else:
|
14 |
-
os.system(f"wget '{ckpt_url}' -O model.ckpt")
|
15 |
-
return "download ckpt done!"
|
16 |
-
|
17 |
-
def download_vae(vae_url):
|
18 |
-
if "drive.google.com" in vae_url:
|
19 |
-
gdown.download(url=vae_url, output="vae.ckpt", quiet=False, fuzzy=True)
|
20 |
-
else:
|
21 |
-
os.system(f"wget '{vae_url}' -O vae.ckpt")
|
22 |
-
return "download vae done!"
|
23 |
-
|
24 |
-
def to_pt():
|
25 |
-
os.system("wget -q https://raw.githubusercontent.com/huggingface/diffusers/v0.13.1/scripts/convert_original_stable_diffusion_to_diffusers.py")
|
26 |
-
os.system(f"python3 convert_original_stable_diffusion_to_diffusers.py --checkpoint_path model.ckpt --dump_path pt")
|
27 |
-
return "convert to pt done!"
|
28 |
-
|
29 |
-
def from_safetensors_to_pt():
|
30 |
-
os.system("wget -v https://raw.githubusercontent.com/huggingface/diffusers/v0.13.1/scripts/convert_original_stable_diffusion_to_diffusers.py")
|
31 |
-
print(subprocess.run(['ls', '-ltr'], stdout=subprocess.PIPE).stdout.decode('utf-8'))
|
32 |
-
os.system("mkdir -p ./pt")
|
33 |
-
os.system(f"python3 convert_original_stable_diffusion_to_diffusers.py --from_safetensors --checkpoint_path model.safetensors --dump_path ./pt")
|
34 |
-
print(subprocess.run(['ls', '-ltr'], stdout=subprocess.PIPE).stdout.decode('utf-8'))
|
35 |
-
return "convert to pt done!"
|
36 |
-
|
37 |
-
def from_ckpt_to_safetensors():
|
38 |
-
os.system("wget -q https://raw.githubusercontent.com/huggingface/diffusers/v0.13.1/scripts/convert_original_stable_diffusion_to_diffusers.py")
|
39 |
-
os.system(f"python3 convert_original_stable_diffusion_to_diffusers.py --checkpoint_path model.ckpt --to_safetensors --dump_path safetensors")
|
40 |
-
return "convert to safetensors done!"
|
41 |
-
|
42 |
-
def from_safetensors_to_safetensors():
|
43 |
-
os.system("wget -q https://raw.githubusercontent.com/huggingface/diffusers/v0.13.1/scripts/convert_original_stable_diffusion_to_diffusers.py")
|
44 |
-
os.system(f"python3 convert_original_stable_diffusion_to_diffusers.py --from_safetensors --checkpoint_path model.safetensors --to_safetensors --dump_path safetensors")
|
45 |
-
return "convert to safetensors done!"
|
46 |
-
|
47 |
-
def from_safetensors_to_emaonly(safetensors_emaonly_name):
|
48 |
-
os.system("mkdir safetensors")
|
49 |
-
tensors = load_file("model.safetensors")
|
50 |
-
filtered_only_ema = {k: v for k, v in tensors.items() if not k.startswith("model.")}
|
51 |
-
save_file(filtered_only_ema, f"safetensors/{safetensors_emaonly_name}-emaonly.safetensors")
|
52 |
-
return "convert to safetensors emaonly done!"
|
53 |
-
|
54 |
-
def swap_ckpt_vae(ckpt_name):
|
55 |
-
os.system("mkdir ckpt")
|
56 |
-
model = torch.load("model.ckpt", map_location="cpu")
|
57 |
-
if "state_dict" in model:
|
58 |
-
sd = model["state_dict"]
|
59 |
-
else:
|
60 |
-
sd = model
|
61 |
-
full_model = False
|
62 |
-
vae_model = torch.load("vae.ckpt", map_location="cpu")
|
63 |
-
vae_sd = vae_model['state_dict']
|
64 |
-
for vae_key in vae_sd:
|
65 |
-
if vae_key.startswith("first_stage_model."):
|
66 |
-
full_model = True
|
67 |
-
break
|
68 |
-
for vae_key in vae_sd:
|
69 |
-
sd_key = vae_key
|
70 |
-
if full_model:
|
71 |
-
if not sd_key.startswith("first_stage_model."):
|
72 |
-
continue
|
73 |
-
else:
|
74 |
-
if sd_key not in sd:
|
75 |
-
sd_key = "first_stage_model." + sd_key
|
76 |
-
if sd_key not in sd:
|
77 |
-
continue
|
78 |
-
sd[sd_key] = vae_sd[vae_key]
|
79 |
-
torch.save(model, f"ckpt/{ckpt_name}-vae-swapped.ckpt")
|
80 |
-
del model
|
81 |
-
del vae_model
|
82 |
-
del sd
|
83 |
-
del vae_sd
|
84 |
-
gc.collect()
|
85 |
-
return "swap ckpt vae done!"
|
86 |
-
|
87 |
-
def push_pt(model_to, token, branch):
|
88 |
-
try:
|
89 |
-
create_repo(model_to, private=True, token=token)
|
90 |
-
except:
|
91 |
-
print("repo already exists, overwriting...")
|
92 |
-
|
93 |
-
upload_folder(folder_path="pt", path_in_repo="", revision=branch, repo_id=model_to, commit_message=f"pt - camenduru/converter", token=token)
|
94 |
-
return "push pt done!"
|
95 |
-
|
96 |
-
def delete_pt():
|
97 |
-
os.system(f"rm -rf pt")
|
98 |
-
return "delete pt done!"
|
99 |
-
|
100 |
-
def clone_pt(model_url):
|
101 |
-
os.system("git lfs install")
|
102 |
-
os.system(f"git clone https://huggingface.co/{model_url} pt")
|
103 |
-
return "clone pt done!"
|
104 |
-
|
105 |
-
def pt_to_flax():
|
106 |
-
pipe, params = FlaxStableDiffusionPipeline.from_pretrained("pt", from_pt=True)
|
107 |
-
pipe.save_pretrained("flax", params=params)
|
108 |
-
return "convert to flax done!"
|
109 |
-
|
110 |
-
def push_flax(model_to, token, branch):
|
111 |
-
try:
|
112 |
-
repo_exists = True
|
113 |
-
r_info = model_info(model_to, token=token)
|
114 |
-
except RepositoryNotFoundError:
|
115 |
-
repo_exists = False
|
116 |
-
finally:
|
117 |
-
if repo_exists:
|
118 |
-
print(r_info)
|
119 |
-
else:
|
120 |
-
create_repo(model_to, private=True, token=token)
|
121 |
-
try:
|
122 |
-
branch_exists = True
|
123 |
-
b_info = model_info(model_to, revision=branch, token=token)
|
124 |
-
except RevisionNotFoundError:
|
125 |
-
branch_exists = False
|
126 |
-
finally:
|
127 |
-
if branch_exists:
|
128 |
-
print(b_info)
|
129 |
-
else:
|
130 |
-
create_branch(model_to, branch=branch, token=token)
|
131 |
-
upload_folder(folder_path="flax", path_in_repo="", revision=branch, repo_id=model_to, commit_message=f"flax - camenduru/converter", token=token)
|
132 |
-
return "push flax done!"
|
133 |
-
|
134 |
-
def delete_flax():
|
135 |
-
os.system(f"rm -rf flax")
|
136 |
-
return "delete flax done!"
|
137 |
-
|
138 |
-
def flax_to_pt():
|
139 |
-
pipe = StableDiffusionPipeline.from_pretrained("flax", from_flax=True, safety_checker=None)
|
140 |
-
pipe.save_pretrained("pt")
|
141 |
-
return "convert to pt done!"
|
142 |
-
|
143 |
-
def clone_flax(model_url):
|
144 |
-
os.system("git lfs install")
|
145 |
-
os.system(f"git clone https://huggingface.co/{model_url} flax")
|
146 |
-
return "clone flax done!"
|
147 |
-
|
148 |
-
def to_ckpt(ckpt_name):
|
149 |
-
os.system("wget -q https://raw.githubusercontent.com/huggingface/diffusers/v0.13.1/scripts/convert_diffusers_to_original_stable_diffusion.py")
|
150 |
-
os.system("mkdir ckpt")
|
151 |
-
os.system(f"python3 convert_diffusers_to_original_stable_diffusion.py --model_path pt --checkpoint_path ckpt/{ckpt_name}.ckpt")
|
152 |
-
return "convert to ckpt done!"
|
153 |
-
|
154 |
-
def push_ckpt(model_to, token, branch):
|
155 |
-
try:
|
156 |
-
repo_exists = True
|
157 |
-
r_info = model_info(model_to, token=token)
|
158 |
-
except RepositoryNotFoundError:
|
159 |
-
repo_exists = False
|
160 |
-
finally:
|
161 |
-
if repo_exists:
|
162 |
-
print(r_info)
|
163 |
-
else:
|
164 |
-
create_repo(model_to, private=True, token=token)
|
165 |
-
try:
|
166 |
-
branch_exists = True
|
167 |
-
b_info = model_info(model_to, revision=branch, token=token)
|
168 |
-
except RevisionNotFoundError:
|
169 |
-
branch_exists = False
|
170 |
-
finally:
|
171 |
-
if branch_exists:
|
172 |
-
print(b_info)
|
173 |
-
else:
|
174 |
-
create_branch(model_to, branch=branch, token=token)
|
175 |
-
upload_folder(folder_path="ckpt", path_in_repo="", revision=branch, repo_id=model_to, commit_message=f"ckpt - camenduru/converter", token=token)
|
176 |
-
return "push ckpt done!"
|
177 |
-
|
178 |
-
def delete_ckpt():
|
179 |
-
os.system(f"rm -rf ckpt")
|
180 |
-
return "delete ckpt done!"
|
181 |
-
|
182 |
-
def to_safetensors(safetensors_name):
|
183 |
-
os.system("mkdir safetensors")
|
184 |
-
weights = torch.load("model.ckpt", map_location="cpu")
|
185 |
-
if "state_dict" in weights:
|
186 |
-
weights = weights["state_dict"]
|
187 |
-
save_file(weights, f"safetensors/{safetensors_name}.safetensors")
|
188 |
-
return "convert to safetensors done!"
|
189 |
-
|
190 |
-
def push_safetensors(model_to, token, branch):
|
191 |
-
try:
|
192 |
-
repo_exists = True
|
193 |
-
r_info = model_info(model_to, token=token)
|
194 |
-
except RepositoryNotFoundError:
|
195 |
-
repo_exists = False
|
196 |
-
finally:
|
197 |
-
if repo_exists:
|
198 |
-
print(r_info)
|
199 |
-
else:
|
200 |
-
create_repo(model_to, private=True, token=token)
|
201 |
try:
|
202 |
-
|
203 |
-
|
204 |
-
|
205 |
-
|
206 |
-
|
207 |
-
|
208 |
-
|
209 |
-
|
210 |
-
|
211 |
-
|
212 |
-
|
213 |
-
|
214 |
-
|
215 |
-
|
216 |
-
|
217 |
-
|
218 |
-
|
219 |
-
|
220 |
-
|
221 |
-
|
222 |
-
os.system(f"wget '{safetensors_url}' -O model.safetensors")
|
223 |
-
print(subprocess.run(['ls', '-ltr'], stdout=subprocess.PIPE).stdout.decode('utf-8'))
|
224 |
-
return "download safetensors done!"
|
225 |
-
|
226 |
-
def from_safetensors_to_ckpt(ckpt_name):
|
227 |
-
weights = load_file("model.safetensors", device="cpu")
|
228 |
-
os.system("mkdir ckpt")
|
229 |
-
torch.save(weights, f"ckpt/{ckpt_name}.ckpt")
|
230 |
-
return "convert to ckpt done!"
|
231 |
-
|
232 |
-
def delete_all():
|
233 |
-
delete_pt()
|
234 |
-
delete_flax()
|
235 |
-
delete_ckpt()
|
236 |
-
delete_safetensors()
|
237 |
-
return "delete all done!"
|
238 |
-
|
239 |
-
block = gr.Blocks()
|
240 |
-
|
241 |
-
with block:
|
242 |
-
gr.Markdown(
|
243 |
-
"""
|
244 |
-
## 🚨 Please first click delete all button 🚨 Thanks to 🤗 ❤ Now with CPU Upgrade! 🎉 <a class="duplicate-button" style="display:inline-block" target="_blank" href="https://huggingface.co/spaces/camenduru/converter?duplicate=true"><img style="margin: 0" src="https://img.shields.io/badge/-Duplicate%20Space-blue?labelColor=white&style=flat&logo=data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAP5JREFUOE+lk7FqAkEURY+ltunEgFXS2sZGIbXfEPdLlnxJyDdYB62sbbUKpLbVNhyYFzbrrA74YJlh9r079973psed0cvUD4A+4HoCjsA85X0Dfn/RBLBgBDxnQPfAEJgBY+A9gALA4tcbamSzS4xq4FOQAJgCDwV2CPKV8tZAJcAjMMkUe1vX+U+SMhfAJEHasQIWmXNN3abzDwHUrgcRGmYcgKe0bxrblHEB4E/pndMazNpSZGcsZdBlYJcEL9Afo75molJyM2FxmPgmgPqlWNLGfwZGG6UiyEvLzHYDmoPkDDiNm9JR9uboiONcBXrpY1qmgs21x1QwyZcpvxt9NS09PlsPAAAAAElFTkSuQmCC&logoWidth=14" alt="Duplicate Space"></a> <a style="display:inline-block" href="https://github.com/camenduru/converter-colab" target="_blank"><img src="https://colab.research.google.com/assets/colab-badge.svg" alt="Open In Colab" style="margin-bottom: 0px; margin-top: 0px;"></a> <a style="display:inline-block" href="https://patreon.com/camenduru"><img style="margin: 0" alt="Become A Patreon" src="https://badgen.net/badge/become/a%20patron/F96854"></a> <a style="display:inline-block" href="https://ko-fi.com/camenduru" target="_blank"><img style="margin: 0" alt="Buy a Coffee" src="https://badgen.net/badge/buy/a%20coffee/green?icon=kofi"></a>
|
245 |
-
🐣 Please follow me for new updates <a href="https://twitter.com/camenduru">https://twitter.com/camenduru</a>
|
246 |
-
""")
|
247 |
-
with gr.Row().style(equal_height=True):
|
248 |
-
btn_delete_all = gr.Button("Delete ALL")
|
249 |
-
out_all = gr.Textbox(show_label=False)
|
250 |
-
btn_delete_all.click(delete_all, outputs=out_all)
|
251 |
-
gr.Markdown(
|
252 |
-
"""
|
253 |
-
### ckpt to diffusers pytorch
|
254 |
-
ckpt_url = <small>https://huggingface.co/prompthero/openjourney/resolve/main/mdjrny-v4.ckpt or https://drive.google.com/file/d/file-id/view?usp=share_link or "https://civitai.com/api/download/models/5616?type=Model&format=PickleTensor"</small><br />
|
255 |
-
pt_model_to = camenduru/openjourney <br />
|
256 |
-
branch = main <br />
|
257 |
-
token = get from [https://huggingface.co/settings/tokens](https://huggingface.co/settings/tokens) new token role=write
|
258 |
-
""")
|
259 |
-
with gr.Group():
|
260 |
-
with gr.Box():
|
261 |
-
with gr.Row().style(equal_height=True):
|
262 |
-
text_ckpt_url = gr.Textbox(show_label=False, max_lines=1, placeholder="ckpt_url")
|
263 |
-
text_pt_model_to = gr.Textbox(show_label=False, max_lines=1, placeholder="pt_model_to")
|
264 |
-
text_pt_branch = gr.Textbox(show_label=False, value="main", max_lines=1, placeholder="pt_branch")
|
265 |
-
text_pt_token = gr.Textbox(show_label=False, max_lines=1, placeholder="🤗 token")
|
266 |
-
out_pt = gr.Textbox(show_label=False)
|
267 |
-
with gr.Row().style(equal_height=True):
|
268 |
-
btn_download_ckpt = gr.Button("Download CKPT")
|
269 |
-
btn_to_pt = gr.Button("Convert to Diffusers PT")
|
270 |
-
btn_push_pt = gr.Button("Push Diffusers PT to 🤗")
|
271 |
-
btn_delete_pt = gr.Button("Delete Diffusers PT")
|
272 |
-
btn_download_ckpt.click(download_ckpt, inputs=[text_ckpt_url], outputs=out_pt)
|
273 |
-
btn_to_pt.click(to_pt, outputs=out_pt)
|
274 |
-
btn_push_pt.click(push_pt, inputs=[text_pt_model_to, text_pt_token, text_pt_branch], outputs=out_pt)
|
275 |
-
btn_delete_pt.click(delete_pt, outputs=out_pt)
|
276 |
-
gr.Markdown(
|
277 |
-
"""
|
278 |
-
### ckpt to diffusers safetensors
|
279 |
-
ckpt_url = <small>https://huggingface.co/prompthero/openjourney/resolve/main/mdjrny-v4.ckpt or https://drive.google.com/file/d/file-id/view?usp=share_link or "https://civitai.com/api/download/models/5616?type=Model&format=PickleTensor"</small><br />
|
280 |
-
safetensors_pt_model_to = camenduru/openjourney <br />
|
281 |
-
branch = main <br />
|
282 |
-
token = get from [https://huggingface.co/settings/tokens](https://huggingface.co/settings/tokens) new token role=write
|
283 |
-
""")
|
284 |
-
with gr.Group():
|
285 |
-
with gr.Box():
|
286 |
-
with gr.Row().style(equal_height=True):
|
287 |
-
text_ckpt_to_safetensors_url = gr.Textbox(show_label=False, max_lines=1, placeholder="ckpt_url")
|
288 |
-
text_ckpt_to_safetensors_model_to = gr.Textbox(show_label=False, max_lines=1, placeholder="safetensors_pt_model_to")
|
289 |
-
text_ckpt_to_safetensors_branch = gr.Textbox(show_label=False, value="main", max_lines=1, placeholder="safetensors_branch")
|
290 |
-
text_ckpt_to_safetensors_token = gr.Textbox(show_label=False, max_lines=1, placeholder="🤗 token")
|
291 |
-
out_ckpt_to_safetensors = gr.Textbox(show_label=False)
|
292 |
-
with gr.Row().style(equal_height=True):
|
293 |
-
btn_download_ckpt_to_safetensors = gr.Button("Download CKPT")
|
294 |
-
btn_ckpt_to_safetensors = gr.Button("Convert to Diffusers Safetensors")
|
295 |
-
btn_push_ckpt_to_safetensors = gr.Button("Push Diffusers Safetensors to 🤗")
|
296 |
-
btn_delete_ckpt_to_safetensors = gr.Button("Delete Diffusers Safetensors")
|
297 |
-
btn_download_ckpt_to_safetensors.click(download_ckpt, inputs=[text_ckpt_to_safetensors_url], outputs=out_ckpt_to_safetensors)
|
298 |
-
btn_ckpt_to_safetensors.click(from_ckpt_to_safetensors, outputs=out_ckpt_to_safetensors)
|
299 |
-
btn_push_ckpt_to_safetensors.click(push_safetensors, inputs=[text_ckpt_to_safetensors_model_to, text_ckpt_to_safetensors_token, text_ckpt_to_safetensors_branch], outputs=out_ckpt_to_safetensors)
|
300 |
-
btn_delete_ckpt_to_safetensors.click(delete_safetensors, outputs=out_ckpt_to_safetensors)
|
301 |
-
gr.Markdown(
|
302 |
-
"""
|
303 |
-
### safetensors to diffusers pytorch
|
304 |
-
safetensors_url = <small>https://huggingface.co/prompthero/openjourney/resolve/main/mdjrny-v4.safetensors or https://drive.google.com/file/d/file-id/view?usp=share_link or "https://civitai.com/api/download/models/5616?type=Model&format=SafeTensor"</small><br />
|
305 |
-
pt_model_to = camenduru/openjourney <br />
|
306 |
-
branch = main <br />
|
307 |
-
token = get from [https://huggingface.co/settings/tokens](https://huggingface.co/settings/tokens) new token role=write
|
308 |
-
""")
|
309 |
-
with gr.Group():
|
310 |
-
with gr.Box():
|
311 |
-
with gr.Row().style(equal_height=True):
|
312 |
-
text_safetensors_to_pt_url = gr.Textbox(show_label=False, max_lines=1, placeholder="safetensors_url")
|
313 |
-
text_safetensors_to_pt_model_to = gr.Textbox(show_label=False, max_lines=1, placeholder="pt_model_to")
|
314 |
-
text_safetensors_to_pt_branch = gr.Textbox(show_label=False, value="main", max_lines=1, placeholder="pt_branch")
|
315 |
-
text_safetensors_to_pt_token = gr.Textbox(show_label=False, max_lines=1, placeholder="🤗 token")
|
316 |
-
out_safetensors_to_pt = gr.Textbox(show_label=False)
|
317 |
-
with gr.Row().style(equal_height=True):
|
318 |
-
btn_download_safetensors_to_pt = gr.Button("Download Safetensors")
|
319 |
-
btn_safetensors_to_pt = gr.Button("Convert to Diffusers PT")
|
320 |
-
btn_push_safetensors_to_pt = gr.Button("Push Diffusers PT to 🤗")
|
321 |
-
btn_delete_safetensors_to_pt = gr.Button("Delete Diffusers PT")
|
322 |
-
btn_download_safetensors_to_pt.click(download_safetensors, inputs=[text_safetensors_to_pt_url], outputs=out_safetensors_to_pt)
|
323 |
-
btn_safetensors_to_pt.click(from_safetensors_to_pt, outputs=out_safetensors_to_pt)
|
324 |
-
btn_push_safetensors_to_pt.click(push_pt, inputs=[text_safetensors_to_pt_model_to, text_safetensors_to_pt_token, text_safetensors_to_pt_branch], outputs=out_safetensors_to_pt)
|
325 |
-
btn_delete_safetensors_to_pt.click(delete_pt, outputs=out_safetensors_to_pt)
|
326 |
-
gr.Markdown(
|
327 |
-
"""
|
328 |
-
### safetensors to diffusers safetensors
|
329 |
-
safetensors_url = <small>https://huggingface.co/prompthero/openjourney/resolve/main/mdjrny-v4.ckpt or https://drive.google.com/file/d/file-id/view?usp=share_link or "https://civitai.com/api/download/models/5616?type=Model&format=SafeTensor"</small><br />
|
330 |
-
safetensors_model_to = camenduru/openjourney <br />
|
331 |
-
branch = main <br />
|
332 |
-
token = get from [https://huggingface.co/settings/tokens](https://huggingface.co/settings/tokens) new token role=write
|
333 |
-
""")
|
334 |
-
with gr.Group():
|
335 |
-
with gr.Box():
|
336 |
-
with gr.Row().style(equal_height=True):
|
337 |
-
text_safetensors_to_safetensors_url = gr.Textbox(show_label=False, max_lines=1, placeholder="safetensors_url")
|
338 |
-
text_safetensors_to_safetensors_model_to = gr.Textbox(show_label=False, max_lines=1, placeholder="safetensors_model_to")
|
339 |
-
text_safetensors_to_safetensors_branch = gr.Textbox(show_label=False, value="main", max_lines=1, placeholder="pt_branch")
|
340 |
-
text_safetensors_to_safetensors_token = gr.Textbox(show_label=False, max_lines=1, placeholder="🤗 token")
|
341 |
-
out_safetensors_to_safetensors = gr.Textbox(show_label=False)
|
342 |
-
with gr.Row().style(equal_height=True):
|
343 |
-
btn_download_safetensors_to_safetensors = gr.Button("Download Safetensors")
|
344 |
-
btn_safetensors_to_safetensors = gr.Button("Convert to Diffusers Safetensors")
|
345 |
-
btn_push_safetensors_to_safetensors = gr.Button("Push Diffusers Safetensors to 🤗")
|
346 |
-
btn_delete_safetensors_to_safetensors = gr.Button("Delete Diffusers Safetensors")
|
347 |
-
btn_download_safetensors_to_safetensors.click(download_safetensors, inputs=[text_safetensors_to_safetensors_url], outputs=out_safetensors_to_safetensors)
|
348 |
-
btn_safetensors_to_safetensors.click(from_safetensors_to_safetensors, outputs=out_safetensors_to_safetensors)
|
349 |
-
btn_push_safetensors_to_safetensors.click(push_safetensors, inputs=[text_safetensors_to_safetensors_model_to, text_safetensors_to_safetensors_token, text_safetensors_to_safetensors_branch], outputs=out_safetensors_to_safetensors)
|
350 |
-
btn_delete_safetensors_to_safetensors.click(delete_safetensors, outputs=out_safetensors_to_safetensors)
|
351 |
-
gr.Markdown(
|
352 |
-
"""
|
353 |
-
### diffusers pytorch to diffusers flax <br />
|
354 |
-
pt_model_from = dreamlike-art/dreamlike-diffusion-1.0 <br />
|
355 |
-
flax_model_to = camenduru/dreamlike-diffusion-1.0 <br />
|
356 |
-
branch = flax <br />
|
357 |
-
token = get from [https://huggingface.co/settings/tokens](https://huggingface.co/settings/tokens) new token role=write <br />
|
358 |
-
""")
|
359 |
-
with gr.Group():
|
360 |
-
with gr.Box():
|
361 |
-
with gr.Row().style(equal_height=True):
|
362 |
-
text_pt_model_from = gr.Textbox(show_label=False, max_lines=1, placeholder="pt_model_from")
|
363 |
-
text_flax_model_to = gr.Textbox(show_label=False, max_lines=1, placeholder="flax_model_to")
|
364 |
-
text_flax_branch = gr.Textbox(show_label=False, value="main", max_lines=1, placeholder="flax_branch")
|
365 |
-
text_flax_token = gr.Textbox(show_label=False, max_lines=1, placeholder="🤗 token")
|
366 |
-
out_flax = gr.Textbox(show_label=False)
|
367 |
-
with gr.Row().style(equal_height=True):
|
368 |
-
btn_clone_pt = gr.Button("Clone Diffusers PT from 🤗")
|
369 |
-
btn_to_flax = gr.Button("Convert to Diffusers Flax")
|
370 |
-
btn_push_flax = gr.Button("Push Diffusers Flax to 🤗")
|
371 |
-
btn_delete_flax = gr.Button("Delete Diffusers Flax")
|
372 |
-
btn_clone_pt.click(clone_pt, inputs=[text_pt_model_from], outputs=out_flax)
|
373 |
-
btn_to_flax.click(pt_to_flax, outputs=out_flax)
|
374 |
-
btn_push_flax.click(push_flax, inputs=[text_flax_model_to, text_flax_token, text_flax_branch], outputs=out_flax)
|
375 |
-
btn_delete_flax.click(delete_flax, outputs=out_flax)
|
376 |
-
gr.Markdown(
|
377 |
-
"""
|
378 |
-
### diffusers flax to diffusers pytorch <br />
|
379 |
-
flax_model_from = flax/mo-di-diffusion <br />
|
380 |
-
pt_model_to = camenduru/mo-di-diffusion <br />
|
381 |
-
branch = pt <br />
|
382 |
-
token = get from [https://huggingface.co/settings/tokens](https://huggingface.co/settings/tokens) new token role=write <br />
|
383 |
-
""")
|
384 |
-
with gr.Group():
|
385 |
-
with gr.Box():
|
386 |
-
with gr.Row().style(equal_height=True):
|
387 |
-
text_flax_model_from = gr.Textbox(show_label=False, max_lines=1, placeholder="flax_model_from")
|
388 |
-
text_pt_model_to = gr.Textbox(show_label=False, max_lines=1, placeholder="pt_model_to")
|
389 |
-
text_pt_branch = gr.Textbox(show_label=False, value="main", max_lines=1, placeholder="pt_branch")
|
390 |
-
text_pt_token = gr.Textbox(show_label=False, max_lines=1, placeholder="🤗 token")
|
391 |
-
out_pt = gr.Textbox(show_label=False)
|
392 |
-
with gr.Row().style(equal_height=True):
|
393 |
-
btn_clone_flax = gr.Button("Clone Diffusers Flax from 🤗")
|
394 |
-
btn_to_pt = gr.Button("Convert to Diffusers PT")
|
395 |
-
btn_push_pt = gr.Button("Push Diffusers PT to 🤗")
|
396 |
-
btn_delete_pt = gr.Button("Delete Diffusers PT")
|
397 |
-
btn_clone_flax.click(clone_flax, inputs=[text_flax_model_from], outputs=out_pt)
|
398 |
-
btn_to_pt.click(flax_to_pt, outputs=out_pt)
|
399 |
-
btn_push_pt.click(push_pt, inputs=[text_pt_model_to, text_pt_token, text_pt_branch], outputs=out_pt)
|
400 |
-
btn_delete_pt.click(delete_pt, outputs=out_pt)
|
401 |
-
gr.Markdown(
|
402 |
-
"""
|
403 |
-
### diffusers pytorch to ckpt
|
404 |
-
pt_model_from = prompthero/openjourney <br />
|
405 |
-
ckpt_name = openjourney <br />
|
406 |
-
ckpt_model_to = camenduru/openjourney <br />
|
407 |
-
branch = ckpt <br />
|
408 |
-
token = get from [https://huggingface.co/settings/tokens](https://huggingface.co/settings/tokens) new token role=write
|
409 |
-
""")
|
410 |
-
with gr.Group():
|
411 |
-
with gr.Box():
|
412 |
-
with gr.Row().style(equal_height=True):
|
413 |
-
text_pt_model_from = gr.Textbox(show_label=False, max_lines=1, placeholder="pt_model_from")
|
414 |
-
text_ckpt_name = gr.Textbox(show_label=False, max_lines=1, placeholder="ckpt_name")
|
415 |
-
text_ckpt_model_to = gr.Textbox(show_label=False, max_lines=1, placeholder="ckpt_model_to")
|
416 |
-
text_ckpt_branch = gr.Textbox(show_label=False, value="main", max_lines=1, placeholder="ckpt_branch")
|
417 |
-
text_ckpt_token = gr.Textbox(show_label=False, max_lines=1, placeholder="🤗 token")
|
418 |
-
out_ckpt = gr.Textbox(show_label=False)
|
419 |
-
with gr.Row().style(equal_height=True):
|
420 |
-
btn_clone_pt = gr.Button("Clone Diffusers PT from 🤗")
|
421 |
-
btn_to_ckpt = gr.Button("Convert to CKPT")
|
422 |
-
btn_push_ckpt = gr.Button("Push CKPT to 🤗")
|
423 |
-
btn_delete_ckpt = gr.Button("Delete CKPT")
|
424 |
-
btn_clone_pt.click(clone_pt, inputs=[text_pt_model_from], outputs=out_ckpt, api_name="difpytorch2ckptclone")
|
425 |
-
btn_to_ckpt.click(to_ckpt, inputs=[text_ckpt_name], outputs=out_ckpt, api_name="difpytorch2ckptconvert")
|
426 |
-
btn_push_ckpt.click(push_ckpt, inputs=[text_ckpt_model_to, text_ckpt_token, text_ckpt_branch], outputs=out_ckpt, api_name="difpytorch2ckptpush")
|
427 |
-
btn_delete_ckpt.click(delete_ckpt, outputs=out_ckpt, api_name="difpytorch2ckptdelete")
|
428 |
-
gr.Markdown(
|
429 |
-
"""
|
430 |
-
### ckpt to safetensors <br />
|
431 |
-
ckpt_url = <small>https://huggingface.co/prompthero/openjourney/resolve/main/mdjrny-v4.ckpt or https://drive.google.com/file/d/file-id/view?usp=share_link or "https://civitai.com/api/download/models/5616?type=Model&format=PickleTensor"</small><br />
|
432 |
-
safetensors_name = openjourney <br />
|
433 |
-
safetensors_model_to = camenduru/openjourney <br />
|
434 |
-
branch = safetensors <br />
|
435 |
-
token = get from [https://huggingface.co/settings/tokens](https://huggingface.co/settings/tokens) new token role=write <br />
|
436 |
-
""")
|
437 |
-
with gr.Group():
|
438 |
-
with gr.Box():
|
439 |
-
with gr.Row().style(equal_height=True):
|
440 |
-
text_ckpt_url = gr.Textbox(show_label=False, max_lines=1, placeholder="ckpt_url")
|
441 |
-
text_safetensors_name = gr.Textbox(show_label=False, max_lines=1, placeholder="safetensors_name")
|
442 |
-
text_safetensors_model_to = gr.Textbox(show_label=False, max_lines=1, placeholder="safetensors_model_to")
|
443 |
-
text_safetensors_branch = gr.Textbox(show_label=False, value="main", max_lines=1, placeholder="safetensors_branch")
|
444 |
-
text_safetensors_token = gr.Textbox(show_label=False, max_lines=1, placeholder="🤗 token")
|
445 |
-
out_safetensors = gr.Textbox(show_label=False)
|
446 |
-
with gr.Row().style(equal_height=True):
|
447 |
-
btn_download_ckpt = gr.Button("Download CKPT")
|
448 |
-
btn_to_safetensors = gr.Button("Convert to Safetensors")
|
449 |
-
btn_push_safetensors = gr.Button("Push Safetensors to 🤗")
|
450 |
-
btn_delete_safetensors = gr.Button("Delete Safetensors")
|
451 |
-
btn_download_ckpt.click(download_ckpt, inputs=[text_ckpt_url], outputs=out_safetensors, api_name="difpytorch2safetensorsclone")
|
452 |
-
btn_to_safetensors.click(to_safetensors, inputs=[text_safetensors_name], outputs=out_safetensors, api_name="difpytorch2safetensorsconvert")
|
453 |
-
btn_push_safetensors.click(push_safetensors, inputs=[text_safetensors_model_to, text_safetensors_token, text_safetensors_branch], outputs=out_safetensors, api_name="difpytorch2safetensorspush")
|
454 |
-
btn_delete_safetensors.click(delete_safetensors, outputs=out_safetensors, api_name="difpytorch2safetensorsdelete")
|
455 |
-
gr.Markdown(
|
456 |
-
"""
|
457 |
-
### safetensors to ckpt <br />
|
458 |
-
safetensors_url = <small>https://huggingface.co/prompthero/openjourney/resolve/main/mdjrny-v4.safetensors or https://drive.google.com/file/d/file-id/view?usp=share_link or "https://civitai.com/api/download/models/5616?type=Model&format=SafeTensor"</small><br />
|
459 |
-
ckpt_name = openjourney <br />
|
460 |
-
ckpt_model_to = camenduru/openjourney <br />
|
461 |
-
branch = ckpt <br />
|
462 |
-
token = get from [https://huggingface.co/settings/tokens](https://huggingface.co/settings/tokens) new token role=write <br />
|
463 |
-
""")
|
464 |
-
with gr.Group():
|
465 |
-
with gr.Box():
|
466 |
-
with gr.Row().style(equal_height=True):
|
467 |
-
text_safetensors_url = gr.Textbox(show_label=False, max_lines=1, placeholder="safetensors_url")
|
468 |
-
text_safetensors_to_ckpt_name = gr.Textbox(show_label=False, max_lines=1, placeholder="ckpt_name")
|
469 |
-
text_safetensors_to_ckpt_model_to = gr.Textbox(show_label=False, max_lines=1, placeholder="ckpt_model_to")
|
470 |
-
text_safetensors_to_ckpt_branch = gr.Textbox(show_label=False, value="main", max_lines=1, placeholder="ckpt_branch")
|
471 |
-
text_safetensors_to_ckpt_token = gr.Textbox(show_label=False, max_lines=1, placeholder="🤗 token")
|
472 |
-
out_safetensors_to_ckpt = gr.Textbox(show_label=False)
|
473 |
-
with gr.Row().style(equal_height=True):
|
474 |
-
btn_download_safetensors = gr.Button("Download Safetensors")
|
475 |
-
btn_safetensors_to_ckpt = gr.Button("Convert to CKPT")
|
476 |
-
btn_push_safetensors_to_ckpt = gr.Button("Push CKPT to 🤗")
|
477 |
-
btn_delete_safetensors_ckpt = gr.Button("Delete CKPT")
|
478 |
-
btn_download_safetensors.click(download_safetensors, inputs=[text_safetensors_url], outputs=out_safetensors_to_ckpt)
|
479 |
-
btn_safetensors_to_ckpt.click(from_safetensors_to_ckpt, inputs=[text_safetensors_to_ckpt_name], outputs=out_safetensors_to_ckpt)
|
480 |
-
btn_push_safetensors_to_ckpt.click(push_ckpt, inputs=[text_safetensors_to_ckpt_model_to, text_safetensors_to_ckpt_token, text_safetensors_to_ckpt_branch], outputs=out_safetensors_to_ckpt)
|
481 |
-
btn_delete_safetensors_ckpt.click(delete_ckpt, outputs=out_safetensors_to_ckpt)
|
482 |
-
gr.Markdown(
|
483 |
-
"""
|
484 |
-
### safetensors to safetensors emaonly <br />
|
485 |
-
safetensors_url = <small>https://huggingface.co/ckpt/anything-v3.0/resolve/main/Anything-V3.0.safetensors or https://drive.google.com/file/d/file-id/view?usp=share_link or "https://civitai.com/api/download/models/4298?type=Model&format=SafeTensor"</small><br />
|
486 |
-
emaonly_name = Anything-V3.0 <br />
|
487 |
-
emaonly_model_to = camenduru/Anything-V3.0 <br />
|
488 |
-
branch = safetensors <br />
|
489 |
-
token = get from [https://huggingface.co/settings/tokens](https://huggingface.co/settings/tokens) new token role=write <br />
|
490 |
-
""")
|
491 |
-
with gr.Group():
|
492 |
-
with gr.Box():
|
493 |
-
with gr.Row().style(equal_height=True):
|
494 |
-
text_safetensors_url = gr.Textbox(show_label=False, max_lines=1, placeholder="safetensors_url")
|
495 |
-
text_safetensors_to_emaonly_name = gr.Textbox(show_label=False, max_lines=1, placeholder="emaonly_name")
|
496 |
-
text_safetensors_to_emaonly_model_to = gr.Textbox(show_label=False, max_lines=1, placeholder="emaonly_model_to")
|
497 |
-
text_safetensors_to_emaonly_branch = gr.Textbox(show_label=False, value="main", max_lines=1, placeholder="emaonly_branch")
|
498 |
-
text_safetensors_to_emaonly_token = gr.Textbox(show_label=False, max_lines=1, placeholder="🤗 token")
|
499 |
-
out_safetensors_to_emaonly = gr.Textbox(show_label=False)
|
500 |
-
with gr.Row().style(equal_height=True):
|
501 |
-
btn_download_safetensors = gr.Button("Download Safetensors")
|
502 |
-
btn_safetensors_to_emaonly = gr.Button("Convert to EMA Safetensors")
|
503 |
-
btn_push_safetensors_to_emaonly = gr.Button("Push EMA Safetensors to 🤗")
|
504 |
-
btn_delete_safetensors_emaonly = gr.Button("Delete EMA Safetensors")
|
505 |
-
btn_download_safetensors.click(download_safetensors, inputs=[text_safetensors_url], outputs=out_safetensors_to_emaonly)
|
506 |
-
btn_safetensors_to_emaonly.click(from_safetensors_to_emaonly, inputs=[text_safetensors_to_emaonly_name], outputs=out_safetensors_to_emaonly)
|
507 |
-
btn_push_safetensors_to_emaonly.click(push_safetensors, inputs=[text_safetensors_to_emaonly_model_to, text_safetensors_to_emaonly_token, text_safetensors_to_emaonly_branch], outputs=out_safetensors_to_emaonly)
|
508 |
-
btn_delete_safetensors_emaonly.click(delete_safetensors, outputs=out_safetensors_to_emaonly)
|
509 |
-
gr.Markdown(
|
510 |
-
"""
|
511 |
-
### swap ckpt vae <br />
|
512 |
-
ckpt_url = <small>https://huggingface.co/ckpt/anything-v3.0/resolve/main/Anything-V3.0-pruned.ckpt or https://drive.google.com/file/d/file-id/view?usp=share_link or "https://civitai.com/api/download/models/75?type=Model&format=PickleTensor"</small><br />
|
513 |
-
vae_url = <small>https://huggingface.co/ckpt/anything-v3.0/resolve/main/Anything-V3.0.vae.pt or https://drive.google.com/file/d/file-id/view?usp=share_link or "https://civitai.com/api/download/models/5809?type=VAE&format=Other"</small><br />
|
514 |
-
swaped_ckpt_name = Anything-V3.0 <br />
|
515 |
-
swaped_ckpt_model_to = camenduru/Anything-V3.0 <br />
|
516 |
-
swaped_ckpt_branch = ckpt <br />
|
517 |
-
token = get from [https://huggingface.co/settings/tokens](https://huggingface.co/settings/tokens) new token role=write <br />
|
518 |
-
""")
|
519 |
-
with gr.Group():
|
520 |
-
with gr.Box():
|
521 |
-
with gr.Row().style(equal_height=True):
|
522 |
-
text_ckpt_url = gr.Textbox(show_label=False, max_lines=1, placeholder="ckpt_url")
|
523 |
-
text_vae_url = gr.Textbox(show_label=False, max_lines=1, placeholder="vae_url")
|
524 |
-
text_swap_ckpt_name = gr.Textbox(show_label=False, max_lines=1, placeholder="swaped_ckpt_name")
|
525 |
-
text_swap_ckpt_model_to = gr.Textbox(show_label=False, max_lines=1, placeholder="swaped_ckpt_model_to")
|
526 |
-
text_swap_ckpt_branch = gr.Textbox(show_label=False, value="main", max_lines=1, placeholder="swaped_ckpt_branch")
|
527 |
-
text_swap_ckpt_token = gr.Textbox(show_label=False, max_lines=1, placeholder="🤗 token")
|
528 |
-
out_swap_ckpt = gr.Textbox(show_label=False)
|
529 |
-
with gr.Row().style(equal_height=True):
|
530 |
-
btn_download_ckpt = gr.Button("Download CKPT")
|
531 |
-
btn_download_vae = gr.Button("Download VAE")
|
532 |
-
btn_to_swap_ckpt = gr.Button("Swap CKPT VAE")
|
533 |
-
btn_push_swap_ckpt = gr.Button("Push CKPT to 🤗")
|
534 |
-
btn_delete_swap_ckpt = gr.Button("Delete CKPT")
|
535 |
-
btn_download_ckpt.click(download_ckpt, inputs=[text_ckpt_url], outputs=out_swap_ckpt)
|
536 |
-
btn_download_vae.click(download_vae, inputs=[text_vae_url], outputs=out_swap_ckpt)
|
537 |
-
btn_to_swap_ckpt.click(swap_ckpt_vae, inputs=[text_swap_ckpt_name], outputs=out_swap_ckpt)
|
538 |
-
btn_push_swap_ckpt.click(push_ckpt, inputs=[text_swap_ckpt_model_to, text_swap_ckpt_token, text_swap_ckpt_branch], outputs=out_swap_ckpt)
|
539 |
-
btn_delete_swap_ckpt.click(delete_ckpt, outputs=out_swap_ckpt)
|
540 |
-
|
541 |
-
block.launch()
|
|
|
|
|
|
|
1 |
import gradio as gr
|
2 |
+
from deepface import DeepFace
|
|
|
|
|
|
|
|
|
3 |
|
4 |
+
def calculate_similarity(image1, image2):
|
5 |
+
# Analyze the two images for facial similarity
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
6 |
try:
|
7 |
+
result = DeepFace.verify(image1, image2, enforce_detection=False)
|
8 |
+
similarity_percentage = result['distance'] * 100 # Higher distance means less similarity
|
9 |
+
return 100 - similarity_percentage # Convert distance to similarity percentage
|
10 |
+
except Exception as e:
|
11 |
+
return str(e)
|
12 |
+
|
13 |
+
# Create a Gradio interface
|
14 |
+
iface = gr.Interface(
|
15 |
+
fn=calculate_similarity,
|
16 |
+
inputs=[
|
17 |
+
gr.inputs.Image(type="filepath", label="Image 1"),
|
18 |
+
gr.inputs.Image(type="filepath", label="Image 2")
|
19 |
+
],
|
20 |
+
outputs=gr.outputs.Textbox(label="Similarity Percentage"),
|
21 |
+
title="Face Similarity Checker",
|
22 |
+
description="Upload two images of faces to check their similarity."
|
23 |
+
)
|
24 |
+
|
25 |
+
# Launch the interface
|
26 |
+
iface.launch()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|