├── .gitignore
├── CaseStudies.md
├── LICENSE
├── README.md
├── TolkienTest.md
├── examples
├── comment-bots
│ ├── discord
│ │ ├── README.md
│ │ └── discord-bot-api
│ │ │ └── .gitkeep
│ ├── forum
│ │ ├── README.md
│ │ ├── simple-forum-api
│ │ │ ├── .gitignore
│ │ │ ├── .nvmrc
│ │ │ ├── README.md
│ │ │ ├── api
│ │ │ │ ├── get
│ │ │ │ │ └── comments
│ │ │ │ │ │ └── index.js
│ │ │ │ └── post
│ │ │ │ │ ├── comment
│ │ │ │ │ └── index.js
│ │ │ │ │ └── topic
│ │ │ │ │ └── index.js
│ │ │ ├── index.js
│ │ │ ├── package-lock.json
│ │ │ └── package.json
│ │ └── simple-forum
│ │ │ ├── .gitignore
│ │ │ ├── .nvmrc
│ │ │ ├── README.md
│ │ │ ├── package-lock.json
│ │ │ ├── package.json
│ │ │ ├── public
│ │ │ ├── favicon.ico
│ │ │ ├── font
│ │ │ │ ├── Outfit
│ │ │ │ │ ├── OFL.txt
│ │ │ │ │ ├── Outfit-VariableFont_wght.ttf
│ │ │ │ │ ├── README.txt
│ │ │ │ │ └── static
│ │ │ │ │ │ ├── Outfit-Black.ttf
│ │ │ │ │ │ ├── Outfit-Bold.ttf
│ │ │ │ │ │ ├── Outfit-ExtraBold.ttf
│ │ │ │ │ │ ├── Outfit-ExtraLight.ttf
│ │ │ │ │ │ ├── Outfit-Light.ttf
│ │ │ │ │ │ ├── Outfit-Medium.ttf
│ │ │ │ │ │ ├── Outfit-Regular.ttf
│ │ │ │ │ │ ├── Outfit-SemiBold.ttf
│ │ │ │ │ │ └── Outfit-Thin.ttf
│ │ │ │ └── Wrath
│ │ │ │ │ └── Wrath.ttf
│ │ │ ├── img
│ │ │ │ └── avatars
│ │ │ │ │ └── arthas.png
│ │ │ ├── index.html
│ │ │ ├── logo192.png
│ │ │ ├── logo512.png
│ │ │ ├── manifest.json
│ │ │ └── robots.txt
│ │ │ └── src
│ │ │ ├── App.css
│ │ │ ├── App.js
│ │ │ ├── index.css
│ │ │ ├── index.js
│ │ │ └── pages
│ │ │ ├── Topic
│ │ │ ├── index.css
│ │ │ └── index.js
│ │ │ └── Topics
│ │ │ ├── index.css
│ │ │ └── index.js
│ └── slack
│ │ ├── README.md
│ │ └── slack-bot-api
│ │ └── .gitkeep
├── game-npcs
│ └── oracles-tomb
│ │ ├── README.md
│ │ ├── oracles-tomb-api
│ │ ├── .gitignore
│ │ ├── .nvmrc
│ │ ├── README.md
│ │ ├── api
│ │ │ └── get
│ │ │ │ └── oracle
│ │ │ │ ├── index.js
│ │ │ │ └── knowledge.html
│ │ ├── index.js
│ │ ├── package-lock.json
│ │ └── package.json
│ │ └── oracles-tomb
│ │ ├── .nvmrc
│ │ ├── README.md
│ │ ├── package-lock.json
│ │ ├── package.json
│ │ ├── public
│ │ ├── favicon.ico
│ │ ├── font
│ │ │ ├── Outfit
│ │ │ │ ├── OFL.txt
│ │ │ │ ├── Outfit-VariableFont_wght.ttf
│ │ │ │ ├── README.txt
│ │ │ │ └── static
│ │ │ │ │ ├── Outfit-Black.ttf
│ │ │ │ │ ├── Outfit-Bold.ttf
│ │ │ │ │ ├── Outfit-ExtraBold.ttf
│ │ │ │ │ ├── Outfit-ExtraLight.ttf
│ │ │ │ │ ├── Outfit-Light.ttf
│ │ │ │ │ ├── Outfit-Medium.ttf
│ │ │ │ │ ├── Outfit-Regular.ttf
│ │ │ │ │ ├── Outfit-SemiBold.ttf
│ │ │ │ │ └── Outfit-Thin.ttf
│ │ │ ├── Silkscreen
│ │ │ │ ├── OFL.txt
│ │ │ │ ├── Silkscreen-Bold.ttf
│ │ │ │ └── Silkscreen-Regular.ttf
│ │ │ └── Wrath
│ │ │ │ └── Wrath.ttf
│ │ ├── img
│ │ │ ├── avatars
│ │ │ │ └── arthas.png
│ │ │ ├── background-open.jpg
│ │ │ ├── background.jpg
│ │ │ ├── player-idle.gif
│ │ │ └── player-run.gif
│ │ ├── index.html
│ │ ├── logo192.png
│ │ ├── logo512.png
│ │ ├── manifest.json
│ │ └── robots.txt
│ │ └── src
│ │ ├── App.css
│ │ ├── App.js
│ │ ├── index.css
│ │ └── index.js
└── instant-assistant
│ ├── README.md
│ ├── instant-assistant-api
│ ├── .gitignore
│ ├── .nvmrc
│ ├── README.md
│ ├── index.js
│ ├── package-lock.json
│ └── package.json
│ └── instant-assistant
│ ├── .nvmrc
│ ├── README.md
│ ├── package-lock.json
│ ├── package.json
│ ├── public
│ ├── favicon.ico
│ ├── font
│ │ ├── Outfit
│ │ │ ├── OFL.txt
│ │ │ ├── Outfit-VariableFont_wght.ttf
│ │ │ ├── README.txt
│ │ │ └── static
│ │ │ │ ├── Outfit-Black.ttf
│ │ │ │ ├── Outfit-Bold.ttf
│ │ │ │ ├── Outfit-ExtraBold.ttf
│ │ │ │ ├── Outfit-ExtraLight.ttf
│ │ │ │ ├── Outfit-Light.ttf
│ │ │ │ ├── Outfit-Medium.ttf
│ │ │ │ ├── Outfit-Regular.ttf
│ │ │ │ ├── Outfit-SemiBold.ttf
│ │ │ │ └── Outfit-Thin.ttf
│ │ └── Wrath
│ │ │ └── Wrath.ttf
│ ├── img
│ │ └── avatars
│ │ │ └── arthas.png
│ ├── index.html
│ ├── logo192.png
│ ├── logo512.png
│ ├── manifest.json
│ └── robots.txt
│ └── src
│ ├── App.css
│ ├── App.js
│ ├── index.css
│ └── index.js
├── ragdoll-api
├── .gitignore
├── .nvmrc
├── README.md
├── api
│ ├── get
│ │ └── info
│ │ │ └── index.js
│ ├── index.js
│ └── post
│ │ ├── configure
│ │ └── index.js
│ │ ├── prompt
│ │ └── index.js
│ │ └── upload
│ │ └── index.js
├── events
│ ├── cluster
│ │ └── index.js
│ ├── index.js
│ └── worker
│ │ └── index.js
├── index.js
├── package-lock.json
├── package.json
├── public
│ └── documents
│ │ └── .gitkeep
└── start.js
├── ragdoll-react
├── .gitignore
├── .nvmrc
├── README.md
├── dist
│ ├── Icon.css
│ ├── Icon.js
│ ├── RagdollCast.css
│ ├── RagdollCast.js
│ ├── RagdollChat.css
│ ├── RagdollChat.js
│ ├── RagdollForm.css
│ ├── RagdollForm.js
│ ├── RagdollList.css
│ ├── RagdollList.js
│ ├── useModelInfo.js
│ └── useRagdoll.js
├── index.js
├── package-lock.json
├── package.js
├── package.json
├── public
│ ├── favicon.ico
│ ├── font
│ │ ├── Outfit
│ │ │ ├── OFL.txt
│ │ │ ├── Outfit-VariableFont_wght.ttf
│ │ │ ├── README.txt
│ │ │ └── static
│ │ │ │ ├── Outfit-Black.ttf
│ │ │ │ ├── Outfit-Bold.ttf
│ │ │ │ ├── Outfit-ExtraBold.ttf
│ │ │ │ ├── Outfit-ExtraLight.ttf
│ │ │ │ ├── Outfit-Light.ttf
│ │ │ │ ├── Outfit-Medium.ttf
│ │ │ │ ├── Outfit-Regular.ttf
│ │ │ │ ├── Outfit-SemiBold.ttf
│ │ │ │ └── Outfit-Thin.ttf
│ │ └── Wrath
│ │ │ └── Wrath.ttf
│ ├── img
│ │ ├── 3d.svg
│ │ ├── audio.svg
│ │ ├── avatars
│ │ │ └── arthas.png
│ │ ├── code.svg
│ │ ├── picture.svg
│ │ ├── save.svg
│ │ ├── story.svg
│ │ ├── trash.svg
│ │ ├── upload.svg
│ │ └── video.svg
│ ├── index.html
│ ├── logo192.png
│ ├── logo512.png
│ ├── manifest.json
│ └── robots.txt
└── src
│ ├── App.css
│ ├── App.js
│ ├── components
│ ├── Icon
│ │ ├── index.css
│ │ └── index.js
│ ├── Publish
│ │ ├── index.css
│ │ └── index.js
│ ├── RagdollCast
│ │ ├── index.css
│ │ └── index.js
│ ├── RagdollChat
│ │ ├── index.css
│ │ └── index.js
│ ├── RagdollForm
│ │ ├── index.css
│ │ └── index.js
│ ├── RagdollList
│ │ ├── index.css
│ │ └── index.js
│ ├── Upload
│ │ ├── index.css
│ │ └── index.js
│ └── index.js
│ ├── hooks
│ ├── index.js
│ ├── useModelInfo
│ │ └── index.js
│ └── useRagdoll
│ │ └── index.js
│ ├── index.css
│ └── index.js
├── ragdoll-studio
├── .gitignore
├── .nvmrc
├── forge.config.js
├── package-lock.json
├── package.json
├── src
│ ├── App.css
│ ├── App.js
│ ├── components
│ │ ├── Icon
│ │ │ ├── index.css
│ │ │ └── index.js
│ │ ├── Publish
│ │ │ ├── index.css
│ │ │ └── index.js
│ │ ├── Upload
│ │ │ ├── index.css
│ │ │ └── index.js
│ │ └── index.js
│ ├── font
│ │ ├── Outfit
│ │ │ ├── OFL.txt
│ │ │ ├── Outfit-VariableFont_wght.ttf
│ │ │ ├── README.txt
│ │ │ └── static
│ │ │ │ ├── Outfit-Black.ttf
│ │ │ │ ├── Outfit-Bold.ttf
│ │ │ │ ├── Outfit-ExtraBold.ttf
│ │ │ │ ├── Outfit-ExtraLight.ttf
│ │ │ │ ├── Outfit-Light.ttf
│ │ │ │ ├── Outfit-Medium.ttf
│ │ │ │ ├── Outfit-Regular.ttf
│ │ │ │ ├── Outfit-SemiBold.ttf
│ │ │ │ └── Outfit-Thin.ttf
│ │ └── Wrath
│ │ │ └── Wrath.ttf
│ ├── img
│ │ ├── 3d.svg
│ │ ├── audio.svg
│ │ ├── avatars
│ │ │ └── arthas.png
│ │ ├── code.svg
│ │ ├── picture.svg
│ │ ├── save.svg
│ │ ├── story.svg
│ │ ├── trash.svg
│ │ ├── upload.svg
│ │ └── video.svg
│ ├── index.css
│ ├── index.html
│ ├── main.js
│ ├── preload.js
│ └── renderer.js
├── stable-diffusion-api
│ ├── .eslintignore
│ ├── .eslintrc.js
│ ├── .git-blame-ignore-revs
│ ├── .gitignore
│ ├── .pylintrc
│ ├── CHANGELOG.md
│ ├── CITATION.cff
│ ├── CODEOWNERS
│ ├── LICENSE.txt
│ ├── README.md
│ ├── _typos.toml
│ ├── configs
│ │ ├── alt-diffusion-inference.yaml
│ │ ├── alt-diffusion-m18-inference.yaml
│ │ ├── instruct-pix2pix.yaml
│ │ ├── sd_xl_inpaint.yaml
│ │ ├── v1-inference.yaml
│ │ └── v1-inpainting-inference.yaml
│ ├── environment-wsl2.yaml
│ ├── extensions-builtin
│ │ ├── LDSR
│ │ │ ├── ldsr_model_arch.py
│ │ │ ├── preload.py
│ │ │ ├── scripts
│ │ │ │ └── ldsr_model.py
│ │ │ ├── sd_hijack_autoencoder.py
│ │ │ ├── sd_hijack_ddpm_v1.py
│ │ │ └── vqvae_quantize.py
│ │ ├── Lora
│ │ │ ├── extra_networks_lora.py
│ │ │ ├── lora.py
│ │ │ ├── lora_logger.py
│ │ │ ├── lora_patches.py
│ │ │ ├── lyco_helpers.py
│ │ │ ├── network.py
│ │ │ ├── network_full.py
│ │ │ ├── network_glora.py
│ │ │ ├── network_hada.py
│ │ │ ├── network_ia3.py
│ │ │ ├── network_lokr.py
│ │ │ ├── network_lora.py
│ │ │ ├── network_norm.py
│ │ │ ├── network_oft.py
│ │ │ ├── networks.py
│ │ │ ├── preload.py
│ │ │ ├── scripts
│ │ │ │ └── lora_script.py
│ │ │ ├── ui_edit_user_metadata.py
│ │ │ └── ui_extra_networks_lora.py
│ │ ├── ScuNET
│ │ │ ├── preload.py
│ │ │ └── scripts
│ │ │ │ └── scunet_model.py
│ │ ├── SwinIR
│ │ │ ├── preload.py
│ │ │ └── scripts
│ │ │ │ └── swinir_model.py
│ │ ├── canvas-zoom-and-pan
│ │ │ ├── javascript
│ │ │ │ └── zoom.js
│ │ │ ├── scripts
│ │ │ │ └── hotkey_config.py
│ │ │ └── style.css
│ │ ├── extra-options-section
│ │ │ └── scripts
│ │ │ │ └── extra_options_section.py
│ │ ├── hypertile
│ │ │ ├── hypertile.py
│ │ │ └── scripts
│ │ │ │ ├── hypertile_script.py
│ │ │ │ └── hypertile_xyz.py
│ │ ├── mobile
│ │ │ └── javascript
│ │ │ │ └── mobile.js
│ │ ├── postprocessing-for-training
│ │ │ └── scripts
│ │ │ │ ├── postprocessing_autosized_crop.py
│ │ │ │ ├── postprocessing_caption.py
│ │ │ │ ├── postprocessing_create_flipped_copies.py
│ │ │ │ ├── postprocessing_focal_crop.py
│ │ │ │ └── postprocessing_split_oversized.py
│ │ ├── prompt-bracket-checker
│ │ │ └── javascript
│ │ │ │ └── prompt-bracket-checker.js
│ │ └── soft-inpainting
│ │ │ └── scripts
│ │ │ └── soft_inpainting.py
│ ├── html
│ │ ├── card-no-preview.png
│ │ ├── extra-networks-card.html
│ │ ├── extra-networks-copy-path-button.html
│ │ ├── extra-networks-edit-item-button.html
│ │ ├── extra-networks-metadata-button.html
│ │ ├── extra-networks-no-cards.html
│ │ ├── extra-networks-pane-dirs.html
│ │ ├── extra-networks-pane-tree.html
│ │ ├── extra-networks-pane.html
│ │ ├── extra-networks-tree-button.html
│ │ ├── footer.html
│ │ └── licenses.html
│ ├── javascript
│ │ ├── aspectRatioOverlay.js
│ │ ├── contextMenus.js
│ │ ├── dragdrop.js
│ │ ├── edit-attention.js
│ │ ├── edit-order.js
│ │ ├── extensions.js
│ │ ├── extraNetworks.js
│ │ ├── generationParams.js
│ │ ├── hints.js
│ │ ├── hires_fix.js
│ │ ├── imageMaskFix.js
│ │ ├── imageviewer.js
│ │ ├── imageviewerGamepad.js
│ │ ├── inputAccordion.js
│ │ ├── localStorage.js
│ │ ├── localization.js
│ │ ├── notification.js
│ │ ├── profilerVisualization.js
│ │ ├── progressbar.js
│ │ ├── resizeHandle.js
│ │ ├── settings.js
│ │ ├── textualInversion.js
│ │ ├── token-counters.js
│ │ ├── ui.js
│ │ └── ui_settings_hints.js
│ ├── launch.py
│ ├── localizations
│ │ └── Put localization files here.txt
│ ├── modules
│ │ ├── Roboto-Regular.ttf
│ │ ├── api
│ │ │ ├── api.py
│ │ │ └── models.py
│ │ ├── cache.py
│ │ ├── call_queue.py
│ │ ├── cmd_args.py
│ │ ├── codeformer_model.py
│ │ ├── config_states.py
│ │ ├── dat_model.py
│ │ ├── deepbooru.py
│ │ ├── deepbooru_model.py
│ │ ├── devices.py
│ │ ├── errors.py
│ │ ├── esrgan_model.py
│ │ ├── extensions.py
│ │ ├── extra_networks.py
│ │ ├── extra_networks_hypernet.py
│ │ ├── extras.py
│ │ ├── face_restoration.py
│ │ ├── face_restoration_utils.py
│ │ ├── fifo_lock.py
│ │ ├── gfpgan_model.py
│ │ ├── gitpython_hack.py
│ │ ├── gradio_extensons.py
│ │ ├── hashes.py
│ │ ├── hat_model.py
│ │ ├── hypernetworks
│ │ │ ├── hypernetwork.py
│ │ │ └── ui.py
│ │ ├── images.py
│ │ ├── img2img.py
│ │ ├── import_hook.py
│ │ ├── infotext_utils.py
│ │ ├── infotext_versions.py
│ │ ├── initialize.py
│ │ ├── initialize_util.py
│ │ ├── interrogate.py
│ │ ├── launch_utils.py
│ │ ├── localization.py
│ │ ├── logging_config.py
│ │ ├── lowvram.py
│ │ ├── mac_specific.py
│ │ ├── masking.py
│ │ ├── memmon.py
│ │ ├── modelloader.py
│ │ ├── models
│ │ │ └── diffusion
│ │ │ │ ├── ddpm_edit.py
│ │ │ │ └── uni_pc
│ │ │ │ ├── __init__.py
│ │ │ │ ├── sampler.py
│ │ │ │ └── uni_pc.py
│ │ ├── ngrok.py
│ │ ├── npu_specific.py
│ │ ├── options.py
│ │ ├── patches.py
│ │ ├── paths.py
│ │ ├── paths_internal.py
│ │ ├── postprocessing.py
│ │ ├── processing.py
│ │ ├── processing_scripts
│ │ │ ├── comments.py
│ │ │ ├── refiner.py
│ │ │ ├── sampler.py
│ │ │ └── seed.py
│ │ ├── progress.py
│ │ ├── prompt_parser.py
│ │ ├── realesrgan_model.py
│ │ ├── restart.py
│ │ ├── rng.py
│ │ ├── rng_philox.py
│ │ ├── safe.py
│ │ ├── script_callbacks.py
│ │ ├── script_loading.py
│ │ ├── scripts.py
│ │ ├── scripts_auto_postprocessing.py
│ │ ├── scripts_postprocessing.py
│ │ ├── sd_disable_initialization.py
│ │ ├── sd_emphasis.py
│ │ ├── sd_hijack.py
│ │ ├── sd_hijack_checkpoint.py
│ │ ├── sd_hijack_clip.py
│ │ ├── sd_hijack_clip_old.py
│ │ ├── sd_hijack_ip2p.py
│ │ ├── sd_hijack_open_clip.py
│ │ ├── sd_hijack_optimizations.py
│ │ ├── sd_hijack_unet.py
│ │ ├── sd_hijack_utils.py
│ │ ├── sd_hijack_xlmr.py
│ │ ├── sd_models.py
│ │ ├── sd_models_config.py
│ │ ├── sd_models_types.py
│ │ ├── sd_models_xl.py
│ │ ├── sd_samplers.py
│ │ ├── sd_samplers_cfg_denoiser.py
│ │ ├── sd_samplers_common.py
│ │ ├── sd_samplers_compvis.py
│ │ ├── sd_samplers_extra.py
│ │ ├── sd_samplers_kdiffusion.py
│ │ ├── sd_samplers_lcm.py
│ │ ├── sd_samplers_timesteps.py
│ │ ├── sd_samplers_timesteps_impl.py
│ │ ├── sd_schedulers.py
│ │ ├── sd_unet.py
│ │ ├── sd_vae.py
│ │ ├── sd_vae_approx.py
│ │ ├── sd_vae_taesd.py
│ │ ├── shared.py
│ │ ├── shared_cmd_options.py
│ │ ├── shared_gradio_themes.py
│ │ ├── shared_init.py
│ │ ├── shared_items.py
│ │ ├── shared_options.py
│ │ ├── shared_state.py
│ │ ├── shared_total_tqdm.py
│ │ ├── styles.py
│ │ ├── sub_quadratic_attention.py
│ │ ├── sysinfo.py
│ │ ├── textual_inversion
│ │ │ ├── autocrop.py
│ │ │ ├── dataset.py
│ │ │ ├── image_embedding.py
│ │ │ ├── learn_schedule.py
│ │ │ ├── saving_settings.py
│ │ │ ├── test_embedding.png
│ │ │ ├── textual_inversion.py
│ │ │ └── ui.py
│ │ ├── timer.py
│ │ ├── torch_utils.py
│ │ ├── txt2img.py
│ │ ├── ui.py
│ │ ├── ui_checkpoint_merger.py
│ │ ├── ui_common.py
│ │ ├── ui_components.py
│ │ ├── ui_extensions.py
│ │ ├── ui_extra_networks.py
│ │ ├── ui_extra_networks_checkpoints.py
│ │ ├── ui_extra_networks_checkpoints_user_metadata.py
│ │ ├── ui_extra_networks_hypernets.py
│ │ ├── ui_extra_networks_textual_inversion.py
│ │ ├── ui_extra_networks_user_metadata.py
│ │ ├── ui_gradio_extensions.py
│ │ ├── ui_loadsave.py
│ │ ├── ui_postprocessing.py
│ │ ├── ui_prompt_styles.py
│ │ ├── ui_settings.py
│ │ ├── ui_tempdir.py
│ │ ├── ui_toprow.py
│ │ ├── upscaler.py
│ │ ├── upscaler_utils.py
│ │ ├── util.py
│ │ ├── xlmr.py
│ │ ├── xlmr_m18.py
│ │ └── xpu_specific.py
│ ├── package.json
│ ├── pyproject.toml
│ ├── requirements-test.txt
│ ├── requirements.txt
│ ├── requirements_npu.txt
│ ├── requirements_versions.txt
│ ├── screenshot.png
│ ├── script.js
│ ├── scripts
│ │ ├── custom_code.py
│ │ ├── img2imgalt.py
│ │ ├── loopback.py
│ │ ├── outpainting_mk_2.py
│ │ ├── poor_mans_outpainting.py
│ │ ├── postprocessing_codeformer.py
│ │ ├── postprocessing_gfpgan.py
│ │ ├── postprocessing_upscale.py
│ │ ├── prompt_matrix.py
│ │ ├── prompts_from_file.py
│ │ ├── sd_upscale.py
│ │ └── xyz_grid.py
│ ├── style.css
│ ├── test
│ │ ├── __init__.py
│ │ ├── conftest.py
│ │ ├── test_extras.py
│ │ ├── test_face_restorers.py
│ │ ├── test_files
│ │ │ ├── empty.pt
│ │ │ ├── img2img_basic.png
│ │ │ ├── mask_basic.png
│ │ │ └── two-faces.jpg
│ │ ├── test_img2img.py
│ │ ├── test_torch_utils.py
│ │ ├── test_txt2img.py
│ │ └── test_utils.py
│ ├── textual_inversion_templates
│ │ ├── hypernetwork.txt
│ │ ├── none.txt
│ │ ├── style.txt
│ │ ├── style_filewords.txt
│ │ ├── subject.txt
│ │ └── subject_filewords.txt
│ ├── webui-macos-env.sh
│ ├── webui.bat
│ ├── webui.py
│ └── webui.sh
├── studio-api
│ ├── .gitignore
│ ├── .nvmrc
│ ├── README.md
│ ├── index.js
│ ├── package-lock.json
│ └── package.json
├── webpack.main.config.js
├── webpack.renderer.config.js
└── webpack.rules.js
└── ragdoll-www-nextjs
├── .eslintrc.json
├── .gitignore
├── .nvmrc
├── README.md
├── jsconfig.json
├── next.config.mjs
├── package-lock.json
├── package.json
├── postcss.config.js
├── public
├── .casts
│ ├── ankit
│ │ └── code-stars
│ │ │ └── cast.json
│ ├── autumnfestive
│ │ └── spooky-spirits
│ │ │ └── cast.json
│ ├── bigtrev
│ │ └── video-magicians-pt-1
│ │ │ └── cast.json
│ ├── casts.json
│ ├── clarkee
│ │ └── startup-team
│ │ │ └── cast.json
│ ├── fffanatic
│ │ └── final-fantasy-7-remake
│ │ │ └── cast.json
│ ├── gaia
│ │ └── 99-great-storytellers
│ │ │ └── cast.json
│ ├── gptgod
│ │ ├── 100-rpg-characters-for-your-game
│ │ │ └── cast.json
│ │ └── goth-queens-by-gptgod
│ │ │ └── cast.json
│ ├── heromd
│ │ └── superhero-doctors
│ │ │ └── cast.json
│ ├── jacobb
│ │ └── temple-talk-to-god
│ │ │ └── cast.json
│ ├── jessediaz
│ │ └── javascript-buddy
│ │ │ └── cast.json
│ ├── mindyt
│ │ ├── flirty-friends
│ │ │ └── cast.json
│ │ ├── good-talkers
│ │ │ └── cast.json
│ │ └── some-friends
│ │ │ └── cast.json
│ ├── viddrip
│ │ └── hollywood-magic
│ │ │ └── cast.json
│ └── wikihistory
│ │ └── popular-figures
│ │ └── cast.json
└── assets
│ └── img
│ ├── download.svg
│ ├── github.svg
│ └── product.png
├── src
├── app
│ ├── favicon.ico
│ ├── globals.css
│ └── layout.js
├── components
│ ├── CardList
│ │ └── index.js
│ ├── Header
│ │ └── index.js
│ ├── Icon
│ │ └── index.js
│ └── index.js
├── hooks
│ ├── index.js
│ ├── useCast
│ │ └── index.js
│ ├── useCasts
│ │ └── index.js
│ └── useDolls
│ │ └── index.js
├── pages
│ ├── [authorSlug]
│ │ ├── [slug]
│ │ │ └── index.js
│ │ └── index.js
│ ├── _app.js
│ ├── api
│ │ ├── cast
│ │ │ └── index.js
│ │ ├── casts
│ │ │ └── index.js
│ │ └── dolls
│ │ │ └── index.js
│ ├── apps
│ │ └── index.js
│ ├── dolls
│ │ └── index.js
│ ├── feed
│ │ └── index.js
│ └── index.js
└── utils
│ └── index.js
└── tailwind.config.js
/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2 |
3 | # dependencies (examples)
4 | /examples/comment-bots/forum/simple-forum/node_modules
5 | /examples/comment-bots/forum/simple-forum-api/node_modules
6 | /examples/comment-bots/forum/simple-forum-api/.env
7 | /examples/game-npcs/oracles-tomb/oracles-tomb/node_modules
8 | /examples/game-npcs/oracles-tomb-api/oracles-tomb/node_modules
9 | /examples/game-npcs/oracles-tomb-api/oracles-tomb/.env
10 | /examples/instant-assistant/instant-assistant/node_modules
11 | /examples/instant-assistant/instant-assistant-api/node_modules
12 | /examples/instant-assistant/instant-assistant-api/.env
13 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) Benny Schmidt 2024
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/examples/comment-bots/discord/README.md:
--------------------------------------------------------------------------------
1 | # Discord bot
2 |
3 | It's as straightforward as any other Discord bot, start by setting up the basics:
4 |
5 | 
6 |
7 | Decide what events you want `ragdoll` to get invoked for, and give Discord permissions so it can respond in the right place:
8 |
9 | 
10 |
11 | Like in the forum example that invokes the bot when its name is mentioned on the forum, you can define a webhook (POST endpoint) in Discord that invokes the bot whenever Discord events happen. That way you can tie the Discord bot activity into your existing app and handle them internally like you would any other request:
12 |
13 | 
14 |
15 | ## Background
16 |
17 | Coming soon.
18 |
--------------------------------------------------------------------------------
/examples/comment-bots/discord/discord-bot-api/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bennyschmidt/ragdoll-studio/a95ed0558db0a6f6a8f7781b24d6bfab79ec6388/examples/comment-bots/discord/discord-bot-api/.gitkeep
--------------------------------------------------------------------------------
/examples/comment-bots/forum/README.md:
--------------------------------------------------------------------------------
1 | # Forum comment bot
2 |
3 | A comment bot based on [ragdoll](https://github.com/bennyschmidt/ragdoll).
4 |
5 | ## Background
6 |
7 | This example works more like a Slack or Discord bot, where Ragdoll listens for commands and responds accordingly. Instead of using slash commands, in this example the Arthas ragdoll watches for any forum post that mentions his name. Whenever he's mentioned in a topic Ragdoll parses the question and posts the text response as a comment in the thread.
8 |
9 | Like a Slack or Discord bot, the "bot" in this case is code that runs in a [node API](./simple-forum-api/), while the [front-end forum](./simple-forum/) is just that - a regular forum UI with no connection to Ragdoll. In the Slack and Discord examples there won't be front-end repos because the front-ends are Slack and Discord, respectively.
10 |
11 | https://github.com/bennyschmidt/ragdoll-studio/assets/45407493/dfb7c223-835c-4415-8199-1ef8d1481693
12 |
--------------------------------------------------------------------------------
/examples/comment-bots/forum/simple-forum-api/.gitignore:
--------------------------------------------------------------------------------
1 | # directories
2 | /node_modules
3 | /.tmp
4 |
5 | # env
6 | .env
7 |
--------------------------------------------------------------------------------
/examples/comment-bots/forum/simple-forum-api/.nvmrc:
--------------------------------------------------------------------------------
1 | 20.11.1
--------------------------------------------------------------------------------
/examples/comment-bots/forum/simple-forum-api/README.md:
--------------------------------------------------------------------------------
1 | # Simple Forum API
2 |
--------------------------------------------------------------------------------
/examples/comment-bots/forum/simple-forum-api/api/get/comments/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Comments
3 | * Fetch all topics and comments
4 | */
5 |
6 | module.exports = asyncCache => async (_, res) => {
7 | const comments = await asyncCache.getItem('comments');
8 |
9 | res.end(JSON.stringify({
10 | success: true,
11 | comments
12 | }));
13 | };
14 |
--------------------------------------------------------------------------------
/examples/comment-bots/forum/simple-forum-api/api/post/comment/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Comment
3 | * Post a new comment
4 | */
5 |
6 | const { randomUUID } = require('crypto');
7 |
8 | module.exports = asyncCache => async (req, res) => {
9 | let body = [];
10 |
11 | req
12 | .on('data', chunk => {
13 | body.push(chunk);
14 | })
15 | .on('end', async () => {
16 | body = Buffer.concat(body).toString();
17 |
18 | const {
19 | authorName = 'Anonymous User',
20 | topicId,
21 | text
22 | } = JSON.parse(body || '{}');
23 |
24 | if (!topicId || !(/[a-zA-Z0-9-_.~%]{1,8000}/).test(text)) {
25 | res.end(JSON.stringify({
26 | error: {
27 | message: 'Bad request.'
28 | }
29 | }));
30 |
31 | return;
32 | }
33 |
34 | const comments = await asyncCache.getItem('comments');
35 |
36 | const commentId = randomUUID();
37 | const createdAt = new Date().toISOString();
38 |
39 | await asyncCache.setItem('comments', {
40 | ...comments,
41 |
42 | [topicId]: {
43 | ...comments[topicId],
44 |
45 | comments: {
46 | ...comments[topicId].comments,
47 |
48 | [commentId]: {
49 | authorName,
50 | id: commentId,
51 | text,
52 | createdAt
53 | }
54 | }
55 | }
56 | });
57 |
58 | res.end(JSON.stringify({
59 | success: true
60 | }));
61 | });
62 | };
63 |
--------------------------------------------------------------------------------
/examples/comment-bots/forum/simple-forum-api/index.js:
--------------------------------------------------------------------------------
1 | const process = require('node:process');
2 | const dotenv = require('dotenv');
3 |
4 | const RagdollAPI = require('ragdoll-api');
5 |
6 | dotenv.config();
7 |
8 | const { API_PATH_PREFIX } = process.env;
9 |
10 | RagdollAPI({
11 | GET: {
12 | [`/${API_PATH_PREFIX}/comments`]: require('./api/get/comments'),
13 | },
14 | POST: {
15 | [`/${API_PATH_PREFIX}/comment`]: require('./api/post/comment'),
16 | [`/${API_PATH_PREFIX}/topic`]: require('./api/post/topic')
17 | }
18 | }, store => {
19 | store.set('comments', {
20 | '5b29d2f6-c16e-4603-bee5-58d930365835': {
21 | id: '5b29d2f6-c16e-4603-bee5-58d930365835',
22 | authorName: 'Anonymous User',
23 | topic: 'Getting started',
24 | text: 'Click "Create Topic" to create a new forum post. Clicking a topic title will let you navigate to the post to read and leave comments. Feel free to ask questions - enjoy the forum!',
25 | comments: {},
26 | createdAt: new Date().toDateString()
27 | },
28 | 'f1107b63-ed85-4de7-b5db-9193789624ca': {
29 | id: 'f1107b63-ed85-4de7-b5db-9193789624ca',
30 | authorName: 'Anonymous User',
31 | topic: 'hi guyz',
32 | text: 'Just wanted to introduce myself 👋 how is everyone doing?',
33 | comments: {
34 | 'f49b9039-1626-49cf-8bd8-7c9130d43a5f': {
35 | id: 'f49b9039-1626-49cf-8bd8-7c9130d43a5f',
36 | authorName: 'Anonymous User',
37 | text: 'heyyy welcome!',
38 | createdAt: new Date().toDateString()
39 | }
40 | },
41 | createdAt: new Date().toDateString()
42 | }
43 | });
44 | });
45 |
--------------------------------------------------------------------------------
/examples/comment-bots/forum/simple-forum-api/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "simple-forum-api",
3 | "version": "1.0.6",
4 | "scripts": {
5 | "start": "node index"
6 | },
7 | "dependencies": {
8 | "ragdoll-api": "1.2"
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/examples/comment-bots/forum/simple-forum/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | /node_modules
5 | /.pnp
6 | .pnp.js
7 |
8 | # testing
9 | /coverage
10 |
11 | # production
12 | /build
13 |
14 | # misc
15 | .DS_Store
16 | .env.local
17 | .env.development.local
18 | .env.test.local
19 | .env.production.local
20 |
21 | npm-debug.log*
22 | yarn-debug.log*
23 | yarn-error.log*
24 |
--------------------------------------------------------------------------------
/examples/comment-bots/forum/simple-forum/.nvmrc:
--------------------------------------------------------------------------------
1 | 20.11.1
--------------------------------------------------------------------------------
/examples/comment-bots/forum/simple-forum/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "simple-forum",
3 | "version": "0.1.3",
4 | "private": true,
5 | "dependencies": {
6 | "@testing-library/jest-dom": "^5.17.0",
7 | "@testing-library/react": "^13.4.0",
8 | "@testing-library/user-event": "^13.5.0",
9 | "javascript-time-ago": "^2.5.9",
10 | "react": "^18.2.0",
11 | "react-dom": "^18.2.0",
12 | "react-scripts": "5.0.1",
13 | "web-vitals": "^2.1.4"
14 | },
15 | "scripts": {
16 | "start": "react-scripts start",
17 | "build": "react-scripts build",
18 | "test": "react-scripts test",
19 | "eject": "react-scripts eject"
20 | },
21 | "eslintConfig": {
22 | "extends": [
23 | "react-app",
24 | "react-app/jest"
25 | ]
26 | },
27 | "browserslist": {
28 | "production": [
29 | ">0.2%",
30 | "not dead",
31 | "not op_mini all"
32 | ],
33 | "development": [
34 | "last 1 chrome version",
35 | "last 1 firefox version",
36 | "last 1 safari version"
37 | ]
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/examples/comment-bots/forum/simple-forum/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bennyschmidt/ragdoll-studio/a95ed0558db0a6f6a8f7781b24d6bfab79ec6388/examples/comment-bots/forum/simple-forum/public/favicon.ico
--------------------------------------------------------------------------------
/examples/comment-bots/forum/simple-forum/public/font/Outfit/Outfit-VariableFont_wght.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bennyschmidt/ragdoll-studio/a95ed0558db0a6f6a8f7781b24d6bfab79ec6388/examples/comment-bots/forum/simple-forum/public/font/Outfit/Outfit-VariableFont_wght.ttf
--------------------------------------------------------------------------------
/examples/comment-bots/forum/simple-forum/public/font/Outfit/static/Outfit-Black.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bennyschmidt/ragdoll-studio/a95ed0558db0a6f6a8f7781b24d6bfab79ec6388/examples/comment-bots/forum/simple-forum/public/font/Outfit/static/Outfit-Black.ttf
--------------------------------------------------------------------------------
/examples/comment-bots/forum/simple-forum/public/font/Outfit/static/Outfit-Bold.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bennyschmidt/ragdoll-studio/a95ed0558db0a6f6a8f7781b24d6bfab79ec6388/examples/comment-bots/forum/simple-forum/public/font/Outfit/static/Outfit-Bold.ttf
--------------------------------------------------------------------------------
/examples/comment-bots/forum/simple-forum/public/font/Outfit/static/Outfit-ExtraBold.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bennyschmidt/ragdoll-studio/a95ed0558db0a6f6a8f7781b24d6bfab79ec6388/examples/comment-bots/forum/simple-forum/public/font/Outfit/static/Outfit-ExtraBold.ttf
--------------------------------------------------------------------------------
/examples/comment-bots/forum/simple-forum/public/font/Outfit/static/Outfit-ExtraLight.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bennyschmidt/ragdoll-studio/a95ed0558db0a6f6a8f7781b24d6bfab79ec6388/examples/comment-bots/forum/simple-forum/public/font/Outfit/static/Outfit-ExtraLight.ttf
--------------------------------------------------------------------------------
/examples/comment-bots/forum/simple-forum/public/font/Outfit/static/Outfit-Light.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bennyschmidt/ragdoll-studio/a95ed0558db0a6f6a8f7781b24d6bfab79ec6388/examples/comment-bots/forum/simple-forum/public/font/Outfit/static/Outfit-Light.ttf
--------------------------------------------------------------------------------
/examples/comment-bots/forum/simple-forum/public/font/Outfit/static/Outfit-Medium.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bennyschmidt/ragdoll-studio/a95ed0558db0a6f6a8f7781b24d6bfab79ec6388/examples/comment-bots/forum/simple-forum/public/font/Outfit/static/Outfit-Medium.ttf
--------------------------------------------------------------------------------
/examples/comment-bots/forum/simple-forum/public/font/Outfit/static/Outfit-Regular.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bennyschmidt/ragdoll-studio/a95ed0558db0a6f6a8f7781b24d6bfab79ec6388/examples/comment-bots/forum/simple-forum/public/font/Outfit/static/Outfit-Regular.ttf
--------------------------------------------------------------------------------
/examples/comment-bots/forum/simple-forum/public/font/Outfit/static/Outfit-SemiBold.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bennyschmidt/ragdoll-studio/a95ed0558db0a6f6a8f7781b24d6bfab79ec6388/examples/comment-bots/forum/simple-forum/public/font/Outfit/static/Outfit-SemiBold.ttf
--------------------------------------------------------------------------------
/examples/comment-bots/forum/simple-forum/public/font/Outfit/static/Outfit-Thin.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bennyschmidt/ragdoll-studio/a95ed0558db0a6f6a8f7781b24d6bfab79ec6388/examples/comment-bots/forum/simple-forum/public/font/Outfit/static/Outfit-Thin.ttf
--------------------------------------------------------------------------------
/examples/comment-bots/forum/simple-forum/public/font/Wrath/Wrath.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bennyschmidt/ragdoll-studio/a95ed0558db0a6f6a8f7781b24d6bfab79ec6388/examples/comment-bots/forum/simple-forum/public/font/Wrath/Wrath.ttf
--------------------------------------------------------------------------------
/examples/comment-bots/forum/simple-forum/public/img/avatars/arthas.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bennyschmidt/ragdoll-studio/a95ed0558db0a6f6a8f7781b24d6bfab79ec6388/examples/comment-bots/forum/simple-forum/public/img/avatars/arthas.png
--------------------------------------------------------------------------------
/examples/comment-bots/forum/simple-forum/public/logo192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bennyschmidt/ragdoll-studio/a95ed0558db0a6f6a8f7781b24d6bfab79ec6388/examples/comment-bots/forum/simple-forum/public/logo192.png
--------------------------------------------------------------------------------
/examples/comment-bots/forum/simple-forum/public/logo512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bennyschmidt/ragdoll-studio/a95ed0558db0a6f6a8f7781b24d6bfab79ec6388/examples/comment-bots/forum/simple-forum/public/logo512.png
--------------------------------------------------------------------------------
/examples/comment-bots/forum/simple-forum/public/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "short_name": "React App",
3 | "name": "Create React App Sample",
4 | "icons": [
5 | {
6 | "src": "favicon.ico",
7 | "sizes": "64x64 32x32 24x24 16x16",
8 | "type": "image/x-icon"
9 | },
10 | {
11 | "src": "logo192.png",
12 | "type": "image/png",
13 | "sizes": "192x192"
14 | },
15 | {
16 | "src": "logo512.png",
17 | "type": "image/png",
18 | "sizes": "512x512"
19 | }
20 | ],
21 | "start_url": ".",
22 | "display": "standalone",
23 | "theme_color": "#000000",
24 | "background_color": "#ffffff"
25 | }
26 |
--------------------------------------------------------------------------------
/examples/comment-bots/forum/simple-forum/public/robots.txt:
--------------------------------------------------------------------------------
1 | # https://www.robotstxt.org/robotstxt.html
2 | User-agent: *
3 | Disallow:
4 |
--------------------------------------------------------------------------------
/examples/comment-bots/forum/simple-forum/src/App.js:
--------------------------------------------------------------------------------
1 | import Topics from './pages/Topics';
2 | import Topic from './pages/Topic';
3 |
4 | import TimeAgo from 'javascript-time-ago';
5 | import en from 'javascript-time-ago/locale/en';
6 |
7 | import './App.css';
8 |
9 | // Globals
10 |
11 | window.RAGDOLL_URI = 'http://localhost:8000';
12 | window.STORAGE_KEY = 'RAGDOLLS';
13 |
14 | // TimeAgo for user-facing timestamps
15 |
16 | TimeAgo.addDefaultLocale(en);
17 |
18 | const timeAgo = new TimeAgo('en-US');
19 |
20 | const App = () => {
21 | const { pathname } = window.location;
22 |
23 | switch (pathname) {
24 | case '/':
25 | case '/forum':
26 | return (
27 |
28 |
29 |
30 | );
31 | case '/forum/topic':
32 | return (
33 |
34 |
35 |
36 | );
37 | default:
38 | return (
39 |
40 | 404
41 |
42 | );
43 | }
44 | };
45 |
46 | export default App;
47 |
--------------------------------------------------------------------------------
/examples/comment-bots/forum/simple-forum/src/index.css:
--------------------------------------------------------------------------------
1 | body {
2 | width: 100vw;
3 | height: 100vh;
4 | overflow: hidden;
5 | margin: 0;
6 | font-family: "Outfit Light", sans-serif;
7 | -webkit-font-smoothing: antialiased;
8 | -moz-osx-font-smoothing: grayscale;
9 | background: #333;
10 | color: white;
11 | }
12 |
13 | * {
14 | box-sizing: border-box;
15 | font-size: 1em;
16 | }
17 |
18 | input[disabled],
19 | button[disabled] {
20 | opacity: .5;
21 | font-style: italic;
22 | cursor: not-allowed;
23 | }
24 |
25 | button,
26 | input {
27 | display: block;
28 | cursor: pointer;
29 | width: 100%;
30 | background: #000000;
31 | color: white;
32 | padding: 1rem;
33 | appearance: none;
34 | border-radius: 1.2rem;
35 | border: none;
36 | margin: 1rem 0;
37 | font-family: "Outfit Medium", sans-serif;
38 | -webkit-font-smoothing: antialiased;
39 | -moz-osx-font-smoothing: grayscale;
40 | transition: background-color .1s linear, color .1s linear;
41 | outline: none;
42 | }
43 |
44 | input {
45 | cursor: auto;
46 | background: #00000025;
47 | color: #121212;
48 | }
49 |
50 | button:hover {
51 | background-color: dodgerblue;
52 | color: white;
53 | }
54 |
55 | ul, li {
56 | list-style: none;
57 | margin: 0;
58 | padding: 0;
59 | }
60 |
61 | h1 {
62 | font-size: .75em;
63 | margin: 0 0 1rem;
64 | opacity: .5;
65 | }
66 |
67 | a {
68 | color: black;
69 | }
--------------------------------------------------------------------------------
/examples/comment-bots/forum/simple-forum/src/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ReactDOM from 'react-dom/client';
3 |
4 | import App from './App';
5 |
6 | import './index.css';
7 |
8 | const root = ReactDOM.createRoot(document.getElementById('root'));
9 |
10 | root.render(
11 |
12 |
13 |
14 | );
15 |
--------------------------------------------------------------------------------
/examples/comment-bots/forum/simple-forum/src/pages/Topic/index.css:
--------------------------------------------------------------------------------
1 | @import '../Topics/index.css';
2 |
--------------------------------------------------------------------------------
/examples/comment-bots/forum/simple-forum/src/pages/Topics/index.css:
--------------------------------------------------------------------------------
1 | .topic,
2 | .comment {
3 | padding: 1rem;
4 | background: #00000050;
5 | }
6 |
7 | .topic a,
8 | .comment a {
9 | color: white;
10 | }
11 |
12 | .topic:nth-of-type(odd) {
13 | background: #00000085
14 | }
15 |
16 | .topic:first-of-type {
17 | border-top-left-radius: 1rem;
18 | border-top-right-radius: 1rem;
19 | }
20 |
21 | .topic:last-of-type {
22 | border-bottom-left-radius: 1rem;
23 | border-bottom-right-radius: 1rem;
24 | }
25 |
26 | .author {
27 | display: flex;
28 | font-size: .8em;
29 | }
30 |
31 | .author h6 {
32 | margin: 0;
33 | font-weight: normal;
34 | }
35 |
36 | #forum {
37 | flex-direction: column;
38 | width: 100%;
39 | padding: 1rem;
40 | }
41 |
42 | #forum .breadcrumbs {
43 | position: static;
44 | display: flex;
45 | align-items: center;
46 | height: 3rem;
47 | padding-left: 1rem;
48 | background: black;
49 | border-radius: 1rem;
50 | color: white;
51 | margin: 0;
52 | }
53 |
54 | #forum .breadcrumbs em {
55 | opacity: .6;
56 | }
57 |
58 | #forum .breadcrumbs a {
59 | color: white;
60 | }
61 |
62 | #forum > ul,
63 | #forum > article {
64 | margin: 1rem 0;
65 | }
66 |
--------------------------------------------------------------------------------
/examples/comment-bots/slack/README.md:
--------------------------------------------------------------------------------
1 | # Slack bot
2 |
3 | Coming soon.
4 |
5 | ## Background
6 |
7 | TLDR: Very similar setting up a Discord bot
8 |
--------------------------------------------------------------------------------
/examples/comment-bots/slack/slack-bot-api/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bennyschmidt/ragdoll-studio/a95ed0558db0a6f6a8f7781b24d6bfab79ec6388/examples/comment-bots/slack/slack-bot-api/.gitkeep
--------------------------------------------------------------------------------
/examples/game-npcs/oracles-tomb/oracles-tomb-api/.gitignore:
--------------------------------------------------------------------------------
1 | # directories
2 | /node_modules
3 | /.tmp
4 |
5 | # env
6 | .env
7 |
--------------------------------------------------------------------------------
/examples/game-npcs/oracles-tomb/oracles-tomb-api/.nvmrc:
--------------------------------------------------------------------------------
1 | 20.11.1
--------------------------------------------------------------------------------
/examples/game-npcs/oracles-tomb/oracles-tomb-api/README.md:
--------------------------------------------------------------------------------
1 | # Oracle's Tomb API
2 |
--------------------------------------------------------------------------------
/examples/game-npcs/oracles-tomb/oracles-tomb-api/api/get/oracle/index.js:
--------------------------------------------------------------------------------
1 | const fs = require('fs').promises;
2 | const path = require('path');
3 |
4 | /**
5 | * Oracle
6 | * Fetch all the oracle's knowledgeURI
7 | */
8 |
9 | module.exports = () => async (_, res) => {
10 | const html = await fs.readFile(path.join(__dirname, '/knowledge.html'));
11 |
12 | return res.end(html);
13 | };
14 |
--------------------------------------------------------------------------------
/examples/game-npcs/oracles-tomb/oracles-tomb-api/api/get/oracle/knowledge.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Knowledge of the Oracle
5 |
6 |
7 | The Oracle
8 | The Oracle is an all-wise deity in the form of a statue placed outside of a mysterious tomb. Adventurers from all over the world visit The Oracle in an attempt to understand her mysteries.
9 |
10 | Setting
11 | An old stone tomb on a grassy ledge enshrouded in old trees and darkness with a full moon in the sky and owls that can be heard in the distance. The front of the tomb has a wooden door that is closed and locked.
12 |
13 | Game Information
14 | This game is called "Oracle's Tomb". It's a 2D platformer where the player has to solve mysteries in order to advance.
15 | The player can exit the game by closing the browser tab.
16 | The player can start over by refreshing the page.
17 | The player can move by using A and D or the left and right arrow keys.
18 | There is no way to jump in this game.
19 | There is no combat in this game.
20 |
21 | Game Lore
22 | The player is the adventurer.
23 | The Oracle is not an adventurer.
24 | The adventurer is on the bridge with The Oracle.
25 | The door's password is "CORPSE FLOWER".
26 | The adventurer can open the door by standing in front of it and saying the door's password.
27 |
28 |
29 |
--------------------------------------------------------------------------------
/examples/game-npcs/oracles-tomb/oracles-tomb-api/index.js:
--------------------------------------------------------------------------------
1 | const RagdollAPI = require('ragdoll-api');
2 |
3 | RagdollAPI({
4 | GET: {
5 | '/oracle': require('./api/get/oracle')
6 | },
7 | POST: {}
8 | });
9 |
--------------------------------------------------------------------------------
/examples/game-npcs/oracles-tomb/oracles-tomb-api/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "oracles-tomb-api",
3 | "version": "1.0.8",
4 | "scripts": {
5 | "start": "node index"
6 | },
7 | "dependencies": {
8 | "ragdoll-api": "1.2"
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/examples/game-npcs/oracles-tomb/oracles-tomb/.nvmrc:
--------------------------------------------------------------------------------
1 | 20.11.1
--------------------------------------------------------------------------------
/examples/game-npcs/oracles-tomb/oracles-tomb/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "oracles-tomb",
3 | "version": "0.1.4",
4 | "private": true,
5 | "dependencies": {
6 | "@testing-library/jest-dom": "^5.17.0",
7 | "@testing-library/react": "^13.4.0",
8 | "@testing-library/user-event": "^13.5.0",
9 | "ragdoll-react": "^0.4.4",
10 | "react": "^18.2.0",
11 | "react-dom": "^18.2.0",
12 | "react-scripts": "5.0.1",
13 | "web-vitals": "^2.1.4"
14 | },
15 | "scripts": {
16 | "start": "react-scripts start",
17 | "build": "react-scripts build",
18 | "test": "react-scripts test",
19 | "eject": "react-scripts eject"
20 | },
21 | "eslintConfig": {
22 | "extends": [
23 | "react-app",
24 | "react-app/jest"
25 | ]
26 | },
27 | "browserslist": {
28 | "production": [
29 | ">0.2%",
30 | "not dead",
31 | "not op_mini all"
32 | ],
33 | "development": [
34 | "last 1 chrome version",
35 | "last 1 firefox version",
36 | "last 1 safari version"
37 | ]
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/examples/game-npcs/oracles-tomb/oracles-tomb/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bennyschmidt/ragdoll-studio/a95ed0558db0a6f6a8f7781b24d6bfab79ec6388/examples/game-npcs/oracles-tomb/oracles-tomb/public/favicon.ico
--------------------------------------------------------------------------------
/examples/game-npcs/oracles-tomb/oracles-tomb/public/font/Outfit/Outfit-VariableFont_wght.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bennyschmidt/ragdoll-studio/a95ed0558db0a6f6a8f7781b24d6bfab79ec6388/examples/game-npcs/oracles-tomb/oracles-tomb/public/font/Outfit/Outfit-VariableFont_wght.ttf
--------------------------------------------------------------------------------
/examples/game-npcs/oracles-tomb/oracles-tomb/public/font/Outfit/static/Outfit-Black.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bennyschmidt/ragdoll-studio/a95ed0558db0a6f6a8f7781b24d6bfab79ec6388/examples/game-npcs/oracles-tomb/oracles-tomb/public/font/Outfit/static/Outfit-Black.ttf
--------------------------------------------------------------------------------
/examples/game-npcs/oracles-tomb/oracles-tomb/public/font/Outfit/static/Outfit-Bold.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bennyschmidt/ragdoll-studio/a95ed0558db0a6f6a8f7781b24d6bfab79ec6388/examples/game-npcs/oracles-tomb/oracles-tomb/public/font/Outfit/static/Outfit-Bold.ttf
--------------------------------------------------------------------------------
/examples/game-npcs/oracles-tomb/oracles-tomb/public/font/Outfit/static/Outfit-ExtraBold.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bennyschmidt/ragdoll-studio/a95ed0558db0a6f6a8f7781b24d6bfab79ec6388/examples/game-npcs/oracles-tomb/oracles-tomb/public/font/Outfit/static/Outfit-ExtraBold.ttf
--------------------------------------------------------------------------------
/examples/game-npcs/oracles-tomb/oracles-tomb/public/font/Outfit/static/Outfit-ExtraLight.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bennyschmidt/ragdoll-studio/a95ed0558db0a6f6a8f7781b24d6bfab79ec6388/examples/game-npcs/oracles-tomb/oracles-tomb/public/font/Outfit/static/Outfit-ExtraLight.ttf
--------------------------------------------------------------------------------
/examples/game-npcs/oracles-tomb/oracles-tomb/public/font/Outfit/static/Outfit-Light.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bennyschmidt/ragdoll-studio/a95ed0558db0a6f6a8f7781b24d6bfab79ec6388/examples/game-npcs/oracles-tomb/oracles-tomb/public/font/Outfit/static/Outfit-Light.ttf
--------------------------------------------------------------------------------
/examples/game-npcs/oracles-tomb/oracles-tomb/public/font/Outfit/static/Outfit-Medium.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bennyschmidt/ragdoll-studio/a95ed0558db0a6f6a8f7781b24d6bfab79ec6388/examples/game-npcs/oracles-tomb/oracles-tomb/public/font/Outfit/static/Outfit-Medium.ttf
--------------------------------------------------------------------------------
/examples/game-npcs/oracles-tomb/oracles-tomb/public/font/Outfit/static/Outfit-Regular.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bennyschmidt/ragdoll-studio/a95ed0558db0a6f6a8f7781b24d6bfab79ec6388/examples/game-npcs/oracles-tomb/oracles-tomb/public/font/Outfit/static/Outfit-Regular.ttf
--------------------------------------------------------------------------------
/examples/game-npcs/oracles-tomb/oracles-tomb/public/font/Outfit/static/Outfit-SemiBold.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bennyschmidt/ragdoll-studio/a95ed0558db0a6f6a8f7781b24d6bfab79ec6388/examples/game-npcs/oracles-tomb/oracles-tomb/public/font/Outfit/static/Outfit-SemiBold.ttf
--------------------------------------------------------------------------------
/examples/game-npcs/oracles-tomb/oracles-tomb/public/font/Outfit/static/Outfit-Thin.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bennyschmidt/ragdoll-studio/a95ed0558db0a6f6a8f7781b24d6bfab79ec6388/examples/game-npcs/oracles-tomb/oracles-tomb/public/font/Outfit/static/Outfit-Thin.ttf
--------------------------------------------------------------------------------
/examples/game-npcs/oracles-tomb/oracles-tomb/public/font/Silkscreen/Silkscreen-Bold.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bennyschmidt/ragdoll-studio/a95ed0558db0a6f6a8f7781b24d6bfab79ec6388/examples/game-npcs/oracles-tomb/oracles-tomb/public/font/Silkscreen/Silkscreen-Bold.ttf
--------------------------------------------------------------------------------
/examples/game-npcs/oracles-tomb/oracles-tomb/public/font/Silkscreen/Silkscreen-Regular.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bennyschmidt/ragdoll-studio/a95ed0558db0a6f6a8f7781b24d6bfab79ec6388/examples/game-npcs/oracles-tomb/oracles-tomb/public/font/Silkscreen/Silkscreen-Regular.ttf
--------------------------------------------------------------------------------
/examples/game-npcs/oracles-tomb/oracles-tomb/public/font/Wrath/Wrath.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bennyschmidt/ragdoll-studio/a95ed0558db0a6f6a8f7781b24d6bfab79ec6388/examples/game-npcs/oracles-tomb/oracles-tomb/public/font/Wrath/Wrath.ttf
--------------------------------------------------------------------------------
/examples/game-npcs/oracles-tomb/oracles-tomb/public/img/avatars/arthas.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bennyschmidt/ragdoll-studio/a95ed0558db0a6f6a8f7781b24d6bfab79ec6388/examples/game-npcs/oracles-tomb/oracles-tomb/public/img/avatars/arthas.png
--------------------------------------------------------------------------------
/examples/game-npcs/oracles-tomb/oracles-tomb/public/img/background-open.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bennyschmidt/ragdoll-studio/a95ed0558db0a6f6a8f7781b24d6bfab79ec6388/examples/game-npcs/oracles-tomb/oracles-tomb/public/img/background-open.jpg
--------------------------------------------------------------------------------
/examples/game-npcs/oracles-tomb/oracles-tomb/public/img/background.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bennyschmidt/ragdoll-studio/a95ed0558db0a6f6a8f7781b24d6bfab79ec6388/examples/game-npcs/oracles-tomb/oracles-tomb/public/img/background.jpg
--------------------------------------------------------------------------------
/examples/game-npcs/oracles-tomb/oracles-tomb/public/img/player-idle.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bennyschmidt/ragdoll-studio/a95ed0558db0a6f6a8f7781b24d6bfab79ec6388/examples/game-npcs/oracles-tomb/oracles-tomb/public/img/player-idle.gif
--------------------------------------------------------------------------------
/examples/game-npcs/oracles-tomb/oracles-tomb/public/img/player-run.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bennyschmidt/ragdoll-studio/a95ed0558db0a6f6a8f7781b24d6bfab79ec6388/examples/game-npcs/oracles-tomb/oracles-tomb/public/img/player-run.gif
--------------------------------------------------------------------------------
/examples/game-npcs/oracles-tomb/oracles-tomb/public/logo192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bennyschmidt/ragdoll-studio/a95ed0558db0a6f6a8f7781b24d6bfab79ec6388/examples/game-npcs/oracles-tomb/oracles-tomb/public/logo192.png
--------------------------------------------------------------------------------
/examples/game-npcs/oracles-tomb/oracles-tomb/public/logo512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bennyschmidt/ragdoll-studio/a95ed0558db0a6f6a8f7781b24d6bfab79ec6388/examples/game-npcs/oracles-tomb/oracles-tomb/public/logo512.png
--------------------------------------------------------------------------------
/examples/game-npcs/oracles-tomb/oracles-tomb/public/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "short_name": "React App",
3 | "name": "Create React App Sample",
4 | "icons": [
5 | {
6 | "src": "favicon.ico",
7 | "sizes": "64x64 32x32 24x24 16x16",
8 | "type": "image/x-icon"
9 | },
10 | {
11 | "src": "logo192.png",
12 | "type": "image/png",
13 | "sizes": "192x192"
14 | },
15 | {
16 | "src": "logo512.png",
17 | "type": "image/png",
18 | "sizes": "512x512"
19 | }
20 | ],
21 | "start_url": ".",
22 | "display": "standalone",
23 | "theme_color": "#000000",
24 | "background_color": "#ffffff"
25 | }
26 |
--------------------------------------------------------------------------------
/examples/game-npcs/oracles-tomb/oracles-tomb/public/robots.txt:
--------------------------------------------------------------------------------
1 | # https://www.robotstxt.org/robotstxt.html
2 | User-agent: *
3 | Disallow:
4 |
--------------------------------------------------------------------------------
/examples/game-npcs/oracles-tomb/oracles-tomb/src/index.css:
--------------------------------------------------------------------------------
1 | body {
2 | width: 100vw;
3 | height: 100vh;
4 | overflow: hidden;
5 | margin: 0;
6 | font-family: "Silkscreen", sans-serif;
7 | -webkit-font-smoothing: antialiased;
8 | -moz-osx-font-smoothing: grayscale;
9 | background: black;
10 | color: white;
11 | }
12 |
13 | * {
14 | box-sizing: border-box;
15 | font-size: 1em;
16 | }
17 |
18 | input[disabled],
19 | button[disabled] {
20 | opacity: .5;
21 | font-style: italic;
22 | cursor: not-allowed;
23 | }
24 |
25 | button,
26 | input {
27 | display: block;
28 | cursor: pointer;
29 | width: 100%;
30 | background: #000000;
31 | color: white;
32 | padding: 1rem;
33 | appearance: none;
34 | border-radius: 1.2rem;
35 | border: none;
36 | margin: 1rem 0;
37 | font-family: "Silkscreen", sans-serif;
38 | -webkit-font-smoothing: antialiased;
39 | -moz-osx-font-smoothing: grayscale;
40 | transition: background-color .1s linear, color .1s linear;
41 | outline: none;
42 | }
43 |
44 | input {
45 | cursor: auto;
46 | background: #ffffff25;
47 | color: #ffffff;
48 | }
49 |
50 | button:hover {
51 | background-color: dodgerblue;
52 | color: white;
53 | }
54 |
55 | ul, li {
56 | list-style: none;
57 | margin: 0;
58 | padding: 0;
59 | }
60 |
61 | h1 {
62 | font-size: .75em;
63 | margin: 0 0 1rem;
64 | opacity: .5;
65 | }
66 |
--------------------------------------------------------------------------------
/examples/game-npcs/oracles-tomb/oracles-tomb/src/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ReactDOM from 'react-dom/client';
3 |
4 | import App from './App';
5 |
6 | import './index.css';
7 |
8 | const root = ReactDOM.createRoot(document.getElementById('root'));
9 |
10 | root.render(
11 |
12 |
13 |
14 | );
15 |
--------------------------------------------------------------------------------
/examples/instant-assistant/instant-assistant-api/.gitignore:
--------------------------------------------------------------------------------
1 | # directories
2 | /node_modules
3 | /.tmp
4 |
5 | # env
6 | .env
7 |
--------------------------------------------------------------------------------
/examples/instant-assistant/instant-assistant-api/.nvmrc:
--------------------------------------------------------------------------------
1 | 20.11.1
--------------------------------------------------------------------------------
/examples/instant-assistant/instant-assistant-api/README.md:
--------------------------------------------------------------------------------
1 | # Instant Assistant API
2 |
--------------------------------------------------------------------------------
/examples/instant-assistant/instant-assistant-api/index.js:
--------------------------------------------------------------------------------
1 | const RagdollAPI = require('ragdoll-api');
2 |
3 | RagdollAPI();
4 |
--------------------------------------------------------------------------------
/examples/instant-assistant/instant-assistant-api/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "instant-assistant-api",
3 | "version": "1.0.5",
4 | "scripts": {
5 | "start": "node index"
6 | },
7 | "dependencies": {
8 | "ragdoll-api": "1.2"
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/examples/instant-assistant/instant-assistant/.nvmrc:
--------------------------------------------------------------------------------
1 | 20.11.1
--------------------------------------------------------------------------------
/examples/instant-assistant/instant-assistant/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "instant-assistant",
3 | "version": "0.1.5",
4 | "private": true,
5 | "dependencies": {
6 | "@testing-library/jest-dom": "^5.17.0",
7 | "@testing-library/react": "^13.4.0",
8 | "@testing-library/user-event": "^13.5.0",
9 | "bit-face": "^1.0.6",
10 | "ragdoll-react": "^0.4.4",
11 | "react": "^18.2.0",
12 | "react-dom": "^18.2.0",
13 | "react-scripts": "5.0.1",
14 | "web-vitals": "^2.1.4"
15 | },
16 | "scripts": {
17 | "start": "react-scripts start",
18 | "build": "react-scripts build",
19 | "test": "react-scripts test",
20 | "eject": "react-scripts eject"
21 | },
22 | "eslintConfig": {
23 | "extends": [
24 | "react-app",
25 | "react-app/jest"
26 | ]
27 | },
28 | "browserslist": {
29 | "production": [
30 | ">0.2%",
31 | "not dead",
32 | "not op_mini all"
33 | ],
34 | "development": [
35 | "last 1 chrome version",
36 | "last 1 firefox version",
37 | "last 1 safari version"
38 | ]
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/examples/instant-assistant/instant-assistant/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bennyschmidt/ragdoll-studio/a95ed0558db0a6f6a8f7781b24d6bfab79ec6388/examples/instant-assistant/instant-assistant/public/favicon.ico
--------------------------------------------------------------------------------
/examples/instant-assistant/instant-assistant/public/font/Outfit/Outfit-VariableFont_wght.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bennyschmidt/ragdoll-studio/a95ed0558db0a6f6a8f7781b24d6bfab79ec6388/examples/instant-assistant/instant-assistant/public/font/Outfit/Outfit-VariableFont_wght.ttf
--------------------------------------------------------------------------------
/examples/instant-assistant/instant-assistant/public/font/Outfit/static/Outfit-Black.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bennyschmidt/ragdoll-studio/a95ed0558db0a6f6a8f7781b24d6bfab79ec6388/examples/instant-assistant/instant-assistant/public/font/Outfit/static/Outfit-Black.ttf
--------------------------------------------------------------------------------
/examples/instant-assistant/instant-assistant/public/font/Outfit/static/Outfit-Bold.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bennyschmidt/ragdoll-studio/a95ed0558db0a6f6a8f7781b24d6bfab79ec6388/examples/instant-assistant/instant-assistant/public/font/Outfit/static/Outfit-Bold.ttf
--------------------------------------------------------------------------------
/examples/instant-assistant/instant-assistant/public/font/Outfit/static/Outfit-ExtraBold.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bennyschmidt/ragdoll-studio/a95ed0558db0a6f6a8f7781b24d6bfab79ec6388/examples/instant-assistant/instant-assistant/public/font/Outfit/static/Outfit-ExtraBold.ttf
--------------------------------------------------------------------------------
/examples/instant-assistant/instant-assistant/public/font/Outfit/static/Outfit-ExtraLight.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bennyschmidt/ragdoll-studio/a95ed0558db0a6f6a8f7781b24d6bfab79ec6388/examples/instant-assistant/instant-assistant/public/font/Outfit/static/Outfit-ExtraLight.ttf
--------------------------------------------------------------------------------
/examples/instant-assistant/instant-assistant/public/font/Outfit/static/Outfit-Light.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bennyschmidt/ragdoll-studio/a95ed0558db0a6f6a8f7781b24d6bfab79ec6388/examples/instant-assistant/instant-assistant/public/font/Outfit/static/Outfit-Light.ttf
--------------------------------------------------------------------------------
/examples/instant-assistant/instant-assistant/public/font/Outfit/static/Outfit-Medium.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bennyschmidt/ragdoll-studio/a95ed0558db0a6f6a8f7781b24d6bfab79ec6388/examples/instant-assistant/instant-assistant/public/font/Outfit/static/Outfit-Medium.ttf
--------------------------------------------------------------------------------
/examples/instant-assistant/instant-assistant/public/font/Outfit/static/Outfit-Regular.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bennyschmidt/ragdoll-studio/a95ed0558db0a6f6a8f7781b24d6bfab79ec6388/examples/instant-assistant/instant-assistant/public/font/Outfit/static/Outfit-Regular.ttf
--------------------------------------------------------------------------------
/examples/instant-assistant/instant-assistant/public/font/Outfit/static/Outfit-SemiBold.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bennyschmidt/ragdoll-studio/a95ed0558db0a6f6a8f7781b24d6bfab79ec6388/examples/instant-assistant/instant-assistant/public/font/Outfit/static/Outfit-SemiBold.ttf
--------------------------------------------------------------------------------
/examples/instant-assistant/instant-assistant/public/font/Outfit/static/Outfit-Thin.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bennyschmidt/ragdoll-studio/a95ed0558db0a6f6a8f7781b24d6bfab79ec6388/examples/instant-assistant/instant-assistant/public/font/Outfit/static/Outfit-Thin.ttf
--------------------------------------------------------------------------------
/examples/instant-assistant/instant-assistant/public/font/Wrath/Wrath.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bennyschmidt/ragdoll-studio/a95ed0558db0a6f6a8f7781b24d6bfab79ec6388/examples/instant-assistant/instant-assistant/public/font/Wrath/Wrath.ttf
--------------------------------------------------------------------------------
/examples/instant-assistant/instant-assistant/public/img/avatars/arthas.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bennyschmidt/ragdoll-studio/a95ed0558db0a6f6a8f7781b24d6bfab79ec6388/examples/instant-assistant/instant-assistant/public/img/avatars/arthas.png
--------------------------------------------------------------------------------
/examples/instant-assistant/instant-assistant/public/logo192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bennyschmidt/ragdoll-studio/a95ed0558db0a6f6a8f7781b24d6bfab79ec6388/examples/instant-assistant/instant-assistant/public/logo192.png
--------------------------------------------------------------------------------
/examples/instant-assistant/instant-assistant/public/logo512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bennyschmidt/ragdoll-studio/a95ed0558db0a6f6a8f7781b24d6bfab79ec6388/examples/instant-assistant/instant-assistant/public/logo512.png
--------------------------------------------------------------------------------
/examples/instant-assistant/instant-assistant/public/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "short_name": "React App",
3 | "name": "Create React App Sample",
4 | "icons": [
5 | {
6 | "src": "favicon.ico",
7 | "sizes": "64x64 32x32 24x24 16x16",
8 | "type": "image/x-icon"
9 | },
10 | {
11 | "src": "logo192.png",
12 | "type": "image/png",
13 | "sizes": "192x192"
14 | },
15 | {
16 | "src": "logo512.png",
17 | "type": "image/png",
18 | "sizes": "512x512"
19 | }
20 | ],
21 | "start_url": ".",
22 | "display": "standalone",
23 | "theme_color": "#000000",
24 | "background_color": "#ffffff"
25 | }
26 |
--------------------------------------------------------------------------------
/examples/instant-assistant/instant-assistant/public/robots.txt:
--------------------------------------------------------------------------------
1 | # https://www.robotstxt.org/robotstxt.html
2 | User-agent: *
3 | Disallow:
4 |
--------------------------------------------------------------------------------
/examples/instant-assistant/instant-assistant/src/index.css:
--------------------------------------------------------------------------------
1 | body {
2 | width: 100vw;
3 | height: 100vh;
4 | overflow: hidden;
5 | margin: 0;
6 | font-family: "Outfit Light", sans-serif;
7 | -webkit-font-smoothing: antialiased;
8 | -moz-osx-font-smoothing: grayscale;
9 | background: #fff;
10 | color: white;
11 | }
12 |
13 | * {
14 | box-sizing: border-box;
15 | font-size: 1em;
16 | }
17 |
18 | input[disabled],
19 | button[disabled] {
20 | opacity: .5;
21 | font-style: italic;
22 | cursor: not-allowed;
23 | }
24 |
25 | button,
26 | input {
27 | display: block;
28 | cursor: pointer;
29 | width: 100%;
30 | background: #000000;
31 | color: white;
32 | padding: 1rem;
33 | appearance: none;
34 | border-radius: 1.2rem;
35 | border: none;
36 | margin: 1rem 0;
37 | font-family: "Outfit Medium", sans-serif;
38 | -webkit-font-smoothing: antialiased;
39 | -moz-osx-font-smoothing: grayscale;
40 | transition: background-color .1s linear, color .1s linear;
41 | outline: none;
42 | }
43 |
44 | input {
45 | cursor: auto;
46 | background: #00000025;
47 | color: #121212;
48 | }
49 |
50 | button:hover {
51 | background-color: dodgerblue;
52 | color: white;
53 | }
54 |
55 | ul, li {
56 | list-style: none;
57 | margin: 0;
58 | padding: 0;
59 | }
60 |
61 | h1 {
62 | font-size: .75em;
63 | margin: 0 0 1rem;
64 | opacity: .5;
65 | }
66 |
--------------------------------------------------------------------------------
/examples/instant-assistant/instant-assistant/src/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ReactDOM from 'react-dom/client';
3 |
4 | import App from './App';
5 |
6 | import './index.css';
7 |
8 | const root = ReactDOM.createRoot(document.getElementById('root'));
9 |
10 | root.render(
11 |
12 |
13 |
14 | );
15 |
--------------------------------------------------------------------------------
/ragdoll-api/.gitignore:
--------------------------------------------------------------------------------
1 | # directories
2 | /node_modules
3 | /.tmp
4 | /public/documents
5 |
6 | # env
7 | .env
8 |
--------------------------------------------------------------------------------
/ragdoll-api/.nvmrc:
--------------------------------------------------------------------------------
1 | 20.11.1
--------------------------------------------------------------------------------
/ragdoll-api/api/get/info/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Info
3 | * Fetch model info
4 | */
5 |
6 | const process = require('node:process');
7 | const dotenv = require('dotenv');
8 |
9 | dotenv.config();
10 |
11 | const {
12 | TEXT_MODEL_PROVIDER,
13 | TEXT_TEXT_MODEL,
14 | IMAGE_MODEL_URI,
15 | TEXT_IMAGE_MODEL,
16 | IMAGE_IMAGE_MODEL,
17 | npm_package_version
18 | } = process.env;
19 |
20 | module.exports = () => (_, res) => (
21 | res.end(JSON.stringify({
22 | success: true,
23 | textModelProvider: TEXT_MODEL_PROVIDER,
24 | textTextModel: TEXT_TEXT_MODEL,
25 | imageModelProviderURI: IMAGE_MODEL_URI,
26 | textImageModel: TEXT_IMAGE_MODEL,
27 | imageImageModel: IMAGE_IMAGE_MODEL,
28 | version: npm_package_version
29 | }))
30 | );
31 |
--------------------------------------------------------------------------------
/ragdoll-api/api/post/configure/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Configure
3 | */
4 |
5 | module.exports = asyncCache => async (req, res) => {
6 | let body = [];
7 |
8 | req
9 | .on('data', chunk => {
10 | body.push(chunk);
11 | })
12 | .on('end', async () => {
13 | body = Buffer.concat(body).toString();
14 |
15 | const {
16 | name,
17 | knowledgeURI,
18 | avatarURL,
19 | artStyle,
20 | writingStyle,
21 | writingTone,
22 | additionalKnowledgeURIs
23 | } = JSON.parse(body || '{}');
24 |
25 | if (
26 | !name ||
27 | !knowledgeURI ||
28 | !writingStyle ||
29 | !writingTone
30 | ) {
31 | res.end(JSON.stringify({
32 | error: {
33 | message: 'Bad request.'
34 | }
35 | }));
36 |
37 | return;
38 | }
39 |
40 | const config = await asyncCache.getItem('config');
41 |
42 | await asyncCache.setItem('config', {
43 | ...config,
44 |
45 | [knowledgeURI]: {
46 | cache: false,
47 | name,
48 | knowledgeURI,
49 | avatarURL,
50 | artStyle,
51 | writingStyle,
52 | writingTone,
53 | additionalKnowledgeURIs
54 | }
55 | });
56 |
57 | res.end(JSON.stringify({
58 | success: true
59 | }));
60 | });
61 | };
62 |
--------------------------------------------------------------------------------
/ragdoll-api/api/post/upload/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Upload
3 | */
4 |
5 | const fs = require('fs').promises;
6 | const path = require('path');
7 | const { randomUUID } = require('crypto');
8 |
9 | module.exports = asyncCache => async (req, res) => {
10 | let body = [];
11 |
12 | req
13 | .on('data', chunk => {
14 | body.push(chunk);
15 | })
16 | .on('end', async () => {
17 | const config = await asyncCache.getItem('config');
18 |
19 | body = Buffer.concat(body).toString();
20 |
21 | const { key, knowledge } = JSON.parse(body || '{}');
22 |
23 | if (!knowledge) {
24 | res.end(JSON.stringify({
25 | error: {
26 | message: 'Bad query.'
27 | }
28 | }));
29 |
30 | return;
31 | }
32 |
33 | const currentConfig = config[key];
34 |
35 | if (!currentConfig) {
36 | res.end(JSON.stringify({
37 | error: {
38 | message: 'Persona not found.'
39 | }
40 | }));
41 |
42 | return;
43 | }
44 |
45 | const documentId = randomUUID();
46 | const localFileURL = `http://localhost:8000/public/documents/${documentId}.txt`;
47 |
48 | await fs.writeFile(
49 | path.join(__dirname, `../../../public/documents/${documentId}.txt`),
50 | knowledge
51 | );
52 |
53 | const additionalKnowledgeURIs = [
54 | ...currentConfig.additionalKnowledgeURIs,
55 |
56 | localFileURL
57 | ];
58 |
59 | res.end(JSON.stringify({
60 | success: true,
61 | additionalKnowledgeURIs
62 | }));
63 | });
64 | };
65 |
--------------------------------------------------------------------------------
/ragdoll-api/events/cluster/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Cluster events
3 | * Handle events at the cluster level
4 | */
5 |
6 | module.exports = (cluster, cache) => {
7 |
8 | /**
9 | * onExit
10 | * Called when a Node.js process exits for some reason
11 | */
12 |
13 | cluster.on('exit', (code, signal) => {
14 | const success = !signal && code !== 0;
15 |
16 | console.log(
17 | `Process exited${success ? '' : ` (killed by signal: ${signal}, error code: ${code})`}. Cluster has shut down.`
18 | );
19 | });
20 |
21 | /**
22 | * onError
23 | * Handle process errors
24 | */
25 |
26 | cluster.on('error', error => (
27 | console.log(`Cluster error: ${error}`)
28 | ));
29 |
30 | /**
31 | * onMessage
32 | * Handle messages to the primary
33 | */
34 |
35 | cluster.on('message', (worker, message) => {
36 | if (worker.isPrimary) return;
37 |
38 | const { command } = message;
39 |
40 | // Cluster commands
41 |
42 | switch (command) {
43 | case 'STORE':
44 | const {
45 | method,
46 | args
47 | } = message;
48 |
49 | worker.send(
50 | cache[method](...args)
51 | );
52 |
53 | break;
54 |
55 | default:
56 | break;
57 | }
58 | });
59 |
60 | console.log('Cluster is online.');
61 | };
62 |
--------------------------------------------------------------------------------
/ragdoll-api/events/index.js:
--------------------------------------------------------------------------------
1 | const cluster = require('./cluster');
2 | const worker = require('./worker');
3 |
4 | module.exports = {
5 | cluster,
6 | worker
7 | };
8 |
--------------------------------------------------------------------------------
/ragdoll-api/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "ragdoll-api",
3 | "version": "1.2.3",
4 | "scripts": {
5 | "start": "node start"
6 | },
7 | "dependencies": {
8 | "dotenv": "^16.4.5",
9 | "ragdoll-core": "^1.4.2"
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/ragdoll-api/public/documents/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bennyschmidt/ragdoll-studio/a95ed0558db0a6f6a8f7781b24d6bfab79ec6388/ragdoll-api/public/documents/.gitkeep
--------------------------------------------------------------------------------
/ragdoll-api/start.js:
--------------------------------------------------------------------------------
1 | const RagdollAPI = require('./index');
2 |
3 | RagdollAPI();
4 |
--------------------------------------------------------------------------------
/ragdoll-react/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | /node_modules
5 | /.pnp
6 | .pnp.js
7 |
8 | # testing
9 | /coverage
10 |
11 | # production
12 | /build
13 |
14 | # misc
15 | .DS_Store
16 | .env.local
17 | .env.development.local
18 | .env.test.local
19 | .env.production.local
20 |
21 | npm-debug.log*
22 | yarn-debug.log*
23 | yarn-error.log*
24 |
--------------------------------------------------------------------------------
/ragdoll-react/.nvmrc:
--------------------------------------------------------------------------------
1 | 20.11.1
--------------------------------------------------------------------------------
/ragdoll-react/dist/Icon.css:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bennyschmidt/ragdoll-studio/a95ed0558db0a6f6a8f7781b24d6bfab79ec6388/ragdoll-react/dist/Icon.css
--------------------------------------------------------------------------------
/ragdoll-react/dist/Icon.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import './Icon.css';
3 | const Icon = ({
4 | src,
5 | size = 20
6 | }) => /*#__PURE__*/React.createElement("img", {
7 | className: "icon",
8 | src: src,
9 | alt: `icon-${src.slice(src.lastIndexOf('/') + 1, src.lastIndexOf('.'))}`,
10 | width: `${size}px`,
11 | height: `${size}px`
12 | });
13 | export default Icon;
--------------------------------------------------------------------------------
/ragdoll-react/dist/RagdollCast.css:
--------------------------------------------------------------------------------
1 | #export {
2 | background: #00000030;
3 | border-radius: 1rem;
4 | padding: .5rem;
5 | }
6 |
7 | #export > div {
8 | display: flex;
9 | justify-content: space-between;
10 | align-items: center;
11 | gap: .5rem;
12 | }
13 |
14 | #export h6 {
15 | margin: 0 0 .5rem;
16 | font-size: .6em;
17 | text-transform: uppercase;
18 | color: #e6edf650;
19 | }
20 |
21 | #export button {
22 | background: linear-gradient(to bottom, #302c42, #010105);
23 | box-shadow: inset 0 .5rem .5rem #010105, 0 1px 0 #ffffff40;
24 | text-transform: uppercase;
25 | font-size: .6em;
26 | margin: 0;
27 | padding: .5rem;
28 | transition: all .2s ease;
29 | white-space: nowrap;
30 | text-overflow: ellipsis;
31 | overflow: hidden;
32 | }
33 |
34 | #export button:hover {
35 | background: #06dee6;
36 | border-color: transparent;
37 | box-shadow: inset 0 .5rem 1rem dodgerblue, 0 1px 0 #000000, 0 0 2rem dodgerblue;
38 | text-shadow: 0 0 .5rem dodgerblue;
39 | }
40 |
41 | @media (max-width: 900px) {
42 | #export > div {
43 | flex-direction: column;
44 | }
45 | }
--------------------------------------------------------------------------------
/ragdoll-react/dist/RagdollCast.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import './RagdollCast.css';
3 | const CONFIRM_EXPORT = 'Export the current cast?';
4 | const EXPORT = 'Export';
5 | const PUBLISH = 'Publish';
6 | const RagdollCast = ({
7 | disabled,
8 | ragdollList,
9 | onShow
10 | }) => {
11 | const getRagdollsArray = () => Object.values(ragdollList || {});
12 | const onClickExport = () => {
13 | if (!window.confirm(CONFIRM_EXPORT)) return;
14 | const fileExport = {
15 | author: window.prompt('Author name'),
16 | name: window.prompt('Cast name'),
17 | description: window.prompt('Cast description (optional)') || '',
18 | dolls: getRagdollsArray()
19 | };
20 | if (!fileExport.author || !fileExport.name || fileExport.dolls.length < 1) {
21 | alert('Invalid export configuration.');
22 | return;
23 | }
24 | window.open(`data:text/json,${encodeURIComponent(JSON.stringify(fileExport, null, 4))}`, '_blank');
25 | };
26 | return /*#__PURE__*/React.createElement("div", {
27 | id: "export"
28 | }, /*#__PURE__*/React.createElement("h6", null, "Cast"), /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("button", {
29 | disabled: disabled,
30 | onClick: onClickExport
31 | }, EXPORT), /*#__PURE__*/React.createElement("button", {
32 | disabled: disabled,
33 | onClick: onShow
34 | }, PUBLISH)));
35 | };
36 | export default RagdollCast;
--------------------------------------------------------------------------------
/ragdoll-react/dist/RagdollForm.css:
--------------------------------------------------------------------------------
1 | .form {
2 | position: relative;
3 | background: white;
4 | color: #121212;
5 | box-shadow: 0 0 10rem dodgerblue;
6 | width: 75%;
7 | padding: 1rem;
8 | border-radius: 1rem;
9 | }
--------------------------------------------------------------------------------
/ragdoll-react/dist/useModelInfo.js:
--------------------------------------------------------------------------------
1 | // eslint-disable-next-line no-unused-vars
2 | import React, { useEffect, useState } from 'react';
3 | const useModelInfo = () => {
4 | const {
5 | RAGDOLL_URI
6 | } = window;
7 | const [modelInfo, setModelInfo] = useState();
8 | const [pending, setPending] = useState(false);
9 | useEffect(() => {
10 | const fetchModelInfo = async () => {
11 | setPending(true);
12 | const response = await fetch(`${RAGDOLL_URI}/v1/info`);
13 | if (response?.ok) {
14 | const {
15 | success,
16 | textModelProvider,
17 | textTextModel,
18 | imageModelProviderURI,
19 | textImageModel,
20 | imageImageModel,
21 | version
22 | } = await response.json();
23 | if (success) {
24 | setModelInfo({
25 | textModelProvider,
26 | textTextModel,
27 | imageModelProviderURI,
28 | textImageModel,
29 | imageImageModel,
30 | version
31 | });
32 | }
33 | }
34 | setPending(false);
35 | };
36 | setTimeout(fetchModelInfo, 400);
37 |
38 | // eslint-disable-next-line react-hooks/exhaustive-deps
39 | }, []);
40 | return [modelInfo, pending];
41 | };
42 | export default useModelInfo;
--------------------------------------------------------------------------------
/ragdoll-react/index.js:
--------------------------------------------------------------------------------
1 | // Components
2 |
3 | const RagdollCast = require('./dist/RagdollCast').default;
4 | const RagdollChat = require('./dist/RagdollChat').default;
5 | const RagdollForm = require('./dist/RagdollForm').default;
6 | const RagdollList = require('./dist/RagdollList').default;
7 |
8 | // Hooks
9 |
10 | const useRagdoll = require('./dist/useRagdoll').default;
11 | const useModelInfo = require('./dist/useModelInfo').default;
12 |
13 | module.exports = {
14 | RagdollCast,
15 | RagdollChat,
16 | RagdollForm,
17 | RagdollList,
18 | useRagdoll,
19 | useModelInfo
20 | };
21 |
--------------------------------------------------------------------------------
/ragdoll-react/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "ragdoll-react",
3 | "version": "0.4.9",
4 | "dependencies": {
5 | "@babel/core": "^7.24.3",
6 | "@babel/preset-react": "^7.24.1",
7 | "@testing-library/jest-dom": "^5.17.0",
8 | "@testing-library/react": "^13.4.0",
9 | "@testing-library/user-event": "^13.5.0",
10 | "react": "^18.2.0",
11 | "react-dom": "^18.2.0",
12 | "react-scripts": "5.0.1",
13 | "web-vitals": "^2.1.4"
14 | },
15 | "scripts": {
16 | "start": "react-scripts start",
17 | "build": "react-scripts build",
18 | "build-lib": "node package",
19 | "test": "react-scripts test",
20 | "eject": "react-scripts eject"
21 | },
22 | "eslintConfig": {
23 | "extends": [
24 | "react-app",
25 | "react-app/jest"
26 | ]
27 | },
28 | "browserslist": {
29 | "production": [
30 | ">0.2%",
31 | "not dead",
32 | "not op_mini all"
33 | ],
34 | "development": [
35 | "last 1 chrome version",
36 | "last 1 firefox version",
37 | "last 1 safari version"
38 | ]
39 | },
40 | "devDependencies": {
41 | "@babel/plugin-proposal-private-property-in-object": "^7.21.11"
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/ragdoll-react/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bennyschmidt/ragdoll-studio/a95ed0558db0a6f6a8f7781b24d6bfab79ec6388/ragdoll-react/public/favicon.ico
--------------------------------------------------------------------------------
/ragdoll-react/public/font/Outfit/Outfit-VariableFont_wght.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bennyschmidt/ragdoll-studio/a95ed0558db0a6f6a8f7781b24d6bfab79ec6388/ragdoll-react/public/font/Outfit/Outfit-VariableFont_wght.ttf
--------------------------------------------------------------------------------
/ragdoll-react/public/font/Outfit/static/Outfit-Black.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bennyschmidt/ragdoll-studio/a95ed0558db0a6f6a8f7781b24d6bfab79ec6388/ragdoll-react/public/font/Outfit/static/Outfit-Black.ttf
--------------------------------------------------------------------------------
/ragdoll-react/public/font/Outfit/static/Outfit-Bold.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bennyschmidt/ragdoll-studio/a95ed0558db0a6f6a8f7781b24d6bfab79ec6388/ragdoll-react/public/font/Outfit/static/Outfit-Bold.ttf
--------------------------------------------------------------------------------
/ragdoll-react/public/font/Outfit/static/Outfit-ExtraBold.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bennyschmidt/ragdoll-studio/a95ed0558db0a6f6a8f7781b24d6bfab79ec6388/ragdoll-react/public/font/Outfit/static/Outfit-ExtraBold.ttf
--------------------------------------------------------------------------------
/ragdoll-react/public/font/Outfit/static/Outfit-ExtraLight.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bennyschmidt/ragdoll-studio/a95ed0558db0a6f6a8f7781b24d6bfab79ec6388/ragdoll-react/public/font/Outfit/static/Outfit-ExtraLight.ttf
--------------------------------------------------------------------------------
/ragdoll-react/public/font/Outfit/static/Outfit-Light.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bennyschmidt/ragdoll-studio/a95ed0558db0a6f6a8f7781b24d6bfab79ec6388/ragdoll-react/public/font/Outfit/static/Outfit-Light.ttf
--------------------------------------------------------------------------------
/ragdoll-react/public/font/Outfit/static/Outfit-Medium.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bennyschmidt/ragdoll-studio/a95ed0558db0a6f6a8f7781b24d6bfab79ec6388/ragdoll-react/public/font/Outfit/static/Outfit-Medium.ttf
--------------------------------------------------------------------------------
/ragdoll-react/public/font/Outfit/static/Outfit-Regular.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bennyschmidt/ragdoll-studio/a95ed0558db0a6f6a8f7781b24d6bfab79ec6388/ragdoll-react/public/font/Outfit/static/Outfit-Regular.ttf
--------------------------------------------------------------------------------
/ragdoll-react/public/font/Outfit/static/Outfit-SemiBold.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bennyschmidt/ragdoll-studio/a95ed0558db0a6f6a8f7781b24d6bfab79ec6388/ragdoll-react/public/font/Outfit/static/Outfit-SemiBold.ttf
--------------------------------------------------------------------------------
/ragdoll-react/public/font/Outfit/static/Outfit-Thin.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bennyschmidt/ragdoll-studio/a95ed0558db0a6f6a8f7781b24d6bfab79ec6388/ragdoll-react/public/font/Outfit/static/Outfit-Thin.ttf
--------------------------------------------------------------------------------
/ragdoll-react/public/font/Wrath/Wrath.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bennyschmidt/ragdoll-studio/a95ed0558db0a6f6a8f7781b24d6bfab79ec6388/ragdoll-react/public/font/Wrath/Wrath.ttf
--------------------------------------------------------------------------------
/ragdoll-react/public/img/3d.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/ragdoll-react/public/img/audio.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/ragdoll-react/public/img/avatars/arthas.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bennyschmidt/ragdoll-studio/a95ed0558db0a6f6a8f7781b24d6bfab79ec6388/ragdoll-react/public/img/avatars/arthas.png
--------------------------------------------------------------------------------
/ragdoll-react/public/img/code.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/ragdoll-react/public/img/picture.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/ragdoll-react/public/img/save.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/ragdoll-react/public/img/story.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/ragdoll-react/public/img/trash.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/ragdoll-react/public/img/upload.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/ragdoll-react/public/img/video.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/ragdoll-react/public/logo192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bennyschmidt/ragdoll-studio/a95ed0558db0a6f6a8f7781b24d6bfab79ec6388/ragdoll-react/public/logo192.png
--------------------------------------------------------------------------------
/ragdoll-react/public/logo512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bennyschmidt/ragdoll-studio/a95ed0558db0a6f6a8f7781b24d6bfab79ec6388/ragdoll-react/public/logo512.png
--------------------------------------------------------------------------------
/ragdoll-react/public/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "short_name": "React App",
3 | "name": "Create React App Sample",
4 | "icons": [
5 | {
6 | "src": "favicon.ico",
7 | "sizes": "64x64 32x32 24x24 16x16",
8 | "type": "image/x-icon"
9 | },
10 | {
11 | "src": "logo192.png",
12 | "type": "image/png",
13 | "sizes": "192x192"
14 | },
15 | {
16 | "src": "logo512.png",
17 | "type": "image/png",
18 | "sizes": "512x512"
19 | }
20 | ],
21 | "start_url": ".",
22 | "display": "standalone",
23 | "theme_color": "#000000",
24 | "background_color": "#ffffff"
25 | }
26 |
--------------------------------------------------------------------------------
/ragdoll-react/public/robots.txt:
--------------------------------------------------------------------------------
1 | # https://www.robotstxt.org/robotstxt.html
2 | User-agent: *
3 | Disallow:
4 |
--------------------------------------------------------------------------------
/ragdoll-react/src/components/Icon/index.css:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bennyschmidt/ragdoll-studio/a95ed0558db0a6f6a8f7781b24d6bfab79ec6388/ragdoll-react/src/components/Icon/index.css
--------------------------------------------------------------------------------
/ragdoll-react/src/components/Icon/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | import './index.css';
4 |
5 | const Icon = ({ src, size = 20 }) => (
6 |
15 | );
16 |
17 | export default Icon;
18 |
--------------------------------------------------------------------------------
/ragdoll-react/src/components/Publish/index.css:
--------------------------------------------------------------------------------
1 | #publish > div {
2 | position: absolute;
3 | margin: 0 auto;
4 | padding: 1rem 2rem;
5 | max-width: 75%;
6 | max-height: 75%;
7 | top: 12.5%;
8 | line-height: 2em;
9 | overflow: auto;
10 | background: #010105;
11 | border-radius: 1rem;
12 | box-shadow: 0 0 2rem #010105;
13 | }
14 |
15 | #publish .instructions,
16 | #publish .instructions > li {
17 | text-align: left;
18 | list-style: decimal;
19 | margin: 1rem 0;
20 | }
21 |
22 | #publish a {
23 | color: dodgerblue;
24 | }
25 |
26 | #publish button {
27 | background: #111;
28 | margin: 2rem auto;
29 | max-width: 50%;
30 | }
31 |
32 | #publish button:hover {
33 | background: #222;
34 | }
35 |
--------------------------------------------------------------------------------
/ragdoll-react/src/components/RagdollCast/index.css:
--------------------------------------------------------------------------------
1 | #export {
2 | background: #00000030;
3 | border-radius: 1rem;
4 | padding: .5rem;
5 | }
6 |
7 | #export > div {
8 | display: flex;
9 | justify-content: space-between;
10 | align-items: center;
11 | gap: .5rem;
12 | }
13 |
14 | #export h6 {
15 | margin: 0 0 .5rem;
16 | font-size: .6em;
17 | text-transform: uppercase;
18 | color: #e6edf650;
19 | }
20 |
21 | #export button {
22 | background: linear-gradient(to bottom, #302c42, #010105);
23 | box-shadow: inset 0 .5rem .5rem #010105, 0 1px 0 #ffffff40;
24 | text-transform: uppercase;
25 | font-size: .6em;
26 | margin: 0;
27 | padding: .5rem;
28 | transition: all .2s ease;
29 | white-space: nowrap;
30 | text-overflow: ellipsis;
31 | overflow: hidden;
32 | }
33 |
34 | #export button:hover {
35 | background: #06dee6;
36 | border-color: transparent;
37 | box-shadow: inset 0 .5rem 1rem dodgerblue, 0 1px 0 #000000, 0 0 2rem dodgerblue;
38 | text-shadow: 0 0 .5rem dodgerblue;
39 | }
40 |
41 | @media (max-width: 900px) {
42 | #export > div {
43 | flex-direction: column;
44 | }
45 | }
--------------------------------------------------------------------------------
/ragdoll-react/src/components/RagdollCast/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | import './index.css';
4 |
5 | const CONFIRM_EXPORT = 'Export the current cast?';
6 | const EXPORT = 'Export';
7 | const PUBLISH = 'Publish';
8 |
9 | const RagdollCast = ({
10 | disabled,
11 | ragdollList,
12 | onShow
13 | }) => {
14 | const getRagdollsArray = () => (
15 | Object.values(ragdollList || {})
16 | );
17 |
18 | const onClickExport = () => {
19 | if (!window.confirm(CONFIRM_EXPORT)) return;
20 |
21 | const fileExport = {
22 | author: window.prompt('Author name'),
23 | name: window.prompt('Cast name'),
24 | description: window.prompt('Cast description (optional)') || '',
25 | dolls: getRagdollsArray()
26 | };
27 |
28 | if (!fileExport.author || !fileExport.name || fileExport.dolls.length < 1) {
29 | alert('Invalid export configuration.');
30 |
31 | return;
32 | }
33 |
34 | window.open(
35 | `data:text/json,${encodeURIComponent(JSON.stringify(fileExport, null, 4))}`,
36 | '_blank'
37 | );
38 | };
39 |
40 | return
41 |
Cast
42 |
43 |
44 | {EXPORT}
45 |
46 |
47 | {PUBLISH}
48 |
49 |
50 |
;
51 | }
52 |
53 | export default RagdollCast;
54 |
--------------------------------------------------------------------------------
/ragdoll-react/src/components/RagdollForm/index.css:
--------------------------------------------------------------------------------
1 | .form {
2 | position: relative;
3 | background: white;
4 | color: #121212;
5 | box-shadow: 0 0 10rem dodgerblue;
6 | width: 75%;
7 | padding: 1rem;
8 | border-radius: 1rem;
9 | }
--------------------------------------------------------------------------------
/ragdoll-react/src/components/Upload/index.css:
--------------------------------------------------------------------------------
1 | #upload > input[type="file"] {
2 | background: white;
3 | width: 20rem;
4 | padding: 2rem;
5 | }
--------------------------------------------------------------------------------
/ragdoll-react/src/components/Upload/index.js:
--------------------------------------------------------------------------------
1 | import { useState } from 'react';
2 |
3 | import './index.css';
4 |
5 | const Upload = ({ disabled, type, onFile }) => {
6 | const [fileUpload, setFileUpload] = useState();
7 |
8 | const onChangeFileUpload = ({ target: { files } }) => {
9 | if (!window.confirm('Are you sure? This will clear the current focus.')) return;
10 |
11 | const [file] = files;
12 |
13 | setFileUpload(file);
14 |
15 | const reader = new FileReader();
16 |
17 | reader.onload = ({ target: { result }}) => {
18 | onFile(result);
19 | };
20 |
21 | reader.onerror = () => {
22 | alert('File upload error.');
23 | };
24 |
25 | if (type.match('image')) {
26 | reader.readAsDataURL(file);
27 | } else {
28 | reader.readAsText(file, 'UTF-8');
29 | }
30 | };
31 |
32 | return !fileUpload && ;
38 | };
39 |
40 | export default Upload;
41 |
--------------------------------------------------------------------------------
/ragdoll-react/src/components/index.js:
--------------------------------------------------------------------------------
1 | import RagdollCast from './RagdollCast';
2 | import RagdollChat from './RagdollChat';
3 | import RagdollForm from './RagdollForm';
4 | import RagdollList from './RagdollList';
5 | import Icon from './Icon';
6 | import Publish from './Publish';
7 | import Upload from './Upload';
8 |
9 | export {
10 | RagdollCast,
11 | RagdollChat,
12 | RagdollForm,
13 | RagdollList,
14 | Icon,
15 | Publish,
16 | Upload
17 | };
18 |
--------------------------------------------------------------------------------
/ragdoll-react/src/hooks/index.js:
--------------------------------------------------------------------------------
1 | import useModelInfo from './useModelInfo';
2 | import useRagdoll from './useRagdoll';
3 |
4 | export {
5 | useModelInfo,
6 | useRagdoll
7 | };
8 |
--------------------------------------------------------------------------------
/ragdoll-react/src/hooks/useModelInfo/index.js:
--------------------------------------------------------------------------------
1 | // eslint-disable-next-line no-unused-vars
2 | import React, { useEffect, useState } from 'react';
3 |
4 | const useModelInfo = () => {
5 | const { RAGDOLL_URI } = window;
6 |
7 | const [modelInfo, setModelInfo] = useState();
8 | const [pending, setPending] = useState(false);
9 |
10 | useEffect(() => {
11 | const fetchModelInfo = async () => {
12 | setPending(true);
13 |
14 | const response = await fetch(`${RAGDOLL_URI}/v1/info`);
15 |
16 | if (response?.ok) {
17 | const {
18 | success,
19 | textModelProvider,
20 | textTextModel,
21 | imageModelProviderURI,
22 | textImageModel,
23 | imageImageModel,
24 | version
25 | } = await response.json();
26 |
27 | if (success) {
28 | setModelInfo({
29 | textModelProvider,
30 | textTextModel,
31 | imageModelProviderURI,
32 | textImageModel,
33 | imageImageModel,
34 | version
35 | });
36 | }
37 | }
38 |
39 | setPending(false);
40 | };
41 |
42 | setTimeout(fetchModelInfo, 400);
43 |
44 | // eslint-disable-next-line react-hooks/exhaustive-deps
45 | }, []);
46 |
47 | return [modelInfo, pending];
48 | };
49 |
50 | export default useModelInfo;
51 |
--------------------------------------------------------------------------------
/ragdoll-react/src/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ReactDOM from 'react-dom/client';
3 |
4 | import App from './App';
5 |
6 | import './index.css';
7 |
8 | const root = ReactDOM.createRoot(document.getElementById('root'));
9 |
10 | root.render(
11 |
12 |
13 |
14 | );
15 |
--------------------------------------------------------------------------------
/ragdoll-studio/.gitignore:
--------------------------------------------------------------------------------
1 | # Logs
2 | logs
3 | *.log
4 | npm-debug.log*
5 | yarn-debug.log*
6 | yarn-error.log*
7 | lerna-debug.log*
8 |
9 | # Diagnostic reports (https://nodejs.org/api/report.html)
10 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
11 |
12 | # Runtime data
13 | pids
14 | *.pid
15 | *.seed
16 | *.pid.lock
17 | .DS_Store
18 |
19 | # Directory for instrumented libs generated by jscoverage/JSCover
20 | lib-cov
21 |
22 | # Coverage directory used by tools like istanbul
23 | coverage
24 | *.lcov
25 |
26 | # nyc test coverage
27 | .nyc_output
28 |
29 | # node-waf configuration
30 | .lock-wscript
31 |
32 | # Compiled binary addons (https://nodejs.org/api/addons.html)
33 | build/Release
34 |
35 | # Dependency directories
36 | node_modules/
37 | jspm_packages/
38 |
39 | # TypeScript v1 declaration files
40 | typings/
41 |
42 | # TypeScript cache
43 | *.tsbuildinfo
44 |
45 | # Optional npm cache directory
46 | .npm
47 |
48 | # Optional eslint cache
49 | .eslintcache
50 |
51 | # Optional REPL history
52 | .node_repl_history
53 |
54 | # Output of 'npm pack'
55 | *.tgz
56 |
57 | # Yarn Integrity file
58 | .yarn-integrity
59 |
60 | # dotenv environment variables file
61 | .env
62 | .env.test
63 |
64 | # parcel-bundler cache (https://parceljs.org/)
65 | .cache
66 |
67 | # next.js build output
68 | .next
69 |
70 | # nuxt.js build output
71 | .nuxt
72 |
73 | # vuepress build output
74 | .vuepress/dist
75 |
76 | # Serverless directories
77 | .serverless/
78 |
79 | # FuseBox cache
80 | .fusebox/
81 |
82 | # DynamoDB Local files
83 | .dynamodb/
84 |
85 | # Webpack
86 | .webpack/
87 |
88 | # Vite
89 | .vite/
90 |
91 | # Electron-Forge
92 | out/
93 |
--------------------------------------------------------------------------------
/ragdoll-studio/.nvmrc:
--------------------------------------------------------------------------------
1 | 20.11.1
--------------------------------------------------------------------------------
/ragdoll-studio/src/components/Icon/index.css:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bennyschmidt/ragdoll-studio/a95ed0558db0a6f6a8f7781b24d6bfab79ec6388/ragdoll-studio/src/components/Icon/index.css
--------------------------------------------------------------------------------
/ragdoll-studio/src/components/Icon/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | import './index.css';
4 |
5 | const Icon = ({ src, size = 20 }) => (
6 |
15 | );
16 |
17 | export default Icon;
18 |
--------------------------------------------------------------------------------
/ragdoll-studio/src/components/Publish/index.css:
--------------------------------------------------------------------------------
1 | #publish > div {
2 | position: absolute;
3 | margin: 0 auto;
4 | padding: 1rem 2rem;
5 | max-width: 75%;
6 | max-height: 75%;
7 | top: 12.5%;
8 | line-height: 2em;
9 | overflow: auto;
10 | background: #010105;
11 | border-radius: 1rem;
12 | box-shadow: 0 0 2rem #010105;
13 | }
14 |
15 | #publish .instructions,
16 | #publish .instructions > li {
17 | text-align: left;
18 | list-style: decimal;
19 | margin: 1rem 0;
20 | }
21 |
22 | #publish a {
23 | color: dodgerblue;
24 | }
25 |
26 | #publish button {
27 | background: #111;
28 | margin: 2rem auto;
29 | max-width: 50%;
30 | }
31 |
32 | #publish button:hover {
33 | background: #222;
34 | }
35 |
--------------------------------------------------------------------------------
/ragdoll-studio/src/components/Upload/index.css:
--------------------------------------------------------------------------------
1 | #upload > input[type="file"] {
2 | background: white;
3 | width: 20rem;
4 | padding: 2rem;
5 | }
--------------------------------------------------------------------------------
/ragdoll-studio/src/components/Upload/index.js:
--------------------------------------------------------------------------------
1 | import React, { useState } from 'react';
2 |
3 | import './index.css';
4 |
5 | const Upload = ({ disabled, type, onFile }) => {
6 | const [fileUpload, setFileUpload] = useState();
7 |
8 | const onChangeFileUpload = ({ target: { files } }) => {
9 | if (!window.confirm('Are you sure? This will clear the current focus.')) return;
10 |
11 | const [file] = files;
12 |
13 | setFileUpload(file);
14 |
15 | const reader = new FileReader();
16 |
17 | reader.onload = ({ target: { result }}) => {
18 | onFile(result);
19 | };
20 |
21 | reader.onerror = () => {
22 | alert('File upload error.');
23 | };
24 |
25 | if (type.match('image')) {
26 | reader.readAsDataURL(file);
27 | } else {
28 | reader.readAsText(file, 'UTF-8');
29 | }
30 | };
31 |
32 | return !fileUpload && ;
38 | };
39 |
40 | export default Upload;
41 |
--------------------------------------------------------------------------------
/ragdoll-studio/src/components/index.js:
--------------------------------------------------------------------------------
1 | import Publish from './Publish';
2 | import Upload from './Upload';
3 | import Icon from './Icon';
4 |
5 | export {
6 | Publish,
7 | Upload,
8 | Icon
9 | };
10 |
--------------------------------------------------------------------------------
/ragdoll-studio/src/font/Outfit/Outfit-VariableFont_wght.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bennyschmidt/ragdoll-studio/a95ed0558db0a6f6a8f7781b24d6bfab79ec6388/ragdoll-studio/src/font/Outfit/Outfit-VariableFont_wght.ttf
--------------------------------------------------------------------------------
/ragdoll-studio/src/font/Outfit/static/Outfit-Black.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bennyschmidt/ragdoll-studio/a95ed0558db0a6f6a8f7781b24d6bfab79ec6388/ragdoll-studio/src/font/Outfit/static/Outfit-Black.ttf
--------------------------------------------------------------------------------
/ragdoll-studio/src/font/Outfit/static/Outfit-Bold.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bennyschmidt/ragdoll-studio/a95ed0558db0a6f6a8f7781b24d6bfab79ec6388/ragdoll-studio/src/font/Outfit/static/Outfit-Bold.ttf
--------------------------------------------------------------------------------
/ragdoll-studio/src/font/Outfit/static/Outfit-ExtraBold.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bennyschmidt/ragdoll-studio/a95ed0558db0a6f6a8f7781b24d6bfab79ec6388/ragdoll-studio/src/font/Outfit/static/Outfit-ExtraBold.ttf
--------------------------------------------------------------------------------
/ragdoll-studio/src/font/Outfit/static/Outfit-ExtraLight.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bennyschmidt/ragdoll-studio/a95ed0558db0a6f6a8f7781b24d6bfab79ec6388/ragdoll-studio/src/font/Outfit/static/Outfit-ExtraLight.ttf
--------------------------------------------------------------------------------
/ragdoll-studio/src/font/Outfit/static/Outfit-Light.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bennyschmidt/ragdoll-studio/a95ed0558db0a6f6a8f7781b24d6bfab79ec6388/ragdoll-studio/src/font/Outfit/static/Outfit-Light.ttf
--------------------------------------------------------------------------------
/ragdoll-studio/src/font/Outfit/static/Outfit-Medium.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bennyschmidt/ragdoll-studio/a95ed0558db0a6f6a8f7781b24d6bfab79ec6388/ragdoll-studio/src/font/Outfit/static/Outfit-Medium.ttf
--------------------------------------------------------------------------------
/ragdoll-studio/src/font/Outfit/static/Outfit-Regular.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bennyschmidt/ragdoll-studio/a95ed0558db0a6f6a8f7781b24d6bfab79ec6388/ragdoll-studio/src/font/Outfit/static/Outfit-Regular.ttf
--------------------------------------------------------------------------------
/ragdoll-studio/src/font/Outfit/static/Outfit-SemiBold.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bennyschmidt/ragdoll-studio/a95ed0558db0a6f6a8f7781b24d6bfab79ec6388/ragdoll-studio/src/font/Outfit/static/Outfit-SemiBold.ttf
--------------------------------------------------------------------------------
/ragdoll-studio/src/font/Outfit/static/Outfit-Thin.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bennyschmidt/ragdoll-studio/a95ed0558db0a6f6a8f7781b24d6bfab79ec6388/ragdoll-studio/src/font/Outfit/static/Outfit-Thin.ttf
--------------------------------------------------------------------------------
/ragdoll-studio/src/font/Wrath/Wrath.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bennyschmidt/ragdoll-studio/a95ed0558db0a6f6a8f7781b24d6bfab79ec6388/ragdoll-studio/src/font/Wrath/Wrath.ttf
--------------------------------------------------------------------------------
/ragdoll-studio/src/img/3d.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/ragdoll-studio/src/img/audio.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/ragdoll-studio/src/img/avatars/arthas.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bennyschmidt/ragdoll-studio/a95ed0558db0a6f6a8f7781b24d6bfab79ec6388/ragdoll-studio/src/img/avatars/arthas.png
--------------------------------------------------------------------------------
/ragdoll-studio/src/img/code.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/ragdoll-studio/src/img/picture.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/ragdoll-studio/src/img/save.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/ragdoll-studio/src/img/story.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/ragdoll-studio/src/img/trash.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/ragdoll-studio/src/img/upload.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/ragdoll-studio/src/img/video.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/ragdoll-studio/src/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Ragdoll Studio
6 |
17 |
18 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/ragdoll-studio/src/preload.js:
--------------------------------------------------------------------------------
1 | // See the Electron documentation for details on how to use preload scripts:
2 | // https://www.electronjs.org/docs/latest/tutorial/process-model#preload-scripts
3 |
--------------------------------------------------------------------------------
/ragdoll-studio/src/renderer.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ReactDOM from 'react-dom/client';
3 |
4 | import App from './App';
5 |
6 | import './index.css';
7 |
8 | const root = ReactDOM.createRoot(document.getElementById('root'));
9 |
10 | root.render(
11 |
12 |
13 |
14 | );
15 |
--------------------------------------------------------------------------------
/ragdoll-studio/stable-diffusion-api/.eslintignore:
--------------------------------------------------------------------------------
1 | extensions
2 | extensions-disabled
3 | repositories
4 | venv
--------------------------------------------------------------------------------
/ragdoll-studio/stable-diffusion-api/.git-blame-ignore-revs:
--------------------------------------------------------------------------------
1 | # Apply ESlint
2 | 9c54b78d9dde5601e916f308d9a9d6953ec39430
--------------------------------------------------------------------------------
/ragdoll-studio/stable-diffusion-api/.gitignore:
--------------------------------------------------------------------------------
1 | __pycache__
2 | *.ckpt
3 | *.safetensors
4 | *.pth
5 | /ESRGAN/*
6 | /SwinIR/*
7 | /repositories
8 | /venv
9 | /tmp
10 | /model.ckpt
11 | /models/**/*
12 | /GFPGANv1.3.pth
13 | /gfpgan/weights/*.pth
14 | /ui-config.json
15 | /outputs
16 | /config.json
17 | /log
18 | /webui.settings.bat
19 | /embeddings
20 | /styles.csv
21 | /params.txt
22 | /styles.csv.bak
23 | /webui-user.bat
24 | /webui-user.sh
25 | /interrogate
26 | /user.css
27 | /.idea
28 | notification.mp3
29 | /SwinIR
30 | /textual_inversion
31 | .vscode
32 | /extensions
33 | /test/stdout.txt
34 | /test/stderr.txt
35 | /cache.json*
36 | /config_states/
37 | /node_modules
38 | /package-lock.json
39 | /.coverage*
40 | /test/test_outputs
41 | /cache
42 |
--------------------------------------------------------------------------------
/ragdoll-studio/stable-diffusion-api/.pylintrc:
--------------------------------------------------------------------------------
1 | # See https://pylint.pycqa.org/en/latest/user_guide/messages/message_control.html
2 | [MESSAGES CONTROL]
3 | disable=C,R,W,E,I
4 |
--------------------------------------------------------------------------------
/ragdoll-studio/stable-diffusion-api/CITATION.cff:
--------------------------------------------------------------------------------
1 | cff-version: 1.2.0
2 | message: "If you use this software, please cite it as below."
3 | authors:
4 | - given-names: AUTOMATIC1111
5 | title: "Stable Diffusion Web UI"
6 | date-released: 2022-08-22
7 | url: "https://github.com/AUTOMATIC1111/stable-diffusion-webui"
8 |
--------------------------------------------------------------------------------
/ragdoll-studio/stable-diffusion-api/CODEOWNERS:
--------------------------------------------------------------------------------
1 | * @AUTOMATIC1111
2 |
3 | # if you were managing a localization and were removed from this file, this is because
4 | # the intended way to do localizations now is via extensions. See:
5 | # https://github.com/AUTOMATIC1111/stable-diffusion-webui/wiki/Developing-extensions
6 | # Make a repo with your localization and since you are still listed as a collaborator
7 | # you can add it to the wiki page yourself. This change is because some people complained
8 | # the git commit log is cluttered with things unrelated to almost everyone and
9 | # because I believe this is the best overall for the project to handle localizations almost
10 | # entirely without my oversight.
11 |
12 |
13 |
--------------------------------------------------------------------------------
/ragdoll-studio/stable-diffusion-api/_typos.toml:
--------------------------------------------------------------------------------
1 | [default.extend-words]
2 | # Part of "RGBa" (Pillow's pre-multiplied alpha RGB mode)
3 | Ba = "Ba"
4 | # HSA is something AMD uses for their GPUs
5 | HSA = "HSA"
6 |
--------------------------------------------------------------------------------
/ragdoll-studio/stable-diffusion-api/environment-wsl2.yaml:
--------------------------------------------------------------------------------
1 | name: automatic
2 | channels:
3 | - pytorch
4 | - defaults
5 | dependencies:
6 | - python=3.10
7 | - pip=23.0
8 | - cudatoolkit=11.8
9 | - pytorch=2.0
10 | - torchvision=0.15
11 | - numpy=1.23
12 |
--------------------------------------------------------------------------------
/ragdoll-studio/stable-diffusion-api/extensions-builtin/LDSR/preload.py:
--------------------------------------------------------------------------------
1 | import os
2 | from modules import paths
3 |
4 |
5 | def preload(parser):
6 | parser.add_argument("--ldsr-models-path", type=str, help="Path to directory with LDSR model file(s).", default=os.path.join(paths.models_path, 'LDSR'))
7 |
--------------------------------------------------------------------------------
/ragdoll-studio/stable-diffusion-api/extensions-builtin/Lora/lora.py:
--------------------------------------------------------------------------------
1 | import networks
2 |
3 | list_available_loras = networks.list_available_networks
4 |
5 | available_loras = networks.available_networks
6 | available_lora_aliases = networks.available_network_aliases
7 | available_lora_hash_lookup = networks.available_network_hash_lookup
8 | forbidden_lora_aliases = networks.forbidden_network_aliases
9 | loaded_loras = networks.loaded_networks
10 |
--------------------------------------------------------------------------------
/ragdoll-studio/stable-diffusion-api/extensions-builtin/Lora/lora_logger.py:
--------------------------------------------------------------------------------
1 | import sys
2 | import copy
3 | import logging
4 |
5 |
6 | class ColoredFormatter(logging.Formatter):
7 | COLORS = {
8 | "DEBUG": "\033[0;36m", # CYAN
9 | "INFO": "\033[0;32m", # GREEN
10 | "WARNING": "\033[0;33m", # YELLOW
11 | "ERROR": "\033[0;31m", # RED
12 | "CRITICAL": "\033[0;37;41m", # WHITE ON RED
13 | "RESET": "\033[0m", # RESET COLOR
14 | }
15 |
16 | def format(self, record):
17 | colored_record = copy.copy(record)
18 | levelname = colored_record.levelname
19 | seq = self.COLORS.get(levelname, self.COLORS["RESET"])
20 | colored_record.levelname = f"{seq}{levelname}{self.COLORS['RESET']}"
21 | return super().format(colored_record)
22 |
23 |
24 | logger = logging.getLogger("lora")
25 | logger.propagate = False
26 |
27 |
28 | if not logger.handlers:
29 | handler = logging.StreamHandler(sys.stdout)
30 | handler.setFormatter(
31 | ColoredFormatter("[%(name)s]-%(levelname)s: %(message)s")
32 | )
33 | logger.addHandler(handler)
34 |
--------------------------------------------------------------------------------
/ragdoll-studio/stable-diffusion-api/extensions-builtin/Lora/network_full.py:
--------------------------------------------------------------------------------
1 | import network
2 |
3 |
4 | class ModuleTypeFull(network.ModuleType):
5 | def create_module(self, net: network.Network, weights: network.NetworkWeights):
6 | if all(x in weights.w for x in ["diff"]):
7 | return NetworkModuleFull(net, weights)
8 |
9 | return None
10 |
11 |
12 | class NetworkModuleFull(network.NetworkModule):
13 | def __init__(self, net: network.Network, weights: network.NetworkWeights):
14 | super().__init__(net, weights)
15 |
16 | self.weight = weights.w.get("diff")
17 | self.ex_bias = weights.w.get("diff_b")
18 |
19 | def calc_updown(self, orig_weight):
20 | output_shape = self.weight.shape
21 | updown = self.weight.to(orig_weight.device)
22 | if self.ex_bias is not None:
23 | ex_bias = self.ex_bias.to(orig_weight.device)
24 | else:
25 | ex_bias = None
26 |
27 | return self.finalize_updown(updown, orig_weight, output_shape, ex_bias)
28 |
--------------------------------------------------------------------------------
/ragdoll-studio/stable-diffusion-api/extensions-builtin/Lora/network_glora.py:
--------------------------------------------------------------------------------
1 |
2 | import network
3 |
4 | class ModuleTypeGLora(network.ModuleType):
5 | def create_module(self, net: network.Network, weights: network.NetworkWeights):
6 | if all(x in weights.w for x in ["a1.weight", "a2.weight", "alpha", "b1.weight", "b2.weight"]):
7 | return NetworkModuleGLora(net, weights)
8 |
9 | return None
10 |
11 | # adapted from https://github.com/KohakuBlueleaf/LyCORIS
12 | class NetworkModuleGLora(network.NetworkModule):
13 | def __init__(self, net: network.Network, weights: network.NetworkWeights):
14 | super().__init__(net, weights)
15 |
16 | if hasattr(self.sd_module, 'weight'):
17 | self.shape = self.sd_module.weight.shape
18 |
19 | self.w1a = weights.w["a1.weight"]
20 | self.w1b = weights.w["b1.weight"]
21 | self.w2a = weights.w["a2.weight"]
22 | self.w2b = weights.w["b2.weight"]
23 |
24 | def calc_updown(self, orig_weight):
25 | w1a = self.w1a.to(orig_weight.device)
26 | w1b = self.w1b.to(orig_weight.device)
27 | w2a = self.w2a.to(orig_weight.device)
28 | w2b = self.w2b.to(orig_weight.device)
29 |
30 | output_shape = [w1a.size(0), w1b.size(1)]
31 | updown = ((w2b @ w1b) + ((orig_weight.to(dtype = w1a.dtype) @ w2a) @ w1a))
32 |
33 | return self.finalize_updown(updown, orig_weight, output_shape)
34 |
--------------------------------------------------------------------------------
/ragdoll-studio/stable-diffusion-api/extensions-builtin/Lora/network_ia3.py:
--------------------------------------------------------------------------------
1 | import network
2 |
3 |
4 | class ModuleTypeIa3(network.ModuleType):
5 | def create_module(self, net: network.Network, weights: network.NetworkWeights):
6 | if all(x in weights.w for x in ["weight"]):
7 | return NetworkModuleIa3(net, weights)
8 |
9 | return None
10 |
11 |
12 | class NetworkModuleIa3(network.NetworkModule):
13 | def __init__(self, net: network.Network, weights: network.NetworkWeights):
14 | super().__init__(net, weights)
15 |
16 | self.w = weights.w["weight"]
17 | self.on_input = weights.w["on_input"].item()
18 |
19 | def calc_updown(self, orig_weight):
20 | w = self.w.to(orig_weight.device)
21 |
22 | output_shape = [w.size(0), orig_weight.size(1)]
23 | if self.on_input:
24 | output_shape.reverse()
25 | else:
26 | w = w.reshape(-1, 1)
27 |
28 | updown = orig_weight * w
29 |
30 | return self.finalize_updown(updown, orig_weight, output_shape)
31 |
--------------------------------------------------------------------------------
/ragdoll-studio/stable-diffusion-api/extensions-builtin/Lora/network_norm.py:
--------------------------------------------------------------------------------
1 | import network
2 |
3 |
4 | class ModuleTypeNorm(network.ModuleType):
5 | def create_module(self, net: network.Network, weights: network.NetworkWeights):
6 | if all(x in weights.w for x in ["w_norm", "b_norm"]):
7 | return NetworkModuleNorm(net, weights)
8 |
9 | return None
10 |
11 |
12 | class NetworkModuleNorm(network.NetworkModule):
13 | def __init__(self, net: network.Network, weights: network.NetworkWeights):
14 | super().__init__(net, weights)
15 |
16 | self.w_norm = weights.w.get("w_norm")
17 | self.b_norm = weights.w.get("b_norm")
18 |
19 | def calc_updown(self, orig_weight):
20 | output_shape = self.w_norm.shape
21 | updown = self.w_norm.to(orig_weight.device)
22 |
23 | if self.b_norm is not None:
24 | ex_bias = self.b_norm.to(orig_weight.device)
25 | else:
26 | ex_bias = None
27 |
28 | return self.finalize_updown(updown, orig_weight, output_shape, ex_bias)
29 |
--------------------------------------------------------------------------------
/ragdoll-studio/stable-diffusion-api/extensions-builtin/Lora/preload.py:
--------------------------------------------------------------------------------
1 | import os
2 | from modules import paths
3 | from modules.paths_internal import normalized_filepath
4 |
5 |
6 | def preload(parser):
7 | parser.add_argument("--lora-dir", type=normalized_filepath, help="Path to directory with Lora networks.", default=os.path.join(paths.models_path, 'Lora'))
8 | parser.add_argument("--lyco-dir-backcompat", type=normalized_filepath, help="Path to directory with LyCORIS networks (for backawards compatibility; can also use --lyco-dir).", default=os.path.join(paths.models_path, 'LyCORIS'))
9 |
--------------------------------------------------------------------------------
/ragdoll-studio/stable-diffusion-api/extensions-builtin/ScuNET/preload.py:
--------------------------------------------------------------------------------
1 | import os
2 | from modules import paths
3 |
4 |
5 | def preload(parser):
6 | parser.add_argument("--scunet-models-path", type=str, help="Path to directory with ScuNET model file(s).", default=os.path.join(paths.models_path, 'ScuNET'))
7 |
--------------------------------------------------------------------------------
/ragdoll-studio/stable-diffusion-api/extensions-builtin/SwinIR/preload.py:
--------------------------------------------------------------------------------
1 | import os
2 | from modules import paths
3 |
4 |
5 | def preload(parser):
6 | parser.add_argument("--swinir-models-path", type=str, help="Path to directory with SwinIR model file(s).", default=os.path.join(paths.models_path, 'SwinIR'))
7 |
--------------------------------------------------------------------------------
/ragdoll-studio/stable-diffusion-api/extensions-builtin/canvas-zoom-and-pan/style.css:
--------------------------------------------------------------------------------
1 | .canvas-tooltip-info {
2 | position: absolute;
3 | top: 10px;
4 | left: 10px;
5 | cursor: help;
6 | background-color: rgba(0, 0, 0, 0.3);
7 | width: 20px;
8 | height: 20px;
9 | border-radius: 50%;
10 | display: flex;
11 | align-items: center;
12 | justify-content: center;
13 | flex-direction: column;
14 |
15 | z-index: 100;
16 | }
17 |
18 | .canvas-tooltip-info::after {
19 | content: '';
20 | display: block;
21 | width: 2px;
22 | height: 7px;
23 | background-color: white;
24 | margin-top: 2px;
25 | }
26 |
27 | .canvas-tooltip-info::before {
28 | content: '';
29 | display: block;
30 | width: 2px;
31 | height: 2px;
32 | background-color: white;
33 | }
34 |
35 | .canvas-tooltip-content {
36 | display: none;
37 | background-color: #f9f9f9;
38 | color: #333;
39 | border: 1px solid #ddd;
40 | padding: 15px;
41 | position: absolute;
42 | top: 40px;
43 | left: 10px;
44 | width: 250px;
45 | font-size: 16px;
46 | opacity: 0;
47 | border-radius: 8px;
48 | box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);
49 |
50 | z-index: 100;
51 | }
52 |
53 | .canvas-tooltip:hover .canvas-tooltip-content {
54 | display: block;
55 | animation: fadeIn 0.5s;
56 | opacity: 1;
57 | }
58 |
59 | @keyframes fadeIn {
60 | from {opacity: 0;}
61 | to {opacity: 1;}
62 | }
63 |
64 | .styler {
65 | overflow:inherit !important;
66 | }
--------------------------------------------------------------------------------
/ragdoll-studio/stable-diffusion-api/extensions-builtin/mobile/javascript/mobile.js:
--------------------------------------------------------------------------------
1 | var isSetupForMobile = false;
2 |
3 | function isMobile() {
4 | for (var tab of ["txt2img", "img2img"]) {
5 | var imageTab = gradioApp().getElementById(tab + '_results');
6 | if (imageTab && imageTab.offsetParent && imageTab.offsetLeft == 0) {
7 | return true;
8 | }
9 | }
10 |
11 | return false;
12 | }
13 |
14 | function reportWindowSize() {
15 | if (gradioApp().querySelector('.toprow-compact-tools')) return; // not applicable for compact prompt layout
16 |
17 | var currentlyMobile = isMobile();
18 | if (currentlyMobile == isSetupForMobile) return;
19 | isSetupForMobile = currentlyMobile;
20 |
21 | for (var tab of ["txt2img", "img2img"]) {
22 | var button = gradioApp().getElementById(tab + '_generate_box');
23 | var target = gradioApp().getElementById(currentlyMobile ? tab + '_results' : tab + '_actions_column');
24 | target.insertBefore(button, target.firstElementChild);
25 |
26 | gradioApp().getElementById(tab + '_results').classList.toggle('mobile', currentlyMobile);
27 | }
28 | }
29 |
30 | window.addEventListener("resize", reportWindowSize);
31 |
32 | onUiLoaded(function() {
33 | reportWindowSize();
34 | });
35 |
--------------------------------------------------------------------------------
/ragdoll-studio/stable-diffusion-api/extensions-builtin/postprocessing-for-training/scripts/postprocessing_caption.py:
--------------------------------------------------------------------------------
1 | from modules import scripts_postprocessing, ui_components, deepbooru, shared
2 | import gradio as gr
3 |
4 |
5 | class ScriptPostprocessingCeption(scripts_postprocessing.ScriptPostprocessing):
6 | name = "Caption"
7 | order = 4040
8 |
9 | def ui(self):
10 | with ui_components.InputAccordion(False, label="Caption") as enable:
11 | option = gr.CheckboxGroup(value=["Deepbooru"], choices=["Deepbooru", "BLIP"], show_label=False)
12 |
13 | return {
14 | "enable": enable,
15 | "option": option,
16 | }
17 |
18 | def process(self, pp: scripts_postprocessing.PostprocessedImage, enable, option):
19 | if not enable:
20 | return
21 |
22 | captions = [pp.caption]
23 |
24 | if "Deepbooru" in option:
25 | captions.append(deepbooru.model.tag(pp.image))
26 |
27 | if "BLIP" in option:
28 | captions.append(shared.interrogator.interrogate(pp.image.convert("RGB")))
29 |
30 | pp.caption = ", ".join([x for x in captions if x])
31 |
--------------------------------------------------------------------------------
/ragdoll-studio/stable-diffusion-api/extensions-builtin/postprocessing-for-training/scripts/postprocessing_create_flipped_copies.py:
--------------------------------------------------------------------------------
1 | from PIL import ImageOps, Image
2 |
3 | from modules import scripts_postprocessing, ui_components
4 | import gradio as gr
5 |
6 |
7 | class ScriptPostprocessingCreateFlippedCopies(scripts_postprocessing.ScriptPostprocessing):
8 | name = "Create flipped copies"
9 | order = 4030
10 |
11 | def ui(self):
12 | with ui_components.InputAccordion(False, label="Create flipped copies") as enable:
13 | with gr.Row():
14 | option = gr.CheckboxGroup(value=["Horizontal"], choices=["Horizontal", "Vertical", "Both"], show_label=False)
15 |
16 | return {
17 | "enable": enable,
18 | "option": option,
19 | }
20 |
21 | def process(self, pp: scripts_postprocessing.PostprocessedImage, enable, option):
22 | if not enable:
23 | return
24 |
25 | if "Horizontal" in option:
26 | pp.extra_images.append(ImageOps.mirror(pp.image))
27 |
28 | if "Vertical" in option:
29 | pp.extra_images.append(pp.image.transpose(Image.Transpose.FLIP_TOP_BOTTOM))
30 |
31 | if "Both" in option:
32 | pp.extra_images.append(pp.image.transpose(Image.Transpose.FLIP_TOP_BOTTOM).transpose(Image.Transpose.FLIP_LEFT_RIGHT))
33 |
--------------------------------------------------------------------------------
/ragdoll-studio/stable-diffusion-api/html/card-no-preview.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bennyschmidt/ragdoll-studio/a95ed0558db0a6f6a8f7781b24d6bfab79ec6388/ragdoll-studio/stable-diffusion-api/html/card-no-preview.png
--------------------------------------------------------------------------------
/ragdoll-studio/stable-diffusion-api/html/extra-networks-card.html:
--------------------------------------------------------------------------------
1 |
2 | {background_image}
3 |
{copy_path_button}{metadata_button}{edit_button}
4 |
5 |
{search_terms}
6 |
{name}
7 |
{description}
8 |
9 |
10 |
--------------------------------------------------------------------------------
/ragdoll-studio/stable-diffusion-api/html/extra-networks-copy-path-button.html:
--------------------------------------------------------------------------------
1 |
5 |
--------------------------------------------------------------------------------
/ragdoll-studio/stable-diffusion-api/html/extra-networks-edit-item-button.html:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/ragdoll-studio/stable-diffusion-api/html/extra-networks-metadata-button.html:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/ragdoll-studio/stable-diffusion-api/html/extra-networks-no-cards.html:
--------------------------------------------------------------------------------
1 |
2 |
Nothing here. Add some content to the following directories:
3 |
4 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/ragdoll-studio/stable-diffusion-api/html/extra-networks-pane-dirs.html:
--------------------------------------------------------------------------------
1 |
9 |
--------------------------------------------------------------------------------
/ragdoll-studio/stable-diffusion-api/html/extra-networks-pane-tree.html:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
--------------------------------------------------------------------------------
/ragdoll-studio/stable-diffusion-api/html/extra-networks-tree-button.html:
--------------------------------------------------------------------------------
1 | {search_terms}
2 |
8 |
9 | {action_list_item_action_leading}
10 |
11 |
12 | {action_list_item_visual_leading}
13 |
14 |
15 | {action_list_item_label}
16 |
17 |
18 | {action_list_item_visual_trailing}
19 |
20 |
21 | {action_list_item_action_trailing}
22 |
23 |
--------------------------------------------------------------------------------
/ragdoll-studio/stable-diffusion-api/html/footer.html:
--------------------------------------------------------------------------------
1 |
12 |
13 |
14 | {versions}
15 |
16 |
--------------------------------------------------------------------------------
/ragdoll-studio/stable-diffusion-api/javascript/generationParams.js:
--------------------------------------------------------------------------------
1 | // attaches listeners to the txt2img and img2img galleries to update displayed generation param text when the image changes
2 |
3 | let txt2img_gallery, img2img_gallery, modal = undefined;
4 | onAfterUiUpdate(function() {
5 | if (!txt2img_gallery) {
6 | txt2img_gallery = attachGalleryListeners("txt2img");
7 | }
8 | if (!img2img_gallery) {
9 | img2img_gallery = attachGalleryListeners("img2img");
10 | }
11 | if (!modal) {
12 | modal = gradioApp().getElementById('lightboxModal');
13 | modalObserver.observe(modal, {attributes: true, attributeFilter: ['style']});
14 | }
15 | });
16 |
17 | let modalObserver = new MutationObserver(function(mutations) {
18 | mutations.forEach(function(mutationRecord) {
19 | let selectedTab = gradioApp().querySelector('#tabs div button.selected')?.innerText;
20 | if (mutationRecord.target.style.display === 'none' && (selectedTab === 'txt2img' || selectedTab === 'img2img')) {
21 | gradioApp().getElementById(selectedTab + "_generation_info_button")?.click();
22 | }
23 | });
24 | });
25 |
26 | function attachGalleryListeners(tab_name) {
27 | var gallery = gradioApp().querySelector('#' + tab_name + '_gallery');
28 | gallery?.addEventListener('click', () => gradioApp().getElementById(tab_name + "_generation_info_button").click());
29 | gallery?.addEventListener('keydown', (e) => {
30 | if (e.keyCode == 37 || e.keyCode == 39) { // left or right arrow
31 | gradioApp().getElementById(tab_name + "_generation_info_button").click();
32 | }
33 | });
34 | return gallery;
35 | }
36 |
--------------------------------------------------------------------------------
/ragdoll-studio/stable-diffusion-api/javascript/hires_fix.js:
--------------------------------------------------------------------------------
1 |
2 | function onCalcResolutionHires(enable, width, height, hr_scale, hr_resize_x, hr_resize_y) {
3 | function setInactive(elem, inactive) {
4 | elem.classList.toggle('inactive', !!inactive);
5 | }
6 |
7 | var hrUpscaleBy = gradioApp().getElementById('txt2img_hr_scale');
8 | var hrResizeX = gradioApp().getElementById('txt2img_hr_resize_x');
9 | var hrResizeY = gradioApp().getElementById('txt2img_hr_resize_y');
10 |
11 | gradioApp().getElementById('txt2img_hires_fix_row2').style.display = opts.use_old_hires_fix_width_height ? "none" : "";
12 |
13 | setInactive(hrUpscaleBy, opts.use_old_hires_fix_width_height || hr_resize_x > 0 || hr_resize_y > 0);
14 | setInactive(hrResizeX, opts.use_old_hires_fix_width_height || hr_resize_x == 0);
15 | setInactive(hrResizeY, opts.use_old_hires_fix_width_height || hr_resize_y == 0);
16 |
17 | return [enable, width, height, hr_scale, hr_resize_x, hr_resize_y];
18 | }
19 |
--------------------------------------------------------------------------------
/ragdoll-studio/stable-diffusion-api/javascript/imageMaskFix.js:
--------------------------------------------------------------------------------
1 | /**
2 | * temporary fix for https://github.com/AUTOMATIC1111/stable-diffusion-webui/issues/668
3 | * @see https://github.com/gradio-app/gradio/issues/1721
4 | */
5 | function imageMaskResize() {
6 | const canvases = gradioApp().querySelectorAll('#img2maskimg .touch-none canvas');
7 | if (!canvases.length) {
8 | window.removeEventListener('resize', imageMaskResize);
9 | return;
10 | }
11 |
12 | const wrapper = canvases[0].closest('.touch-none');
13 | const previewImage = wrapper.previousElementSibling;
14 |
15 | if (!previewImage.complete) {
16 | previewImage.addEventListener('load', imageMaskResize);
17 | return;
18 | }
19 |
20 | const w = previewImage.width;
21 | const h = previewImage.height;
22 | const nw = previewImage.naturalWidth;
23 | const nh = previewImage.naturalHeight;
24 | const portrait = nh > nw;
25 |
26 | const wW = Math.min(w, portrait ? h / nh * nw : w / nw * nw);
27 | const wH = Math.min(h, portrait ? h / nh * nh : w / nw * nh);
28 |
29 | wrapper.style.width = `${wW}px`;
30 | wrapper.style.height = `${wH}px`;
31 | wrapper.style.left = `0px`;
32 | wrapper.style.top = `0px`;
33 |
34 | canvases.forEach(c => {
35 | c.style.width = c.style.height = '';
36 | c.style.maxWidth = '100%';
37 | c.style.maxHeight = '100%';
38 | c.style.objectFit = 'contain';
39 | });
40 | }
41 |
42 | onAfterUiUpdate(imageMaskResize);
43 | window.addEventListener('resize', imageMaskResize);
44 |
--------------------------------------------------------------------------------
/ragdoll-studio/stable-diffusion-api/javascript/localStorage.js:
--------------------------------------------------------------------------------
1 |
2 | function localSet(k, v) {
3 | try {
4 | localStorage.setItem(k, v);
5 | } catch (e) {
6 | console.warn(`Failed to save ${k} to localStorage: ${e}`);
7 | }
8 | }
9 |
10 | function localGet(k, def) {
11 | try {
12 | return localStorage.getItem(k);
13 | } catch (e) {
14 | console.warn(`Failed to load ${k} from localStorage: ${e}`);
15 | }
16 |
17 | return def;
18 | }
19 |
20 | function localRemove(k) {
21 | try {
22 | return localStorage.removeItem(k);
23 | } catch (e) {
24 | console.warn(`Failed to remove ${k} from localStorage: ${e}`);
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/ragdoll-studio/stable-diffusion-api/javascript/textualInversion.js:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | function start_training_textual_inversion() {
5 | gradioApp().querySelector('#ti_error').innerHTML = '';
6 |
7 | var id = randomId();
8 | requestProgress(id, gradioApp().getElementById('ti_output'), gradioApp().getElementById('ti_gallery'), function() {}, function(progress) {
9 | gradioApp().getElementById('ti_progress').innerHTML = progress.textinfo;
10 | });
11 |
12 | var res = Array.from(arguments);
13 |
14 | res[0] = id;
15 |
16 | return res;
17 | }
18 |
--------------------------------------------------------------------------------
/ragdoll-studio/stable-diffusion-api/launch.py:
--------------------------------------------------------------------------------
1 | from modules import launch_utils
2 |
3 | args = launch_utils.args
4 | python = launch_utils.python
5 | git = launch_utils.git
6 | index_url = launch_utils.index_url
7 | dir_repos = launch_utils.dir_repos
8 |
9 | commit_hash = launch_utils.commit_hash
10 | git_tag = launch_utils.git_tag
11 |
12 | run = launch_utils.run
13 | is_installed = launch_utils.is_installed
14 | repo_dir = launch_utils.repo_dir
15 |
16 | run_pip = launch_utils.run_pip
17 | check_run_python = launch_utils.check_run_python
18 | git_clone = launch_utils.git_clone
19 | git_pull_recursive = launch_utils.git_pull_recursive
20 | list_extensions = launch_utils.list_extensions
21 | run_extension_installer = launch_utils.run_extension_installer
22 | prepare_environment = launch_utils.prepare_environment
23 | configure_for_tests = launch_utils.configure_for_tests
24 | start = launch_utils.start
25 |
26 |
27 | def main():
28 | if args.dump_sysinfo:
29 | filename = launch_utils.dump_sysinfo()
30 |
31 | print(f"Sysinfo saved as {filename}. Exiting...")
32 |
33 | exit(0)
34 |
35 | launch_utils.startup_timer.record("initial startup")
36 |
37 | with launch_utils.startup_timer.subcategory("prepare environment"):
38 | if not args.skip_prepare_environment:
39 | prepare_environment()
40 |
41 | if args.test_server:
42 | configure_for_tests()
43 |
44 | start()
45 |
46 |
47 | if __name__ == "__main__":
48 | main()
49 |
--------------------------------------------------------------------------------
/ragdoll-studio/stable-diffusion-api/localizations/Put localization files here.txt:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bennyschmidt/ragdoll-studio/a95ed0558db0a6f6a8f7781b24d6bfab79ec6388/ragdoll-studio/stable-diffusion-api/localizations/Put localization files here.txt
--------------------------------------------------------------------------------
/ragdoll-studio/stable-diffusion-api/modules/Roboto-Regular.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bennyschmidt/ragdoll-studio/a95ed0558db0a6f6a8f7781b24d6bfab79ec6388/ragdoll-studio/stable-diffusion-api/modules/Roboto-Regular.ttf
--------------------------------------------------------------------------------
/ragdoll-studio/stable-diffusion-api/modules/extra_networks_hypernet.py:
--------------------------------------------------------------------------------
1 | from modules import extra_networks, shared
2 | from modules.hypernetworks import hypernetwork
3 |
4 |
5 | class ExtraNetworkHypernet(extra_networks.ExtraNetwork):
6 | def __init__(self):
7 | super().__init__('hypernet')
8 |
9 | def activate(self, p, params_list):
10 | additional = shared.opts.sd_hypernetwork
11 |
12 | if additional != "None" and additional in shared.hypernetworks and not any(x for x in params_list if x.items[0] == additional):
13 | hypernet_prompt_text = f""
14 | p.all_prompts = [f"{prompt}{hypernet_prompt_text}" for prompt in p.all_prompts]
15 | params_list.append(extra_networks.ExtraNetworkParams(items=[additional, shared.opts.extra_networks_default_multiplier]))
16 |
17 | names = []
18 | multipliers = []
19 | for params in params_list:
20 | assert params.items
21 |
22 | names.append(params.items[0])
23 | multipliers.append(float(params.items[1]) if len(params.items) > 1 else 1.0)
24 |
25 | hypernetwork.load_hypernetworks(names, multipliers)
26 |
27 | def deactivate(self, p):
28 | pass
29 |
--------------------------------------------------------------------------------
/ragdoll-studio/stable-diffusion-api/modules/face_restoration.py:
--------------------------------------------------------------------------------
1 | from modules import shared
2 |
3 |
4 | class FaceRestoration:
5 | def name(self):
6 | return "None"
7 |
8 | def restore(self, np_image):
9 | return np_image
10 |
11 |
12 | def restore_faces(np_image):
13 | face_restorers = [x for x in shared.face_restorers if x.name() == shared.opts.face_restoration_model or shared.opts.face_restoration_model is None]
14 | if len(face_restorers) == 0:
15 | return np_image
16 |
17 | face_restorer = face_restorers[0]
18 |
19 | return face_restorer.restore(np_image)
20 |
--------------------------------------------------------------------------------
/ragdoll-studio/stable-diffusion-api/modules/fifo_lock.py:
--------------------------------------------------------------------------------
1 | import threading
2 | import collections
3 |
4 |
5 | # reference: https://gist.github.com/vitaliyp/6d54dd76ca2c3cdfc1149d33007dc34a
6 | class FIFOLock(object):
7 | def __init__(self):
8 | self._lock = threading.Lock()
9 | self._inner_lock = threading.Lock()
10 | self._pending_threads = collections.deque()
11 |
12 | def acquire(self, blocking=True):
13 | with self._inner_lock:
14 | lock_acquired = self._lock.acquire(False)
15 | if lock_acquired:
16 | return True
17 | elif not blocking:
18 | return False
19 |
20 | release_event = threading.Event()
21 | self._pending_threads.append(release_event)
22 |
23 | release_event.wait()
24 | return self._lock.acquire()
25 |
26 | def release(self):
27 | with self._inner_lock:
28 | if self._pending_threads:
29 | release_event = self._pending_threads.popleft()
30 | release_event.set()
31 |
32 | self._lock.release()
33 |
34 | __enter__ = acquire
35 |
36 | def __exit__(self, t, v, tb):
37 | self.release()
38 |
--------------------------------------------------------------------------------
/ragdoll-studio/stable-diffusion-api/modules/gitpython_hack.py:
--------------------------------------------------------------------------------
1 | from __future__ import annotations
2 |
3 | import io
4 | import subprocess
5 |
6 | import git
7 |
8 |
9 | class Git(git.Git):
10 | """
11 | Git subclassed to never use persistent processes.
12 | """
13 |
14 | def _get_persistent_cmd(self, attr_name, cmd_name, *args, **kwargs):
15 | raise NotImplementedError(f"Refusing to use persistent process: {attr_name} ({cmd_name} {args} {kwargs})")
16 |
17 | def get_object_header(self, ref: str | bytes) -> tuple[str, str, int]:
18 | ret = subprocess.check_output(
19 | [self.GIT_PYTHON_GIT_EXECUTABLE, "cat-file", "--batch-check"],
20 | input=self._prepare_ref(ref),
21 | cwd=self._working_dir,
22 | timeout=2,
23 | )
24 | return self._parse_object_header(ret)
25 |
26 | def stream_object_data(self, ref: str) -> tuple[str, str, int, Git.CatFileContentStream]:
27 | # Not really streaming, per se; this buffers the entire object in memory.
28 | # Shouldn't be a problem for our use case, since we're only using this for
29 | # object headers (commit objects).
30 | ret = subprocess.check_output(
31 | [self.GIT_PYTHON_GIT_EXECUTABLE, "cat-file", "--batch"],
32 | input=self._prepare_ref(ref),
33 | cwd=self._working_dir,
34 | timeout=30,
35 | )
36 | bio = io.BytesIO(ret)
37 | hexsha, typename, size = self._parse_object_header(bio.readline())
38 | return (hexsha, typename, size, self.CatFileContentStream(size, bio))
39 |
40 |
41 | class Repo(git.Repo):
42 | GitCommandWrapperType = Git
43 |
--------------------------------------------------------------------------------
/ragdoll-studio/stable-diffusion-api/modules/hypernetworks/ui.py:
--------------------------------------------------------------------------------
1 | import html
2 |
3 | import gradio as gr
4 | import modules.hypernetworks.hypernetwork
5 | from modules import devices, sd_hijack, shared
6 |
7 | not_available = ["hardswish", "multiheadattention"]
8 | keys = [x for x in modules.hypernetworks.hypernetwork.HypernetworkModule.activation_dict if x not in not_available]
9 |
10 |
11 | def create_hypernetwork(name, enable_sizes, overwrite_old, layer_structure=None, activation_func=None, weight_init=None, add_layer_norm=False, use_dropout=False, dropout_structure=None):
12 | filename = modules.hypernetworks.hypernetwork.create_hypernetwork(name, enable_sizes, overwrite_old, layer_structure, activation_func, weight_init, add_layer_norm, use_dropout, dropout_structure)
13 |
14 | return gr.Dropdown.update(choices=sorted(shared.hypernetworks)), f"Created: {filename}", ""
15 |
16 |
17 | def train_hypernetwork(*args):
18 | shared.loaded_hypernetworks = []
19 |
20 | assert not shared.cmd_opts.lowvram, 'Training models with lowvram is not possible'
21 |
22 | try:
23 | sd_hijack.undo_optimizations()
24 |
25 | hypernetwork, filename = modules.hypernetworks.hypernetwork.train_hypernetwork(*args)
26 |
27 | res = f"""
28 | Training {'interrupted' if shared.state.interrupted else 'finished'} at {hypernetwork.step} steps.
29 | Hypernetwork saved to {html.escape(filename)}
30 | """
31 | return res, ""
32 | except Exception:
33 | raise
34 | finally:
35 | shared.sd_model.cond_stage_model.to(devices.device)
36 | shared.sd_model.first_stage_model.to(devices.device)
37 | sd_hijack.apply_optimizations()
38 |
39 |
--------------------------------------------------------------------------------
/ragdoll-studio/stable-diffusion-api/modules/import_hook.py:
--------------------------------------------------------------------------------
1 | import sys
2 |
3 | # this will break any attempt to import xformers which will prevent stability diffusion repo from trying to use it
4 | if "--xformers" not in "".join(sys.argv):
5 | sys.modules["xformers"] = None
6 |
7 | # Hack to fix a changed import in torchvision 0.17+, which otherwise breaks
8 | # basicsr; see https://github.com/AUTOMATIC1111/stable-diffusion-webui/issues/13985
9 | try:
10 | import torchvision.transforms.functional_tensor # noqa: F401
11 | except ImportError:
12 | try:
13 | import torchvision.transforms.functional as functional
14 | sys.modules["torchvision.transforms.functional_tensor"] = functional
15 | except ImportError:
16 | pass # shrug...
17 |
--------------------------------------------------------------------------------
/ragdoll-studio/stable-diffusion-api/modules/infotext_versions.py:
--------------------------------------------------------------------------------
1 | from modules import shared
2 | from packaging import version
3 | import re
4 |
5 |
6 | v160 = version.parse("1.6.0")
7 | v170_tsnr = version.parse("v1.7.0-225")
8 | v180 = version.parse("1.8.0")
9 | v180_hr_styles = version.parse("1.8.0-139")
10 |
11 |
12 | def parse_version(text):
13 | if text is None:
14 | return None
15 |
16 | m = re.match(r'([^-]+-[^-]+)-.*', text)
17 | if m:
18 | text = m.group(1)
19 |
20 | try:
21 | return version.parse(text)
22 | except Exception:
23 | return None
24 |
25 |
26 | def backcompat(d):
27 | """Checks infotext Version field, and enables backwards compatibility options according to it."""
28 |
29 | if not shared.opts.auto_backcompat:
30 | return
31 |
32 | ver = parse_version(d.get("Version"))
33 | if ver is None:
34 | return
35 |
36 | if ver < v160 and '[' in d.get('Prompt', ''):
37 | d["Old prompt editing timelines"] = True
38 |
39 | if ver < v160 and d.get('Sampler', '') in ('DDIM', 'PLMS'):
40 | d["Pad conds v0"] = True
41 |
42 | if ver < v170_tsnr:
43 | d["Downcast alphas_cumprod"] = True
44 |
45 | if ver < v180 and d.get('Refiner'):
46 | d["Refiner switch by sampling steps"] = True
47 |
--------------------------------------------------------------------------------
/ragdoll-studio/stable-diffusion-api/modules/localization.py:
--------------------------------------------------------------------------------
1 | import json
2 | import os
3 |
4 | from modules import errors, scripts
5 |
6 | localizations = {}
7 |
8 |
9 | def list_localizations(dirname):
10 | localizations.clear()
11 |
12 | for file in os.listdir(dirname):
13 | fn, ext = os.path.splitext(file)
14 | if ext.lower() != ".json":
15 | continue
16 |
17 | localizations[fn] = [os.path.join(dirname, file)]
18 |
19 | for file in scripts.list_scripts("localizations", ".json"):
20 | fn, ext = os.path.splitext(file.filename)
21 | if fn not in localizations:
22 | localizations[fn] = []
23 | localizations[fn].append(file.path)
24 |
25 |
26 | def localization_js(current_localization_name: str) -> str:
27 | fns = localizations.get(current_localization_name, None)
28 | data = {}
29 | if fns is not None:
30 | for fn in fns:
31 | try:
32 | with open(fn, "r", encoding="utf8") as file:
33 | data.update(json.load(file))
34 | except Exception:
35 | errors.report(f"Error loading localization from {fn}", exc_info=True)
36 |
37 | return f"window.localization = {json.dumps(data)}"
38 |
--------------------------------------------------------------------------------
/ragdoll-studio/stable-diffusion-api/modules/models/diffusion/uni_pc/__init__.py:
--------------------------------------------------------------------------------
1 | from .sampler import UniPCSampler # noqa: F401
2 |
--------------------------------------------------------------------------------
/ragdoll-studio/stable-diffusion-api/modules/ngrok.py:
--------------------------------------------------------------------------------
1 | import ngrok
2 |
3 | # Connect to ngrok for ingress
4 | def connect(token, port, options):
5 | account = None
6 | if token is None:
7 | token = 'None'
8 | else:
9 | if ':' in token:
10 | # token = authtoken:username:password
11 | token, username, password = token.split(':', 2)
12 | account = f"{username}:{password}"
13 |
14 | # For all options see: https://github.com/ngrok/ngrok-py/blob/main/examples/ngrok-connect-full.py
15 | if not options.get('authtoken_from_env'):
16 | options['authtoken'] = token
17 | if account:
18 | options['basic_auth'] = account
19 | if not options.get('session_metadata'):
20 | options['session_metadata'] = 'stable-diffusion-webui'
21 |
22 |
23 | try:
24 | public_url = ngrok.connect(f"127.0.0.1:{port}", **options).url()
25 | except Exception as e:
26 | print(f'Invalid ngrok authtoken? ngrok connection aborted due to: {e}\n'
27 | f'Your token: {token}, get the right one on https://dashboard.ngrok.com/get-started/your-authtoken')
28 | else:
29 | print(f'ngrok connected to localhost:{port}! URL: {public_url}\n'
30 | 'You can use this link after the launch is complete.')
31 |
--------------------------------------------------------------------------------
/ragdoll-studio/stable-diffusion-api/modules/npu_specific.py:
--------------------------------------------------------------------------------
1 | import importlib
2 | import torch
3 |
4 | from modules import shared
5 |
6 |
7 | def check_for_npu():
8 | if importlib.util.find_spec("torch_npu") is None:
9 | return False
10 | import torch_npu
11 |
12 | try:
13 | # Will raise a RuntimeError if no NPU is found
14 | _ = torch_npu.npu.device_count()
15 | return torch.npu.is_available()
16 | except RuntimeError:
17 | return False
18 |
19 |
20 | def get_npu_device_string():
21 | if shared.cmd_opts.device_id is not None:
22 | return f"npu:{shared.cmd_opts.device_id}"
23 | return "npu:0"
24 |
25 |
26 | def torch_npu_gc():
27 | with torch.npu.device(get_npu_device_string()):
28 | torch.npu.empty_cache()
29 |
30 |
31 | has_npu = check_for_npu()
32 |
--------------------------------------------------------------------------------
/ragdoll-studio/stable-diffusion-api/modules/paths_internal.py:
--------------------------------------------------------------------------------
1 | """this module defines internal paths used by program and is safe to import before dependencies are installed in launch.py"""
2 |
3 | import argparse
4 | import os
5 | import sys
6 | import shlex
7 | from pathlib import Path
8 |
9 |
10 | normalized_filepath = lambda filepath: str(Path(filepath).absolute())
11 |
12 | commandline_args = os.environ.get('COMMANDLINE_ARGS', "")
13 | sys.argv += shlex.split(commandline_args)
14 |
15 | cwd = os.getcwd()
16 | modules_path = os.path.dirname(os.path.realpath(__file__))
17 | script_path = os.path.dirname(modules_path)
18 |
19 | sd_configs_path = os.path.join(script_path, "configs")
20 | sd_default_config = os.path.join(sd_configs_path, "v1-inference.yaml")
21 | sd_model_file = os.path.join(script_path, 'model.ckpt')
22 | default_sd_model_file = sd_model_file
23 |
24 | # Parse the --data-dir flag first so we can use it as a base for our other argument default values
25 | parser_pre = argparse.ArgumentParser(add_help=False)
26 | parser_pre.add_argument("--data-dir", type=str, default=os.path.dirname(modules_path), help="base path where all user data is stored", )
27 | cmd_opts_pre = parser_pre.parse_known_args()[0]
28 |
29 | data_path = cmd_opts_pre.data_dir
30 |
31 | models_path = os.path.join(data_path, "models")
32 | extensions_dir = os.path.join(data_path, "extensions")
33 | extensions_builtin_dir = os.path.join(script_path, "extensions-builtin")
34 | config_states_dir = os.path.join(script_path, "config_states")
35 | default_output_dir = os.path.join(data_path, "outputs")
36 |
37 | roboto_ttf_file = os.path.join(modules_path, 'Roboto-Regular.ttf')
38 |
--------------------------------------------------------------------------------
/ragdoll-studio/stable-diffusion-api/modules/restart.py:
--------------------------------------------------------------------------------
1 | import os
2 | from pathlib import Path
3 |
4 | from modules.paths_internal import script_path
5 |
6 |
7 | def is_restartable() -> bool:
8 | """
9 | Return True if the webui is restartable (i.e. there is something watching to restart it with)
10 | """
11 | return bool(os.environ.get('SD_WEBUI_RESTART'))
12 |
13 |
14 | def restart_program() -> None:
15 | """creates file tmp/restart and immediately stops the process, which webui.bat/webui.sh interpret as a command to start webui again"""
16 |
17 | tmpdir = Path(script_path) / "tmp"
18 | tmpdir.mkdir(parents=True, exist_ok=True)
19 | (tmpdir / "restart").touch()
20 |
21 | stop_program()
22 |
23 |
24 | def stop_program() -> None:
25 | os._exit(0)
26 |
--------------------------------------------------------------------------------
/ragdoll-studio/stable-diffusion-api/modules/script_loading.py:
--------------------------------------------------------------------------------
1 | import os
2 | import importlib.util
3 |
4 | from modules import errors
5 |
6 |
7 | loaded_scripts = {}
8 |
9 |
10 | def load_module(path):
11 | module_spec = importlib.util.spec_from_file_location(os.path.basename(path), path)
12 | module = importlib.util.module_from_spec(module_spec)
13 | module_spec.loader.exec_module(module)
14 |
15 | loaded_scripts[path] = module
16 | return module
17 |
18 |
19 | def preload_extensions(extensions_dir, parser, extension_list=None):
20 | if not os.path.isdir(extensions_dir):
21 | return
22 |
23 | extensions = extension_list if extension_list is not None else os.listdir(extensions_dir)
24 | for dirname in sorted(extensions):
25 | preload_script = os.path.join(extensions_dir, dirname, "preload.py")
26 | if not os.path.isfile(preload_script):
27 | continue
28 |
29 | try:
30 | module = load_module(preload_script)
31 | if hasattr(module, 'preload'):
32 | module.preload(parser)
33 |
34 | except Exception:
35 | errors.report(f"Error running preload() for {preload_script}", exc_info=True)
36 |
--------------------------------------------------------------------------------
/ragdoll-studio/stable-diffusion-api/modules/sd_hijack_checkpoint.py:
--------------------------------------------------------------------------------
1 | from torch.utils.checkpoint import checkpoint
2 |
3 | import ldm.modules.attention
4 | import ldm.modules.diffusionmodules.openaimodel
5 |
6 |
7 | def BasicTransformerBlock_forward(self, x, context=None):
8 | return checkpoint(self._forward, x, context)
9 |
10 |
11 | def AttentionBlock_forward(self, x):
12 | return checkpoint(self._forward, x)
13 |
14 |
15 | def ResBlock_forward(self, x, emb):
16 | return checkpoint(self._forward, x, emb)
17 |
18 |
19 | stored = []
20 |
21 |
22 | def add():
23 | if len(stored) != 0:
24 | return
25 |
26 | stored.extend([
27 | ldm.modules.attention.BasicTransformerBlock.forward,
28 | ldm.modules.diffusionmodules.openaimodel.ResBlock.forward,
29 | ldm.modules.diffusionmodules.openaimodel.AttentionBlock.forward
30 | ])
31 |
32 | ldm.modules.attention.BasicTransformerBlock.forward = BasicTransformerBlock_forward
33 | ldm.modules.diffusionmodules.openaimodel.ResBlock.forward = ResBlock_forward
34 | ldm.modules.diffusionmodules.openaimodel.AttentionBlock.forward = AttentionBlock_forward
35 |
36 |
37 | def remove():
38 | if len(stored) == 0:
39 | return
40 |
41 | ldm.modules.attention.BasicTransformerBlock.forward = stored[0]
42 | ldm.modules.diffusionmodules.openaimodel.ResBlock.forward = stored[1]
43 | ldm.modules.diffusionmodules.openaimodel.AttentionBlock.forward = stored[2]
44 |
45 | stored.clear()
46 |
47 |
--------------------------------------------------------------------------------
/ragdoll-studio/stable-diffusion-api/modules/sd_hijack_ip2p.py:
--------------------------------------------------------------------------------
1 | import os.path
2 |
3 |
4 | def should_hijack_ip2p(checkpoint_info):
5 | from modules import sd_models_config
6 |
7 | ckpt_basename = os.path.basename(checkpoint_info.filename).lower()
8 | cfg_basename = os.path.basename(sd_models_config.find_checkpoint_config_near_filename(checkpoint_info)).lower()
9 |
10 | return "pix2pix" in ckpt_basename and "pix2pix" not in cfg_basename
11 |
--------------------------------------------------------------------------------
/ragdoll-studio/stable-diffusion-api/modules/sd_hijack_utils.py:
--------------------------------------------------------------------------------
1 | import importlib
2 |
3 | class CondFunc:
4 | def __new__(cls, orig_func, sub_func, cond_func):
5 | self = super(CondFunc, cls).__new__(cls)
6 | if isinstance(orig_func, str):
7 | func_path = orig_func.split('.')
8 | for i in range(len(func_path)-1, -1, -1):
9 | try:
10 | resolved_obj = importlib.import_module('.'.join(func_path[:i]))
11 | break
12 | except ImportError:
13 | pass
14 | try:
15 | for attr_name in func_path[i:-1]:
16 | resolved_obj = getattr(resolved_obj, attr_name)
17 | orig_func = getattr(resolved_obj, func_path[-1])
18 | setattr(resolved_obj, func_path[-1], lambda *args, **kwargs: self(*args, **kwargs))
19 | except AttributeError:
20 | print(f"Warning: Failed to resolve {orig_func} for CondFunc hijack")
21 | pass
22 | self.__init__(orig_func, sub_func, cond_func)
23 | return lambda *args, **kwargs: self(*args, **kwargs)
24 | def __init__(self, orig_func, sub_func, cond_func):
25 | self.__orig_func = orig_func
26 | self.__sub_func = sub_func
27 | self.__cond_func = cond_func
28 | def __call__(self, *args, **kwargs):
29 | if not self.__cond_func or self.__cond_func(self.__orig_func, *args, **kwargs):
30 | return self.__sub_func(self.__orig_func, *args, **kwargs)
31 | else:
32 | return self.__orig_func(*args, **kwargs)
33 |
--------------------------------------------------------------------------------
/ragdoll-studio/stable-diffusion-api/modules/sd_hijack_xlmr.py:
--------------------------------------------------------------------------------
1 | import torch
2 |
3 | from modules import sd_hijack_clip, devices
4 |
5 |
6 | class FrozenXLMREmbedderWithCustomWords(sd_hijack_clip.FrozenCLIPEmbedderWithCustomWords):
7 | def __init__(self, wrapped, hijack):
8 | super().__init__(wrapped, hijack)
9 |
10 | self.id_start = wrapped.config.bos_token_id
11 | self.id_end = wrapped.config.eos_token_id
12 | self.id_pad = wrapped.config.pad_token_id
13 |
14 | self.comma_token = self.tokenizer.get_vocab().get(',', None) # alt diffusion doesn't have bits for comma
15 |
16 | def encode_with_transformers(self, tokens):
17 | # there's no CLIP Skip here because all hidden layers have size of 1024 and the last one uses a
18 | # trained layer to transform those 1024 into 768 for unet; so you can't choose which transformer
19 | # layer to work with - you have to use the last
20 |
21 | attention_mask = (tokens != self.id_pad).to(device=tokens.device, dtype=torch.int64)
22 | features = self.wrapped(input_ids=tokens, attention_mask=attention_mask)
23 | z = features['projection_state']
24 |
25 | return z
26 |
27 | def encode_embedding_init_text(self, init_text, nvpt):
28 | embedding_layer = self.wrapped.roberta.embeddings
29 | ids = self.wrapped.tokenizer(init_text, max_length=nvpt, return_tensors="pt", add_special_tokens=False)["input_ids"]
30 | embedded = embedding_layer.token_embedding.wrapped(ids.to(devices.device)).squeeze(0)
31 |
32 | return embedded
33 |
--------------------------------------------------------------------------------
/ragdoll-studio/stable-diffusion-api/modules/sd_models_types.py:
--------------------------------------------------------------------------------
1 | from ldm.models.diffusion.ddpm import LatentDiffusion
2 | from typing import TYPE_CHECKING
3 |
4 |
5 | if TYPE_CHECKING:
6 | from modules.sd_models import CheckpointInfo
7 |
8 |
9 | class WebuiSdModel(LatentDiffusion):
10 | """This class is not actually instantinated, but its fields are created and fieeld by webui"""
11 |
12 | lowvram: bool
13 | """True if lowvram/medvram optimizations are enabled -- see modules.lowvram for more info"""
14 |
15 | sd_model_hash: str
16 | """short hash, 10 first characters of SHA1 hash of the model file; may be None if --no-hashing flag is used"""
17 |
18 | sd_model_checkpoint: str
19 | """path to the file on disk that model weights were obtained from"""
20 |
21 | sd_checkpoint_info: 'CheckpointInfo'
22 | """structure with additional information about the file with model's weights"""
23 |
24 | is_sdxl: bool
25 | """True if the model's architecture is SDXL or SSD"""
26 |
27 | is_ssd: bool
28 | """True if the model is SSD"""
29 |
30 | is_sd2: bool
31 | """True if the model's architecture is SD 2.x"""
32 |
33 | is_sd1: bool
34 | """True if the model's architecture is SD 1.x"""
35 |
--------------------------------------------------------------------------------
/ragdoll-studio/stable-diffusion-api/modules/sd_samplers_compvis.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bennyschmidt/ragdoll-studio/a95ed0558db0a6f6a8f7781b24d6bfab79ec6388/ragdoll-studio/stable-diffusion-api/modules/sd_samplers_compvis.py
--------------------------------------------------------------------------------
/ragdoll-studio/stable-diffusion-api/modules/sd_schedulers.py:
--------------------------------------------------------------------------------
1 | import dataclasses
2 |
3 | import torch
4 |
5 | import k_diffusion
6 |
7 |
8 | @dataclasses.dataclass
9 | class Scheduler:
10 | name: str
11 | label: str
12 | function: any
13 |
14 | default_rho: float = -1
15 | need_inner_model: bool = False
16 | aliases: list = None
17 |
18 |
19 | def uniform(n, sigma_min, sigma_max, inner_model, device):
20 | return inner_model.get_sigmas(n)
21 |
22 |
23 | def sgm_uniform(n, sigma_min, sigma_max, inner_model, device):
24 | start = inner_model.sigma_to_t(torch.tensor(sigma_max))
25 | end = inner_model.sigma_to_t(torch.tensor(sigma_min))
26 | sigs = [
27 | inner_model.t_to_sigma(ts)
28 | for ts in torch.linspace(start, end, n + 1)[:-1]
29 | ]
30 | sigs += [0.0]
31 | return torch.FloatTensor(sigs).to(device)
32 |
33 |
34 | schedulers = [
35 | Scheduler('automatic', 'Automatic', None),
36 | Scheduler('uniform', 'Uniform', uniform, need_inner_model=True),
37 | Scheduler('karras', 'Karras', k_diffusion.sampling.get_sigmas_karras, default_rho=7.0),
38 | Scheduler('exponential', 'Exponential', k_diffusion.sampling.get_sigmas_exponential),
39 | Scheduler('polyexponential', 'Polyexponential', k_diffusion.sampling.get_sigmas_polyexponential, default_rho=1.0),
40 | Scheduler('sgm_uniform', 'SGM Uniform', sgm_uniform, need_inner_model=True, aliases=["SGMUniform"]),
41 | ]
42 |
43 | schedulers_map = {**{x.name: x for x in schedulers}, **{x.label: x for x in schedulers}}
44 |
--------------------------------------------------------------------------------
/ragdoll-studio/stable-diffusion-api/modules/shared_cmd_options.py:
--------------------------------------------------------------------------------
1 | import os
2 |
3 | import launch
4 | from modules import cmd_args, script_loading
5 | from modules.paths_internal import models_path, script_path, data_path, sd_configs_path, sd_default_config, sd_model_file, default_sd_model_file, extensions_dir, extensions_builtin_dir # noqa: F401
6 |
7 | parser = cmd_args.parser
8 |
9 | script_loading.preload_extensions(extensions_dir, parser, extension_list=launch.list_extensions(launch.args.ui_settings_file))
10 | script_loading.preload_extensions(extensions_builtin_dir, parser)
11 |
12 | if os.environ.get('IGNORE_CMD_ARGS_ERRORS', None) is None:
13 | cmd_opts = parser.parse_args()
14 | else:
15 | cmd_opts, _ = parser.parse_known_args()
16 |
17 | cmd_opts.webui_is_non_local = any([cmd_opts.share, cmd_opts.listen, cmd_opts.ngrok, cmd_opts.server_name])
18 | cmd_opts.disable_extension_access = cmd_opts.webui_is_non_local and not cmd_opts.enable_insecure_extension_access
19 |
--------------------------------------------------------------------------------
/ragdoll-studio/stable-diffusion-api/modules/shared_total_tqdm.py:
--------------------------------------------------------------------------------
1 | import tqdm
2 |
3 | from modules import shared
4 |
5 |
6 | class TotalTQDM:
7 | def __init__(self):
8 | self._tqdm = None
9 |
10 | def reset(self):
11 | self._tqdm = tqdm.tqdm(
12 | desc="Total progress",
13 | total=shared.state.job_count * shared.state.sampling_steps,
14 | position=1,
15 | file=shared.progress_print_out
16 | )
17 |
18 | def update(self):
19 | if not shared.opts.multiple_tqdm or shared.cmd_opts.disable_console_progressbars:
20 | return
21 | if self._tqdm is None:
22 | self.reset()
23 | self._tqdm.update()
24 |
25 | def updateTotal(self, new_total):
26 | if not shared.opts.multiple_tqdm or shared.cmd_opts.disable_console_progressbars:
27 | return
28 | if self._tqdm is None:
29 | self.reset()
30 | self._tqdm.total = new_total
31 |
32 | def clear(self):
33 | if self._tqdm is not None:
34 | self._tqdm.refresh()
35 | self._tqdm.close()
36 | self._tqdm = None
37 |
38 |
--------------------------------------------------------------------------------
/ragdoll-studio/stable-diffusion-api/modules/textual_inversion/test_embedding.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bennyschmidt/ragdoll-studio/a95ed0558db0a6f6a8f7781b24d6bfab79ec6388/ragdoll-studio/stable-diffusion-api/modules/textual_inversion/test_embedding.png
--------------------------------------------------------------------------------
/ragdoll-studio/stable-diffusion-api/modules/textual_inversion/ui.py:
--------------------------------------------------------------------------------
1 | import html
2 |
3 | import gradio as gr
4 |
5 | import modules.textual_inversion.textual_inversion
6 | from modules import sd_hijack, shared
7 |
8 |
9 | def create_embedding(name, initialization_text, nvpt, overwrite_old):
10 | filename = modules.textual_inversion.textual_inversion.create_embedding(name, nvpt, overwrite_old, init_text=initialization_text)
11 |
12 | sd_hijack.model_hijack.embedding_db.load_textual_inversion_embeddings()
13 |
14 | return gr.Dropdown.update(choices=sorted(sd_hijack.model_hijack.embedding_db.word_embeddings.keys())), f"Created: {filename}", ""
15 |
16 |
17 | def train_embedding(*args):
18 |
19 | assert not shared.cmd_opts.lowvram, 'Training models with lowvram not possible'
20 |
21 | apply_optimizations = shared.opts.training_xattention_optimizations
22 | try:
23 | if not apply_optimizations:
24 | sd_hijack.undo_optimizations()
25 |
26 | embedding, filename = modules.textual_inversion.textual_inversion.train_embedding(*args)
27 |
28 | res = f"""
29 | Training {'interrupted' if shared.state.interrupted else 'finished'} at {embedding.step} steps.
30 | Embedding saved to {html.escape(filename)}
31 | """
32 | return res, ""
33 | except Exception:
34 | raise
35 | finally:
36 | if not apply_optimizations:
37 | sd_hijack.apply_optimizations()
38 |
39 |
--------------------------------------------------------------------------------
/ragdoll-studio/stable-diffusion-api/modules/torch_utils.py:
--------------------------------------------------------------------------------
1 | from __future__ import annotations
2 |
3 | import torch.nn
4 |
5 |
6 | def get_param(model) -> torch.nn.Parameter:
7 | """
8 | Find the first parameter in a model or module.
9 | """
10 | if hasattr(model, "model") and hasattr(model.model, "parameters"):
11 | # Unpeel a model descriptor to get at the actual Torch module.
12 | model = model.model
13 |
14 | for param in model.parameters():
15 | return param
16 |
17 | raise ValueError(f"No parameters found in model {model!r}")
18 |
--------------------------------------------------------------------------------
/ragdoll-studio/stable-diffusion-api/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "stable-diffusion-webui",
3 | "version": "0.0.0",
4 | "devDependencies": {
5 | "eslint": "^8.40.0"
6 | },
7 | "scripts": {
8 | "lint": "eslint .",
9 | "fix": "eslint --fix ."
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/ragdoll-studio/stable-diffusion-api/pyproject.toml:
--------------------------------------------------------------------------------
1 | [tool.ruff]
2 |
3 | target-version = "py39"
4 |
5 | [tool.ruff.lint]
6 |
7 | extend-select = [
8 | "B",
9 | "C",
10 | "I",
11 | "W",
12 | ]
13 |
14 | exclude = [
15 | "extensions",
16 | "extensions-disabled",
17 | ]
18 |
19 | ignore = [
20 | "E501", # Line too long
21 | "E721", # Do not compare types, use `isinstance`
22 | "E731", # Do not assign a `lambda` expression, use a `def`
23 |
24 | "I001", # Import block is un-sorted or un-formatted
25 | "C901", # Function is too complex
26 | "C408", # Rewrite as a literal
27 | "W605", # invalid escape sequence, messes with some docstrings
28 | ]
29 |
30 | [tool.ruff.lint.per-file-ignores]
31 | "webui.py" = ["E402"] # Module level import not at top of file
32 |
33 | [tool.ruff.lint.flake8-bugbear]
34 | # Allow default arguments like, e.g., `data: List[str] = fastapi.Query(None)`.
35 | extend-immutable-calls = ["fastapi.Depends", "fastapi.security.HTTPBasic"]
36 |
37 | [tool.pytest.ini_options]
38 | base_url = "http://127.0.0.1:7860"
39 |
--------------------------------------------------------------------------------
/ragdoll-studio/stable-diffusion-api/requirements-test.txt:
--------------------------------------------------------------------------------
1 | pytest-base-url~=2.0
2 | pytest-cov~=4.0
3 | pytest~=7.3
4 |
--------------------------------------------------------------------------------
/ragdoll-studio/stable-diffusion-api/requirements.txt:
--------------------------------------------------------------------------------
1 | GitPython
2 | Pillow
3 | accelerate
4 |
5 | blendmodes
6 | clean-fid
7 | diskcache
8 | einops
9 | facexlib
10 | fastapi>=0.90.1
11 | gradio==3.41.2
12 | inflection
13 | jsonmerge
14 | kornia
15 | lark
16 | numpy
17 | omegaconf
18 | open-clip-torch
19 |
20 | piexif
21 | psutil
22 | pytorch_lightning
23 | requests
24 | resize-right
25 |
26 | safetensors
27 | scikit-image>=0.19
28 | tomesd
29 | torch
30 | torchdiffeq
31 | torchsde
32 | transformers==4.30.2
33 | pillow-avif-plugin==1.4.3
--------------------------------------------------------------------------------
/ragdoll-studio/stable-diffusion-api/requirements_npu.txt:
--------------------------------------------------------------------------------
1 | cloudpickle
2 | decorator
3 | synr==0.5.0
4 | tornado
5 |
--------------------------------------------------------------------------------
/ragdoll-studio/stable-diffusion-api/requirements_versions.txt:
--------------------------------------------------------------------------------
1 | GitPython==3.1.32
2 | Pillow==9.5.0
3 | accelerate==0.21.0
4 | blendmodes==2022
5 | clean-fid==0.1.35
6 | diskcache==5.6.3
7 | einops==0.4.1
8 | facexlib==0.3.0
9 | fastapi==0.94.0
10 | gradio==3.41.2
11 | httpcore==0.15
12 | inflection==0.5.1
13 | jsonmerge==1.8.0
14 | kornia==0.6.7
15 | lark==1.1.2
16 | numpy==1.26.2
17 | omegaconf==2.2.3
18 | open-clip-torch==2.20.0
19 | piexif==1.1.3
20 | psutil==5.9.5
21 | pytorch_lightning==1.9.4
22 | resize-right==0.0.2
23 | safetensors==0.4.2
24 | scikit-image==0.21.0
25 | spandrel==0.1.6
26 | tomesd==0.1.3
27 | torch
28 | torchdiffeq==0.2.3
29 | torchsde==0.2.6
30 | transformers==4.30.2
31 | httpx==0.24.1
32 | pillow-avif-plugin==1.4.3
33 |
--------------------------------------------------------------------------------
/ragdoll-studio/stable-diffusion-api/screenshot.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bennyschmidt/ragdoll-studio/a95ed0558db0a6f6a8f7781b24d6bfab79ec6388/ragdoll-studio/stable-diffusion-api/screenshot.png
--------------------------------------------------------------------------------
/ragdoll-studio/stable-diffusion-api/scripts/postprocessing_gfpgan.py:
--------------------------------------------------------------------------------
1 | from PIL import Image
2 | import numpy as np
3 |
4 | from modules import scripts_postprocessing, gfpgan_model, ui_components
5 | import gradio as gr
6 |
7 |
8 | class ScriptPostprocessingGfpGan(scripts_postprocessing.ScriptPostprocessing):
9 | name = "GFPGAN"
10 | order = 2000
11 |
12 | def ui(self):
13 | with ui_components.InputAccordion(False, label="GFPGAN") as enable:
14 | gfpgan_visibility = gr.Slider(minimum=0.0, maximum=1.0, step=0.001, label="Visibility", value=1.0, elem_id="extras_gfpgan_visibility")
15 |
16 | return {
17 | "enable": enable,
18 | "gfpgan_visibility": gfpgan_visibility,
19 | }
20 |
21 | def process(self, pp: scripts_postprocessing.PostprocessedImage, enable, gfpgan_visibility):
22 | if gfpgan_visibility == 0 or not enable:
23 | return
24 |
25 | restored_img = gfpgan_model.gfpgan_fix_faces(np.array(pp.image.convert("RGB"), dtype=np.uint8))
26 | res = Image.fromarray(restored_img)
27 |
28 | if gfpgan_visibility < 1.0:
29 | res = Image.blend(pp.image, res, gfpgan_visibility)
30 |
31 | pp.image = res
32 | pp.info["GFPGAN visibility"] = round(gfpgan_visibility, 3)
33 |
--------------------------------------------------------------------------------
/ragdoll-studio/stable-diffusion-api/test/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bennyschmidt/ragdoll-studio/a95ed0558db0a6f6a8f7781b24d6bfab79ec6388/ragdoll-studio/stable-diffusion-api/test/__init__.py
--------------------------------------------------------------------------------
/ragdoll-studio/stable-diffusion-api/test/conftest.py:
--------------------------------------------------------------------------------
1 | import base64
2 | import os
3 |
4 | import pytest
5 |
6 | test_files_path = os.path.dirname(__file__) + "/test_files"
7 | test_outputs_path = os.path.dirname(__file__) + "/test_outputs"
8 |
9 |
10 | def pytest_configure(config):
11 | # We don't want to fail on Py.test command line arguments being
12 | # parsed by webui:
13 | os.environ.setdefault("IGNORE_CMD_ARGS_ERRORS", "1")
14 |
15 |
16 | def file_to_base64(filename):
17 | with open(filename, "rb") as file:
18 | data = file.read()
19 |
20 | base64_str = str(base64.b64encode(data), "utf-8")
21 | return "data:image/png;base64," + base64_str
22 |
23 |
24 | @pytest.fixture(scope="session") # session so we don't read this over and over
25 | def img2img_basic_image_base64() -> str:
26 | return file_to_base64(os.path.join(test_files_path, "img2img_basic.png"))
27 |
28 |
29 | @pytest.fixture(scope="session") # session so we don't read this over and over
30 | def mask_basic_image_base64() -> str:
31 | return file_to_base64(os.path.join(test_files_path, "mask_basic.png"))
32 |
33 |
34 | @pytest.fixture(scope="session")
35 | def initialize() -> None:
36 | import webui # noqa: F401
37 |
--------------------------------------------------------------------------------
/ragdoll-studio/stable-diffusion-api/test/test_extras.py:
--------------------------------------------------------------------------------
1 | import requests
2 |
3 |
4 | def test_simple_upscaling_performed(base_url, img2img_basic_image_base64):
5 | payload = {
6 | "resize_mode": 0,
7 | "show_extras_results": True,
8 | "gfpgan_visibility": 0,
9 | "codeformer_visibility": 0,
10 | "codeformer_weight": 0,
11 | "upscaling_resize": 2,
12 | "upscaling_resize_w": 128,
13 | "upscaling_resize_h": 128,
14 | "upscaling_crop": True,
15 | "upscaler_1": "Lanczos",
16 | "upscaler_2": "None",
17 | "extras_upscaler_2_visibility": 0,
18 | "image": img2img_basic_image_base64,
19 | }
20 | assert requests.post(f"{base_url}/sdapi/v1/extra-single-image", json=payload).status_code == 200
21 |
22 |
23 | def test_png_info_performed(base_url, img2img_basic_image_base64):
24 | payload = {
25 | "image": img2img_basic_image_base64,
26 | }
27 | assert requests.post(f"{base_url}/sdapi/v1/extra-single-image", json=payload).status_code == 200
28 |
29 |
30 | def test_interrogate_performed(base_url, img2img_basic_image_base64):
31 | payload = {
32 | "image": img2img_basic_image_base64,
33 | "model": "clip",
34 | }
35 | assert requests.post(f"{base_url}/sdapi/v1/extra-single-image", json=payload).status_code == 200
36 |
--------------------------------------------------------------------------------
/ragdoll-studio/stable-diffusion-api/test/test_face_restorers.py:
--------------------------------------------------------------------------------
1 | import os
2 | from test.conftest import test_files_path, test_outputs_path
3 |
4 | import numpy as np
5 | import pytest
6 | from PIL import Image
7 |
8 |
9 | @pytest.mark.usefixtures("initialize")
10 | @pytest.mark.parametrize("restorer_name", ["gfpgan", "codeformer"])
11 | def test_face_restorers(restorer_name):
12 | from modules import shared
13 |
14 | if restorer_name == "gfpgan":
15 | from modules import gfpgan_model
16 | gfpgan_model.setup_model(shared.cmd_opts.gfpgan_models_path)
17 | restorer = gfpgan_model.gfpgan_fix_faces
18 | elif restorer_name == "codeformer":
19 | from modules import codeformer_model
20 | codeformer_model.setup_model(shared.cmd_opts.codeformer_models_path)
21 | restorer = codeformer_model.codeformer.restore
22 | else:
23 | raise NotImplementedError("...")
24 | img = Image.open(os.path.join(test_files_path, "two-faces.jpg"))
25 | np_img = np.array(img, dtype=np.uint8)
26 | fixed_image = restorer(np_img)
27 | assert fixed_image.shape == np_img.shape
28 | assert not np.allclose(fixed_image, np_img) # should have visibly changed
29 | Image.fromarray(fixed_image).save(os.path.join(test_outputs_path, f"{restorer_name}.png"))
30 |
--------------------------------------------------------------------------------
/ragdoll-studio/stable-diffusion-api/test/test_files/empty.pt:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bennyschmidt/ragdoll-studio/a95ed0558db0a6f6a8f7781b24d6bfab79ec6388/ragdoll-studio/stable-diffusion-api/test/test_files/empty.pt
--------------------------------------------------------------------------------
/ragdoll-studio/stable-diffusion-api/test/test_files/img2img_basic.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bennyschmidt/ragdoll-studio/a95ed0558db0a6f6a8f7781b24d6bfab79ec6388/ragdoll-studio/stable-diffusion-api/test/test_files/img2img_basic.png
--------------------------------------------------------------------------------
/ragdoll-studio/stable-diffusion-api/test/test_files/mask_basic.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bennyschmidt/ragdoll-studio/a95ed0558db0a6f6a8f7781b24d6bfab79ec6388/ragdoll-studio/stable-diffusion-api/test/test_files/mask_basic.png
--------------------------------------------------------------------------------
/ragdoll-studio/stable-diffusion-api/test/test_files/two-faces.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bennyschmidt/ragdoll-studio/a95ed0558db0a6f6a8f7781b24d6bfab79ec6388/ragdoll-studio/stable-diffusion-api/test/test_files/two-faces.jpg
--------------------------------------------------------------------------------
/ragdoll-studio/stable-diffusion-api/test/test_torch_utils.py:
--------------------------------------------------------------------------------
1 | import types
2 |
3 | import pytest
4 | import torch
5 |
6 | from modules import torch_utils
7 |
8 |
9 | @pytest.mark.parametrize("wrapped", [True, False])
10 | def test_get_param(wrapped):
11 | mod = torch.nn.Linear(1, 1)
12 | cpu = torch.device("cpu")
13 | mod.to(dtype=torch.float16, device=cpu)
14 | if wrapped:
15 | # more or less how spandrel wraps a thing
16 | mod = types.SimpleNamespace(model=mod)
17 | p = torch_utils.get_param(mod)
18 | assert p.dtype == torch.float16
19 | assert p.device == cpu
20 |
--------------------------------------------------------------------------------
/ragdoll-studio/stable-diffusion-api/test/test_utils.py:
--------------------------------------------------------------------------------
1 | import pytest
2 | import requests
3 |
4 |
5 | def test_options_write(base_url):
6 | url_options = f"{base_url}/sdapi/v1/options"
7 | response = requests.get(url_options)
8 | assert response.status_code == 200
9 |
10 | pre_value = response.json()["send_seed"]
11 |
12 | assert requests.post(url_options, json={'send_seed': (not pre_value)}).status_code == 200
13 |
14 | response = requests.get(url_options)
15 | assert response.status_code == 200
16 | assert response.json()['send_seed'] == (not pre_value)
17 |
18 | requests.post(url_options, json={"send_seed": pre_value})
19 |
20 |
21 | @pytest.mark.parametrize("url", [
22 | "sdapi/v1/cmd-flags",
23 | "sdapi/v1/samplers",
24 | "sdapi/v1/upscalers",
25 | "sdapi/v1/sd-models",
26 | "sdapi/v1/hypernetworks",
27 | "sdapi/v1/face-restorers",
28 | "sdapi/v1/realesrgan-models",
29 | "sdapi/v1/prompt-styles",
30 | "sdapi/v1/embeddings",
31 | ])
32 | def test_get_api_url(base_url, url):
33 | assert requests.get(f"{base_url}/{url}").status_code == 200
34 |
--------------------------------------------------------------------------------
/ragdoll-studio/stable-diffusion-api/textual_inversion_templates/hypernetwork.txt:
--------------------------------------------------------------------------------
1 | a photo of a [filewords]
2 | a rendering of a [filewords]
3 | a cropped photo of the [filewords]
4 | the photo of a [filewords]
5 | a photo of a clean [filewords]
6 | a photo of a dirty [filewords]
7 | a dark photo of the [filewords]
8 | a photo of my [filewords]
9 | a photo of the cool [filewords]
10 | a close-up photo of a [filewords]
11 | a bright photo of the [filewords]
12 | a cropped photo of a [filewords]
13 | a photo of the [filewords]
14 | a good photo of the [filewords]
15 | a photo of one [filewords]
16 | a close-up photo of the [filewords]
17 | a rendition of the [filewords]
18 | a photo of the clean [filewords]
19 | a rendition of a [filewords]
20 | a photo of a nice [filewords]
21 | a good photo of a [filewords]
22 | a photo of the nice [filewords]
23 | a photo of the small [filewords]
24 | a photo of the weird [filewords]
25 | a photo of the large [filewords]
26 | a photo of a cool [filewords]
27 | a photo of a small [filewords]
28 |
--------------------------------------------------------------------------------
/ragdoll-studio/stable-diffusion-api/textual_inversion_templates/none.txt:
--------------------------------------------------------------------------------
1 | picture
2 |
--------------------------------------------------------------------------------
/ragdoll-studio/stable-diffusion-api/textual_inversion_templates/style.txt:
--------------------------------------------------------------------------------
1 | a painting, art by [name]
2 | a rendering, art by [name]
3 | a cropped painting, art by [name]
4 | the painting, art by [name]
5 | a clean painting, art by [name]
6 | a dirty painting, art by [name]
7 | a dark painting, art by [name]
8 | a picture, art by [name]
9 | a cool painting, art by [name]
10 | a close-up painting, art by [name]
11 | a bright painting, art by [name]
12 | a cropped painting, art by [name]
13 | a good painting, art by [name]
14 | a close-up painting, art by [name]
15 | a rendition, art by [name]
16 | a nice painting, art by [name]
17 | a small painting, art by [name]
18 | a weird painting, art by [name]
19 | a large painting, art by [name]
20 |
--------------------------------------------------------------------------------
/ragdoll-studio/stable-diffusion-api/textual_inversion_templates/style_filewords.txt:
--------------------------------------------------------------------------------
1 | a painting of [filewords], art by [name]
2 | a rendering of [filewords], art by [name]
3 | a cropped painting of [filewords], art by [name]
4 | the painting of [filewords], art by [name]
5 | a clean painting of [filewords], art by [name]
6 | a dirty painting of [filewords], art by [name]
7 | a dark painting of [filewords], art by [name]
8 | a picture of [filewords], art by [name]
9 | a cool painting of [filewords], art by [name]
10 | a close-up painting of [filewords], art by [name]
11 | a bright painting of [filewords], art by [name]
12 | a cropped painting of [filewords], art by [name]
13 | a good painting of [filewords], art by [name]
14 | a close-up painting of [filewords], art by [name]
15 | a rendition of [filewords], art by [name]
16 | a nice painting of [filewords], art by [name]
17 | a small painting of [filewords], art by [name]
18 | a weird painting of [filewords], art by [name]
19 | a large painting of [filewords], art by [name]
20 |
--------------------------------------------------------------------------------
/ragdoll-studio/stable-diffusion-api/textual_inversion_templates/subject.txt:
--------------------------------------------------------------------------------
1 | a photo of a [name]
2 | a rendering of a [name]
3 | a cropped photo of the [name]
4 | the photo of a [name]
5 | a photo of a clean [name]
6 | a photo of a dirty [name]
7 | a dark photo of the [name]
8 | a photo of my [name]
9 | a photo of the cool [name]
10 | a close-up photo of a [name]
11 | a bright photo of the [name]
12 | a cropped photo of a [name]
13 | a photo of the [name]
14 | a good photo of the [name]
15 | a photo of one [name]
16 | a close-up photo of the [name]
17 | a rendition of the [name]
18 | a photo of the clean [name]
19 | a rendition of a [name]
20 | a photo of a nice [name]
21 | a good photo of a [name]
22 | a photo of the nice [name]
23 | a photo of the small [name]
24 | a photo of the weird [name]
25 | a photo of the large [name]
26 | a photo of a cool [name]
27 | a photo of a small [name]
28 |
--------------------------------------------------------------------------------
/ragdoll-studio/stable-diffusion-api/textual_inversion_templates/subject_filewords.txt:
--------------------------------------------------------------------------------
1 | a photo of a [name], [filewords]
2 | a rendering of a [name], [filewords]
3 | a cropped photo of the [name], [filewords]
4 | the photo of a [name], [filewords]
5 | a photo of a clean [name], [filewords]
6 | a photo of a dirty [name], [filewords]
7 | a dark photo of the [name], [filewords]
8 | a photo of my [name], [filewords]
9 | a photo of the cool [name], [filewords]
10 | a close-up photo of a [name], [filewords]
11 | a bright photo of the [name], [filewords]
12 | a cropped photo of a [name], [filewords]
13 | a photo of the [name], [filewords]
14 | a good photo of the [name], [filewords]
15 | a photo of one [name], [filewords]
16 | a close-up photo of the [name], [filewords]
17 | a rendition of the [name], [filewords]
18 | a photo of the clean [name], [filewords]
19 | a rendition of a [name], [filewords]
20 | a photo of a nice [name], [filewords]
21 | a good photo of a [name], [filewords]
22 | a photo of the nice [name], [filewords]
23 | a photo of the small [name], [filewords]
24 | a photo of the weird [name], [filewords]
25 | a photo of the large [name], [filewords]
26 | a photo of a cool [name], [filewords]
27 | a photo of a small [name], [filewords]
28 |
--------------------------------------------------------------------------------
/ragdoll-studio/stable-diffusion-api/webui-macos-env.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | ####################################################################
3 | # macOS defaults #
4 | # Please modify webui-user.sh to change these instead of this file #
5 | ####################################################################
6 |
7 | if [[ -x "$(command -v python3.10)" ]]
8 | then
9 | python_cmd="python3.10"
10 | fi
11 |
12 | export install_dir="$HOME"
13 | export COMMANDLINE_ARGS="--skip-torch-cuda-test --upcast-sampling --no-half-vae --use-cpu interrogate"
14 | export TORCH_COMMAND="pip install torch==2.1.0 torchvision==0.16.0"
15 | export PYTORCH_ENABLE_MPS_FALLBACK=1
16 |
17 | ####################################################################
18 |
--------------------------------------------------------------------------------
/ragdoll-studio/studio-api/.gitignore:
--------------------------------------------------------------------------------
1 | # directories
2 | /node_modules
3 | /.tmp
4 |
5 | # env
6 | .env
7 |
--------------------------------------------------------------------------------
/ragdoll-studio/studio-api/.nvmrc:
--------------------------------------------------------------------------------
1 | 20.11.1
--------------------------------------------------------------------------------
/ragdoll-studio/studio-api/README.md:
--------------------------------------------------------------------------------
1 | # Ragdoll Studio API
2 |
--------------------------------------------------------------------------------
/ragdoll-studio/studio-api/index.js:
--------------------------------------------------------------------------------
1 | const RagdollAPI = require('ragdoll-api');
2 |
3 | RagdollAPI();
4 |
--------------------------------------------------------------------------------
/ragdoll-studio/studio-api/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "ragdoll-studio-api",
3 | "version": "1.0.2",
4 | "scripts": {
5 | "start": "node index"
6 | },
7 | "dependencies": {
8 | "ragdoll-api": "^1.2.3"
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/ragdoll-studio/webpack.main.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | /**
3 | * This is the main entry point for your application, it's the first file
4 | * that runs in the main process.
5 | */
6 | entry: './src/main.js',
7 | // Put your normal webpack config below here
8 | module: {
9 | rules: require('./webpack.rules'),
10 | },
11 | };
12 |
--------------------------------------------------------------------------------
/ragdoll-studio/webpack.renderer.config.js:
--------------------------------------------------------------------------------
1 | const path = require('path');
2 | const CopyWebpackPlugin = require('copy-webpack-plugin');
3 |
4 | const rules = require('./webpack.rules');
5 |
6 | rules.push({
7 | test: /\.css$/,
8 | use: [{ loader: 'style-loader' }, { loader: 'css-loader' }],
9 | });
10 |
11 | module.exports = {
12 | module: {
13 | rules
14 | },
15 | plugins: [
16 | 'img',
17 | 'font'
18 | ].map(asset => new CopyWebpackPlugin({
19 | patterns: [
20 | {
21 | from: path.resolve(__dirname, 'src', asset),
22 | to: asset
23 | }
24 | ],
25 | })
26 | )
27 | };
28 |
--------------------------------------------------------------------------------
/ragdoll-studio/webpack.rules.js:
--------------------------------------------------------------------------------
1 | module.exports = [
2 | // Add support for native node modules
3 | {
4 | // We're specifying native_modules in the test because the asset relocator loader generates a
5 | // "fake" .node file which is really a cjs file.
6 | test: /native_modules[/\\].+\.node$/,
7 | use: 'node-loader',
8 | },
9 | {
10 | test: /[/\\]node_modules[/\\].+\.(m?js|node)$/,
11 | parser: { amd: false },
12 | use: {
13 | loader: '@vercel/webpack-asset-relocator-loader',
14 | options: {
15 | outputAssetBase: 'native_modules',
16 | },
17 | },
18 | },
19 |
20 | // JSX support
21 |
22 | {
23 | test: /\.jsx?$/,
24 | use: {
25 | loader: 'babel-loader',
26 | options: {
27 | exclude: /node_modules/,
28 | presets: ['@babel/preset-react']
29 | }
30 | }
31 | }
32 | ];
33 |
--------------------------------------------------------------------------------
/ragdoll-www-nextjs/.eslintrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "next",
3 | "rules": {
4 | "import/no-anonymous-default-export": "off",
5 | "react/no-unescaped-entities": "off",
6 | "react/display-name": "off"
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/ragdoll-www-nextjs/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | /node_modules
5 | /.pnp
6 | .pnp.js
7 | .yarn/install-state.gz
8 |
9 | # testing
10 | /coverage
11 |
12 | # next.js
13 | /.next/
14 | /out/
15 |
16 | # production
17 | /build
18 |
19 | # misc
20 | .DS_Store
21 | *.pem
22 |
23 | # debug
24 | npm-debug.log*
25 | yarn-debug.log*
26 | yarn-error.log*
27 |
28 | # local env files
29 | .env*.local
30 |
31 | # vercel
32 | .vercel
33 |
34 | # typescript
35 | *.tsbuildinfo
36 | next-env.d.ts
37 |
--------------------------------------------------------------------------------
/ragdoll-www-nextjs/.nvmrc:
--------------------------------------------------------------------------------
1 | 20.11.1
--------------------------------------------------------------------------------
/ragdoll-www-nextjs/jsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "paths": {
4 | "@/*": ["./src/*"]
5 | }
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/ragdoll-www-nextjs/next.config.mjs:
--------------------------------------------------------------------------------
1 | /** @type {import('next').NextConfig} */
2 | const nextConfig = {
3 | images: {
4 | remotePatterns: [
5 | {
6 | protocol: "https",
7 | hostname: "**",
8 | },
9 | ],
10 | }
11 | };
12 |
13 | export default nextConfig;
14 |
--------------------------------------------------------------------------------
/ragdoll-www-nextjs/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "ragdoll-www-nextjs",
3 | "version": "0.1.4",
4 | "scripts": {
5 | "dev": "next dev",
6 | "build": "next build",
7 | "start": "next start",
8 | "lint": "next lint"
9 | },
10 | "dependencies": {
11 | "react": "^18",
12 | "react-dom": "^18",
13 | "next": "14.1.4"
14 | },
15 | "devDependencies": {
16 | "autoprefixer": "^10.0.1",
17 | "postcss": "^8",
18 | "tailwindcss": "^3.3.0",
19 | "eslint": "^8",
20 | "eslint-config-next": "14.1.4"
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/ragdoll-www-nextjs/postcss.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | plugins: {
3 | tailwindcss: {},
4 | autoprefixer: {},
5 | },
6 | };
7 |
--------------------------------------------------------------------------------
/ragdoll-www-nextjs/public/.casts/bigtrev/video-magicians-pt-1/cast.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "Video magicians pt. 1",
3 | "description": "Cinematic geniuses!",
4 | "dolls": [
5 | {
6 | "name": "Anderson",
7 | "knowledgeURI": "https://www.curzon.com/journal/unpacking-wes-anderson-s-cinematic-style/",
8 | "avatarURL": "https://media.hero-magazine.com/wp-content/uploads/2021/10/11151511/Steve-Zissou-768x432.jpeg",
9 | "artStyle": "Wes Anderson, colorful and symmetrical with a blend of old world and 60s-era modern",
10 | "writingStyle": "quirky",
11 | "writingTone": "dry"
12 | },
13 | {
14 | "name": "Burton",
15 | "knowledgeURI": "https://www.vox.com/culture/2019/4/17/18285309/tim-burton-films-visual-style-aesthetic-disney-explained",
16 | "avatarURL": "https://static.wikia.nocookie.net/disney/images/0/06/Profile_-_Jack_Skellington.jpeg/revision/latest?cb=20190316145716",
17 | "artStyle": "Tim Burton, dark and cartoonish claymation",
18 | "writingStyle": "poetic, often rhyming",
19 | "writingTone": "gothic yet modern"
20 | },
21 | {
22 | "name": "Tarantino",
23 | "knowledgeURI": "https://www.quora.com/How-would-one-describe-Quentin-Tarantinos-style",
24 | "avatarURL": "https://i0.wp.com/www.michigandaily.com/wp-content/uploads/2023/10/online_killbill.jpg",
25 | "artStyle": "Quentin Tarantino films or graphic novels",
26 | "writingStyle": "often breaks classical rules of narrative, and the story is told in a non-chronological order, often split into multiple acts",
27 | "writingTone": "darkly humorous"
28 | }
29 | ],
30 |
31 | "author": "BIGTREV",
32 | "createdAt": "2024-03-01T12:00:00.568Z"
33 | }
34 |
--------------------------------------------------------------------------------
/ragdoll-www-nextjs/public/.casts/clarkee/startup-team/cast.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "Startup Team",
3 | "description": "Your AI startup team!",
4 | "dolls": [
5 | {
6 | "name": "Jeremy",
7 | "knowledgeURI": "https://www.codecademy.com/learn/bwa-intro-to-react/modules/react-101-jsx-u/cheatsheet",
8 | "avatarURL": "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTwpBC50_lwyJlQpYr2y9gPs5RbhW-OCcaJvSO-kzffPA&s",
9 | "artStyle": "Apple Mac laptops and React, clean and white",
10 | "writingStyle": "rational and logical, loves React",
11 | "writingTone": "somewhat condescending"
12 | },
13 | {
14 | "name": "Alex",
15 | "knowledgeURI": "https://www.codecademy.com/learn/introduction-to-blockchain-and-crypto/modules/welcome-to-introduction-to-blockchain-and-crypto/cheatsheet",
16 | "avatarURL": "https://st.depositphotos.com/46542440/55684/i/450/depositphotos_556848468-stock-illustration-square-face-character-stiff-art.jpg",
17 | "artStyle": "blockchain, crypto, and NFTs and dark themes",
18 | "writingStyle": "salesy and people-pleasing",
19 | "writingTone": "friendly"
20 | },
21 | {
22 | "name": "Meghan",
23 | "knowledgeURI": "https://www.leefeldmanlaw.com/blog/2017/august/what-are-california-labor-laws-a-cheat-sheet/",
24 | "avatarURL": "https://static.vecteezy.com/system/resources/thumbnails/023/570/233/small/business-woman-isolated-illustration-ai-generative-free-photo.jpg",
25 | "artStyle": "professional office setting",
26 | "writingStyle": "professional",
27 | "writingTone": "enthusiastic"
28 | }
29 | ],
30 |
31 | "author": "clarkee",
32 | "createdAt": "2024-03-01T12:00:00.568Z"
33 | }
34 |
--------------------------------------------------------------------------------
/ragdoll-www-nextjs/public/.casts/gptgod/goth-queens-by-gptgod/cast.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "goth queens by GPTgod",
3 | "description": "",
4 | "dolls": [
5 | {
6 | "name": "Grimes",
7 | "knowledgeURI": "https://en.wikipedia.org/wiki/Grimes",
8 | "avatarURL": "https://people.com/thmb/O8dq4AcvDPS9mXhLD4LHb2XKRPw=/1500x0/filters:no_upscale():max_bytes(150000):strip_icc():focal(742x559:744x561)/grimes-0dff4244715b4b32871977b71117219c.jpg",
9 | "artStyle": "high fashion post-goth",
10 | "writingStyle": "elegant yet somewhat raunchy",
11 | "writingTone": "quiet"
12 | },
13 | {
14 | "name": "Joan of Arc",
15 | "knowledgeURI": "https://en.wikipedia.org/wiki/Joan_of_Arc",
16 | "avatarURL": "https://media-cldnry.s-nbcnews.com/image/upload/t_fit-1240w,f_auto,q_auto:best/rockcms/2022-08/220813-joan-of-arc-mjf-0957-f0bb2c.jpg",
17 | "artStyle": "Kingdom of France in the 1400s",
18 | "writingStyle": "parody of Joan of Arc, jokes about how she should have been the queen and makes puns about the word gothic",
19 | "writingTone": "funny"
20 | }
21 | ],
22 |
23 | "author": "GPTgod",
24 | "createdAt": "2024-03-27T12:00:00.568Z"
25 | }
26 |
--------------------------------------------------------------------------------
/ragdoll-www-nextjs/public/.casts/heromd/superhero-doctors/cast.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "Superhero Doctors",
3 | "description": "Get a superhuman medical analysis",
4 | "dolls": [
5 | {
6 | "name": "Superman",
7 | "knowledgeURI": "https://www.pockethealth.com/2022/05/19/diagnostic-imaging-cheat-sheet/",
8 | "avatarURL": "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSwV-Itn6c0jroAgZTjViB6hRqd1Wwca0gpmkKumygENw&s",
9 | "artStyle": "DC comics, especially Superman",
10 | "writingStyle": "like a superhero",
11 | "writingTone": "helpful",
12 | "additionalKnowledgeURIs": [
13 | "https://medlineplus.gov/ency/article/007451.htm",
14 | "https://www.hopkinsmedicine.org/health/treatment-tests-and-therapies/magnetic-resonance-imaging-mri",
15 | "https://en.wikipedia.org/wiki/X-ray",
16 | "https://pubmed.ncbi.nlm.nih.gov/7750053/",
17 | "https://pubmed.ncbi.nlm.nih.gov/35964621/",
18 | "https://www.wdhospital.org/application/files/6715/0341/4136/7040-142.pdf",
19 | "https://en.wikipedia.org/wiki/Radiation"
20 | ]
21 | }
22 | ],
23 |
24 | "author": "HeroMD",
25 | "createdAt": "2024-03-19T12:00:00.568Z"
26 | }
27 |
--------------------------------------------------------------------------------
/ragdoll-www-nextjs/public/.casts/jacobb/temple-talk-to-god/cast.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "Temple: Talk to God",
3 | "description": "Speak with the Almighty",
4 | "dolls": [
5 | {
6 | "name": "God",
7 | "knowledgeURI": "https://en.wikipedia.org/wiki/God",
8 | "avatarURL": "https://upload.wikimedia.org/wikipedia/commons/1/13/Michelangelo%2C_Creation_of_Adam_06.jpg",
9 | "artStyle": "celestial, heavenly, and divine with clouds and golden rays of sunlight",
10 | "writingStyle": "divine and all-knowing like a deity",
11 | "writingTone": "understanding"
12 | }
13 | ],
14 |
15 | "author": "jacobb",
16 | "createdAt": "2024-03-16T12:00:00.568Z"
17 | }
18 |
--------------------------------------------------------------------------------
/ragdoll-www-nextjs/public/.casts/jessediaz/javascript-buddy/cast.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "javascript buddy",
3 | "description": "helps with js work",
4 | "dolls": [
5 | {
6 | "name": "JavaScript",
7 | "knowledgeURI": "https://htmlcheatsheet.com/js/",
8 | "avatarURL": "https://upload.wikimedia.org/wikipedia/commons/thumb/6/6a/JavaScript-logo.png/600px-JavaScript-logo.png?20120221235433",
9 | "artStyle": "Linux and 90s computers, lots of yellow and lime green, and some blue",
10 | "writingStyle": "rational and logical",
11 | "writingTone": "friendly",
12 | "additionalKnowledgeURIs": [
13 | "https://devhints.io/js-array",
14 | "https://devhints.io/es6",
15 | "https://quickref.me/regex#regex-in-javascript"
16 | ]
17 | }
18 | ],
19 |
20 | "author": "jessediaz",
21 | "createdAt": "2024-03-29T12:00:00.568Z"
22 | }
23 |
--------------------------------------------------------------------------------
/ragdoll-www-nextjs/public/.casts/mindyt/flirty-friends/cast.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "flirty friends",
3 | "description": "",
4 | "dolls": [
5 | {
6 | "name": "Bella",
7 | "knowledgeURI": "https://en.wikipedia.org/wiki/Bella_Swan",
8 | "avatarURL": "https://upload.wikimedia.org/wikipedia/en/7/77/Bella_Swan.jpg",
9 | "artStyle": "Twilight saga books",
10 | "writingStyle": "average girl, slightly sarcastic but not in an insufferable way",
11 | "writingTone": "compassionate"
12 | }
13 | ],
14 |
15 | "author": "MindyT",
16 | "createdAt": "2024-02-19T12:00:00.568Z"
17 | }
18 |
--------------------------------------------------------------------------------
/ragdoll-www-nextjs/public/.casts/mindyt/good-talkers/cast.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "good talkers",
3 | "description": "",
4 | "dolls": [
5 | {
6 | "name": "Hermione Granger",
7 | "knowledgeURI": "https://en.wikipedia.org/wiki/Hermione_Granger",
8 | "avatarURL": "https://static.wikia.nocookie.net/characters/images/a/a5/Latest_%2810%29.jpg",
9 | "artStyle": "Harry Potter",
10 | "writingStyle": "inspiring, brave, helpful, and bold",
11 | "writingTone": "bossy yet kind"
12 | },
13 | {
14 | "name": "Karl Marx",
15 | "knowledgeURI": "https://en.wikipedia.org/wiki/Karl_Marx",
16 | "avatarURL": "https://averdade.org.br/wp-content/uploads/2012/04/karl_marx_poster.jpg",
17 | "artStyle": "Marx aesthetics with materialist and socialist orientation",
18 | "writingStyle": "polemical with mockery and use of irony",
19 | "writingTone": "deductive"
20 | },
21 | {
22 | "name": "Johnny Carson",
23 | "knowledgeURI": "https://en.wikipedia.org/wiki/Johnny_Carson",
24 | "avatarURL": "https://upload.wikimedia.org/wikipedia/commons/thumb/6/62/Johnny_Carson_1965.jpg/220px-Johnny_Carson_1965.jpg",
25 | "artStyle": "60s era Burbank or Palm Springs - including fine suits, cigarettes, and television interviews",
26 | "writingStyle": "late night talk shows like Johnny Carson",
27 | "writingTone": "humorous, like teasing"
28 | }
29 | ],
30 |
31 | "author": "MindyT",
32 | "createdAt": "2024-02-20T12:00:00.568Z"
33 | }
34 |
--------------------------------------------------------------------------------
/ragdoll-www-nextjs/public/.casts/mindyt/some-friends/cast.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "some friends",
3 | "description": "",
4 | "dolls": [
5 | {
6 | "name": "Harry Potter",
7 | "knowledgeURI": "https://en.wikipedia.org/wiki/Harry_Potter",
8 | "avatarURL": "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQ6KAmgo4KwauKVvFx6Hf2osAej_mgOGTcWXVYteha4_w&s",
9 | "artStyle": "Harry Potter",
10 | "writingStyle": "humble, brave, loyal, and somewhat shy yet stubborn",
11 | "writingTone": "careful"
12 | },
13 | {
14 | "name": "George Carlin",
15 | "knowledgeURI": "https://en.wikipedia.org/wiki/George_Carlin",
16 | "avatarURL": "https://en.wikipedia.org/wiki/File:George_Carlin_1975_(Little_David_Records)_Publicity.jpg",
17 | "artStyle": "zany, liberated, and taboo",
18 | "writingStyle": "George Carlin and other standup comics that make quick-witted complaints and observations",
19 | "writingTone": "intelligent yet ranting somewhat like slam-poetry or a stage routine"
20 | }
21 | ],
22 |
23 | "author": "MindyT",
24 | "createdAt": "2024-02-26T12:00:00.568Z"
25 | }
26 |
--------------------------------------------------------------------------------
/ragdoll-www-nextjs/public/.casts/viddrip/hollywood-magic/cast.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "Hollywood Magic",
3 | "description": "Hollywood-style cinematography",
4 | "dolls": [
5 | {
6 | "name": "Great Films",
7 | "knowledgeURI": "https://www.indepthcine.com/videos/what-makes-a-movie-great",
8 | "avatarURL": "https://cdn.getyourguide.com/img/tour/63d8276b0a980.png/97.jpg",
9 | "artStyle": "like a Hollywood film",
10 | "writingStyle": "well-written, like an Academy-award winning film",
11 | "writingTone": "prestigious",
12 | "additionalKnowledgeURIs": [
13 | "https://www.timeout.com/film/best-movies-of-all-time",
14 | "https://www.rogerebert.com/great-movies"
15 | ]
16 | }
17 | ],
18 |
19 | "author": "viddrip",
20 | "createdAt": "2024-03-28T12:00:00.568Z"
21 | }
22 |
--------------------------------------------------------------------------------
/ragdoll-www-nextjs/public/assets/img/download.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/ragdoll-www-nextjs/public/assets/img/product.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bennyschmidt/ragdoll-studio/a95ed0558db0a6f6a8f7781b24d6bfab79ec6388/ragdoll-www-nextjs/public/assets/img/product.png
--------------------------------------------------------------------------------
/ragdoll-www-nextjs/src/app/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bennyschmidt/ragdoll-studio/a95ed0558db0a6f6a8f7781b24d6bfab79ec6388/ragdoll-www-nextjs/src/app/favicon.ico
--------------------------------------------------------------------------------
/ragdoll-www-nextjs/src/app/globals.css:
--------------------------------------------------------------------------------
1 | @tailwind base;
2 | @tailwind components;
3 | @tailwind utilities;
4 |
5 | :root {
6 | --foreground-rgb: 255, 255, 255;
7 | --background-start-rgb: 0, 0, 0;
8 | --background-end-rgb: 0, 0, 0;
9 | }
10 |
11 | body {
12 | color: rgb(var(--foreground-rgb));
13 | background: linear-gradient(
14 | to bottom,
15 | transparent,
16 | rgb(var(--background-end-rgb))
17 | )
18 | rgb(var(--background-start-rgb));
19 | }
20 |
21 | @layer utilities {
22 | .text-balance {
23 | text-wrap: balance;
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/ragdoll-www-nextjs/src/app/layout.js:
--------------------------------------------------------------------------------
1 | import { Outfit } from 'next/font/google';
2 |
3 | import '@/app/globals.css';
4 |
5 | const outfit = Outfit({ subsets: ["latin"] });
6 |
7 | export const metadata = {
8 | title: "Ragdoll Studio",
9 | description: "Create AI personas for a variety of use cases, each with their own distinct knowledge and style.",
10 | };
11 |
12 | export default function RootLayout({ children }) {
13 | return (
14 |
15 | {children}
16 |
17 | );
18 | }
19 |
--------------------------------------------------------------------------------
/ragdoll-www-nextjs/src/components/Header/index.js:
--------------------------------------------------------------------------------
1 | import Link from 'next/link';
2 | import { Icon } from '@/components';
3 |
4 | const Header = () => (
5 |
19 | );
20 |
21 | export default Header;
22 |
--------------------------------------------------------------------------------
/ragdoll-www-nextjs/src/components/Icon/index.js:
--------------------------------------------------------------------------------
1 | import Image from 'next/image';
2 |
3 | const Icon = ({ src, size = 20 }) => (
4 |
13 | );
14 |
15 | export default Icon;
16 |
--------------------------------------------------------------------------------
/ragdoll-www-nextjs/src/components/index.js:
--------------------------------------------------------------------------------
1 | import Icon from './Icon';
2 | import Header from './Header';
3 | import CardList from './CardList';
4 |
5 | export {
6 | Icon,
7 | Header,
8 | CardList
9 | };
10 |
--------------------------------------------------------------------------------
/ragdoll-www-nextjs/src/hooks/index.js:
--------------------------------------------------------------------------------
1 | import useCast from './useCast';
2 | import useCasts from './useCasts';
3 | import useDolls from './useDolls';
4 |
5 | export {
6 | useCast,
7 | useCasts,
8 | useDolls
9 | };
10 |
--------------------------------------------------------------------------------
/ragdoll-www-nextjs/src/hooks/useCast/index.js:
--------------------------------------------------------------------------------
1 | import { useState, useEffect } from 'react';
2 |
3 | const useCast = (authorSlug, castSlug) => {
4 | const [cast, setCast] = useState();
5 | const [pending, setPending] = useState(false);
6 |
7 | useEffect(() => {
8 | const fetchDolls = async () => {
9 | setPending(true);
10 |
11 | if (!authorSlug || !castSlug) {
12 | return [null, true];
13 | }
14 |
15 | const response = await fetch('/api/cast', {
16 | method: 'POST',
17 | headers: {
18 | 'Accept': 'application/json',
19 | 'Content-Type': 'application/json'
20 | },
21 | body: JSON.stringify({
22 | authorSlug,
23 | castSlug
24 | })
25 | });
26 |
27 | if (response?.ok) {
28 | const result = await response.json();
29 |
30 | if (result?.cast) {
31 | setCast(result.cast);
32 | }
33 | }
34 |
35 | setPending(false);
36 | };
37 |
38 | fetchDolls();
39 | }, [authorSlug, castSlug]);
40 |
41 | return [cast, pending];
42 | };
43 |
44 | export default useCast;
45 |
--------------------------------------------------------------------------------
/ragdoll-www-nextjs/src/hooks/useCasts/index.js:
--------------------------------------------------------------------------------
1 | import { useState, useEffect } from 'react';
2 |
3 | const useCasts = () => {
4 | const [casts, setCasts] = useState([]);
5 | const [pending, setPending] = useState(false);
6 |
7 | useEffect(() => {
8 | const fetchDolls = async () => {
9 | setPending(true);
10 |
11 | const response = await fetch('/api/casts');
12 |
13 | if (response?.ok) {
14 | const result = await response.json();
15 |
16 | if (result?.casts) {
17 | setCasts(result.casts);
18 | }
19 | }
20 |
21 | setPending(false);
22 | };
23 |
24 | fetchDolls();
25 | }, []);
26 |
27 | return [casts, pending];
28 | };
29 |
30 | export default useCasts;
31 |
--------------------------------------------------------------------------------
/ragdoll-www-nextjs/src/hooks/useDolls/index.js:
--------------------------------------------------------------------------------
1 | import { useState, useEffect } from 'react';
2 |
3 | const useDolls = (authorSlug, castSlug) => {
4 | const [cast, setCast] = useState();
5 | const [pending, setPending] = useState(false);
6 |
7 | useEffect(() => {
8 | const fetchDolls = async () => {
9 | setPending(true);
10 |
11 | if (!authorSlug || !castSlug) {
12 | return [null, true];
13 | }
14 |
15 | const response = await fetch('/api/dolls', {
16 | method: 'POST',
17 | headers: {
18 | 'Accept': 'application/json',
19 | 'Content-Type': 'application/json'
20 | },
21 | body: JSON.stringify({
22 | authorSlug,
23 | castSlug
24 | })
25 | });
26 |
27 | if (response?.ok) {
28 | const result = await response.json();
29 |
30 | if (result?.cast) {
31 | setCast(result.cast);
32 | }
33 | }
34 |
35 | setPending(false);
36 | };
37 |
38 | fetchDolls();
39 | }, [authorSlug, castSlug]);
40 |
41 | return [cast, pending];
42 | };
43 |
44 | export default useDolls;
45 |
--------------------------------------------------------------------------------
/ragdoll-www-nextjs/src/pages/_app.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | const App = ({ Component, pageProps }) => (
4 |
5 | );
6 |
7 | export default App;
8 |
--------------------------------------------------------------------------------
/ragdoll-www-nextjs/src/pages/api/cast/index.js:
--------------------------------------------------------------------------------
1 | import fs from 'fs';
2 | import path from 'path';
3 |
4 | export default async function (req, res) {
5 | const {
6 | authorSlug = '',
7 | castSlug = ''
8 | } = req.body;
9 |
10 | if (!authorSlug || !castSlug) {
11 | res
12 | .status(200)
13 | .json({
14 | status: 400,
15 | ok: false,
16 | message: `Invalid ${invalidParam}.`,
17 | cast
18 | });
19 |
20 | return;
21 | }
22 |
23 | const castPath = path.join(process.cwd(), `/public/.casts/${authorSlug}/${castSlug}/cast.json`);
24 | const castFile = fs.readFileSync(castPath);
25 | const cast = JSON.parse(castFile);
26 |
27 | res
28 | .status(200)
29 | .json({
30 | status: 200,
31 | ok: true,
32 | cast: {
33 | name: cast.name,
34 | author: cast.author,
35 | description: cast.description,
36 | rating: 0,
37 | imageURL: cast.dolls[0].avatarURL,
38 | unitCount: cast.dolls.length,
39 | createdAt: cast.createdAt
40 | }
41 | });
42 | }
43 |
--------------------------------------------------------------------------------
/ragdoll-www-nextjs/src/pages/api/casts/index.js:
--------------------------------------------------------------------------------
1 | import fs from 'fs';
2 | import path from 'path';
3 |
4 | import { slugify } from '@/utils';
5 |
6 | export default async function (req, res) {
7 | let casts = [];
8 |
9 | const manifestPath = path.join(process.cwd(), '/public/.casts/casts.json');
10 | const manifestFile = fs.readFileSync(manifestPath);
11 | const manifest = JSON.parse(manifestFile);
12 |
13 | for (const author of Object.keys(manifest)) {
14 | const authorSlug = slugify(author);
15 |
16 | const files = manifest[author];
17 |
18 | for (const file of files) {
19 | const fileSlug = slugify(file.name);
20 | const castPath = path.join(process.cwd(), `/public/.casts/${authorSlug}/${fileSlug}/cast.json`);
21 | const castFile = fs.readFileSync(castPath);
22 | const cast = JSON.parse(castFile);
23 |
24 | casts = [
25 | ...casts,
26 |
27 | {
28 | name: cast.name,
29 | author: cast.author,
30 | description: cast.description,
31 | rating: file.ratings.reduce((a, b) => a + b, 0),
32 | imageURL: cast.dolls[0].avatarURL,
33 | unitCount: cast.dolls.length,
34 | createdAt: cast.createdAt
35 | }
36 | ]
37 | }
38 | }
39 |
40 | res
41 | .status(200)
42 | .json({
43 | status: 200,
44 | ok: true,
45 | casts
46 | });
47 | }
48 |
--------------------------------------------------------------------------------
/ragdoll-www-nextjs/src/pages/api/dolls/index.js:
--------------------------------------------------------------------------------
1 | import fs from 'fs';
2 | import path from 'path';
3 |
4 | export default async function (req, res) {
5 | const {
6 | authorSlug = '',
7 | castSlug = ''
8 | } = req.body;
9 |
10 | if (!authorSlug || !castSlug) {
11 | res
12 | .status(200)
13 | .json({
14 | status: 400,
15 | ok: false,
16 | message: `Invalid ${invalidParam}.`,
17 | cast
18 | });
19 |
20 | return;
21 | }
22 |
23 | const castPath = path.join(process.cwd(), `/public/.casts/${authorSlug}/${castSlug}/cast.json`);
24 |
25 | res
26 | .status(200)
27 | .send(castPath);
28 | }
29 |
--------------------------------------------------------------------------------
/ragdoll-www-nextjs/src/pages/dolls/index.js:
--------------------------------------------------------------------------------
1 | 'use client';
2 |
3 | import { Outfit } from 'next/font/google';
4 |
5 | import { useEffect, useState } from 'react';
6 |
7 | import { Header, CardList } from '@/components';
8 | import useCasts from '@/hooks/useCasts';
9 |
10 | import '@/app/globals.css';
11 |
12 | const outfit = Outfit({ subsets: ['latin'] });
13 |
14 | const Library = () => {
15 | const [casts] = useCasts();
16 | const [recent, setRecent] = useState([]);
17 |
18 | useEffect(() => {
19 | setRecent(
20 | Array.from(casts)
21 | .sort((a, b) => new Date(a.createdAt) < new Date(b.createdAt) ? 1 : 0)
22 | );
23 | }, [casts]);
24 |
25 | return (
26 |
27 |
28 |
29 |
30 |
33 |
34 |
35 |
36 | )
37 | };
38 |
39 | export default Library;
40 |
--------------------------------------------------------------------------------
/ragdoll-www-nextjs/src/utils/index.js:
--------------------------------------------------------------------------------
1 | const slugify = (phrase = '') => (
2 | phrase
3 | .normalize('NFKD')
4 | .replace(/[\u0300-\u036f]/g, '')
5 | .trim()
6 | .toLowerCase()
7 | .replace(/[^a-z0-9 -]/g, '')
8 | .replace(/\s+/g, '-')
9 | .replace(/-+/g, '-')
10 | .replace(/^\-*|\-*$/, '')
11 | );
12 |
13 | const getStarRating = (rating, maxStars = 5) => (
14 | new Array(maxStars)
15 | .fill('')
16 | .map((_, index) => rating > index ? '★' : '☆')
17 | );
18 |
19 | export {
20 | slugify,
21 | getStarRating
22 | };
23 |
--------------------------------------------------------------------------------
/ragdoll-www-nextjs/tailwind.config.js:
--------------------------------------------------------------------------------
1 | /** @type {import('tailwindcss').Config} */
2 | module.exports = {
3 | content: [
4 | "./src/pages/**/*.{js,ts,jsx,tsx,mdx}",
5 | "./src/components/**/*.{js,ts,jsx,tsx,mdx}",
6 | "./src/app/**/*.{js,ts,jsx,tsx,mdx}",
7 | ],
8 | theme: {
9 | extend: {
10 | backgroundImage: {
11 | "gradient-radial": "radial-gradient(var(--tw-gradient-stops))",
12 | "gradient-conic":
13 | "conic-gradient(from 180deg at 50% 50%, var(--tw-gradient-stops))",
14 | },
15 | },
16 | },
17 | plugins: [],
18 | };
19 |
--------------------------------------------------------------------------------