community_icon_html = """"""
def get_community_loading_icon(task = "text2img"):
if task == "text2img":
community_icon = """"""
loading_icon = """"""
elif task == "img2img":
community_icon = """"""
loading_icon = """"""
elif task == "inpainting":
community_icon = """"""
loading_icon = """"""
return community_icon, loading_icon
loading_icon_html = """"""
CSS = """
#col-container {margin-left: auto; margin-right: auto;}
a {text-decoration-line: underline; font-weight: 600;}
.animate-spin {
animation: spin 1s linear infinite;
}
@keyframes spin {
from { transform: rotate(0deg); }
to { transform: rotate(360deg); }
}
.gradio-container {
font-family: 'IBM Plex Sans', sans-serif;
}
.gr-button {
color: white;
border-color: black;
background: black;
}
input[type='range'] {
accent-color: black;
}
.dark input[type='range'] {
accent-color: #dfdfdf;
}
.container {
max-width: 730px;
margin: auto;
padding-top: 1.5rem;
}
#gallery {
min-height: 22rem;
margin-bottom: 15px;
margin-left: auto;
margin-right: auto;
border-bottom-right-radius: .5rem !important;
border-bottom-left-radius: .5rem !important;
}
#gallery>div>.h-full {
min-height: 20rem;
}
.details:hover {
text-decoration: underline;
}
.gr-button {
white-space: nowrap;
}
.gr-button:focus {
border-color: rgb(147 197 253 / var(--tw-border-opacity));
outline: none;
box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000);
--tw-border-opacity: 1;
--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);
--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(3px var(--tw-ring-offset-width)) var(--tw-ring-color);
--tw-ring-color: rgb(191 219 254 / var(--tw-ring-opacity));
--tw-ring-opacity: .5;
}
#advanced-btn {
font-size: .7rem !important;
line-height: 19px;
margin-top: 12px;
margin-bottom: 12px;
padding: 2px 8px;
border-radius: 14px !important;
}
#advanced-options {
display: none;
margin-bottom: 20px;
}
.footer {
margin-bottom: 45px;
margin-top: 35px;
text-align: center;
border-bottom: 1px solid #e5e5e5;
}
.footer>p {
font-size: .8rem;
display: inline-block;
padding: 0 10px;
transform: translateY(10px);
background: white;
}
.dark .footer {
border-color: #303030;
}
.dark .footer>p {
background: #0b0f19;
}
.acknowledgments h4{
margin: 1.25em 0 .25em 0;
font-weight: bold;
font-size: 115%;
}
.animate-spin {
animation: spin 1s linear infinite;
}
@keyframes spin {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}
#share-btn-container {
display: flex; padding-left: 0.5rem !important; padding-right: 0.5rem !important; background-color: #000000; justify-content: center; align-items: center; border-radius: 9999px !important; width: 13rem;
margin-top: 10px;
margin-left: auto;
margin-right: auto;
}
#share-btn {
all: initial; color: #ffffff;font-weight: 600; cursor:pointer; font-family: 'IBM Plex Sans', sans-serif; margin-left: 0.5rem !important; padding-top: 0.25rem !important; padding-bottom: 0.25rem !important;right:0;
}
#share-btn * {
all: unset;
}
#share-btn-inpainting {
all: initial; color: #ffffff;font-weight: 600; cursor:pointer; font-family: 'IBM Plex Sans', sans-serif; margin-left: 0.5rem !important; padding-top: 0.25rem !important; padding-bottom: 0.25rem !important;right:0;
}
#share-btn-inpainting * {
all: unset;
}
#share-btn-img2img {
all: initial; color: #ffffff;font-weight: 600; cursor:pointer; font-family: 'IBM Plex Sans', sans-serif; margin-left: 0.5rem !important; padding-top: 0.25rem !important; padding-bottom: 0.25rem !important;right:0;
}
#share-btn-img2img * {
all: unset;
}
#share-btn-container div:nth-child(-n+2){
width: auto !important;
min-height: 0px !important;
}
#share-btn-container .wrap {
display: none !important;
}
#download-btn-container {
display: flex; padding-left: 0.5rem !important; padding-right: 0.5rem !important; background-color: #000000; justify-content: center; align-items: center; border-radius: 9999px !important; width: 13rem;
margin-top: 10px;
margin-left: auto;
margin-right: auto;
}
#download-btn {
all: initial; color: #ffffff;font-weight: 600; cursor:pointer; font-family: 'IBM Plex Sans', sans-serif; margin-left: 0.5rem !important; padding-top: 0.25rem !important; padding-bottom: 0.25rem !important;right:0;
}
#download-btn * {
all: unset;
}
#download-btn-container div:nth-child(-n+2){
width: auto !important;
min-height: 0px !important;
}
#download-btn-container .wrap {
display: none !important;
}
.gr-form{
flex: 1 1 50%; border-top-right-radius: 0; border-bottom-right-radius: 0;
}
#prompt-container{
gap: 0;
}
#prompt-text-input, #negative-prompt-text-input{padding: .45rem 0.625rem}
#component-16{border-top-width: 1px!important;margin-top: 1em}
.image_duplication{position: absolute; width: 100px; left: 50px}
"""
# window.addEventListener('message', function (event) {
# if (event.origin !== 'http://127.0.0.1:5000'){
# console.log('Origin not allowed');
# return;
# }
# userId = event.data.userId;
# console.log('User ID received from parent:', userId);
# });
def get_share_js():
share_js = """
async () => {
// Get the username from the URL itself
const urlParams = new URLSearchParams(window.location.search);
const username = urlParams.get('username');
async function uploadFile(
file,
_meta_prompt,
_meta_negative_prompt,
_meta_model_name,
_meta_scheduler_name,
_meta_model_guidance_scale,
_meta_model_num_steps,
_meta_model_image_size,
_meta_seed,
_meta_mask = null,
_meta_reference_image = null,
){
const UPLOAD_URL = 'http://127.0.0.1:5000/v1/api/upload-image';
const formData = new FormData();
formData.append('file', file);
// Add the meta data headers to the form data
formData.append('text_prompt', _meta_prompt);
formData.append('negative_prompt', _meta_negative_prompt);
formData.append('model_name', _meta_model_name);
formData.append('model_guidance_scale', _meta_model_guidance_scale);
formData.append('model_num_steps', _meta_model_num_steps);
formData.append('scheduler_name', _meta_scheduler_name);
formData.append('seed', _meta_seed);
formData.append('model_image_size', _meta_model_image_size);
// Add the optional meta data headers to the form data
if(_meta_mask){
formData.append('mask', _meta_mask);
}
if(_meta_reference_image){
formData.append('reference_image', _meta_reference_image);
}
formData.append('username',username); // This is constant for all the images
const response = await fetch(UPLOAD_URL, {
method: 'POST',
headers: {
'X-Requested-With': 'XMLHttpRequest',
},
body: formData,
});
const url = await response.text(); // This returns the URL of the uploaded file (S3) bucket
return url;
}
const gradioEl = document.querySelector('gradio-app');
const imgEls = gradioEl.querySelectorAll('#gallery img');
// Get the necessary fields
const promptTxt = gradioEl.querySelector('#prompt-text-input textarea').value;
const negativePromptTxt = gradioEl.querySelector('#negative-prompt-text-input textarea').value;
console.log(promptTxt);
console.log(negativePromptTxt);
// Get values from the sliders
const modelGuidanceScale = parseFloat(gradioEl.querySelector('#guidance-scale-slider input').value);
console.log(modelGuidanceScale);
const numSteps = parseInt(gradioEl.querySelector('#num-inference-step-slider input').value);
const imageSize = parseInt(gradioEl.querySelector('#image-size-slider input').value);
const seed = parseInt(gradioEl.querySelector('#seed-slider input').value);
console.log(numSteps);
console.log(imageSize);
console.log(seed);
// Get the values from dropdowns
const modelName = gradioEl.querySelector('#model-dropdown input').value;
const schedulerName = gradioEl.querySelector('#scheduler-dropdown input').value;
console.log(modelName);
console.log(schedulerName);
const shareBtnEl = gradioEl.querySelector('#share-btn');
const shareIconEl = gradioEl.querySelector('#share-btn-share-icon');
const loadingIconEl = gradioEl.querySelector('#share-btn-loading-icon');
if(!imgEls.length){
return;
};
shareBtnEl.style.pointerEvents = 'none';
shareIconEl.style.display = 'none';
loadingIconEl.style.removeProperty('display');
const files = await Promise.all(
[...imgEls].map(async (imgEl) => {
const res = await fetch(imgEl.src);
const blob = await res.blob();
const fileSrc = imgEl.src.split('/').pop(); // Get the file name from the img src path
const imgId = Date.now();
const fileName = `${fileSrc}-${imgId}.jpg`; // Fixed fileName construction
return new File([blob], fileName, { type: 'image/jpeg' });
})
);
// Ensure that only one image is uploaded by taking the first element if there are multiple
if (files.length > 1) {
files.splice(1, files.length - 1);
}
const urls = await Promise.all(files.map((f) => uploadFile(
f,
promptTxt,
negativePromptTxt,
modelName,
schedulerName,
modelGuidanceScale,
numSteps,
imageSize,
seed,
)));
const htmlImgs = urls.map(url => ``);
shareBtnEl.style.removeProperty('pointer-events');
shareIconEl.style.removeProperty('display');
loadingIconEl.style.display = 'none';
}
"""
return share_js
def get_load_from_artwork_js():
load_artwork_js = """
async () => {
const urlParams = new URLSearchParams(window.location.search);
const username = urlParams.get('username');
const artworkId = urlParams.get('artworkId');
const LOAD_URL = `http://127.0.0.1:5000/v1/api/load-parameters?artworkId=${artworkId}`;
const response = await fetch(LOAD_URL, {
method: 'GET',
headers: {
'X-Requested-With': 'XMLHttpRequest',
}
});
// Check if the response is okay
if (!response.ok) {
console.error("An error occurred while fetching the parameters.");
return;
}
const parameters = await response.json(); // Assuming you're getting a JSON response
// Get the necessary elements
const gradioEl = document.querySelector('gradio-app');
const promptInput = gradioEl.querySelector('#prompt-text-input textarea');
const negativePromptInput = gradioEl.querySelector('#negative-prompt-text-input textarea');
// Get the slider inputs
const guidanceScaleInput = gradioEl.querySelector('#guidance-scale-slider input');
const numInferenceStepInput = gradioEl.querySelector('#num-inference-step-slider input');
const imageSizeInput = gradioEl.querySelector('#image-size-slider input');
const seedInput = gradioEl.querySelector('#seed-slider input');
// Get the dropdown inputs
const modelDropdown = gradioEl.querySelector('#model-dropdown input');
const schedulerDropdown = gradioEl.querySelector('#scheduler-dropdown input');
// Set the values based on the parameters received
promptInput.value = parameters.text_prompt;
negativePromptInput.value = parameters.negative_prompt;
guidanceScaleInput.value = parameters.model_guidance_scale;
numInferenceStepInput.value = parameters.model_num_steps;
imageSizeInput.value = parameters.model_image_size;
seedInput.value = parameters.seed;
modelDropdown.value = parameters.model_name;
schedulerDropdown.value = parameters.scheduler_name;
}
"""
return load_artwork_js