Spaces:
Running
Running
selfitcamera
commited on
Commit
·
bf2bbef
1
Parent(s):
4035ddb
init
Browse files
app.py
CHANGED
|
@@ -468,8 +468,8 @@ def edit_image_interface(input_image1, input_image2, input_image3, prompt, aspec
|
|
| 468 |
|
| 469 |
print(f"✅ Multi-image processing started - IP: {client_ip}, phase: {current_phase}, total count: {updated_count}, images: {len(valid_images)}, size: {width}x{height}, prompt: {prompt.strip()}", flush=True)
|
| 470 |
|
| 471 |
-
# Determine priority (first
|
| 472 |
-
task_priority = 1 if current_count
|
| 473 |
|
| 474 |
# Call multi-image editing processing function
|
| 475 |
result_url, message, task_uuid = process_multi_image_edit(valid_images, prompt.strip(), width, height, progress_callback, priority=task_priority, client_ip=client_ip)
|
|
@@ -604,310 +604,7 @@ def edit_image_interface(input_image1, input_image2, input_image3, prompt, aspec
|
|
| 604 |
finally:
|
| 605 |
# Always clear active task status when done (success or failure)
|
| 606 |
set_active_task(client_ip, active=False)
|
| 607 |
-
|
| 608 |
-
def local_edit_interface(image_dict, prompt, request: gr.Request, progress=gr.Progress()):
|
| 609 |
-
"""
|
| 610 |
-
Handle local editing requests (with phase-based limitations)
|
| 611 |
-
"""
|
| 612 |
-
try:
|
| 613 |
-
# Extract user IP
|
| 614 |
-
client_ip = request.client.host
|
| 615 |
-
x_forwarded_for = dict(request.headers).get('x-forwarded-for')
|
| 616 |
-
if x_forwarded_for:
|
| 617 |
-
client_ip = x_forwarded_for
|
| 618 |
-
if client_ip not in IP_Dict:
|
| 619 |
-
IP_Dict[client_ip] = 0
|
| 620 |
-
IP_Dict[client_ip] += 1
|
| 621 |
-
|
| 622 |
-
if image_dict is None:
|
| 623 |
-
return None, "Please upload an image and draw the area to edit", gr.update(visible=False)
|
| 624 |
-
|
| 625 |
-
# Check if background and layers exist
|
| 626 |
-
if "background" not in image_dict or "layers" not in image_dict:
|
| 627 |
-
return None, "Please draw the area to edit on the image", gr.update(visible=False)
|
| 628 |
-
|
| 629 |
-
base_image = image_dict["background"]
|
| 630 |
-
layers = image_dict["layers"]
|
| 631 |
-
|
| 632 |
-
if not layers:
|
| 633 |
-
return None, "Please draw the area to edit on the image", gr.update(visible=False)
|
| 634 |
-
|
| 635 |
-
if not prompt or prompt.strip() == "":
|
| 636 |
-
return None, "Please enter editing prompt", gr.update(visible=False)
|
| 637 |
-
|
| 638 |
-
# Check prompt length
|
| 639 |
-
if len(prompt.strip()) <= 3:
|
| 640 |
-
return None, "❌ Editing prompt must be more than 3 characters", gr.update(visible=False)
|
| 641 |
-
except Exception as e:
|
| 642 |
-
print(f"⚠️ Local edit request preprocessing error: {e}")
|
| 643 |
-
return None, "❌ Request processing error", gr.update(visible=False)
|
| 644 |
-
|
| 645 |
-
# Check if user has an active task in progress
|
| 646 |
-
if has_active_task(client_ip):
|
| 647 |
-
concurrent_button_html = f"""
|
| 648 |
-
<div style='display: flex; justify-content: center; gap: 15px; margin: 10px 0 5px 0; padding: 0px;'>
|
| 649 |
-
<a href='https://omnicreator.net/multi-image-edit#generator' target='_blank' style='
|
| 650 |
-
display: inline-flex;
|
| 651 |
-
align-items: center;
|
| 652 |
-
justify-content: center;
|
| 653 |
-
padding: 16px 32px;
|
| 654 |
-
background: linear-gradient(135deg, #f39c12 0%, #e67e22 100%);
|
| 655 |
-
color: white;
|
| 656 |
-
text-decoration: none;
|
| 657 |
-
border-radius: 12px;
|
| 658 |
-
font-weight: 600;
|
| 659 |
-
font-size: 16px;
|
| 660 |
-
text-align: center;
|
| 661 |
-
min-width: 200px;
|
| 662 |
-
box-shadow: 0 4px 15px rgba(243, 156, 18, 0.4);
|
| 663 |
-
transition: all 0.3s ease;
|
| 664 |
-
border: none;
|
| 665 |
-
'>⏰ Process Multiple Tasks Simultaneously</a>
|
| 666 |
-
</div>
|
| 667 |
-
"""
|
| 668 |
-
return None, "❌ You have a task in progress. Please wait for it to complete before submitting a new task. Or visit https://omnicreator.net/multi-image-edit#generator to process multiple tasks simultaneously.", gr.update(value=concurrent_button_html, visible=True)
|
| 669 |
-
|
| 670 |
-
# Get user current phase
|
| 671 |
-
current_phase = get_ip_phase(client_ip)
|
| 672 |
-
current_count = get_ip_generation_count(client_ip)
|
| 673 |
-
geo_info = IP_Country_Cache.get(client_ip, {"country": "Unknown", "region": "Unknown", "city": "Unknown"})
|
| 674 |
-
is_restricted = is_restricted_country_ip(client_ip)
|
| 675 |
-
|
| 676 |
-
print(f"📊 Local edit user phase info - IP: {client_ip}, Location: {geo_info['country']}/{geo_info['region']}/{geo_info['city']}, Phase: {current_phase}, Count: {current_count}, Restricted: {is_restricted}, Active task: {has_active_task(client_ip)}")
|
| 677 |
-
|
| 678 |
-
# Check if completely blocked
|
| 679 |
-
if current_phase == 'blocked':
|
| 680 |
-
# Generate blocked limit button
|
| 681 |
-
blocked_button_html = f"""
|
| 682 |
-
<div style='display: flex; justify-content: center; gap: 15px; margin: 10px 0 5px 0; padding: 0px;'>
|
| 683 |
-
<a href='https://omnicreator.net/multi-image-edit#generator' target='_blank' style='
|
| 684 |
-
display: inline-flex;
|
| 685 |
-
align-items: center;
|
| 686 |
-
justify-content: center;
|
| 687 |
-
padding: 16px 32px;
|
| 688 |
-
background: linear-gradient(135deg, #e74c3c 0%, #c0392b 100%);
|
| 689 |
-
color: white;
|
| 690 |
-
text-decoration: none;
|
| 691 |
-
border-radius: 12px;
|
| 692 |
-
font-weight: 600;
|
| 693 |
-
font-size: 16px;
|
| 694 |
-
text-align: center;
|
| 695 |
-
min-width: 200px;
|
| 696 |
-
box-shadow: 0 4px 15px rgba(231, 76, 60, 0.4);
|
| 697 |
-
transition: all 0.3s ease;
|
| 698 |
-
border: none;
|
| 699 |
-
'>🚀 Unlimited Generation</a>
|
| 700 |
-
</div>
|
| 701 |
-
"""
|
| 702 |
-
return None, f"❌ You have reached Hugging Face's free generation limit. Please visit https://omnicreator.net/multi-image-edit#generator for unlimited generation", gr.update(value=blocked_button_html, visible=True)
|
| 703 |
-
|
| 704 |
-
# Check rate limit (applies to rate_limit phases)
|
| 705 |
-
if current_phase in ['rate_limit_1', 'rate_limit_2', 'rate_limit_3']:
|
| 706 |
-
is_limited, wait_minutes, window_count = check_rate_limit_for_phase(client_ip, current_phase)
|
| 707 |
-
if is_limited:
|
| 708 |
-
wait_minutes_int = int(wait_minutes) + 1
|
| 709 |
-
# Generate rate limit button
|
| 710 |
-
rate_limit_button_html = f"""
|
| 711 |
-
<div style='display: flex; justify-content: center; gap: 15px; margin: 10px 0 5px 0; padding: 0px;'>
|
| 712 |
-
<a href='https://omnicreator.net/multi-image-edit#generator' target='_blank' style='
|
| 713 |
-
display: inline-flex;
|
| 714 |
-
align-items: center;
|
| 715 |
-
justify-content: center;
|
| 716 |
-
padding: 16px 32px;
|
| 717 |
-
background: linear-gradient(135deg, #f39c12 0%, #e67e22 100%);
|
| 718 |
-
color: white;
|
| 719 |
-
text-decoration: none;
|
| 720 |
-
border-radius: 12px;
|
| 721 |
-
font-weight: 600;
|
| 722 |
-
font-size: 16px;
|
| 723 |
-
text-align: center;
|
| 724 |
-
min-width: 200px;
|
| 725 |
-
box-shadow: 0 4px 15px rgba(243, 156, 18, 0.4);
|
| 726 |
-
transition: all 0.3s ease;
|
| 727 |
-
border: none;
|
| 728 |
-
'>⏰ Skip Wait - Unlimited Generation</a>
|
| 729 |
-
</div>
|
| 730 |
-
"""
|
| 731 |
-
return None, f"❌ You have reached Hugging Face's free generation limit. Please visit https://omnicreator.net/multi-image-edit#generator for unlimited generation, or wait {wait_minutes_int} minutes before generating again", gr.update(value=rate_limit_button_html, visible=True)
|
| 732 |
-
|
| 733 |
-
# Handle NSFW detection based on phase
|
| 734 |
-
is_nsfw_task = False # Track if this task involves NSFW content
|
| 735 |
-
|
| 736 |
-
# Skip NSFW detection in free phase
|
| 737 |
-
if current_phase != 'free' and nsfw_detector is not None and base_image is not None:
|
| 738 |
-
try:
|
| 739 |
-
nsfw_result = nsfw_detector.predict_pil_label_only(base_image)
|
| 740 |
-
|
| 741 |
-
if nsfw_result.lower() == "nsfw":
|
| 742 |
-
is_nsfw_task = True
|
| 743 |
-
print(f"🔍 Local edit input NSFW detected in {current_phase} phase: ❌❌❌ {nsfw_result} - IP: {client_ip} (will blur result)")
|
| 744 |
-
else:
|
| 745 |
-
print(f"🔍 Local edit input NSFW check passed: ✅✅✅ {nsfw_result} - IP: {client_ip}")
|
| 746 |
-
|
| 747 |
-
except Exception as e:
|
| 748 |
-
print(f"⚠️ Local edit input NSFW detection failed: {e}")
|
| 749 |
-
# Allow continuation when detection fails
|
| 750 |
-
|
| 751 |
-
result_url = None
|
| 752 |
-
status_message = ""
|
| 753 |
-
|
| 754 |
-
def progress_callback(message):
|
| 755 |
-
try:
|
| 756 |
-
nonlocal status_message
|
| 757 |
-
status_message = message
|
| 758 |
-
# Add error handling to prevent progress update failure
|
| 759 |
-
if progress is not None:
|
| 760 |
-
progress(0.5, desc=message)
|
| 761 |
-
except Exception as e:
|
| 762 |
-
print(f"⚠️ Local edit progress update failed: {e}")
|
| 763 |
-
|
| 764 |
-
try:
|
| 765 |
-
# Record generation attempt (before actual generation to ensure correct count)
|
| 766 |
-
record_generation_attempt(client_ip, current_phase)
|
| 767 |
-
updated_count = get_ip_generation_count(client_ip)
|
| 768 |
-
|
| 769 |
-
# Mark this IP as having an active task
|
| 770 |
-
set_active_task(client_ip, active=True)
|
| 771 |
|
| 772 |
-
print(f"✅ Local editing started - IP: {client_ip}, phase: {current_phase}, total count: {updated_count}, prompt: {prompt.strip()}", flush=True)
|
| 773 |
-
|
| 774 |
-
# Determine priority (first few tasks for each IP get priority)
|
| 775 |
-
task_priority = 1 if current_count < 2 else 0
|
| 776 |
-
|
| 777 |
-
# Call local image editing processing function
|
| 778 |
-
result_url, message, task_uuid = process_local_image_edit(base_image, layers, prompt.strip(), progress_callback, priority=task_priority, client_ip=client_ip)
|
| 779 |
-
|
| 780 |
-
if result_url:
|
| 781 |
-
print(f"✅ Local editing completed successfully - IP: {client_ip}, result_url: {result_url}, task_uuid: {task_uuid}", flush=True)
|
| 782 |
-
|
| 783 |
-
# Detect result image NSFW content (only in rate limit phases)
|
| 784 |
-
if nsfw_detector is not None and current_phase != 'free':
|
| 785 |
-
try:
|
| 786 |
-
if progress is not None:
|
| 787 |
-
progress(0.9, desc="Checking result image...")
|
| 788 |
-
|
| 789 |
-
is_nsfw, nsfw_error = download_and_check_result_nsfw(result_url, nsfw_detector)
|
| 790 |
-
|
| 791 |
-
if nsfw_error:
|
| 792 |
-
print(f"⚠️ Local edit result image NSFW detection error - IP: {client_ip}, error: {nsfw_error}")
|
| 793 |
-
elif is_nsfw:
|
| 794 |
-
is_nsfw_task = True # Mark task as NSFW
|
| 795 |
-
print(f"🔍 Local edit result image NSFW detected in {current_phase} phase: ❌❌❌ - IP: {client_ip} (will blur result)")
|
| 796 |
-
else:
|
| 797 |
-
print(f"🔍 Local edit result image NSFW check passed: ✅✅✅ - IP: {client_ip}")
|
| 798 |
-
|
| 799 |
-
except Exception as e:
|
| 800 |
-
print(f"⚠️ Local edit result image NSFW detection exception - IP: {client_ip}, error: {str(e)}")
|
| 801 |
-
|
| 802 |
-
# Apply blur if this is an NSFW task in rate limit phases
|
| 803 |
-
should_blur = False
|
| 804 |
-
|
| 805 |
-
if current_phase in ['rate_limit_1', 'rate_limit_2', 'rate_limit_3'] and is_nsfw_task:
|
| 806 |
-
should_blur = True
|
| 807 |
-
|
| 808 |
-
# Apply blur processing
|
| 809 |
-
if should_blur:
|
| 810 |
-
if progress is not None:
|
| 811 |
-
progress(0.95, desc="Applying content filter...")
|
| 812 |
-
|
| 813 |
-
blurred_image = apply_gaussian_blur_to_image_url(result_url)
|
| 814 |
-
if blurred_image is not None:
|
| 815 |
-
final_result = blurred_image # Return PIL Image object
|
| 816 |
-
final_message = f"⚠️ NSFW content detected, content filter applied. NSFW content is prohibited by Hugging Face, but you can generate unlimited content at our official website https://omnicreator.net/multi-image-edit#generator"
|
| 817 |
-
print(f"🔒 Local edit applied Gaussian blur for NSFW content - IP: {client_ip}")
|
| 818 |
-
else:
|
| 819 |
-
# Blur failed, return original URL with warning
|
| 820 |
-
final_result = result_url
|
| 821 |
-
final_message = f"⚠️ NSFW content detected, but content filter failed. Please visit https://omnicreator.net/multi-image-edit#generator for better experience"
|
| 822 |
-
|
| 823 |
-
# Generate NSFW button for blurred content
|
| 824 |
-
nsfw_action_buttons_html = f"""
|
| 825 |
-
<div style='display: flex; justify-content: center; gap: 15px; margin: 10px 0 5px 0; padding: 0px;'>
|
| 826 |
-
<a href='https://omnicreator.net/multi-image-edit#generator' target='_blank' style='
|
| 827 |
-
display: inline-flex;
|
| 828 |
-
align-items: center;
|
| 829 |
-
justify-content: center;
|
| 830 |
-
padding: 16px 32px;
|
| 831 |
-
background: linear-gradient(135deg, #ff6b6b 0%, #feca57 100%);
|
| 832 |
-
color: white;
|
| 833 |
-
text-decoration: none;
|
| 834 |
-
border-radius: 12px;
|
| 835 |
-
font-weight: 600;
|
| 836 |
-
font-size: 16px;
|
| 837 |
-
text-align: center;
|
| 838 |
-
min-width: 200px;
|
| 839 |
-
box-shadow: 0 4px 15px rgba(255, 107, 107, 0.4);
|
| 840 |
-
transition: all 0.3s ease;
|
| 841 |
-
border: none;
|
| 842 |
-
'>🔥 Unlimited NSFW Generation</a>
|
| 843 |
-
</div>
|
| 844 |
-
"""
|
| 845 |
-
return final_result, final_message, gr.update(value=nsfw_action_buttons_html, visible=True)
|
| 846 |
-
else:
|
| 847 |
-
final_result = result_url
|
| 848 |
-
final_message = "✅ " + message
|
| 849 |
-
|
| 850 |
-
try:
|
| 851 |
-
if progress is not None:
|
| 852 |
-
progress(1.0, desc="Processing completed")
|
| 853 |
-
except Exception as e:
|
| 854 |
-
print(f"⚠️ Local edit final progress update failed: {e}")
|
| 855 |
-
|
| 856 |
-
# Generate action buttons HTML like Trump AI Voice
|
| 857 |
-
action_buttons_html = ""
|
| 858 |
-
if task_uuid:
|
| 859 |
-
task_detail_url = f"https://omnicreator.net/my-creations/task/{task_uuid}"
|
| 860 |
-
action_buttons_html = f"""
|
| 861 |
-
<div style='display: flex; justify-content: center; gap: 15px; margin: 10px 0 5px 0; padding: 0px;'>
|
| 862 |
-
<a href='{task_detail_url}' target='_blank' style='
|
| 863 |
-
display: inline-flex;
|
| 864 |
-
align-items: center;
|
| 865 |
-
justify-content: center;
|
| 866 |
-
padding: 16px 32px;
|
| 867 |
-
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
| 868 |
-
color: white;
|
| 869 |
-
text-decoration: none;
|
| 870 |
-
border-radius: 12px;
|
| 871 |
-
font-weight: 600;
|
| 872 |
-
font-size: 16px;
|
| 873 |
-
text-align: center;
|
| 874 |
-
min-width: 160px;
|
| 875 |
-
box-shadow: 0 4px 15px rgba(102, 126, 234, 0.4);
|
| 876 |
-
transition: all 0.3s ease;
|
| 877 |
-
border: none;
|
| 878 |
-
'>🖼️ Download HD Image</a>
|
| 879 |
-
<a href='https://omnicreator.net/multi-image-edit#generator' target='_blank' style='
|
| 880 |
-
display: inline-flex;
|
| 881 |
-
align-items: center;
|
| 882 |
-
justify-content: center;
|
| 883 |
-
padding: 16px 32px;
|
| 884 |
-
background: linear-gradient(135deg, #11998e 0%, #38ef7d 100%);
|
| 885 |
-
color: white;
|
| 886 |
-
text-decoration: none;
|
| 887 |
-
border-radius: 12px;
|
| 888 |
-
font-weight: 600;
|
| 889 |
-
font-size: 16px;
|
| 890 |
-
text-align: center;
|
| 891 |
-
min-width: 160px;
|
| 892 |
-
box-shadow: 0 4px 15px rgba(17, 153, 142, 0.4);
|
| 893 |
-
transition: all 0.3s ease;
|
| 894 |
-
border: none;
|
| 895 |
-
'>🚀 Unlimited Generation</a>
|
| 896 |
-
</div>
|
| 897 |
-
"""
|
| 898 |
-
|
| 899 |
-
return final_result, final_message, gr.update(value=action_buttons_html, visible=True)
|
| 900 |
-
else:
|
| 901 |
-
print(f"❌ Local editing processing failed - IP: {client_ip}, error: {message}", flush=True)
|
| 902 |
-
return None, "❌ " + message, gr.update(visible=False)
|
| 903 |
-
|
| 904 |
-
except Exception as e:
|
| 905 |
-
print(f"❌ Local editing exception - IP: {client_ip}, error: {str(e)}")
|
| 906 |
-
return None, f"❌ Error occurred during processing: {str(e)}", gr.update(visible=False)
|
| 907 |
-
finally:
|
| 908 |
-
# Always clear active task status when done (success or failure)
|
| 909 |
-
set_active_task(client_ip, active=False)
|
| 910 |
-
|
| 911 |
# Create Gradio interface
|
| 912 |
def create_app():
|
| 913 |
with gr.Blocks(
|
|
|
|
| 468 |
|
| 469 |
print(f"✅ Multi-image processing started - IP: {client_ip}, phase: {current_phase}, total count: {updated_count}, images: {len(valid_images)}, size: {width}x{height}, prompt: {prompt.strip()}", flush=True)
|
| 470 |
|
| 471 |
+
# Determine priority (only the first task for each IP gets priority)
|
| 472 |
+
task_priority = 1 if current_count == 0 else 0
|
| 473 |
|
| 474 |
# Call multi-image editing processing function
|
| 475 |
result_url, message, task_uuid = process_multi_image_edit(valid_images, prompt.strip(), width, height, progress_callback, priority=task_priority, client_ip=client_ip)
|
|
|
|
| 604 |
finally:
|
| 605 |
# Always clear active task status when done (success or failure)
|
| 606 |
set_active_task(client_ip, active=False)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 607 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 608 |
# Create Gradio interface
|
| 609 |
def create_app():
|
| 610 |
with gr.Blocks(
|