Merge branch 'dev' into better-status-reporting-1
This commit is contained in:
commit
fc049a2fd3
@ -200,7 +200,8 @@ onUiLoaded(async() => {
|
|||||||
canvas_hotkey_move: "KeyF",
|
canvas_hotkey_move: "KeyF",
|
||||||
canvas_hotkey_overlap: "KeyO",
|
canvas_hotkey_overlap: "KeyO",
|
||||||
canvas_disabled_functions: [],
|
canvas_disabled_functions: [],
|
||||||
canvas_show_tooltip: true
|
canvas_show_tooltip: true,
|
||||||
|
canvas_blur_prompt: false
|
||||||
};
|
};
|
||||||
|
|
||||||
const functionMap = {
|
const functionMap = {
|
||||||
@ -608,6 +609,19 @@ onUiLoaded(async() => {
|
|||||||
|
|
||||||
// Handle keydown events
|
// Handle keydown events
|
||||||
function handleKeyDown(event) {
|
function handleKeyDown(event) {
|
||||||
|
// Disable key locks to make pasting from the buffer work correctly
|
||||||
|
if ((event.ctrlKey && event.code === 'KeyV') || (event.ctrlKey && event.code === 'KeyC') || event.code === "F5") {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// before activating shortcut, ensure user is not actively typing in an input field
|
||||||
|
if (!hotkeysConfig.canvas_blur_prompt) {
|
||||||
|
if (event.target.nodeName === 'TEXTAREA' || event.target.nodeName === 'INPUT') {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
const hotkeyActions = {
|
const hotkeyActions = {
|
||||||
[hotkeysConfig.canvas_hotkey_reset]: resetZoom,
|
[hotkeysConfig.canvas_hotkey_reset]: resetZoom,
|
||||||
[hotkeysConfig.canvas_hotkey_overlap]: toggleOverlap,
|
[hotkeysConfig.canvas_hotkey_overlap]: toggleOverlap,
|
||||||
@ -686,6 +700,20 @@ onUiLoaded(async() => {
|
|||||||
|
|
||||||
// Handle the move event for pan functionality. Updates the panX and panY variables and applies the new transform to the target element.
|
// Handle the move event for pan functionality. Updates the panX and panY variables and applies the new transform to the target element.
|
||||||
function handleMoveKeyDown(e) {
|
function handleMoveKeyDown(e) {
|
||||||
|
|
||||||
|
// Disable key locks to make pasting from the buffer work correctly
|
||||||
|
if ((e.ctrlKey && e.code === 'KeyV') || (e.ctrlKey && event.code === 'KeyC') || e.code === "F5") {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// before activating shortcut, ensure user is not actively typing in an input field
|
||||||
|
if (!hotkeysConfig.canvas_blur_prompt) {
|
||||||
|
if (e.target.nodeName === 'TEXTAREA' || e.target.nodeName === 'INPUT') {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
if (e.code === hotkeysConfig.canvas_hotkey_move) {
|
if (e.code === hotkeysConfig.canvas_hotkey_move) {
|
||||||
if (!e.ctrlKey && !e.metaKey && isKeyDownHandlerAttached) {
|
if (!e.ctrlKey && !e.metaKey && isKeyDownHandlerAttached) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
@ -9,5 +9,6 @@ shared.options_templates.update(shared.options_section(('canvas_hotkey', "Canvas
|
|||||||
"canvas_hotkey_reset": shared.OptionInfo("R", "Reset zoom and canvas positon"),
|
"canvas_hotkey_reset": shared.OptionInfo("R", "Reset zoom and canvas positon"),
|
||||||
"canvas_hotkey_overlap": shared.OptionInfo("O", "Toggle overlap").info("Technical button, neededs for testing"),
|
"canvas_hotkey_overlap": shared.OptionInfo("O", "Toggle overlap").info("Technical button, neededs for testing"),
|
||||||
"canvas_show_tooltip": shared.OptionInfo(True, "Enable tooltip on the canvas"),
|
"canvas_show_tooltip": shared.OptionInfo(True, "Enable tooltip on the canvas"),
|
||||||
|
"canvas_blur_prompt": shared.OptionInfo(False, "Take the focus off the prompt when working with a canvas"),
|
||||||
"canvas_disabled_functions": shared.OptionInfo(["Overlap"], "Disable function that you don't use", gr.CheckboxGroup, {"choices": ["Zoom","Adjust brush size", "Moving canvas","Fullscreen","Reset Zoom","Overlap"]}),
|
"canvas_disabled_functions": shared.OptionInfo(["Overlap"], "Disable function that you don't use", gr.CheckboxGroup, {"choices": ["Zoom","Adjust brush size", "Moving canvas","Fullscreen","Reset Zoom","Overlap"]}),
|
||||||
}))
|
}))
|
||||||
|
@ -30,6 +30,7 @@ from modules import devices
|
|||||||
from typing import Dict, List, Any
|
from typing import Dict, List, Any
|
||||||
import piexif
|
import piexif
|
||||||
import piexif.helper
|
import piexif.helper
|
||||||
|
from contextlib import closing
|
||||||
|
|
||||||
|
|
||||||
def script_name_to_index(name, scripts):
|
def script_name_to_index(name, scripts):
|
||||||
@ -77,6 +78,8 @@ def encode_pil_to_base64(image):
|
|||||||
image.save(output_bytes, format="PNG", pnginfo=(metadata if use_metadata else None), quality=opts.jpeg_quality)
|
image.save(output_bytes, format="PNG", pnginfo=(metadata if use_metadata else None), quality=opts.jpeg_quality)
|
||||||
|
|
||||||
elif opts.samples_format.lower() in ("jpg", "jpeg", "webp"):
|
elif opts.samples_format.lower() in ("jpg", "jpeg", "webp"):
|
||||||
|
if image.mode == "RGBA":
|
||||||
|
image = image.convert("RGB")
|
||||||
parameters = image.info.get('parameters', None)
|
parameters = image.info.get('parameters', None)
|
||||||
exif_bytes = piexif.dump({
|
exif_bytes = piexif.dump({
|
||||||
"Exif": { piexif.ExifIFD.UserComment: piexif.helper.UserComment.dump(parameters or "", encoding="unicode") }
|
"Exif": { piexif.ExifIFD.UserComment: piexif.helper.UserComment.dump(parameters or "", encoding="unicode") }
|
||||||
@ -322,19 +325,19 @@ class Api:
|
|||||||
args.pop('save_images', None)
|
args.pop('save_images', None)
|
||||||
|
|
||||||
with self.queue_lock:
|
with self.queue_lock:
|
||||||
p = StableDiffusionProcessingTxt2Img(sd_model=shared.sd_model, **args)
|
with closing(StableDiffusionProcessingTxt2Img(sd_model=shared.sd_model, **args)) as p:
|
||||||
p.scripts = script_runner
|
p.scripts = script_runner
|
||||||
p.outpath_grids = opts.outdir_txt2img_grids
|
p.outpath_grids = opts.outdir_txt2img_grids
|
||||||
p.outpath_samples = opts.outdir_txt2img_samples
|
p.outpath_samples = opts.outdir_txt2img_samples
|
||||||
|
|
||||||
shared.state.begin(job="scripts_txt2img")
|
shared.state.begin(job="scripts_txt2img")
|
||||||
if selectable_scripts is not None:
|
if selectable_scripts is not None:
|
||||||
p.script_args = script_args
|
p.script_args = script_args
|
||||||
processed = scripts.scripts_txt2img.run(p, *p.script_args) # Need to pass args as list here
|
processed = scripts.scripts_txt2img.run(p, *p.script_args) # Need to pass args as list here
|
||||||
else:
|
else:
|
||||||
p.script_args = tuple(script_args) # Need to pass args as tuple here
|
p.script_args = tuple(script_args) # Need to pass args as tuple here
|
||||||
processed = process_images(p)
|
processed = process_images(p)
|
||||||
shared.state.end()
|
shared.state.end()
|
||||||
|
|
||||||
b64images = list(map(encode_pil_to_base64, processed.images)) if send_images else []
|
b64images = list(map(encode_pil_to_base64, processed.images)) if send_images else []
|
||||||
|
|
||||||
@ -378,20 +381,20 @@ class Api:
|
|||||||
args.pop('save_images', None)
|
args.pop('save_images', None)
|
||||||
|
|
||||||
with self.queue_lock:
|
with self.queue_lock:
|
||||||
p = StableDiffusionProcessingImg2Img(sd_model=shared.sd_model, **args)
|
with closing(StableDiffusionProcessingImg2Img(sd_model=shared.sd_model, **args)) as p:
|
||||||
p.init_images = [decode_base64_to_image(x) for x in init_images]
|
p.init_images = [decode_base64_to_image(x) for x in init_images]
|
||||||
p.scripts = script_runner
|
p.scripts = script_runner
|
||||||
p.outpath_grids = opts.outdir_img2img_grids
|
p.outpath_grids = opts.outdir_img2img_grids
|
||||||
p.outpath_samples = opts.outdir_img2img_samples
|
p.outpath_samples = opts.outdir_img2img_samples
|
||||||
|
|
||||||
shared.state.begin(job="scripts_img2img")
|
shared.state.begin(job="scripts_img2img")
|
||||||
if selectable_scripts is not None:
|
if selectable_scripts is not None:
|
||||||
p.script_args = script_args
|
p.script_args = script_args
|
||||||
processed = scripts.scripts_img2img.run(p, *p.script_args) # Need to pass args as list here
|
processed = scripts.scripts_img2img.run(p, *p.script_args) # Need to pass args as list here
|
||||||
else:
|
else:
|
||||||
p.script_args = tuple(script_args) # Need to pass args as tuple here
|
p.script_args = tuple(script_args) # Need to pass args as tuple here
|
||||||
processed = process_images(p)
|
processed = process_images(p)
|
||||||
shared.state.end()
|
shared.state.end()
|
||||||
|
|
||||||
b64images = list(map(encode_pil_to_base64, processed.images)) if send_images else []
|
b64images = list(map(encode_pil_to_base64, processed.images)) if send_images else []
|
||||||
|
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
import datetime
|
import datetime
|
||||||
|
|
||||||
import pytz
|
import pytz
|
||||||
@ -497,13 +499,23 @@ def get_next_sequence_number(path, basename):
|
|||||||
return result + 1
|
return result + 1
|
||||||
|
|
||||||
|
|
||||||
def save_image_with_geninfo(image, geninfo, filename, extension=None, existing_pnginfo=None):
|
def save_image_with_geninfo(image, geninfo, filename, extension=None, existing_pnginfo=None, pnginfo_section_name='parameters'):
|
||||||
|
"""
|
||||||
|
Saves image to filename, including geninfo as text information for generation info.
|
||||||
|
For PNG images, geninfo is added to existing pnginfo dictionary using the pnginfo_section_name argument as key.
|
||||||
|
For JPG images, there's no dictionary and geninfo just replaces the EXIF description.
|
||||||
|
"""
|
||||||
|
|
||||||
if extension is None:
|
if extension is None:
|
||||||
extension = os.path.splitext(filename)[1]
|
extension = os.path.splitext(filename)[1]
|
||||||
|
|
||||||
image_format = Image.registered_extensions()[extension]
|
image_format = Image.registered_extensions()[extension]
|
||||||
|
|
||||||
if extension.lower() == '.png':
|
if extension.lower() == '.png':
|
||||||
|
existing_pnginfo = existing_pnginfo or {}
|
||||||
|
if opts.enable_pnginfo:
|
||||||
|
existing_pnginfo[pnginfo_section_name] = geninfo
|
||||||
|
|
||||||
if opts.enable_pnginfo:
|
if opts.enable_pnginfo:
|
||||||
pnginfo_data = PngImagePlugin.PngInfo()
|
pnginfo_data = PngImagePlugin.PngInfo()
|
||||||
for k, v in (existing_pnginfo or {}).items():
|
for k, v in (existing_pnginfo or {}).items():
|
||||||
@ -622,7 +634,7 @@ def save_image(image, path, basename, seed=None, prompt=None, extension='png', i
|
|||||||
"""
|
"""
|
||||||
temp_file_path = f"{filename_without_extension}.tmp"
|
temp_file_path = f"{filename_without_extension}.tmp"
|
||||||
|
|
||||||
save_image_with_geninfo(image_to_save, info, temp_file_path, extension, params.pnginfo)
|
save_image_with_geninfo(image_to_save, info, temp_file_path, extension, existing_pnginfo=params.pnginfo, pnginfo_section_name=pnginfo_section_name)
|
||||||
|
|
||||||
os.replace(temp_file_path, filename_without_extension + extension)
|
os.replace(temp_file_path, filename_without_extension + extension)
|
||||||
|
|
||||||
@ -639,12 +651,18 @@ def save_image(image, path, basename, seed=None, prompt=None, extension='png', i
|
|||||||
oversize = image.width > opts.target_side_length or image.height > opts.target_side_length
|
oversize = image.width > opts.target_side_length or image.height > opts.target_side_length
|
||||||
if opts.export_for_4chan and (oversize or os.stat(fullfn).st_size > opts.img_downscale_threshold * 1024 * 1024):
|
if opts.export_for_4chan and (oversize or os.stat(fullfn).st_size > opts.img_downscale_threshold * 1024 * 1024):
|
||||||
ratio = image.width / image.height
|
ratio = image.width / image.height
|
||||||
|
resize_to = None
|
||||||
if oversize and ratio > 1:
|
if oversize and ratio > 1:
|
||||||
image = image.resize((round(opts.target_side_length), round(image.height * opts.target_side_length / image.width)), LANCZOS)
|
resize_to = round(opts.target_side_length), round(image.height * opts.target_side_length / image.width)
|
||||||
elif oversize:
|
elif oversize:
|
||||||
image = image.resize((round(image.width * opts.target_side_length / image.height), round(opts.target_side_length)), LANCZOS)
|
resize_to = round(image.width * opts.target_side_length / image.height), round(opts.target_side_length)
|
||||||
|
|
||||||
|
if resize_to is not None:
|
||||||
|
try:
|
||||||
|
# Resizing image with LANCZOS could throw an exception if e.g. image mode is I;16
|
||||||
|
image = image.resize(resize_to, LANCZOS)
|
||||||
|
except:
|
||||||
|
image = image.resize(resize_to)
|
||||||
try:
|
try:
|
||||||
_atomically_save_image(image, fullfn_without_extension, ".jpg")
|
_atomically_save_image(image, fullfn_without_extension, ".jpg")
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
@ -662,8 +680,15 @@ def save_image(image, path, basename, seed=None, prompt=None, extension='png', i
|
|||||||
return fullfn, txt_fullfn
|
return fullfn, txt_fullfn
|
||||||
|
|
||||||
|
|
||||||
def read_info_from_image(image):
|
IGNORED_INFO_KEYS = {
|
||||||
items = image.info or {}
|
'jfif', 'jfif_version', 'jfif_unit', 'jfif_density', 'dpi', 'exif',
|
||||||
|
'loop', 'background', 'timestamp', 'duration', 'progressive', 'progression',
|
||||||
|
'icc_profile', 'chromaticity', 'photoshop',
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def read_info_from_image(image: Image.Image) -> tuple[str | None, dict]:
|
||||||
|
items = (image.info or {}).copy()
|
||||||
|
|
||||||
geninfo = items.pop('parameters', None)
|
geninfo = items.pop('parameters', None)
|
||||||
|
|
||||||
@ -679,9 +704,7 @@ def read_info_from_image(image):
|
|||||||
items['exif comment'] = exif_comment
|
items['exif comment'] = exif_comment
|
||||||
geninfo = exif_comment
|
geninfo = exif_comment
|
||||||
|
|
||||||
for field in ['jfif', 'jfif_version', 'jfif_unit', 'jfif_density', 'dpi', 'exif',
|
for field in IGNORED_INFO_KEYS:
|
||||||
'loop', 'background', 'timestamp', 'duration', 'progressive', 'progression',
|
|
||||||
'icc_profile', 'chromaticity']:
|
|
||||||
items.pop(field, None)
|
items.pop(field, None)
|
||||||
|
|
||||||
if items.get("Software", None) == "NovelAI":
|
if items.get("Software", None) == "NovelAI":
|
||||||
|
@ -4,16 +4,21 @@ from modules.sd_hijack_utils import CondFunc
|
|||||||
from packaging import version
|
from packaging import version
|
||||||
|
|
||||||
|
|
||||||
# has_mps is only available in nightly pytorch (for now) and macOS 12.3+.
|
# before torch version 1.13, has_mps is only available in nightly pytorch and macOS 12.3+,
|
||||||
# check `getattr` and try it for compatibility
|
# use check `getattr` and try it for compatibility.
|
||||||
|
# in torch version 1.13, backends.mps.is_available() and backends.mps.is_built() are introduced in to check mps availabilty,
|
||||||
|
# since torch 2.0.1+ nightly build, getattr(torch, 'has_mps', False) was deprecated, see https://github.com/pytorch/pytorch/pull/103279
|
||||||
def check_for_mps() -> bool:
|
def check_for_mps() -> bool:
|
||||||
if not getattr(torch, 'has_mps', False):
|
if version.parse(torch.__version__) <= version.parse("2.0.1"):
|
||||||
return False
|
if not getattr(torch, 'has_mps', False):
|
||||||
try:
|
return False
|
||||||
torch.zeros(1).to(torch.device("mps"))
|
try:
|
||||||
return True
|
torch.zeros(1).to(torch.device("mps"))
|
||||||
except Exception:
|
return True
|
||||||
return False
|
except Exception:
|
||||||
|
return False
|
||||||
|
else:
|
||||||
|
return torch.backends.mps.is_available() and torch.backends.mps.is_built()
|
||||||
has_mps = check_for_mps()
|
has_mps = check_for_mps()
|
||||||
|
|
||||||
|
|
||||||
|
@ -53,7 +53,9 @@ def run_postprocessing(extras_mode, image, image_folder, input_dir, output_dir,
|
|||||||
for image, name in zip(image_data, image_names):
|
for image, name in zip(image_data, image_names):
|
||||||
shared.state.textinfo = name
|
shared.state.textinfo = name
|
||||||
|
|
||||||
existing_pnginfo = image.info or {}
|
parameters, existing_pnginfo = images.read_info_from_image(image)
|
||||||
|
if parameters:
|
||||||
|
existing_pnginfo["parameters"] = parameters
|
||||||
|
|
||||||
pp = scripts_postprocessing.PostprocessedImage(image.convert("RGB"))
|
pp = scripts_postprocessing.PostprocessedImage(image.convert("RGB"))
|
||||||
|
|
||||||
|
@ -575,7 +575,7 @@ def create_infotext(p, all_prompts, all_seeds, all_subseeds, comments=None, iter
|
|||||||
"Model": (None if not opts.add_model_name_to_info or not shared.sd_model.sd_checkpoint_info.model_name else shared.sd_model.sd_checkpoint_info.model_name.replace(',', '').replace(':', '')),
|
"Model": (None if not opts.add_model_name_to_info or not shared.sd_model.sd_checkpoint_info.model_name else shared.sd_model.sd_checkpoint_info.model_name.replace(',', '').replace(':', '')),
|
||||||
"Variation seed": (None if p.subseed_strength == 0 else all_subseeds[index]),
|
"Variation seed": (None if p.subseed_strength == 0 else all_subseeds[index]),
|
||||||
"Variation seed strength": (None if p.subseed_strength == 0 else p.subseed_strength),
|
"Variation seed strength": (None if p.subseed_strength == 0 else p.subseed_strength),
|
||||||
"Seed resize from": (None if p.seed_resize_from_w == 0 or p.seed_resize_from_h == 0 else f"{p.seed_resize_from_w}x{p.seed_resize_from_h}"),
|
"Seed resize from": (None if p.seed_resize_from_w <= 0 or p.seed_resize_from_h <= 0 else f"{p.seed_resize_from_w}x{p.seed_resize_from_h}"),
|
||||||
"Denoising strength": getattr(p, 'denoising_strength', None),
|
"Denoising strength": getattr(p, 'denoising_strength', None),
|
||||||
"Conditional mask weight": getattr(p, "inpainting_mask_weight", shared.opts.inpainting_mask_weight) if p.is_using_inpainting_conditioning else None,
|
"Conditional mask weight": getattr(p, "inpainting_mask_weight", shared.opts.inpainting_mask_weight) if p.is_using_inpainting_conditioning else None,
|
||||||
"Clip skip": None if clip_skip <= 1 else clip_skip,
|
"Clip skip": None if clip_skip <= 1 else clip_skip,
|
||||||
|
@ -155,7 +155,7 @@ def process_interrogate(interrogation_function, mode, ii_input_dir, ii_output_di
|
|||||||
img = Image.open(image)
|
img = Image.open(image)
|
||||||
filename = os.path.basename(image)
|
filename = os.path.basename(image)
|
||||||
left, _ = os.path.splitext(filename)
|
left, _ = os.path.splitext(filename)
|
||||||
print(interrogation_function(img), file=open(os.path.join(ii_output_dir, f"{left}.txt"), 'a'))
|
print(interrogation_function(img), file=open(os.path.join(ii_output_dir, f"{left}.txt"), 'a', encoding='utf-8'))
|
||||||
|
|
||||||
return [gr.update(), None]
|
return [gr.update(), None]
|
||||||
|
|
||||||
|
@ -30,8 +30,8 @@ def fetch_file(filename: str = ""):
|
|||||||
raise ValueError(f"File cannot be fetched: {filename}. Must be in one of directories registered by extra pages.")
|
raise ValueError(f"File cannot be fetched: {filename}. Must be in one of directories registered by extra pages.")
|
||||||
|
|
||||||
ext = os.path.splitext(filename)[1].lower()
|
ext = os.path.splitext(filename)[1].lower()
|
||||||
if ext not in (".png", ".jpg", ".jpeg", ".webp"):
|
if ext not in (".png", ".jpg", ".jpeg", ".webp", ".gif"):
|
||||||
raise ValueError(f"File cannot be fetched: {filename}. Only png and jpg and webp.")
|
raise ValueError(f"File cannot be fetched: {filename}. Only png, jpg, webp, and gif.")
|
||||||
|
|
||||||
# would profit from returning 304
|
# would profit from returning 304
|
||||||
return FileResponse(filename, headers={"Accept-Ranges": "bytes"})
|
return FileResponse(filename, headers={"Accept-Ranges": "bytes"})
|
||||||
|
12
webui.sh
12
webui.sh
@ -4,26 +4,28 @@
|
|||||||
# change the variables in webui-user.sh instead #
|
# change the variables in webui-user.sh instead #
|
||||||
#################################################
|
#################################################
|
||||||
|
|
||||||
|
SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )
|
||||||
|
|
||||||
# If run from macOS, load defaults from webui-macos-env.sh
|
# If run from macOS, load defaults from webui-macos-env.sh
|
||||||
if [[ "$OSTYPE" == "darwin"* ]]; then
|
if [[ "$OSTYPE" == "darwin"* ]]; then
|
||||||
if [[ -f webui-macos-env.sh ]]
|
if [[ -f "$SCRIPT_DIR"/webui-macos-env.sh ]]
|
||||||
then
|
then
|
||||||
source ./webui-macos-env.sh
|
source "$SCRIPT_DIR"/webui-macos-env.sh
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Read variables from webui-user.sh
|
# Read variables from webui-user.sh
|
||||||
# shellcheck source=/dev/null
|
# shellcheck source=/dev/null
|
||||||
if [[ -f webui-user.sh ]]
|
if [[ -f "$SCRIPT_DIR"/webui-user.sh ]]
|
||||||
then
|
then
|
||||||
source ./webui-user.sh
|
source "$SCRIPT_DIR"/webui-user.sh
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Set defaults
|
# Set defaults
|
||||||
# Install directory without trailing slash
|
# Install directory without trailing slash
|
||||||
if [[ -z "${install_dir}" ]]
|
if [[ -z "${install_dir}" ]]
|
||||||
then
|
then
|
||||||
install_dir="$(pwd)"
|
install_dir="$SCRIPT_DIR"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Name of the subdirectory (defaults to stable-diffusion-webui)
|
# Name of the subdirectory (defaults to stable-diffusion-webui)
|
||||||
|
Loading…
Reference in New Issue
Block a user