diff --git a/.dockerignore b/.dockerignore index aaae97f0760826b7738dc8f572c905a662fcd893..b145da9a17d393070619b1170acf44c83d947a36 100644 --- a/.dockerignore +++ b/.dockerignore @@ -3,4 +3,10 @@ Compose.yaml Dockerfile-Base Dockerfile-Light entrypoint.sh -railway.json +.gitignore +.github +.git +.pre-commit-config.yaml +start-venv.sh +/components/ +/components/* diff --git a/.github/workflows/docker-publish.yml b/.github/workflows/docker-publish.yml index a8d3656a0805a1a2d82bbe3434901c24ffce224b..c1f36b69871174c80e920ccc448cbe9b78186e69 100644 --- a/.github/workflows/docker-publish.yml +++ b/.github/workflows/docker-publish.yml @@ -1,27 +1,30 @@ +# Docker image build and publish workflow +# CREDIT: Adopted from name: Docker Build & Publish +# running on every release and on manual dispatch on: release: types: [created] env: - # Use docker.io for Docker Hub if empty + # set the registry to the GitHub Container Registry REGISTRY: ghcr.io - # github.repository as / - IMAGE_NAME: ${{ github.repository }} - + # set github.repository as / + IMAGE_NAME: ${{ github.repository }}:${{ github.ref }} +# jobs to run jobs: - build: + # build job + build: runs-on: ubuntu-latest permissions: contents: read packages: write - # This is used to complete the identity challenge - # with sigstore/fulcio when running outside of PRs. id-token: write + # steps to run on the job steps: - name: Checkout repository uses: actions/checkout@v3 @@ -29,7 +32,6 @@ jobs: # Install the cosign tool except on PR # https://github.com/sigstore/cosign-installer - name: Install cosign - if: github.event_name != 'pull_request' uses: sigstore/cosign-installer@6e04d228eb30da1757ee4e1dd75a0ec73a653e06 #v3.1.1 with: cosign-release: 'v2.1.1' diff --git a/.github/workflows/hgf-sync-main.yml b/.github/workflows/hgf-sync-main.yml new file mode 100644 index 0000000000000000000000000000000000000000..873bb99012849cda4f650c268d20873578259dfa --- /dev/null +++ b/.github/workflows/hgf-sync-main.yml @@ -0,0 +1,28 @@ +# workflow that syncs the main branch to the Hugging Face Hub (Huggingface Spaces) +#CREDIT Copied from Hugging Face, Inc. + +name: HGF Hub Sync (Main) +# runs on pushes to the main branch and manually triggered workflows +on: + push: + branches: [main] + + workflow_dispatch: + +# jobs to run +jobs: + # sync job + sync-to-hub: + runs-on: ubuntu-latest + steps: + # checkout the repository + - uses: actions/checkout@v3 + with: + fetch-depth: 0 + lfs: true + # push to hub with huggingface token + - name: Push to hub + env: + HF_TOKEN: ${{ secrets.HF_TOKEN }} + # run git push + run: git push https://LennardZuendorf:$HF_TOKEN@huggingface.co/spaces/LennardZuendorf/thesis-webapp-docker main diff --git a/.github/workflows/hgf-sync.yml b/.github/workflows/hgf-sync.yml deleted file mode 100644 index 69023bcbd72698d46f783151c834dfba65d97c76..0000000000000000000000000000000000000000 --- a/.github/workflows/hgf-sync.yml +++ /dev/null @@ -1,20 +0,0 @@ -name: Sync to Hugging Face hub -on: - push: - branches: [main] - - # to run this workflow manually from the Actions tab - workflow_dispatch: - -jobs: - sync-to-hub: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - with: - fetch-depth: 0 - lfs: true - - name: Push to hub - env: - HF_TOKEN: ${{ secrets.HF_TOKEN }} - run: git push https://LennardZuendorf:$HF_TOKEN@huggingface.co/spaces/LennardZuendorf/thesis-webapp main diff --git a/.github/workflows/hgf.yml b/.github/workflows/hgf.yml deleted file mode 100644 index 69023bcbd72698d46f783151c834dfba65d97c76..0000000000000000000000000000000000000000 --- a/.github/workflows/hgf.yml +++ /dev/null @@ -1,20 +0,0 @@ -name: Sync to Hugging Face hub -on: - push: - branches: [main] - - # to run this workflow manually from the Actions tab - workflow_dispatch: - -jobs: - sync-to-hub: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - with: - fetch-depth: 0 - lfs: true - - name: Push to hub - env: - HF_TOKEN: ${{ secrets.HF_TOKEN }} - run: git push https://LennardZuendorf:$HF_TOKEN@huggingface.co/spaces/LennardZuendorf/thesis-webapp main diff --git a/.github/workflows/python-app.yml b/.github/workflows/python-app.yml new file mode 100644 index 0000000000000000000000000000000000000000..dd12573ff6c1d0494634a5985b32156715117d2e --- /dev/null +++ b/.github/workflows/python-app.yml @@ -0,0 +1,43 @@ +# workflow file tp build a python app and lint it +# CREDIT: Adopted from Github Actions Documentation +## see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-python + +name: Python Install and Linting + +# runs on every push/pr to any repo and on manual dispatch +on: + push: + + pull_request: + + workflow_dispatch: + +permissions: + contents: read + +# jobs to run +jobs: + # main build job that installs dependencies and lints + build: + runs-on: ubuntu-latest + + steps: + # checkout the repository + - uses: actions/checkout@v3 + # set up python 3.10 + - name: Set up Python 3.10 + uses: actions/setup-python@v3 + with: + python-version: "3.10" + # install dependencies from requirements.txt + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install pylint black + if [ -f requirements.txt ]; then pip install -r requirements.txt; fi + # lint and format all files with black (as defined in pyproject.toml) + - name: Lint & Fix with Black + run: black . + # lint with pylint + - name: Lint with Pylint + run: pylint . diff --git a/.gitignore b/.gitignore index f807b0e61fb246ab4b7b01003d5b4d200188e82f..8c78f1f13e781a97fb701c3b563a56b8c7d407fc 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ /.env/ -__pycache__/ \ No newline at end of file +__pycache__/ +/start-venv.sh diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..13566b81b018ad684f3a35fee301741b2734c8f4 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,8 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Editor-based HTTP Client requests +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/.idea/inspectionProfiles/profiles_settings.xml b/.idea/inspectionProfiles/profiles_settings.xml new file mode 100644 index 0000000000000000000000000000000000000000..cc5462daf866cfdd7bf0c21d7ecd6e94db1f0a00 --- /dev/null +++ b/.idea/inspectionProfiles/profiles_settings.xml @@ -0,0 +1,6 @@ + + + + diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000000000000000000000000000000000000..ba7547e188b6dca1e35866a4ba8ba15a7c47b003 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,7 @@ + + + + + + diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000000000000000000000000000000000000..8105d29ce42855d0876a8673774fe9558388670f --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/.idea/thesis-webapp.iml b/.idea/thesis-webapp.iml new file mode 100644 index 0000000000000000000000000000000000000000..56c25918044dd519101c0bf5b282f1dcdafcbeb6 --- /dev/null +++ b/.idea/thesis-webapp.iml @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000000000000000000000000000000000000..dcb6b8c4cc2ba1defdbc89a1e3d14f60a116ae8e --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 0000000000000000000000000000000000000000..c958d176c8ec9cee54982bf5ebab0661148031f6 --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,25 @@ +repos: +- repo: https://github.com/pre-commit/pre-commit-hooks + rev: v2.3.0 + hooks: + - id: check-yaml + - id: end-of-file-fixer + - id: trailing-whitespace +- repo: https://github.com/psf/black-pre-commit-mirror + rev: 23.12.1 + hooks: + - id: black + language_version: python3.11 + exclude: ^components/ +- repo: local + hooks: + - id: pylint + name: pylint + entry: pylint + exclude: ^components/ + language: system + types: [python] + args: + [ + "-rn", # Only display messages + ] diff --git a/Compose.yaml b/Compose.yaml deleted file mode 100644 index cd32ae9d6253b47860e13967f189aefe87f652aa..0000000000000000000000000000000000000000 --- a/Compose.yaml +++ /dev/null @@ -1,7 +0,0 @@ -version: '3.8' - -services: - application: - build: . - ports: - - "80:80" \ No newline at end of file diff --git a/Dockerfile b/Dockerfile index 7ecee44eae678ec436698bff2f3d9b526d29297b..55986297e9884b0b6ba62fc40b19e5e502077217 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,22 +1,23 @@ -# Standard Dockerfile to build image of the webapp +# standard Dockerfile to build a complete, working image of the webapp -## complete build based on clean python (slower) -FROM python:3.11.6 +# complete build based on clean python (slower) +#FROM python:3.11.6 -## build based on python with dependencies (quicker) -# FROM thesis:0.1.6-base +# build based on python with dependencies (quicker) - for dev +FROM thesis:0.2.0-base -# install dependencies and copy files +# install dependencies and copy files into image folder COPY requirements.txt . RUN pip install --no-cache-dir --upgrade -r requirements.txt RUN pip install fastapi uvicorn COPY . . +# display files in image folder (for debugging) RUN ls --recursive . # setting config and run command CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8080"] -# build and run commands -## docker build -t thesis:0.1.6 -f Dockerfile-Light . -## docker run -d --name thesis -p 8080:8080 thesis:0.1.6-small \ No newline at end of file +# build and run commands: +## docker build -t thesis:0.2.0-full -f Dockerfile . +## docker run -d --name thesis -p 8080:8080 thesis:0.2.0 diff --git a/Dockerfile-Base b/Dockerfile-Base index 6637effbc25bcfef998ef74f88da0626ad1c0096..893b176ca697cb54b10c14eff2f8c107a8f5b4a2 100644 --- a/Dockerfile-Base +++ b/Dockerfile-Base @@ -1,4 +1,5 @@ -# Dockerfile to create base image with all needed dependencies +# Dockerfile to create base image with all needed dependencies. for the quick dockerfile build of the webapp +# because all dependencies are already installed, the next webapp build using this base image is much quicker # using newest python as a base image FROM python:3.11.6 diff --git a/Dockerfile-Light b/Dockerfile-Light deleted file mode 100644 index 63a4b3ff1652379eb2c6bdd3b2f687c0cfb9093c..0000000000000000000000000000000000000000 --- a/Dockerfile-Light +++ /dev/null @@ -1,19 +0,0 @@ -# Light Dockerfile with not ready built dependencies (1GB vs. 7-8 GB) - -## newest python version as base image -FROM python:3.11.6 - -#set working directory and copying files, endpoint script -COPY . . -COPY entrypoint.sh . - -# show files in directory -RUN ls --recursive . - -# setting config and run command -RUN chmod +x ./entrypoint.sh -ENTRYPOINT [ "/webapp/entrypoint.sh" ] - -# build and run commands -## docker build -t thesis:0.1.6-small -f Dockerfile-Light . -## docker run -d --name thesis -p 80:80 thesis:0.1.6-small \ No newline at end of file diff --git a/LICENSE.md b/LICENSE.md index 1c1df880882b65323e10d1ab53bc18a41d45d51b..ec606d84f5d45be3d68d33f5f8cfa958fd91cff6 100644 --- a/LICENSE.md +++ b/LICENSE.md @@ -18,4 +18,4 @@ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. \ No newline at end of file +SOFTWARE. diff --git a/README.md b/README.md index 0657d89476017f992b826b1206672fa7ccd3025a..dd2f8643bbf4caa59ad0dcdddfeb9452f1f1f2bd 100644 --- a/README.md +++ b/README.md @@ -12,33 +12,31 @@ app_port: 8080 --- # Bachelor Thesis +## Webapp #### This is the ui showcase for my thesis about interpretability in a LLM based chatbot application and applications of XAI. ## ๐Ÿ”— Links: -**[Github Repository](https://github.com/LennardZuendorf/thesis)** +**[Github Repository](https://github.com/LennardZuendorf/thesis-webapp)** +**[Huggingface Spaces Showcase](https://huggingface.co/spaces/lennardzuendorf/thesis-webapp-docker** ## ๐Ÿ—๏ธ Tech Stack: -**Language and Framework:** Python, JupyterNotebook +**Language and Framework:** Python -**Noteable Packages:** ๐Ÿค— Transformers, Gradio, SHAP, BERTViz, Shapas +**Noteable Packages:** ๐Ÿค— Transformers, FastAPI, Gradio, SHAP, BERTViz ## ๐Ÿ‘จโ€๐Ÿ’ป Author and Credits: - **Author:** [@LennardZuendorf](https://github.com/LennardZuendorf) -**Thesis Supervisor**: [Prof. Dr. Simbeck](https://www.htw-berlin.de/hochschule/personen/person/?eid=9862) +**Thesis Supervisor**: [Prof. Dr. Simbeck](https://www.htw-berlin.de/hochschule/personen/person/?eid=9862)
Second Corrector: [Prof. Dr. Hochstein](https://www.htw-berlin.de/hochschule/personen/person/?eid=10628) +See code for in detailed credits, work is based on -See code for in detail credits, work is based on - -- Mistral AI +- GODEL: - SHAP: - BERTViz: - This Project was part of my studies of Business Computing at University of Applied Science for Technology and Business Berlin (HTW Berlin). - diff --git a/__init__.py b/__init__.py index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..7d8ca1294b578f33d8e7daf450212ba1e8befa7c 100644 --- a/__init__.py +++ b/__init__.py @@ -0,0 +1,2 @@ +# empty init file for the package +# for fastapi to recognize the module diff --git a/backend/__init__.py b/backend/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..7d8ca1294b578f33d8e7daf450212ba1e8befa7c --- /dev/null +++ b/backend/__init__.py @@ -0,0 +1,2 @@ +# empty init file for the package +# for fastapi to recognize the module diff --git a/backend/controller.py b/backend/controller.py new file mode 100644 index 0000000000000000000000000000000000000000..f6d46aab76a38de0d3ff4c25c968bdb4d0802b50 --- /dev/null +++ b/backend/controller.py @@ -0,0 +1,104 @@ +# controller for the application that calls the model and explanation functions +# and returns the updated conversation history + +# external imports +import gradio as gr + +# internal imports +from model import godel +from explanation import interpret, visualize + + +# main interference function that that calls chat functions depending on selections +# TODO: Limit maximum tokens/model input +def interference( + prompt: str, + history: list, + knowledge: str, + system_prompt: str, + xai_selection: str, +): + # if no system prompt is given, use a default one + if system_prompt == "": + system_prompt = """ + You are a helpful, respectful and honest assistant. + Always answer as helpfully as possible, while being safe. + """ + + # if a XAI approach is selected, grab the XAI instance + if xai_selection in ("SHAP", "Visualizer"): + match xai_selection.lower(): + case "shap": + xai = interpret + case "visualizer": + xai = visualize + case _: + # use Gradio warning to display error message + gr.Warning(f""" + There was an error in the selected XAI Approach. + It is "{xai_selection}" + """) + raise RuntimeError("There was an error in the selected XAI approach.") + + # call the explained chat function + prompt_output, history_output, xai_graphic, xai_plot = explained_chat( + model=godel, + xai=xai, + message=prompt, + history=history, + system_prompt=system_prompt, + knowledge=knowledge, + ) + # if no (or invalid) XAI approach is selected call the vanilla chat function + else: + # call the vanilla chat function + prompt_output, history_output = vanilla_chat( + model=godel, + message=prompt, + history=history, + system_prompt=system_prompt, + knowledge=knowledge, + ) + # set XAI outputs to disclaimer html/none + xai_graphic, xai_plot = ( + """ +

Without Selected XAI Approach, + no graphic will be displayed

+ """, + None, + ) + + # return the outputs + return prompt_output, history_output, xai_graphic, xai_plot + + +# simple chat function that calls the model +# formats prompts, calls for an answer and returns updated conversation history +def vanilla_chat( + model, message: str, history: list, system_prompt: str, knowledge: str = "" +): + # formatting the prompt using the model's format_prompt function + prompt = model.format_prompt(message, history, system_prompt, knowledge) + # generating an answer using the model's respond function + answer = model.respond(prompt) + + # updating the chat history with the new answer + history.append((message, answer)) + + # returning the updated history + return "", history + + +def explained_chat( + model, xai, message: str, history: list, system_prompt: str, knowledge: str = "" +): + # formatting the prompt using the model's format_prompt function + prompt = model.format_prompt(message, history, system_prompt, knowledge) + + # generating an answer using the xai methods explain and respond function + answer, xai_graphic, xai_plot = xai.chat_explained(model, prompt) + # updating the chat history with the new answer + history.append((message, answer)) + + # returning the updated history, xai graphic and xai plot elements + return "", history, xai_graphic, xai_plot diff --git a/components/iframe/.gitignore b/components/iframe/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..f7fed6bde9dd69119312096ef94b5631eea402f7 --- /dev/null +++ b/components/iframe/.gitignore @@ -0,0 +1,9 @@ +.eggs/ +dist/ +*.pyc +__pycache__/ +*.py[cod] +*$py.class +__tmp/* +*.pyi +node_modules diff --git a/components/iframe/README.md b/components/iframe/README.md new file mode 100644 index 0000000000000000000000000000000000000000..0edd2ab2171a4b499c26cd5bf947fcbdd0193d96 --- /dev/null +++ b/components/iframe/README.md @@ -0,0 +1,10 @@ + +# gradio_iframe +A Custom Gradio component. + +## Example usage + +```python +import gradio as gr +from gradio_iframe import iframe +``` diff --git a/components/iframe/backend/gradio_iframe/__init__.py b/components/iframe/backend/gradio_iframe/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..fafa36d3f29fe2d4e1adca14da516909ab064fe8 --- /dev/null +++ b/components/iframe/backend/gradio_iframe/__init__.py @@ -0,0 +1,3 @@ +from .iframe import iframe + +__all__ = ["iframe"] diff --git a/components/iframe/backend/gradio_iframe/iframe.py b/components/iframe/backend/gradio_iframe/iframe.py new file mode 100644 index 0000000000000000000000000000000000000000..9a7544a5f4fadb7dc8f5950e4a6c22182753d495 --- /dev/null +++ b/components/iframe/backend/gradio_iframe/iframe.py @@ -0,0 +1,72 @@ +"""gr.HTML() component.""" + +from __future__ import annotations + +from typing import Any, Callable + +from gradio_client.documentation import document, set_documentation_group + +from gradio.components.base import Component +from gradio.events import Events + +set_documentation_group("component") + + +@document() +class iframe(Component): + """ + Used to display arbitrary iframe output. + Preprocessing: this component does *not* accept input. + Postprocessing: expects a valid iframe {str}. + + Demos: text_analysis + Guides: key-features + """ + + EVENTS = [Events.change] + + def __init__( + self, + value: str | Callable = "", + *, + label: str | None = None, + every: float | None = None, + show_label: bool | None = None, + visible: bool = True, + elem_id: str | None = None, + elem_classes: list[str] | str | None = None, + render: bool = True, + ): + """ + Parameters: + value: Default value. If callable, the function will be called whenever the app loads to set the initial value of the component. + label: The label for this component. Is used as the header if there are a table of examples for this component. If None and used in a `gr.Interface`, the label will be the name of the parameter this component is assigned to. + every: If `value` is a callable, run the function 'every' number of seconds while the client connection is open. Has no effect otherwise. Queue must be enabled. The event can be accessed (e.g. to cancel it) via this component's .load_event attribute. + show_label: This parameter has no effect. + visible: If False, component will be hidden. + elem_id: An optional string that is assigned as the id of this component in the iframe DOM. Can be used for targeting CSS styles. + elem_classes: An optional list of strings that are assigned as the classes of this component in the iframe DOM. Can be used for targeting CSS styles. + render: If False, component will not render be rendered in the Blocks context. Should be used if the intention is to assign event listeners now but render the component later. + """ + super().__init__( + label=label, + every=every, + show_label=show_label, + visible=visible, + elem_id=elem_id, + elem_classes=elem_classes, + render=render, + value=value, + ) + + def example_inputs(self) -> Any: + return "

Hello

" + + def preprocess(self, payload: str | None) -> str | None: + return payload + + def postprocess(self, value: str | None) -> str | None: + return value + + def api_info(self) -> dict[str, Any]: + return {"type": "string"} diff --git a/components/iframe/backend/gradio_iframe/templates/component/index.js b/components/iframe/backend/gradio_iframe/templates/component/index.js new file mode 100644 index 0000000000000000000000000000000000000000..289f51366729b40b04dff9d0f47d9d03491ebfcb --- /dev/null +++ b/components/iframe/backend/gradio_iframe/templates/component/index.js @@ -0,0 +1,1994 @@ +const { + SvelteComponent: lt, + attr: he, + detach: nt, + element: it, + init: st, + insert: ft, + noop: we, + safe_not_equal: ot, + toggle_class: W +} = window.__gradio__svelte__internal, { createEventDispatcher: at } = window.__gradio__svelte__internal; +function rt(n) { + let t, e; + return { + c() { + t = it("div"), he(t, "class", e = "prose " + /*elem_classes*/ + n[0].join(" ") + " svelte-2qygph"), W( + t, + "min", + /*min_height*/ + n[3] + ), W(t, "hide", !/*visible*/ + n[2]); + }, + m(l, i) { + ft(l, t, i), t.innerHTML = /*value*/ + n[1]; + }, + p(l, [i]) { + i & /*value*/ + 2 && (t.innerHTML = /*value*/ + l[1]), i & /*elem_classes*/ + 1 && e !== (e = "prose " + /*elem_classes*/ + l[0].join(" ") + " svelte-2qygph") && he(t, "class", e), i & /*elem_classes, min_height*/ + 9 && W( + t, + "min", + /*min_height*/ + l[3] + ), i & /*elem_classes, visible*/ + 5 && W(t, "hide", !/*visible*/ + l[2]); + }, + i: we, + o: we, + d(l) { + l && nt(t); + } + }; +} +function _t(n, t, e) { + let { elem_classes: l = [] } = t, { value: i } = t, { visible: f = !0 } = t, { min_height: o = !1 } = t; + const a = at(); + return n.$$set = (r) => { + "elem_classes" in r && e(0, l = r.elem_classes), "value" in r && e(1, i = r.value), "visible" in r && e(2, f = r.visible), "min_height" in r && e(3, o = r.min_height); + }, n.$$.update = () => { + n.$$.dirty & /*value*/ + 2 && a("change"); + }, [l, i, f, o]; +} +class ut extends lt { + constructor(t) { + super(), st(this, t, _t, rt, ot, { + elem_classes: 0, + value: 1, + visible: 2, + min_height: 3 + }); + } +} +function X(n) { + let t = ["", "k", "M", "G", "T", "P", "E", "Z"], e = 0; + for (; n > 1e3 && e < t.length - 1; ) + n /= 1e3, e++; + let l = t[e]; + return (Number.isInteger(n) ? n : n.toFixed(1)) + l; +} +function ee() { +} +function ct(n, t) { + return n != n ? t == t : n !== t || n && typeof n == "object" || typeof n == "function"; +} +const Oe = typeof window < "u"; +let ve = Oe ? () => window.performance.now() : () => Date.now(), Re = Oe ? (n) => requestAnimationFrame(n) : ee; +const Y = /* @__PURE__ */ new Set(); +function Ue(n) { + Y.forEach((t) => { + t.c(n) || (Y.delete(t), t.f()); + }), Y.size !== 0 && Re(Ue); +} +function dt(n) { + let t; + return Y.size === 0 && Re(Ue), { + promise: new Promise((e) => { + Y.add(t = { c: n, f: e }); + }), + abort() { + Y.delete(t); + } + }; +} +const H = []; +function mt(n, t = ee) { + let e; + const l = /* @__PURE__ */ new Set(); + function i(a) { + if (ct(n, a) && (n = a, e)) { + const r = !H.length; + for (const s of l) + s[1](), H.push(s, n); + if (r) { + for (let s = 0; s < H.length; s += 2) + H[s][0](H[s + 1]); + H.length = 0; + } + } + } + function f(a) { + i(a(n)); + } + function o(a, r = ee) { + const s = [a, r]; + return l.add(s), l.size === 1 && (e = t(i, f) || ee), a(n), () => { + l.delete(s), l.size === 0 && e && (e(), e = null); + }; + } + return { set: i, update: f, subscribe: o }; +} +function ye(n) { + return Object.prototype.toString.call(n) === "[object Date]"; +} +function se(n, t, e, l) { + if (typeof e == "number" || ye(e)) { + const i = l - e, f = (e - t) / (n.dt || 1 / 60), o = n.opts.stiffness * i, a = n.opts.damping * f, r = (o - a) * n.inv_mass, s = (f + r) * n.dt; + return Math.abs(s) < n.opts.precision && Math.abs(i) < n.opts.precision ? l : (n.settled = !1, ye(e) ? new Date(e.getTime() + s) : e + s); + } else { + if (Array.isArray(e)) + return e.map( + (i, f) => se(n, t[f], e[f], l[f]) + ); + if (typeof e == "object") { + const i = {}; + for (const f in e) + i[f] = se(n, t[f], e[f], l[f]); + return i; + } else + throw new Error(`Cannot spring ${typeof e} values`); + } +} +function ke(n, t = {}) { + const e = mt(n), { stiffness: l = 0.15, damping: i = 0.8, precision: f = 0.01 } = t; + let o, a, r, s = n, _ = n, c = 1, w = 0, h = !1; + function y(p, L = {}) { + _ = p; + const F = r = {}; + return n == null || L.hard || C.stiffness >= 1 && C.damping >= 1 ? (h = !0, o = ve(), s = p, e.set(n = _), Promise.resolve()) : (L.soft && (w = 1 / ((L.soft === !0 ? 0.5 : +L.soft) * 60), c = 0), a || (o = ve(), h = !1, a = dt((u) => { + if (h) + return h = !1, a = null, !1; + c = Math.min(c + w, 1); + const k = { + inv_mass: c, + opts: C, + settled: !0, + dt: (u - o) * 60 / 1e3 + }, m = se(k, s, n, _); + return o = u, s = n, e.set(n = m), k.settled && (a = null), !k.settled; + })), new Promise((u) => { + a.promise.then(() => { + F === r && u(); + }); + })); + } + const C = { + set: y, + update: (p, L) => y(p(_, n), L), + subscribe: e.subscribe, + stiffness: l, + damping: i, + precision: f + }; + return C; +} +const { + SvelteComponent: bt, + append: N, + attr: v, + component_subscribe: pe, + detach: gt, + element: ht, + init: wt, + insert: vt, + noop: qe, + safe_not_equal: yt, + set_style: x, + svg_element: T, + toggle_class: Fe +} = window.__gradio__svelte__internal, { onMount: kt } = window.__gradio__svelte__internal; +function pt(n) { + let t, e, l, i, f, o, a, r, s, _, c, w; + return { + c() { + t = ht("div"), e = T("svg"), l = T("g"), i = T("path"), f = T("path"), o = T("path"), a = T("path"), r = T("g"), s = T("path"), _ = T("path"), c = T("path"), w = T("path"), v(i, "d", "M255.926 0.754768L509.702 139.936V221.027L255.926 81.8465V0.754768Z"), v(i, "fill", "#FF7C00"), v(i, "fill-opacity", "0.4"), v(i, "class", "svelte-43sxxs"), v(f, "d", "M509.69 139.936L254.981 279.641V361.255L509.69 221.55V139.936Z"), v(f, "fill", "#FF7C00"), v(f, "class", "svelte-43sxxs"), v(o, "d", "M0.250138 139.937L254.981 279.641V361.255L0.250138 221.55V139.937Z"), v(o, "fill", "#FF7C00"), v(o, "fill-opacity", "0.4"), v(o, "class", "svelte-43sxxs"), v(a, "d", "M255.923 0.232622L0.236328 139.936V221.55L255.923 81.8469V0.232622Z"), v(a, "fill", "#FF7C00"), v(a, "class", "svelte-43sxxs"), x(l, "transform", "translate(" + /*$top*/ + n[1][0] + "px, " + /*$top*/ + n[1][1] + "px)"), v(s, "d", "M255.926 141.5L509.702 280.681V361.773L255.926 222.592V141.5Z"), v(s, "fill", "#FF7C00"), v(s, "fill-opacity", "0.4"), v(s, "class", "svelte-43sxxs"), v(_, "d", "M509.69 280.679L254.981 420.384V501.998L509.69 362.293V280.679Z"), v(_, "fill", "#FF7C00"), v(_, "class", "svelte-43sxxs"), v(c, "d", "M0.250138 280.681L254.981 420.386V502L0.250138 362.295V280.681Z"), v(c, "fill", "#FF7C00"), v(c, "fill-opacity", "0.4"), v(c, "class", "svelte-43sxxs"), v(w, "d", "M255.923 140.977L0.236328 280.68V362.294L255.923 222.591V140.977Z"), v(w, "fill", "#FF7C00"), v(w, "class", "svelte-43sxxs"), x(r, "transform", "translate(" + /*$bottom*/ + n[2][0] + "px, " + /*$bottom*/ + n[2][1] + "px)"), v(e, "viewBox", "-1200 -1200 3000 3000"), v(e, "fill", "none"), v(e, "xmlns", "http://www.w3.org/2000/svg"), v(e, "class", "svelte-43sxxs"), v(t, "class", "svelte-43sxxs"), Fe( + t, + "margin", + /*margin*/ + n[0] + ); + }, + m(h, y) { + vt(h, t, y), N(t, e), N(e, l), N(l, i), N(l, f), N(l, o), N(l, a), N(e, r), N(r, s), N(r, _), N(r, c), N(r, w); + }, + p(h, [y]) { + y & /*$top*/ + 2 && x(l, "transform", "translate(" + /*$top*/ + h[1][0] + "px, " + /*$top*/ + h[1][1] + "px)"), y & /*$bottom*/ + 4 && x(r, "transform", "translate(" + /*$bottom*/ + h[2][0] + "px, " + /*$bottom*/ + h[2][1] + "px)"), y & /*margin*/ + 1 && Fe( + t, + "margin", + /*margin*/ + h[0] + ); + }, + i: qe, + o: qe, + d(h) { + h && gt(t); + } + }; +} +function qt(n, t, e) { + let l, i, { margin: f = !0 } = t; + const o = ke([0, 0]); + pe(n, o, (w) => e(1, l = w)); + const a = ke([0, 0]); + pe(n, a, (w) => e(2, i = w)); + let r; + async function s() { + await Promise.all([o.set([125, 140]), a.set([-125, -140])]), await Promise.all([o.set([-125, 140]), a.set([125, -140])]), await Promise.all([o.set([-125, 0]), a.set([125, -0])]), await Promise.all([o.set([125, 0]), a.set([-125, 0])]); + } + async function _() { + await s(), r || _(); + } + async function c() { + await Promise.all([o.set([125, 0]), a.set([-125, 0])]), _(); + } + return kt(() => (c(), () => r = !0)), n.$$set = (w) => { + "margin" in w && e(0, f = w.margin); + }, [f, l, i, o, a]; +} +class Ft extends bt { + constructor(t) { + super(), wt(this, t, qt, pt, yt, { margin: 0 }); + } +} +const { + SvelteComponent: Lt, + append: I, + attr: z, + binding_callbacks: Le, + check_outros: Je, + create_component: Ct, + create_slot: Mt, + destroy_component: Vt, + destroy_each: Ke, + detach: b, + element: P, + empty: R, + ensure_array_like: te, + get_all_dirty_from_scope: St, + get_slot_changes: Nt, + group_outros: Qe, + init: Tt, + insert: g, + mount_component: zt, + noop: fe, + safe_not_equal: jt, + set_data: S, + set_style: A, + space: j, + text: q, + toggle_class: V, + transition_in: G, + transition_out: O, + update_slot_base: Pt +} = window.__gradio__svelte__internal, { tick: Zt } = window.__gradio__svelte__internal, { onDestroy: Bt } = window.__gradio__svelte__internal, At = (n) => ({}), Ce = (n) => ({}); +function Me(n, t, e) { + const l = n.slice(); + return l[38] = t[e], l[40] = e, l; +} +function Ve(n, t, e) { + const l = n.slice(); + return l[38] = t[e], l; +} +function Dt(n) { + let t, e = ( + /*i18n*/ + n[1]("common.error") + "" + ), l, i, f; + const o = ( + /*#slots*/ + n[29].error + ), a = Mt( + o, + n, + /*$$scope*/ + n[28], + Ce + ); + return { + c() { + t = P("span"), l = q(e), i = j(), a && a.c(), z(t, "class", "error svelte-1txqlrd"); + }, + m(r, s) { + g(r, t, s), I(t, l), g(r, i, s), a && a.m(r, s), f = !0; + }, + p(r, s) { + (!f || s[0] & /*i18n*/ + 2) && e !== (e = /*i18n*/ + r[1]("common.error") + "") && S(l, e), a && a.p && (!f || s[0] & /*$$scope*/ + 268435456) && Pt( + a, + o, + r, + /*$$scope*/ + r[28], + f ? Nt( + o, + /*$$scope*/ + r[28], + s, + At + ) : St( + /*$$scope*/ + r[28] + ), + Ce + ); + }, + i(r) { + f || (G(a, r), f = !0); + }, + o(r) { + O(a, r), f = !1; + }, + d(r) { + r && (b(t), b(i)), a && a.d(r); + } + }; +} +function Et(n) { + let t, e, l, i, f, o, a, r, s, _ = ( + /*variant*/ + n[8] === "default" && /*show_eta_bar*/ + n[18] && /*show_progress*/ + n[6] === "full" && Se(n) + ); + function c(u, k) { + if ( + /*progress*/ + u[7] + ) + return Xt; + if ( + /*queue_position*/ + u[2] !== null && /*queue_size*/ + u[3] !== void 0 && /*queue_position*/ + u[2] >= 0 + ) + return Ht; + if ( + /*queue_position*/ + u[2] === 0 + ) + return It; + } + let w = c(n), h = w && w(n), y = ( + /*timer*/ + n[5] && ze(n) + ); + const C = [Rt, Ot], p = []; + function L(u, k) { + return ( + /*last_progress_level*/ + u[15] != null ? 0 : ( + /*show_progress*/ + u[6] === "full" ? 1 : -1 + ) + ); + } + ~(f = L(n)) && (o = p[f] = C[f](n)); + let F = !/*timer*/ + n[5] && Ee(n); + return { + c() { + _ && _.c(), t = j(), e = P("div"), h && h.c(), l = j(), y && y.c(), i = j(), o && o.c(), a = j(), F && F.c(), r = R(), z(e, "class", "progress-text svelte-1txqlrd"), V( + e, + "meta-text-center", + /*variant*/ + n[8] === "center" + ), V( + e, + "meta-text", + /*variant*/ + n[8] === "default" + ); + }, + m(u, k) { + _ && _.m(u, k), g(u, t, k), g(u, e, k), h && h.m(e, null), I(e, l), y && y.m(e, null), g(u, i, k), ~f && p[f].m(u, k), g(u, a, k), F && F.m(u, k), g(u, r, k), s = !0; + }, + p(u, k) { + /*variant*/ + u[8] === "default" && /*show_eta_bar*/ + u[18] && /*show_progress*/ + u[6] === "full" ? _ ? _.p(u, k) : (_ = Se(u), _.c(), _.m(t.parentNode, t)) : _ && (_.d(1), _ = null), w === (w = c(u)) && h ? h.p(u, k) : (h && h.d(1), h = w && w(u), h && (h.c(), h.m(e, l))), /*timer*/ + u[5] ? y ? y.p(u, k) : (y = ze(u), y.c(), y.m(e, null)) : y && (y.d(1), y = null), (!s || k[0] & /*variant*/ + 256) && V( + e, + "meta-text-center", + /*variant*/ + u[8] === "center" + ), (!s || k[0] & /*variant*/ + 256) && V( + e, + "meta-text", + /*variant*/ + u[8] === "default" + ); + let m = f; + f = L(u), f === m ? ~f && p[f].p(u, k) : (o && (Qe(), O(p[m], 1, 1, () => { + p[m] = null; + }), Je()), ~f ? (o = p[f], o ? o.p(u, k) : (o = p[f] = C[f](u), o.c()), G(o, 1), o.m(a.parentNode, a)) : o = null), /*timer*/ + u[5] ? F && (F.d(1), F = null) : F ? F.p(u, k) : (F = Ee(u), F.c(), F.m(r.parentNode, r)); + }, + i(u) { + s || (G(o), s = !0); + }, + o(u) { + O(o), s = !1; + }, + d(u) { + u && (b(t), b(e), b(i), b(a), b(r)), _ && _.d(u), h && h.d(), y && y.d(), ~f && p[f].d(u), F && F.d(u); + } + }; +} +function Se(n) { + let t, e = `translateX(${/*eta_level*/ + (n[17] || 0) * 100 - 100}%)`; + return { + c() { + t = P("div"), z(t, "class", "eta-bar svelte-1txqlrd"), A(t, "transform", e); + }, + m(l, i) { + g(l, t, i); + }, + p(l, i) { + i[0] & /*eta_level*/ + 131072 && e !== (e = `translateX(${/*eta_level*/ + (l[17] || 0) * 100 - 100}%)`) && A(t, "transform", e); + }, + d(l) { + l && b(t); + } + }; +} +function It(n) { + let t; + return { + c() { + t = q("processing |"); + }, + m(e, l) { + g(e, t, l); + }, + p: fe, + d(e) { + e && b(t); + } + }; +} +function Ht(n) { + let t, e = ( + /*queue_position*/ + n[2] + 1 + "" + ), l, i, f, o; + return { + c() { + t = q("queue: "), l = q(e), i = q("/"), f = q( + /*queue_size*/ + n[3] + ), o = q(" |"); + }, + m(a, r) { + g(a, t, r), g(a, l, r), g(a, i, r), g(a, f, r), g(a, o, r); + }, + p(a, r) { + r[0] & /*queue_position*/ + 4 && e !== (e = /*queue_position*/ + a[2] + 1 + "") && S(l, e), r[0] & /*queue_size*/ + 8 && S( + f, + /*queue_size*/ + a[3] + ); + }, + d(a) { + a && (b(t), b(l), b(i), b(f), b(o)); + } + }; +} +function Xt(n) { + let t, e = te( + /*progress*/ + n[7] + ), l = []; + for (let i = 0; i < e.length; i += 1) + l[i] = Te(Ve(n, e, i)); + return { + c() { + for (let i = 0; i < l.length; i += 1) + l[i].c(); + t = R(); + }, + m(i, f) { + for (let o = 0; o < l.length; o += 1) + l[o] && l[o].m(i, f); + g(i, t, f); + }, + p(i, f) { + if (f[0] & /*progress*/ + 128) { + e = te( + /*progress*/ + i[7] + ); + let o; + for (o = 0; o < e.length; o += 1) { + const a = Ve(i, e, o); + l[o] ? l[o].p(a, f) : (l[o] = Te(a), l[o].c(), l[o].m(t.parentNode, t)); + } + for (; o < l.length; o += 1) + l[o].d(1); + l.length = e.length; + } + }, + d(i) { + i && b(t), Ke(l, i); + } + }; +} +function Ne(n) { + let t, e = ( + /*p*/ + n[38].unit + "" + ), l, i, f = " ", o; + function a(_, c) { + return ( + /*p*/ + _[38].length != null ? Gt : Yt + ); + } + let r = a(n), s = r(n); + return { + c() { + s.c(), t = j(), l = q(e), i = q(" | "), o = q(f); + }, + m(_, c) { + s.m(_, c), g(_, t, c), g(_, l, c), g(_, i, c), g(_, o, c); + }, + p(_, c) { + r === (r = a(_)) && s ? s.p(_, c) : (s.d(1), s = r(_), s && (s.c(), s.m(t.parentNode, t))), c[0] & /*progress*/ + 128 && e !== (e = /*p*/ + _[38].unit + "") && S(l, e); + }, + d(_) { + _ && (b(t), b(l), b(i), b(o)), s.d(_); + } + }; +} +function Yt(n) { + let t = X( + /*p*/ + n[38].index || 0 + ) + "", e; + return { + c() { + e = q(t); + }, + m(l, i) { + g(l, e, i); + }, + p(l, i) { + i[0] & /*progress*/ + 128 && t !== (t = X( + /*p*/ + l[38].index || 0 + ) + "") && S(e, t); + }, + d(l) { + l && b(e); + } + }; +} +function Gt(n) { + let t = X( + /*p*/ + n[38].index || 0 + ) + "", e, l, i = X( + /*p*/ + n[38].length + ) + "", f; + return { + c() { + e = q(t), l = q("/"), f = q(i); + }, + m(o, a) { + g(o, e, a), g(o, l, a), g(o, f, a); + }, + p(o, a) { + a[0] & /*progress*/ + 128 && t !== (t = X( + /*p*/ + o[38].index || 0 + ) + "") && S(e, t), a[0] & /*progress*/ + 128 && i !== (i = X( + /*p*/ + o[38].length + ) + "") && S(f, i); + }, + d(o) { + o && (b(e), b(l), b(f)); + } + }; +} +function Te(n) { + let t, e = ( + /*p*/ + n[38].index != null && Ne(n) + ); + return { + c() { + e && e.c(), t = R(); + }, + m(l, i) { + e && e.m(l, i), g(l, t, i); + }, + p(l, i) { + /*p*/ + l[38].index != null ? e ? e.p(l, i) : (e = Ne(l), e.c(), e.m(t.parentNode, t)) : e && (e.d(1), e = null); + }, + d(l) { + l && b(t), e && e.d(l); + } + }; +} +function ze(n) { + let t, e = ( + /*eta*/ + n[0] ? `/${/*formatted_eta*/ + n[19]}` : "" + ), l, i; + return { + c() { + t = q( + /*formatted_timer*/ + n[20] + ), l = q(e), i = q("s"); + }, + m(f, o) { + g(f, t, o), g(f, l, o), g(f, i, o); + }, + p(f, o) { + o[0] & /*formatted_timer*/ + 1048576 && S( + t, + /*formatted_timer*/ + f[20] + ), o[0] & /*eta, formatted_eta*/ + 524289 && e !== (e = /*eta*/ + f[0] ? `/${/*formatted_eta*/ + f[19]}` : "") && S(l, e); + }, + d(f) { + f && (b(t), b(l), b(i)); + } + }; +} +function Ot(n) { + let t, e; + return t = new Ft({ + props: { margin: ( + /*variant*/ + n[8] === "default" + ) } + }), { + c() { + Ct(t.$$.fragment); + }, + m(l, i) { + zt(t, l, i), e = !0; + }, + p(l, i) { + const f = {}; + i[0] & /*variant*/ + 256 && (f.margin = /*variant*/ + l[8] === "default"), t.$set(f); + }, + i(l) { + e || (G(t.$$.fragment, l), e = !0); + }, + o(l) { + O(t.$$.fragment, l), e = !1; + }, + d(l) { + Vt(t, l); + } + }; +} +function Rt(n) { + let t, e, l, i, f, o = `${/*last_progress_level*/ + n[15] * 100}%`, a = ( + /*progress*/ + n[7] != null && je(n) + ); + return { + c() { + t = P("div"), e = P("div"), a && a.c(), l = j(), i = P("div"), f = P("div"), z(e, "class", "progress-level-inner svelte-1txqlrd"), z(f, "class", "progress-bar svelte-1txqlrd"), A(f, "width", o), z(i, "class", "progress-bar-wrap svelte-1txqlrd"), z(t, "class", "progress-level svelte-1txqlrd"); + }, + m(r, s) { + g(r, t, s), I(t, e), a && a.m(e, null), I(t, l), I(t, i), I(i, f), n[30](f); + }, + p(r, s) { + /*progress*/ + r[7] != null ? a ? a.p(r, s) : (a = je(r), a.c(), a.m(e, null)) : a && (a.d(1), a = null), s[0] & /*last_progress_level*/ + 32768 && o !== (o = `${/*last_progress_level*/ + r[15] * 100}%`) && A(f, "width", o); + }, + i: fe, + o: fe, + d(r) { + r && b(t), a && a.d(), n[30](null); + } + }; +} +function je(n) { + let t, e = te( + /*progress*/ + n[7] + ), l = []; + for (let i = 0; i < e.length; i += 1) + l[i] = De(Me(n, e, i)); + return { + c() { + for (let i = 0; i < l.length; i += 1) + l[i].c(); + t = R(); + }, + m(i, f) { + for (let o = 0; o < l.length; o += 1) + l[o] && l[o].m(i, f); + g(i, t, f); + }, + p(i, f) { + if (f[0] & /*progress_level, progress*/ + 16512) { + e = te( + /*progress*/ + i[7] + ); + let o; + for (o = 0; o < e.length; o += 1) { + const a = Me(i, e, o); + l[o] ? l[o].p(a, f) : (l[o] = De(a), l[o].c(), l[o].m(t.parentNode, t)); + } + for (; o < l.length; o += 1) + l[o].d(1); + l.length = e.length; + } + }, + d(i) { + i && b(t), Ke(l, i); + } + }; +} +function Pe(n) { + let t, e, l, i, f = ( + /*i*/ + n[40] !== 0 && Ut() + ), o = ( + /*p*/ + n[38].desc != null && Ze(n) + ), a = ( + /*p*/ + n[38].desc != null && /*progress_level*/ + n[14] && /*progress_level*/ + n[14][ + /*i*/ + n[40] + ] != null && Be() + ), r = ( + /*progress_level*/ + n[14] != null && Ae(n) + ); + return { + c() { + f && f.c(), t = j(), o && o.c(), e = j(), a && a.c(), l = j(), r && r.c(), i = R(); + }, + m(s, _) { + f && f.m(s, _), g(s, t, _), o && o.m(s, _), g(s, e, _), a && a.m(s, _), g(s, l, _), r && r.m(s, _), g(s, i, _); + }, + p(s, _) { + /*p*/ + s[38].desc != null ? o ? o.p(s, _) : (o = Ze(s), o.c(), o.m(e.parentNode, e)) : o && (o.d(1), o = null), /*p*/ + s[38].desc != null && /*progress_level*/ + s[14] && /*progress_level*/ + s[14][ + /*i*/ + s[40] + ] != null ? a || (a = Be(), a.c(), a.m(l.parentNode, l)) : a && (a.d(1), a = null), /*progress_level*/ + s[14] != null ? r ? r.p(s, _) : (r = Ae(s), r.c(), r.m(i.parentNode, i)) : r && (r.d(1), r = null); + }, + d(s) { + s && (b(t), b(e), b(l), b(i)), f && f.d(s), o && o.d(s), a && a.d(s), r && r.d(s); + } + }; +} +function Ut(n) { + let t; + return { + c() { + t = q("ย /"); + }, + m(e, l) { + g(e, t, l); + }, + d(e) { + e && b(t); + } + }; +} +function Ze(n) { + let t = ( + /*p*/ + n[38].desc + "" + ), e; + return { + c() { + e = q(t); + }, + m(l, i) { + g(l, e, i); + }, + p(l, i) { + i[0] & /*progress*/ + 128 && t !== (t = /*p*/ + l[38].desc + "") && S(e, t); + }, + d(l) { + l && b(e); + } + }; +} +function Be(n) { + let t; + return { + c() { + t = q("-"); + }, + m(e, l) { + g(e, t, l); + }, + d(e) { + e && b(t); + } + }; +} +function Ae(n) { + let t = (100 * /*progress_level*/ + (n[14][ + /*i*/ + n[40] + ] || 0)).toFixed(1) + "", e, l; + return { + c() { + e = q(t), l = q("%"); + }, + m(i, f) { + g(i, e, f), g(i, l, f); + }, + p(i, f) { + f[0] & /*progress_level*/ + 16384 && t !== (t = (100 * /*progress_level*/ + (i[14][ + /*i*/ + i[40] + ] || 0)).toFixed(1) + "") && S(e, t); + }, + d(i) { + i && (b(e), b(l)); + } + }; +} +function De(n) { + let t, e = ( + /*p*/ + (n[38].desc != null || /*progress_level*/ + n[14] && /*progress_level*/ + n[14][ + /*i*/ + n[40] + ] != null) && Pe(n) + ); + return { + c() { + e && e.c(), t = R(); + }, + m(l, i) { + e && e.m(l, i), g(l, t, i); + }, + p(l, i) { + /*p*/ + l[38].desc != null || /*progress_level*/ + l[14] && /*progress_level*/ + l[14][ + /*i*/ + l[40] + ] != null ? e ? e.p(l, i) : (e = Pe(l), e.c(), e.m(t.parentNode, t)) : e && (e.d(1), e = null); + }, + d(l) { + l && b(t), e && e.d(l); + } + }; +} +function Ee(n) { + let t, e; + return { + c() { + t = P("p"), e = q( + /*loading_text*/ + n[9] + ), z(t, "class", "loading svelte-1txqlrd"); + }, + m(l, i) { + g(l, t, i), I(t, e); + }, + p(l, i) { + i[0] & /*loading_text*/ + 512 && S( + e, + /*loading_text*/ + l[9] + ); + }, + d(l) { + l && b(t); + } + }; +} +function Jt(n) { + let t, e, l, i, f; + const o = [Et, Dt], a = []; + function r(s, _) { + return ( + /*status*/ + s[4] === "pending" ? 0 : ( + /*status*/ + s[4] === "error" ? 1 : -1 + ) + ); + } + return ~(e = r(n)) && (l = a[e] = o[e](n)), { + c() { + t = P("div"), l && l.c(), z(t, "class", i = "wrap " + /*variant*/ + n[8] + " " + /*show_progress*/ + n[6] + " svelte-1txqlrd"), V(t, "hide", !/*status*/ + n[4] || /*status*/ + n[4] === "complete" || /*show_progress*/ + n[6] === "hidden"), V( + t, + "translucent", + /*variant*/ + n[8] === "center" && /*status*/ + (n[4] === "pending" || /*status*/ + n[4] === "error") || /*translucent*/ + n[11] || /*show_progress*/ + n[6] === "minimal" + ), V( + t, + "generating", + /*status*/ + n[4] === "generating" + ), V( + t, + "border", + /*border*/ + n[12] + ), A( + t, + "position", + /*absolute*/ + n[10] ? "absolute" : "static" + ), A( + t, + "padding", + /*absolute*/ + n[10] ? "0" : "var(--size-8) 0" + ); + }, + m(s, _) { + g(s, t, _), ~e && a[e].m(t, null), n[31](t), f = !0; + }, + p(s, _) { + let c = e; + e = r(s), e === c ? ~e && a[e].p(s, _) : (l && (Qe(), O(a[c], 1, 1, () => { + a[c] = null; + }), Je()), ~e ? (l = a[e], l ? l.p(s, _) : (l = a[e] = o[e](s), l.c()), G(l, 1), l.m(t, null)) : l = null), (!f || _[0] & /*variant, show_progress*/ + 320 && i !== (i = "wrap " + /*variant*/ + s[8] + " " + /*show_progress*/ + s[6] + " svelte-1txqlrd")) && z(t, "class", i), (!f || _[0] & /*variant, show_progress, status, show_progress*/ + 336) && V(t, "hide", !/*status*/ + s[4] || /*status*/ + s[4] === "complete" || /*show_progress*/ + s[6] === "hidden"), (!f || _[0] & /*variant, show_progress, variant, status, translucent, show_progress*/ + 2384) && V( + t, + "translucent", + /*variant*/ + s[8] === "center" && /*status*/ + (s[4] === "pending" || /*status*/ + s[4] === "error") || /*translucent*/ + s[11] || /*show_progress*/ + s[6] === "minimal" + ), (!f || _[0] & /*variant, show_progress, status*/ + 336) && V( + t, + "generating", + /*status*/ + s[4] === "generating" + ), (!f || _[0] & /*variant, show_progress, border*/ + 4416) && V( + t, + "border", + /*border*/ + s[12] + ), _[0] & /*absolute*/ + 1024 && A( + t, + "position", + /*absolute*/ + s[10] ? "absolute" : "static" + ), _[0] & /*absolute*/ + 1024 && A( + t, + "padding", + /*absolute*/ + s[10] ? "0" : "var(--size-8) 0" + ); + }, + i(s) { + f || (G(l), f = !0); + }, + o(s) { + O(l), f = !1; + }, + d(s) { + s && b(t), ~e && a[e].d(), n[31](null); + } + }; +} +let $ = [], ie = !1; +async function Kt(n, t = !0) { + if (!(window.__gradio_mode__ === "website" || window.__gradio_mode__ !== "app" && t !== !0)) { + if ($.push(n), !ie) + ie = !0; + else + return; + await Zt(), requestAnimationFrame(() => { + let e = [0, 0]; + for (let l = 0; l < $.length; l++) { + const f = $[l].getBoundingClientRect(); + (l === 0 || f.top + window.scrollY <= e[0]) && (e[0] = f.top + window.scrollY, e[1] = l); + } + window.scrollTo({ top: e[0] - 20, behavior: "smooth" }), ie = !1, $ = []; + }); + } +} +function Qt(n, t, e) { + let l, { $$slots: i = {}, $$scope: f } = t, { i18n: o } = t, { eta: a = null } = t, { queue: r = !1 } = t, { queue_position: s } = t, { queue_size: _ } = t, { status: c } = t, { scroll_to_output: w = !1 } = t, { timer: h = !0 } = t, { show_progress: y = "full" } = t, { message: C = null } = t, { progress: p = null } = t, { variant: L = "default" } = t, { loading_text: F = "Loading..." } = t, { absolute: u = !0 } = t, { translucent: k = !1 } = t, { border: m = !1 } = t, { autoscroll: le } = t, U, J = !1, Q = 0, D = 0, ne = null, ce = 0, E = null, K, Z = null, de = !0; + const $e = () => { + e(25, Q = performance.now()), e(26, D = 0), J = !0, me(); + }; + function me() { + requestAnimationFrame(() => { + e(26, D = (performance.now() - Q) / 1e3), J && me(); + }); + } + function be() { + e(26, D = 0), J && (J = !1); + } + Bt(() => { + J && be(); + }); + let ge = null; + function et(d) { + Le[d ? "unshift" : "push"](() => { + Z = d, e(16, Z), e(7, p), e(14, E), e(15, K); + }); + } + function tt(d) { + Le[d ? "unshift" : "push"](() => { + U = d, e(13, U); + }); + } + return n.$$set = (d) => { + "i18n" in d && e(1, o = d.i18n), "eta" in d && e(0, a = d.eta), "queue" in d && e(21, r = d.queue), "queue_position" in d && e(2, s = d.queue_position), "queue_size" in d && e(3, _ = d.queue_size), "status" in d && e(4, c = d.status), "scroll_to_output" in d && e(22, w = d.scroll_to_output), "timer" in d && e(5, h = d.timer), "show_progress" in d && e(6, y = d.show_progress), "message" in d && e(23, C = d.message), "progress" in d && e(7, p = d.progress), "variant" in d && e(8, L = d.variant), "loading_text" in d && e(9, F = d.loading_text), "absolute" in d && e(10, u = d.absolute), "translucent" in d && e(11, k = d.translucent), "border" in d && e(12, m = d.border), "autoscroll" in d && e(24, le = d.autoscroll), "$$scope" in d && e(28, f = d.$$scope); + }, n.$$.update = () => { + n.$$.dirty[0] & /*eta, old_eta, queue, timer_start*/ + 169869313 && (a === null ? e(0, a = ne) : r && e(0, a = (performance.now() - Q) / 1e3 + a), a != null && (e(19, ge = a.toFixed(1)), e(27, ne = a))), n.$$.dirty[0] & /*eta, timer_diff*/ + 67108865 && e(17, ce = a === null || a <= 0 || !D ? null : Math.min(D / a, 1)), n.$$.dirty[0] & /*progress*/ + 128 && p != null && e(18, de = !1), n.$$.dirty[0] & /*progress, progress_level, progress_bar, last_progress_level*/ + 114816 && (p != null ? e(14, E = p.map((d) => { + if (d.index != null && d.length != null) + return d.index / d.length; + if (d.progress != null) + return d.progress; + })) : e(14, E = null), E ? (e(15, K = E[E.length - 1]), Z && (K === 0 ? e(16, Z.style.transition = "0", Z) : e(16, Z.style.transition = "150ms", Z))) : e(15, K = void 0)), n.$$.dirty[0] & /*status*/ + 16 && (c === "pending" ? $e() : be()), n.$$.dirty[0] & /*el, scroll_to_output, status, autoscroll*/ + 20979728 && U && w && (c === "pending" || c === "complete") && Kt(U, le), n.$$.dirty[0] & /*status, message*/ + 8388624, n.$$.dirty[0] & /*timer_diff*/ + 67108864 && e(20, l = D.toFixed(1)); + }, [ + a, + o, + s, + _, + c, + h, + y, + p, + L, + F, + u, + k, + m, + U, + E, + K, + Z, + ce, + de, + ge, + l, + r, + w, + C, + le, + Q, + D, + ne, + f, + i, + et, + tt + ]; +} +class Wt extends Lt { + constructor(t) { + super(), Tt( + this, + t, + Qt, + Jt, + jt, + { + i18n: 1, + eta: 0, + queue: 21, + queue_position: 2, + queue_size: 3, + status: 4, + scroll_to_output: 22, + timer: 5, + show_progress: 6, + message: 23, + progress: 7, + variant: 8, + loading_text: 9, + absolute: 10, + translucent: 11, + border: 12, + autoscroll: 24 + }, + null, + [-1, -1] + ); + } +} +const { + SvelteComponent: xt, + assign: $t, + create_slot: el, + detach: tl, + element: ll, + get_all_dirty_from_scope: nl, + get_slot_changes: il, + get_spread_update: sl, + init: fl, + insert: ol, + safe_not_equal: al, + set_dynamic_element_data: Ie, + set_style: M, + toggle_class: B, + transition_in: We, + transition_out: xe, + update_slot_base: rl +} = window.__gradio__svelte__internal; +function _l(n) { + let t, e, l; + const i = ( + /*#slots*/ + n[17].default + ), f = el( + i, + n, + /*$$scope*/ + n[16], + null + ); + let o = [ + { "data-testid": ( + /*test_id*/ + n[7] + ) }, + { id: ( + /*elem_id*/ + n[2] + ) }, + { + class: e = "block " + /*elem_classes*/ + n[3].join(" ") + " svelte-1t38q2d" + } + ], a = {}; + for (let r = 0; r < o.length; r += 1) + a = $t(a, o[r]); + return { + c() { + t = ll( + /*tag*/ + n[14] + ), f && f.c(), Ie( + /*tag*/ + n[14] + )(t, a), B( + t, + "hidden", + /*visible*/ + n[10] === !1 + ), B( + t, + "padded", + /*padding*/ + n[6] + ), B( + t, + "border_focus", + /*border_mode*/ + n[5] === "focus" + ), B(t, "hide-container", !/*explicit_call*/ + n[8] && !/*container*/ + n[9]), M(t, "height", typeof /*height*/ + n[0] == "number" ? ( + /*height*/ + n[0] + "px" + ) : void 0), M(t, "width", typeof /*width*/ + n[1] == "number" ? `calc(min(${/*width*/ + n[1]}px, 100%))` : void 0), M( + t, + "border-style", + /*variant*/ + n[4] + ), M( + t, + "overflow", + /*allow_overflow*/ + n[11] ? "visible" : "hidden" + ), M( + t, + "flex-grow", + /*scale*/ + n[12] + ), M(t, "min-width", `calc(min(${/*min_width*/ + n[13]}px, 100%))`), M(t, "border-width", "var(--block-border-width)"); + }, + m(r, s) { + ol(r, t, s), f && f.m(t, null), l = !0; + }, + p(r, s) { + f && f.p && (!l || s & /*$$scope*/ + 65536) && rl( + f, + i, + r, + /*$$scope*/ + r[16], + l ? il( + i, + /*$$scope*/ + r[16], + s, + null + ) : nl( + /*$$scope*/ + r[16] + ), + null + ), Ie( + /*tag*/ + r[14] + )(t, a = sl(o, [ + (!l || s & /*test_id*/ + 128) && { "data-testid": ( + /*test_id*/ + r[7] + ) }, + (!l || s & /*elem_id*/ + 4) && { id: ( + /*elem_id*/ + r[2] + ) }, + (!l || s & /*elem_classes*/ + 8 && e !== (e = "block " + /*elem_classes*/ + r[3].join(" ") + " svelte-1t38q2d")) && { class: e } + ])), B( + t, + "hidden", + /*visible*/ + r[10] === !1 + ), B( + t, + "padded", + /*padding*/ + r[6] + ), B( + t, + "border_focus", + /*border_mode*/ + r[5] === "focus" + ), B(t, "hide-container", !/*explicit_call*/ + r[8] && !/*container*/ + r[9]), s & /*height*/ + 1 && M(t, "height", typeof /*height*/ + r[0] == "number" ? ( + /*height*/ + r[0] + "px" + ) : void 0), s & /*width*/ + 2 && M(t, "width", typeof /*width*/ + r[1] == "number" ? `calc(min(${/*width*/ + r[1]}px, 100%))` : void 0), s & /*variant*/ + 16 && M( + t, + "border-style", + /*variant*/ + r[4] + ), s & /*allow_overflow*/ + 2048 && M( + t, + "overflow", + /*allow_overflow*/ + r[11] ? "visible" : "hidden" + ), s & /*scale*/ + 4096 && M( + t, + "flex-grow", + /*scale*/ + r[12] + ), s & /*min_width*/ + 8192 && M(t, "min-width", `calc(min(${/*min_width*/ + r[13]}px, 100%))`); + }, + i(r) { + l || (We(f, r), l = !0); + }, + o(r) { + xe(f, r), l = !1; + }, + d(r) { + r && tl(t), f && f.d(r); + } + }; +} +function ul(n) { + let t, e = ( + /*tag*/ + n[14] && _l(n) + ); + return { + c() { + e && e.c(); + }, + m(l, i) { + e && e.m(l, i), t = !0; + }, + p(l, [i]) { + /*tag*/ + l[14] && e.p(l, i); + }, + i(l) { + t || (We(e, l), t = !0); + }, + o(l) { + xe(e, l), t = !1; + }, + d(l) { + e && e.d(l); + } + }; +} +function cl(n, t, e) { + let { $$slots: l = {}, $$scope: i } = t, { height: f = void 0 } = t, { width: o = void 0 } = t, { elem_id: a = "" } = t, { elem_classes: r = [] } = t, { variant: s = "solid" } = t, { border_mode: _ = "base" } = t, { padding: c = !0 } = t, { type: w = "normal" } = t, { test_id: h = void 0 } = t, { explicit_call: y = !1 } = t, { container: C = !0 } = t, { visible: p = !0 } = t, { allow_overflow: L = !0 } = t, { scale: F = null } = t, { min_width: u = 0 } = t, k = w === "fieldset" ? "fieldset" : "div"; + return n.$$set = (m) => { + "height" in m && e(0, f = m.height), "width" in m && e(1, o = m.width), "elem_id" in m && e(2, a = m.elem_id), "elem_classes" in m && e(3, r = m.elem_classes), "variant" in m && e(4, s = m.variant), "border_mode" in m && e(5, _ = m.border_mode), "padding" in m && e(6, c = m.padding), "type" in m && e(15, w = m.type), "test_id" in m && e(7, h = m.test_id), "explicit_call" in m && e(8, y = m.explicit_call), "container" in m && e(9, C = m.container), "visible" in m && e(10, p = m.visible), "allow_overflow" in m && e(11, L = m.allow_overflow), "scale" in m && e(12, F = m.scale), "min_width" in m && e(13, u = m.min_width), "$$scope" in m && e(16, i = m.$$scope); + }, [ + f, + o, + a, + r, + s, + _, + c, + h, + y, + C, + p, + L, + F, + u, + k, + w, + i, + l + ]; +} +class dl extends xt { + constructor(t) { + super(), fl(this, t, cl, ul, al, { + height: 0, + width: 1, + elem_id: 2, + elem_classes: 3, + variant: 4, + border_mode: 5, + padding: 6, + type: 15, + test_id: 7, + explicit_call: 8, + container: 9, + visible: 10, + allow_overflow: 11, + scale: 12, + min_width: 13 + }); + } +} +const ml = [ + { color: "red", primary: 600, secondary: 100 }, + { color: "green", primary: 600, secondary: 100 }, + { color: "blue", primary: 600, secondary: 100 }, + { color: "yellow", primary: 500, secondary: 100 }, + { color: "purple", primary: 600, secondary: 100 }, + { color: "teal", primary: 600, secondary: 100 }, + { color: "orange", primary: 600, secondary: 100 }, + { color: "cyan", primary: 600, secondary: 100 }, + { color: "lime", primary: 500, secondary: 100 }, + { color: "pink", primary: 600, secondary: 100 } +], He = { + inherit: "inherit", + current: "currentColor", + transparent: "transparent", + black: "#000", + white: "#fff", + slate: { + 50: "#f8fafc", + 100: "#f1f5f9", + 200: "#e2e8f0", + 300: "#cbd5e1", + 400: "#94a3b8", + 500: "#64748b", + 600: "#475569", + 700: "#334155", + 800: "#1e293b", + 900: "#0f172a", + 950: "#020617" + }, + gray: { + 50: "#f9fafb", + 100: "#f3f4f6", + 200: "#e5e7eb", + 300: "#d1d5db", + 400: "#9ca3af", + 500: "#6b7280", + 600: "#4b5563", + 700: "#374151", + 800: "#1f2937", + 900: "#111827", + 950: "#030712" + }, + zinc: { + 50: "#fafafa", + 100: "#f4f4f5", + 200: "#e4e4e7", + 300: "#d4d4d8", + 400: "#a1a1aa", + 500: "#71717a", + 600: "#52525b", + 700: "#3f3f46", + 800: "#27272a", + 900: "#18181b", + 950: "#09090b" + }, + neutral: { + 50: "#fafafa", + 100: "#f5f5f5", + 200: "#e5e5e5", + 300: "#d4d4d4", + 400: "#a3a3a3", + 500: "#737373", + 600: "#525252", + 700: "#404040", + 800: "#262626", + 900: "#171717", + 950: "#0a0a0a" + }, + stone: { + 50: "#fafaf9", + 100: "#f5f5f4", + 200: "#e7e5e4", + 300: "#d6d3d1", + 400: "#a8a29e", + 500: "#78716c", + 600: "#57534e", + 700: "#44403c", + 800: "#292524", + 900: "#1c1917", + 950: "#0c0a09" + }, + red: { + 50: "#fef2f2", + 100: "#fee2e2", + 200: "#fecaca", + 300: "#fca5a5", + 400: "#f87171", + 500: "#ef4444", + 600: "#dc2626", + 700: "#b91c1c", + 800: "#991b1b", + 900: "#7f1d1d", + 950: "#450a0a" + }, + orange: { + 50: "#fff7ed", + 100: "#ffedd5", + 200: "#fed7aa", + 300: "#fdba74", + 400: "#fb923c", + 500: "#f97316", + 600: "#ea580c", + 700: "#c2410c", + 800: "#9a3412", + 900: "#7c2d12", + 950: "#431407" + }, + amber: { + 50: "#fffbeb", + 100: "#fef3c7", + 200: "#fde68a", + 300: "#fcd34d", + 400: "#fbbf24", + 500: "#f59e0b", + 600: "#d97706", + 700: "#b45309", + 800: "#92400e", + 900: "#78350f", + 950: "#451a03" + }, + yellow: { + 50: "#fefce8", + 100: "#fef9c3", + 200: "#fef08a", + 300: "#fde047", + 400: "#facc15", + 500: "#eab308", + 600: "#ca8a04", + 700: "#a16207", + 800: "#854d0e", + 900: "#713f12", + 950: "#422006" + }, + lime: { + 50: "#f7fee7", + 100: "#ecfccb", + 200: "#d9f99d", + 300: "#bef264", + 400: "#a3e635", + 500: "#84cc16", + 600: "#65a30d", + 700: "#4d7c0f", + 800: "#3f6212", + 900: "#365314", + 950: "#1a2e05" + }, + green: { + 50: "#f0fdf4", + 100: "#dcfce7", + 200: "#bbf7d0", + 300: "#86efac", + 400: "#4ade80", + 500: "#22c55e", + 600: "#16a34a", + 700: "#15803d", + 800: "#166534", + 900: "#14532d", + 950: "#052e16" + }, + emerald: { + 50: "#ecfdf5", + 100: "#d1fae5", + 200: "#a7f3d0", + 300: "#6ee7b7", + 400: "#34d399", + 500: "#10b981", + 600: "#059669", + 700: "#047857", + 800: "#065f46", + 900: "#064e3b", + 950: "#022c22" + }, + teal: { + 50: "#f0fdfa", + 100: "#ccfbf1", + 200: "#99f6e4", + 300: "#5eead4", + 400: "#2dd4bf", + 500: "#14b8a6", + 600: "#0d9488", + 700: "#0f766e", + 800: "#115e59", + 900: "#134e4a", + 950: "#042f2e" + }, + cyan: { + 50: "#ecfeff", + 100: "#cffafe", + 200: "#a5f3fc", + 300: "#67e8f9", + 400: "#22d3ee", + 500: "#06b6d4", + 600: "#0891b2", + 700: "#0e7490", + 800: "#155e75", + 900: "#164e63", + 950: "#083344" + }, + sky: { + 50: "#f0f9ff", + 100: "#e0f2fe", + 200: "#bae6fd", + 300: "#7dd3fc", + 400: "#38bdf8", + 500: "#0ea5e9", + 600: "#0284c7", + 700: "#0369a1", + 800: "#075985", + 900: "#0c4a6e", + 950: "#082f49" + }, + blue: { + 50: "#eff6ff", + 100: "#dbeafe", + 200: "#bfdbfe", + 300: "#93c5fd", + 400: "#60a5fa", + 500: "#3b82f6", + 600: "#2563eb", + 700: "#1d4ed8", + 800: "#1e40af", + 900: "#1e3a8a", + 950: "#172554" + }, + indigo: { + 50: "#eef2ff", + 100: "#e0e7ff", + 200: "#c7d2fe", + 300: "#a5b4fc", + 400: "#818cf8", + 500: "#6366f1", + 600: "#4f46e5", + 700: "#4338ca", + 800: "#3730a3", + 900: "#312e81", + 950: "#1e1b4b" + }, + violet: { + 50: "#f5f3ff", + 100: "#ede9fe", + 200: "#ddd6fe", + 300: "#c4b5fd", + 400: "#a78bfa", + 500: "#8b5cf6", + 600: "#7c3aed", + 700: "#6d28d9", + 800: "#5b21b6", + 900: "#4c1d95", + 950: "#2e1065" + }, + purple: { + 50: "#faf5ff", + 100: "#f3e8ff", + 200: "#e9d5ff", + 300: "#d8b4fe", + 400: "#c084fc", + 500: "#a855f7", + 600: "#9333ea", + 700: "#7e22ce", + 800: "#6b21a8", + 900: "#581c87", + 950: "#3b0764" + }, + fuchsia: { + 50: "#fdf4ff", + 100: "#fae8ff", + 200: "#f5d0fe", + 300: "#f0abfc", + 400: "#e879f9", + 500: "#d946ef", + 600: "#c026d3", + 700: "#a21caf", + 800: "#86198f", + 900: "#701a75", + 950: "#4a044e" + }, + pink: { + 50: "#fdf2f8", + 100: "#fce7f3", + 200: "#fbcfe8", + 300: "#f9a8d4", + 400: "#f472b6", + 500: "#ec4899", + 600: "#db2777", + 700: "#be185d", + 800: "#9d174d", + 900: "#831843", + 950: "#500724" + }, + rose: { + 50: "#fff1f2", + 100: "#ffe4e6", + 200: "#fecdd3", + 300: "#fda4af", + 400: "#fb7185", + 500: "#f43f5e", + 600: "#e11d48", + 700: "#be123c", + 800: "#9f1239", + 900: "#881337", + 950: "#4c0519" + } +}; +ml.reduce( + (n, { color: t, primary: e, secondary: l }) => ({ + ...n, + [t]: { + primary: He[t][e], + secondary: He[t][l] + } + }), + {} +); +const { + SvelteComponent: bl, + assign: gl, + attr: hl, + create_component: oe, + destroy_component: ae, + detach: Xe, + element: wl, + get_spread_object: vl, + get_spread_update: yl, + init: kl, + insert: Ye, + mount_component: re, + safe_not_equal: pl, + space: ql, + toggle_class: Ge, + transition_in: _e, + transition_out: ue +} = window.__gradio__svelte__internal; +function Fl(n) { + var r; + let t, e, l, i, f; + const o = [ + { autoscroll: ( + /*gradio*/ + n[5].autoscroll + ) }, + { i18n: ( + /*gradio*/ + n[5].i18n + ) }, + /*loading_status*/ + n[4], + { variant: "center" } + ]; + let a = {}; + for (let s = 0; s < o.length; s += 1) + a = gl(a, o[s]); + return t = new Wt({ props: a }), i = new ut({ + props: { + min_height: ( + /*loading_status*/ + n[4] && /*loading_status*/ + ((r = n[4]) == null ? void 0 : r.status) !== "complete" + ), + value: ( + /*value*/ + n[3] + ), + elem_classes: ( + /*elem_classes*/ + n[1] + ), + visible: ( + /*visible*/ + n[2] + ) + } + }), i.$on( + "change", + /*change_handler*/ + n[7] + ), { + c() { + var s; + oe(t.$$.fragment), e = ql(), l = wl("div"), oe(i.$$.fragment), hl(l, "class", "svelte-gqsrr7"), Ge( + l, + "pending", + /*loading_status*/ + ((s = n[4]) == null ? void 0 : s.status) === "pending" + ); + }, + m(s, _) { + re(t, s, _), Ye(s, e, _), Ye(s, l, _), re(i, l, null), f = !0; + }, + p(s, _) { + var h, y; + const c = _ & /*gradio, loading_status*/ + 48 ? yl(o, [ + _ & /*gradio*/ + 32 && { autoscroll: ( + /*gradio*/ + s[5].autoscroll + ) }, + _ & /*gradio*/ + 32 && { i18n: ( + /*gradio*/ + s[5].i18n + ) }, + _ & /*loading_status*/ + 16 && vl( + /*loading_status*/ + s[4] + ), + o[3] + ]) : {}; + t.$set(c); + const w = {}; + _ & /*loading_status*/ + 16 && (w.min_height = /*loading_status*/ + s[4] && /*loading_status*/ + ((h = s[4]) == null ? void 0 : h.status) !== "complete"), _ & /*value*/ + 8 && (w.value = /*value*/ + s[3]), _ & /*elem_classes*/ + 2 && (w.elem_classes = /*elem_classes*/ + s[1]), _ & /*visible*/ + 4 && (w.visible = /*visible*/ + s[2]), i.$set(w), (!f || _ & /*loading_status*/ + 16) && Ge( + l, + "pending", + /*loading_status*/ + ((y = s[4]) == null ? void 0 : y.status) === "pending" + ); + }, + i(s) { + f || (_e(t.$$.fragment, s), _e(i.$$.fragment, s), f = !0); + }, + o(s) { + ue(t.$$.fragment, s), ue(i.$$.fragment, s), f = !1; + }, + d(s) { + s && (Xe(e), Xe(l)), ae(t, s), ae(i); + } + }; +} +function Ll(n) { + let t, e; + return t = new dl({ + props: { + visible: ( + /*visible*/ + n[2] + ), + elem_id: ( + /*elem_id*/ + n[0] + ), + elem_classes: ( + /*elem_classes*/ + n[1] + ), + container: !1, + $$slots: { default: [Fl] }, + $$scope: { ctx: n } + } + }), { + c() { + oe(t.$$.fragment); + }, + m(l, i) { + re(t, l, i), e = !0; + }, + p(l, [i]) { + const f = {}; + i & /*visible*/ + 4 && (f.visible = /*visible*/ + l[2]), i & /*elem_id*/ + 1 && (f.elem_id = /*elem_id*/ + l[0]), i & /*elem_classes*/ + 2 && (f.elem_classes = /*elem_classes*/ + l[1]), i & /*$$scope, loading_status, value, elem_classes, visible, gradio*/ + 318 && (f.$$scope = { dirty: i, ctx: l }), t.$set(f); + }, + i(l) { + e || (_e(t.$$.fragment, l), e = !0); + }, + o(l) { + ue(t.$$.fragment, l), e = !1; + }, + d(l) { + ae(t, l); + } + }; +} +function Cl(n, t, e) { + let { label: l } = t, { elem_id: i = "" } = t, { elem_classes: f = [] } = t, { visible: o = !0 } = t, { value: a = "" } = t, { loading_status: r } = t, { gradio: s } = t; + const _ = () => s.dispatch("change"); + return n.$$set = (c) => { + "label" in c && e(6, l = c.label), "elem_id" in c && e(0, i = c.elem_id), "elem_classes" in c && e(1, f = c.elem_classes), "visible" in c && e(2, o = c.visible), "value" in c && e(3, a = c.value), "loading_status" in c && e(4, r = c.loading_status), "gradio" in c && e(5, s = c.gradio); + }, n.$$.update = () => { + n.$$.dirty & /*label, gradio*/ + 96 && s.dispatch("change"); + }, [ + i, + f, + o, + a, + r, + s, + l, + _ + ]; +} +class Ml extends bl { + constructor(t) { + super(), kl(this, t, Cl, Ll, pl, { + label: 6, + elem_id: 0, + elem_classes: 1, + visible: 2, + value: 3, + loading_status: 4, + gradio: 5 + }); + } +} +export { + Ml as default +}; diff --git a/components/iframe/backend/gradio_iframe/templates/component/style.css b/components/iframe/backend/gradio_iframe/templates/component/style.css new file mode 100644 index 0000000000000000000000000000000000000000..d0eac3127373d48ad4663c733169a4d5b96400fd --- /dev/null +++ b/components/iframe/backend/gradio_iframe/templates/component/style.css @@ -0,0 +1 @@ +.min.svelte-2qygph{min-height:var(--size-24)}.hide.svelte-2qygph{display:none}svg.svelte-43sxxs.svelte-43sxxs{width:var(--size-20);height:var(--size-20)}svg.svelte-43sxxs path.svelte-43sxxs{fill:var(--loader-color)}div.svelte-43sxxs.svelte-43sxxs{z-index:var(--layer-2)}.margin.svelte-43sxxs.svelte-43sxxs{margin:var(--size-4)}.wrap.svelte-1txqlrd.svelte-1txqlrd{display:flex;flex-direction:column;justify-content:center;align-items:center;z-index:var(--layer-top);transition:opacity .1s ease-in-out;border-radius:var(--block-radius);background:var(--block-background-fill);padding:0 var(--size-6);max-height:var(--size-screen-h);overflow:hidden;pointer-events:none}.wrap.center.svelte-1txqlrd.svelte-1txqlrd{top:0;right:0;left:0}.wrap.default.svelte-1txqlrd.svelte-1txqlrd{top:0;right:0;bottom:0;left:0}.hide.svelte-1txqlrd.svelte-1txqlrd{opacity:0;pointer-events:none}.generating.svelte-1txqlrd.svelte-1txqlrd{animation:svelte-1txqlrd-pulse 2s cubic-bezier(.4,0,.6,1) infinite;border:2px solid var(--color-accent);background:transparent}.translucent.svelte-1txqlrd.svelte-1txqlrd{background:none}@keyframes svelte-1txqlrd-pulse{0%,to{opacity:1}50%{opacity:.5}}.loading.svelte-1txqlrd.svelte-1txqlrd{z-index:var(--layer-2);color:var(--body-text-color)}.eta-bar.svelte-1txqlrd.svelte-1txqlrd{position:absolute;top:0;right:0;bottom:0;left:0;transform-origin:left;opacity:.8;z-index:var(--layer-1);transition:10ms;background:var(--background-fill-secondary)}.progress-bar-wrap.svelte-1txqlrd.svelte-1txqlrd{border:1px solid var(--border-color-primary);background:var(--background-fill-primary);width:55.5%;height:var(--size-4)}.progress-bar.svelte-1txqlrd.svelte-1txqlrd{transform-origin:left;background-color:var(--loader-color);width:var(--size-full);height:var(--size-full)}.progress-level.svelte-1txqlrd.svelte-1txqlrd{display:flex;flex-direction:column;align-items:center;gap:1;z-index:var(--layer-2);width:var(--size-full)}.progress-level-inner.svelte-1txqlrd.svelte-1txqlrd{margin:var(--size-2) auto;color:var(--body-text-color);font-size:var(--text-sm);font-family:var(--font-mono)}.meta-text.svelte-1txqlrd.svelte-1txqlrd{position:absolute;top:0;right:0;z-index:var(--layer-2);padding:var(--size-1) var(--size-2);font-size:var(--text-sm);font-family:var(--font-mono)}.meta-text-center.svelte-1txqlrd.svelte-1txqlrd{display:flex;position:absolute;top:0;right:0;justify-content:center;align-items:center;transform:translateY(var(--size-6));z-index:var(--layer-2);padding:var(--size-1) var(--size-2);font-size:var(--text-sm);font-family:var(--font-mono);text-align:center}.error.svelte-1txqlrd.svelte-1txqlrd{box-shadow:var(--shadow-drop);border:solid 1px var(--error-border-color);border-radius:var(--radius-full);background:var(--error-background-fill);padding-right:var(--size-4);padding-left:var(--size-4);color:var(--error-text-color);font-weight:var(--weight-semibold);font-size:var(--text-lg);line-height:var(--line-lg);font-family:var(--font)}.minimal.svelte-1txqlrd .progress-text.svelte-1txqlrd{background:var(--block-background-fill)}.border.svelte-1txqlrd.svelte-1txqlrd{border:1px solid var(--border-color-primary)}.dropdown-arrow.svelte-145leq6{fill:currentColor}.toast-body.svelte-solcu7{display:flex;position:relative;right:0;left:0;align-items:center;margin:var(--size-6) var(--size-4);margin:auto;border-radius:var(--container-radius);overflow:hidden;pointer-events:auto}.toast-body.error.svelte-solcu7{border:1px solid var(--color-red-700);background:var(--color-red-50)}.dark .toast-body.error.svelte-solcu7{border:1px solid var(--color-red-500);background-color:var(--color-grey-950)}.toast-body.warning.svelte-solcu7{border:1px solid var(--color-yellow-700);background:var(--color-yellow-50)}.dark .toast-body.warning.svelte-solcu7{border:1px solid var(--color-yellow-500);background-color:var(--color-grey-950)}.toast-body.info.svelte-solcu7{border:1px solid var(--color-grey-700);background:var(--color-grey-50)}.dark .toast-body.info.svelte-solcu7{border:1px solid var(--color-grey-500);background-color:var(--color-grey-950)}.toast-title.svelte-solcu7{display:flex;align-items:center;font-weight:var(--weight-bold);font-size:var(--text-lg);line-height:var(--line-sm);text-transform:capitalize}.toast-title.error.svelte-solcu7{color:var(--color-red-700)}.dark .toast-title.error.svelte-solcu7{color:var(--color-red-50)}.toast-title.warning.svelte-solcu7{color:var(--color-yellow-700)}.dark .toast-title.warning.svelte-solcu7{color:var(--color-yellow-50)}.toast-title.info.svelte-solcu7{color:var(--color-grey-700)}.dark .toast-title.info.svelte-solcu7{color:var(--color-grey-50)}.toast-close.svelte-solcu7{margin:0 var(--size-3);border-radius:var(--size-3);padding:0px var(--size-1-5);font-size:var(--size-5);line-height:var(--size-5)}.toast-close.error.svelte-solcu7{color:var(--color-red-700)}.dark .toast-close.error.svelte-solcu7{color:var(--color-red-500)}.toast-close.warning.svelte-solcu7{color:var(--color-yellow-700)}.dark .toast-close.warning.svelte-solcu7{color:var(--color-yellow-500)}.toast-close.info.svelte-solcu7{color:var(--color-grey-700)}.dark .toast-close.info.svelte-solcu7{color:var(--color-grey-500)}.toast-text.svelte-solcu7{font-size:var(--text-lg)}.toast-text.error.svelte-solcu7{color:var(--color-red-700)}.dark .toast-text.error.svelte-solcu7{color:var(--color-red-50)}.toast-text.warning.svelte-solcu7{color:var(--color-yellow-700)}.dark .toast-text.warning.svelte-solcu7{color:var(--color-yellow-50)}.toast-text.info.svelte-solcu7{color:var(--color-grey-700)}.dark .toast-text.info.svelte-solcu7{color:var(--color-grey-50)}.toast-details.svelte-solcu7{margin:var(--size-3) var(--size-3) var(--size-3) 0;width:100%}.toast-icon.svelte-solcu7{display:flex;position:absolute;position:relative;flex-shrink:0;justify-content:center;align-items:center;margin:var(--size-2);border-radius:var(--radius-full);padding:var(--size-1);padding-left:calc(var(--size-1) - 1px);width:35px;height:35px}.toast-icon.error.svelte-solcu7{color:var(--color-red-700)}.dark .toast-icon.error.svelte-solcu7{color:var(--color-red-500)}.toast-icon.warning.svelte-solcu7{color:var(--color-yellow-700)}.dark .toast-icon.warning.svelte-solcu7{color:var(--color-yellow-500)}.toast-icon.info.svelte-solcu7{color:var(--color-grey-700)}.dark .toast-icon.info.svelte-solcu7{color:var(--color-grey-500)}@keyframes svelte-solcu7-countdown{0%{transform:scaleX(1)}to{transform:scaleX(0)}}.timer.svelte-solcu7{position:absolute;bottom:0;left:0;transform-origin:0 0;animation:svelte-solcu7-countdown 10s linear forwards;width:100%;height:var(--size-1)}.timer.error.svelte-solcu7{background:var(--color-red-700)}.dark .timer.error.svelte-solcu7{background:var(--color-red-500)}.timer.warning.svelte-solcu7{background:var(--color-yellow-700)}.dark .timer.warning.svelte-solcu7{background:var(--color-yellow-500)}.timer.info.svelte-solcu7{background:var(--color-grey-700)}.dark .timer.info.svelte-solcu7{background:var(--color-grey-500)}.toast-wrap.svelte-gatr8h{display:flex;position:fixed;top:var(--size-4);right:var(--size-4);flex-direction:column;align-items:end;gap:var(--size-2);z-index:var(--layer-top);width:calc(100% - var(--size-8))}@media (--screen-sm){.toast-wrap.svelte-gatr8h{width:calc(var(--size-96) + var(--size-10))}}.block.svelte-1t38q2d{position:relative;margin:0;box-shadow:var(--block-shadow);border-width:var(--block-border-width);border-color:var(--block-border-color);border-radius:var(--block-radius);background:var(--block-background-fill);width:100%;line-height:var(--line-sm)}.block.border_focus.svelte-1t38q2d{border-color:var(--color-accent)}.padded.svelte-1t38q2d{padding:var(--block-padding)}.hidden.svelte-1t38q2d{display:none}.hide-container.svelte-1t38q2d{margin:0;box-shadow:none;--block-border-width:0;background:transparent;padding:0;overflow:visible}div.svelte-1hnfib2{margin-bottom:var(--spacing-lg);color:var(--block-info-text-color);font-weight:var(--block-info-text-weight);font-size:var(--block-info-text-size);line-height:var(--line-sm)}span.has-info.svelte-22c38v{margin-bottom:var(--spacing-xs)}span.svelte-22c38v:not(.has-info){margin-bottom:var(--spacing-lg)}span.svelte-22c38v{display:inline-block;position:relative;z-index:var(--layer-4);border:solid var(--block-title-border-width) var(--block-title-border-color);border-radius:var(--block-title-radius);background:var(--block-title-background-fill);padding:var(--block-title-padding);color:var(--block-title-text-color);font-weight:var(--block-title-text-weight);font-size:var(--block-title-text-size);line-height:var(--line-sm)}.hide.svelte-22c38v{margin:0;height:0}label.svelte-9gxdi0{display:inline-flex;align-items:center;z-index:var(--layer-2);box-shadow:var(--block-label-shadow);border:var(--block-label-border-width) solid var(--border-color-primary);border-top:none;border-left:none;border-radius:var(--block-label-radius);background:var(--block-label-background-fill);padding:var(--block-label-padding);pointer-events:none;color:var(--block-label-text-color);font-weight:var(--block-label-text-weight);font-size:var(--block-label-text-size);line-height:var(--line-sm)}.gr-group label.svelte-9gxdi0{border-top-left-radius:0}label.float.svelte-9gxdi0{position:absolute;top:var(--block-label-margin);left:var(--block-label-margin)}label.svelte-9gxdi0:not(.float){position:static;margin-top:var(--block-label-margin);margin-left:var(--block-label-margin)}.hide.svelte-9gxdi0{height:0}span.svelte-9gxdi0{opacity:.8;margin-right:var(--size-2);width:calc(var(--block-label-text-size) - 1px);height:calc(var(--block-label-text-size) - 1px)}.hide-label.svelte-9gxdi0{box-shadow:none;border-width:0;background:transparent;overflow:visible}button.svelte-lpi64a{display:flex;justify-content:center;align-items:center;gap:1px;z-index:var(--layer-2);border-radius:var(--radius-sm);color:var(--block-label-text-color);border:1px solid transparent}button[disabled].svelte-lpi64a{opacity:.5;box-shadow:none}button[disabled].svelte-lpi64a:hover{cursor:not-allowed}.padded.svelte-lpi64a{padding:2px;background:var(--bg-color);box-shadow:var(--shadow-drop);border:1px solid var(--button-secondary-border-color)}button.svelte-lpi64a:hover,button.highlight.svelte-lpi64a{cursor:pointer;color:var(--color-accent)}.padded.svelte-lpi64a:hover{border:2px solid var(--button-secondary-border-color-hover);padding:1px;color:var(--block-label-text-color)}span.svelte-lpi64a{padding:0 1px;font-size:10px}div.svelte-lpi64a{padding:2px;display:flex;align-items:flex-end}.small.svelte-lpi64a{width:14px;height:14px}.large.svelte-lpi64a{width:22px;height:22px}.pending.svelte-lpi64a{animation:svelte-lpi64a-flash .5s infinite}@keyframes svelte-lpi64a-flash{0%{opacity:.5}50%{opacity:1}to{opacity:.5}}.transparent.svelte-lpi64a{background:transparent;border:none;box-shadow:none}.empty.svelte-3w3rth{display:flex;justify-content:center;align-items:center;margin-top:calc(0px - var(--size-6));height:var(--size-full)}.icon.svelte-3w3rth{opacity:.5;height:var(--size-5);color:var(--body-text-color)}.small.svelte-3w3rth{min-height:calc(var(--size-32) - 20px)}.large.svelte-3w3rth{min-height:calc(var(--size-64) - 20px)}.unpadded_box.svelte-3w3rth{margin-top:0}.small_parent.svelte-3w3rth{min-height:100%!important}.wrap.svelte-kzcjhc{display:flex;flex-direction:column;justify-content:center;align-items:center;min-height:var(--size-60);color:var(--block-label-text-color);line-height:var(--line-md);height:100%;padding-top:var(--size-3)}.or.svelte-kzcjhc{color:var(--body-text-color-subdued);display:flex}.icon-wrap.svelte-kzcjhc{width:30px;margin-bottom:var(--spacing-lg)}@media (--screen-md){.wrap.svelte-kzcjhc{font-size:var(--text-lg)}}.hovered.svelte-kzcjhc{color:var(--color-accent)}div.svelte-ipfyu7{border-top:1px solid transparent;display:flex;max-height:100%;justify-content:center;gap:var(--spacing-sm);height:auto;align-items:flex-end;padding-bottom:var(--spacing-xl);color:var(--block-label-text-color);flex-shrink:0;width:95%}.show_border.svelte-ipfyu7{border-top:1px solid var(--block-border-color);margin-top:var(--spacing-xxl);box-shadow:var(--shadow-drop)}.source-selection.svelte-lde7lt{display:flex;align-items:center;justify-content:center;border-top:1px solid var(--border-color-primary);width:95%;bottom:0;left:0;right:0;margin-left:auto;margin-right:auto;align-self:flex-end}.icon.svelte-lde7lt{width:22px;height:22px;margin:var(--spacing-lg) var(--spacing-xs);padding:var(--spacing-xs);color:var(--neutral-400);border-radius:var(--radius-md)}.selected.svelte-lde7lt{color:var(--color-accent)}.icon.svelte-lde7lt:hover,.icon.svelte-lde7lt:focus{color:var(--color-accent)}div.svelte-gqsrr7{transition:.15s}.pending.svelte-gqsrr7{opacity:.2} diff --git a/components/iframe/backend/gradio_iframe/templates/example/index.js b/components/iframe/backend/gradio_iframe/templates/example/index.js new file mode 100644 index 0000000000000000000000000000000000000000..b8e3417893925002a924058bafa493967739ecc3 --- /dev/null +++ b/components/iframe/backend/gradio_iframe/templates/example/index.js @@ -0,0 +1,80 @@ +const { + SvelteComponent: c, + attr: u, + detach: r, + element: o, + init: d, + insert: g, + noop: _, + safe_not_equal: v, + toggle_class: s +} = window.__gradio__svelte__internal; +function y(n) { + let e; + return { + c() { + e = o("div"), u(e, "class", "prose svelte-180qqaf"), s( + e, + "table", + /*type*/ + n[1] === "table" + ), s( + e, + "gallery", + /*type*/ + n[1] === "gallery" + ), s( + e, + "selected", + /*selected*/ + n[2] + ); + }, + m(l, t) { + g(l, e, t), e.innerHTML = /*value*/ + n[0]; + }, + p(l, [t]) { + t & /*value*/ + 1 && (e.innerHTML = /*value*/ + l[0]), t & /*type*/ + 2 && s( + e, + "table", + /*type*/ + l[1] === "table" + ), t & /*type*/ + 2 && s( + e, + "gallery", + /*type*/ + l[1] === "gallery" + ), t & /*selected*/ + 4 && s( + e, + "selected", + /*selected*/ + l[2] + ); + }, + i: _, + o: _, + d(l) { + l && r(e); + } + }; +} +function m(n, e, l) { + let { value: t } = e, { type: i } = e, { selected: f = !1 } = e; + return n.$$set = (a) => { + "value" in a && l(0, t = a.value), "type" in a && l(1, i = a.type), "selected" in a && l(2, f = a.selected); + }, [t, i, f]; +} +class b extends c { + constructor(e) { + super(), d(this, e, m, y, v, { value: 0, type: 1, selected: 2 }); + } +} +export { + b as default +}; diff --git a/components/iframe/backend/gradio_iframe/templates/example/style.css b/components/iframe/backend/gradio_iframe/templates/example/style.css new file mode 100644 index 0000000000000000000000000000000000000000..7b2fefc850e459b799798426c780a5402ef0a701 --- /dev/null +++ b/components/iframe/backend/gradio_iframe/templates/example/style.css @@ -0,0 +1 @@ +.gallery.svelte-180qqaf{padding:var(--size-2)} diff --git a/memory/__init__.py b/components/iframe/demo/__init__.py similarity index 100% rename from memory/__init__.py rename to components/iframe/demo/__init__.py diff --git a/components/iframe/demo/app.py b/components/iframe/demo/app.py new file mode 100644 index 0000000000000000000000000000000000000000..6820bbbd32186d5f446a66592db76581689eac97 --- /dev/null +++ b/components/iframe/demo/app.py @@ -0,0 +1,13 @@ +import gradio as gr +from gradio_iframe import iframe + + +example = iframe().example_inputs() + +with gr.Blocks() as demo: + with gr.Row(): + iframe(label="Blank") # blank component + iframe(value=example, label="Populated") # populated component + + +demo.launch() diff --git a/components/iframe/frontend/Example.svelte b/components/iframe/frontend/Example.svelte new file mode 100644 index 0000000000000000000000000000000000000000..b7b8f6e72b177ae308d613b35e41fee7be8c8bf4 --- /dev/null +++ b/components/iframe/frontend/Example.svelte @@ -0,0 +1,20 @@ + + +
+ {@html value} +
+ + diff --git a/components/iframe/frontend/Index.svelte b/components/iframe/frontend/Index.svelte new file mode 100644 index 0000000000000000000000000000000000000000..b2941c499ba7c4911ef90bc669326e45951cf416 --- /dev/null +++ b/components/iframe/frontend/Index.svelte @@ -0,0 +1,47 @@ + + + + +
+ gradio.dispatch("change")} + /> +
+
+ + diff --git a/components/iframe/frontend/package-lock.json b/components/iframe/frontend/package-lock.json new file mode 100644 index 0000000000000000000000000000000000000000..322c25e254ad32a954b89d20ceea7942c2d045e8 --- /dev/null +++ b/components/iframe/frontend/package-lock.json @@ -0,0 +1,933 @@ +{ + "name": "gradio_iframe", + "version": "0.1.3", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "gradio_iframe", + "version": "0.1.3", + "license": "ISC", + "dependencies": { + "@gradio/atoms": "0.3.0", + "@gradio/statustracker": "0.4.0", + "@gradio/utils": "0.2.0" + } + }, + "node_modules/@ampproject/remapping": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.1.tgz", + "integrity": "sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg==", + "peer": true, + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.0", + "@jridgewell/trace-mapping": "^0.3.9" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.19.10", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.19.10.tgz", + "integrity": "sha512-Q+mk96KJ+FZ30h9fsJl+67IjNJm3x2eX+GBWGmocAKgzp27cowCOOqSdscX80s0SpdFXZnIv/+1xD1EctFx96Q==", + "cpu": [ + "ppc64" + ], + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.19.10", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.19.10.tgz", + "integrity": "sha512-7W0bK7qfkw1fc2viBfrtAEkDKHatYfHzr/jKAHNr9BvkYDXPcC6bodtm8AyLJNNuqClLNaeTLuwURt4PRT9d7w==", + "cpu": [ + "arm" + ], + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.19.10", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.19.10.tgz", + "integrity": "sha512-1X4CClKhDgC3by7k8aOWZeBXQX8dHT5QAMCAQDArCLaYfkppoARvh0fit3X2Qs+MXDngKcHv6XXyQCpY0hkK1Q==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.19.10", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.19.10.tgz", + "integrity": "sha512-O/nO/g+/7NlitUxETkUv/IvADKuZXyH4BHf/g/7laqKC4i/7whLpB0gvpPc2zpF0q9Q6FXS3TS75QHac9MvVWw==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.19.10", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.19.10.tgz", + "integrity": "sha512-YSRRs2zOpwypck+6GL3wGXx2gNP7DXzetmo5pHXLrY/VIMsS59yKfjPizQ4lLt5vEI80M41gjm2BxrGZ5U+VMA==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.19.10", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.19.10.tgz", + "integrity": "sha512-alfGtT+IEICKtNE54hbvPg13xGBe4GkVxyGWtzr+yHO7HIiRJppPDhOKq3zstTcVf8msXb/t4eavW3jCDpMSmA==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.19.10", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.19.10.tgz", + "integrity": "sha512-dMtk1wc7FSH8CCkE854GyGuNKCewlh+7heYP/sclpOG6Cectzk14qdUIY5CrKDbkA/OczXq9WesqnPl09mj5dg==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.19.10", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.19.10.tgz", + "integrity": "sha512-G5UPPspryHu1T3uX8WiOEUa6q6OlQh6gNl4CO4Iw5PS+Kg5bVggVFehzXBJY6X6RSOMS8iXDv2330VzaObm4Ag==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.19.10", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.19.10.tgz", + "integrity": "sha512-j6gUW5aAaPgD416Hk9FHxn27On28H4eVI9rJ4az7oCGTFW48+LcgNDBN+9f8rKZz7EEowo889CPKyeaD0iw9Kg==", + "cpu": [ + "arm" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.19.10", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.19.10.tgz", + "integrity": "sha512-QxaouHWZ+2KWEj7cGJmvTIHVALfhpGxo3WLmlYfJ+dA5fJB6lDEIg+oe/0//FuyVHuS3l79/wyBxbHr0NgtxJQ==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.19.10", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.19.10.tgz", + "integrity": "sha512-4ub1YwXxYjj9h1UIZs2hYbnTZBtenPw5NfXCRgEkGb0b6OJ2gpkMvDqRDYIDRjRdWSe/TBiZltm3Y3Q8SN1xNg==", + "cpu": [ + "ia32" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.19.10", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.19.10.tgz", + "integrity": "sha512-lo3I9k+mbEKoxtoIbM0yC/MZ1i2wM0cIeOejlVdZ3D86LAcFXFRdeuZmh91QJvUTW51bOK5W2BznGNIl4+mDaA==", + "cpu": [ + "loong64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.19.10", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.19.10.tgz", + "integrity": "sha512-J4gH3zhHNbdZN0Bcr1QUGVNkHTdpijgx5VMxeetSk6ntdt+vR1DqGmHxQYHRmNb77tP6GVvD+K0NyO4xjd7y4A==", + "cpu": [ + "mips64el" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.19.10", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.19.10.tgz", + "integrity": "sha512-tgT/7u+QhV6ge8wFMzaklOY7KqiyitgT1AUHMApau32ZlvTB/+efeCtMk4eXS+uEymYK249JsoiklZN64xt6oQ==", + "cpu": [ + "ppc64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.19.10", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.19.10.tgz", + "integrity": "sha512-0f/spw0PfBMZBNqtKe5FLzBDGo0SKZKvMl5PHYQr3+eiSscfJ96XEknCe+JoOayybWUFQbcJTrk946i3j9uYZA==", + "cpu": [ + "riscv64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.19.10", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.19.10.tgz", + "integrity": "sha512-pZFe0OeskMHzHa9U38g+z8Yx5FNCLFtUnJtQMpwhS+r4S566aK2ci3t4NCP4tjt6d5j5uo4h7tExZMjeKoehAA==", + "cpu": [ + "s390x" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.19.10", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.19.10.tgz", + "integrity": "sha512-SpYNEqg/6pZYoc+1zLCjVOYvxfZVZj6w0KROZ3Fje/QrM3nfvT2llI+wmKSrWuX6wmZeTapbarvuNNK/qepSgA==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.19.10", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.19.10.tgz", + "integrity": "sha512-ACbZ0vXy9zksNArWlk2c38NdKg25+L9pr/mVaj9SUq6lHZu/35nx2xnQVRGLrC1KKQqJKRIB0q8GspiHI3J80Q==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.19.10", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.19.10.tgz", + "integrity": "sha512-PxcgvjdSjtgPMiPQrM3pwSaG4kGphP+bLSb+cihuP0LYdZv1epbAIecHVl5sD3npkfYBZ0ZnOjR878I7MdJDFg==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.19.10", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.19.10.tgz", + "integrity": "sha512-ZkIOtrRL8SEJjr+VHjmW0znkPs+oJXhlJbNwfI37rvgeMtk3sxOQevXPXjmAPZPigVTncvFqLMd+uV0IBSEzqA==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.19.10", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.19.10.tgz", + "integrity": "sha512-+Sa4oTDbpBfGpl3Hn3XiUe4f8TU2JF7aX8cOfqFYMMjXp6ma6NJDztl5FDG8Ezx0OjwGikIHw+iA54YLDNNVfw==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.19.10", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.19.10.tgz", + "integrity": "sha512-EOGVLK1oWMBXgfttJdPHDTiivYSjX6jDNaATeNOaCOFEVcfMjtbx7WVQwPSE1eIfCp/CaSF2nSrDtzc4I9f8TQ==", + "cpu": [ + "ia32" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.19.10", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.19.10.tgz", + "integrity": "sha512-whqLG6Sc70AbU73fFYvuYzaE4MNMBIlR1Y/IrUeOXFrWHxBEjjbZaQ3IXIQS8wJdAzue2GwYZCjOrgrU1oUHoA==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@formatjs/ecma402-abstract": { + "version": "1.11.4", + "resolved": "https://registry.npmjs.org/@formatjs/ecma402-abstract/-/ecma402-abstract-1.11.4.tgz", + "integrity": "sha512-EBikYFp2JCdIfGEb5G9dyCkTGDmC57KSHhRQOC3aYxoPWVZvfWCDjZwkGYHN7Lis/fmuWl906bnNTJifDQ3sXw==", + "dependencies": { + "@formatjs/intl-localematcher": "0.2.25", + "tslib": "^2.1.0" + } + }, + "node_modules/@formatjs/fast-memoize": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@formatjs/fast-memoize/-/fast-memoize-1.2.1.tgz", + "integrity": "sha512-Rg0e76nomkz3vF9IPlKeV+Qynok0r7YZjL6syLz4/urSg0IbjPZCB/iYUMNsYA643gh4mgrX3T7KEIFIxJBQeg==", + "dependencies": { + "tslib": "^2.1.0" + } + }, + "node_modules/@formatjs/icu-messageformat-parser": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@formatjs/icu-messageformat-parser/-/icu-messageformat-parser-2.1.0.tgz", + "integrity": "sha512-Qxv/lmCN6hKpBSss2uQ8IROVnta2r9jd3ymUEIjm2UyIkUCHVcbUVRGL/KS/wv7876edvsPe+hjHVJ4z8YuVaw==", + "dependencies": { + "@formatjs/ecma402-abstract": "1.11.4", + "@formatjs/icu-skeleton-parser": "1.3.6", + "tslib": "^2.1.0" + } + }, + "node_modules/@formatjs/icu-skeleton-parser": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/@formatjs/icu-skeleton-parser/-/icu-skeleton-parser-1.3.6.tgz", + "integrity": "sha512-I96mOxvml/YLrwU2Txnd4klA7V8fRhb6JG/4hm3VMNmeJo1F03IpV2L3wWt7EweqNLES59SZ4d6hVOPCSf80Bg==", + "dependencies": { + "@formatjs/ecma402-abstract": "1.11.4", + "tslib": "^2.1.0" + } + }, + "node_modules/@formatjs/intl-localematcher": { + "version": "0.2.25", + "resolved": "https://registry.npmjs.org/@formatjs/intl-localematcher/-/intl-localematcher-0.2.25.tgz", + "integrity": "sha512-YmLcX70BxoSopLFdLr1Ds99NdlTI2oWoLbaUW2M406lxOIPzE1KQhRz2fPUkq34xVZQaihCoU29h0KK7An3bhA==", + "dependencies": { + "tslib": "^2.1.0" + } + }, + "node_modules/@gradio/atoms": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/@gradio/atoms/-/atoms-0.3.0.tgz", + "integrity": "sha512-7WQktAb+d8wEjTIYGzyQ8OdWsFSr0NA8adp8G/jAKoMZILJEoAAZSTnahCTSSQcbYIomVdfYA0ZmM342RCd8gg==", + "dependencies": { + "@gradio/icons": "^0.3.0", + "@gradio/utils": "^0.2.0" + } + }, + "node_modules/@gradio/column": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@gradio/column/-/column-0.1.0.tgz", + "integrity": "sha512-P24nqqVnMXBaDA1f/zSN5HZRho4PxP8Dq+7VltPHlmxIEiZYik2AJ4J0LeuIha34FDO0guu/16evdrpvGIUAfw==" + }, + "node_modules/@gradio/icons": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/@gradio/icons/-/icons-0.3.2.tgz", + "integrity": "sha512-l0jGfSRFiZ/doAXz6L+JEp6MN/a1BTZm88kqVoSnYrKSytP6bnBLRWeF4UvOi2T2fbVrNKenAEt/lwxJE5vK4w==" + }, + "node_modules/@gradio/statustracker": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@gradio/statustracker/-/statustracker-0.4.0.tgz", + "integrity": "sha512-Kgk4R2edFX4IK2UBit4UwmRfSrmvkYjKbiMfupj3qxHFwiDHT4YH4rAOqBlvdEWbCYMmLN6EyqqFaYb2+0GwXA==", + "dependencies": { + "@gradio/atoms": "^0.3.0", + "@gradio/column": "^0.1.0", + "@gradio/icons": "^0.3.0", + "@gradio/utils": "^0.2.0" + } + }, + "node_modules/@gradio/theme": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/@gradio/theme/-/theme-0.2.0.tgz", + "integrity": "sha512-33c68Nk7oRXLn08OxPfjcPm7S4tXGOUV1I1bVgzdM2YV5o1QBOS1GEnXPZPu/CEYPePLMB6bsDwffrLEyLGWVQ==" + }, + "node_modules/@gradio/utils": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/@gradio/utils/-/utils-0.2.0.tgz", + "integrity": "sha512-YkwzXufi6IxQrlMW+1sFo8Yn6F9NLL69ZoBsbo7QEhms0v5L7pmOTw+dfd7M3dwbRP2lgjrb52i1kAIN3n6aqQ==", + "dependencies": { + "@gradio/theme": "^0.2.0", + "svelte-i18n": "^3.6.0" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz", + "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==", + "peer": true, + "dependencies": { + "@jridgewell/set-array": "^1.0.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.9" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz", + "integrity": "sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==", + "peer": true, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/set-array": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", + "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", + "peer": true, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.4.15", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", + "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", + "peer": true + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.20", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.20.tgz", + "integrity": "sha512-R8LcPeWZol2zR8mmH3JeKQ6QRCFb7XgUhV9ZlGhHLGyg4wpPiPZNQOOWhFZhxKw8u//yTbNGI42Bx/3paXEQ+Q==", + "peer": true, + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@types/estree": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", + "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", + "peer": true + }, + "node_modules/acorn": { + "version": "8.11.2", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.2.tgz", + "integrity": "sha512-nc0Axzp/0FILLEVsm4fNwLCwMttvhEI263QtVPQcbpfZZ3ts0hLsZGOpE6czNlid7CJ9MlyH8reXkpsf3YUY4w==", + "peer": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/aria-query": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.0.tgz", + "integrity": "sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==", + "peer": true, + "dependencies": { + "dequal": "^2.0.3" + } + }, + "node_modules/axobject-query": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-3.2.1.tgz", + "integrity": "sha512-jsyHu61e6N4Vbz/v18DHwWYKK0bSWLqn47eeDSKPB7m8tqMHF9YJ+mhIk2lVteyZrY8tnSj/jHOv4YiTCuCJgg==", + "peer": true, + "dependencies": { + "dequal": "^2.0.3" + } + }, + "node_modules/cli-color": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/cli-color/-/cli-color-2.0.3.tgz", + "integrity": "sha512-OkoZnxyC4ERN3zLzZaY9Emb7f/MhBOIpePv0Ycok0fJYT+Ouo00UBEIwsVsr0yoow++n5YWlSUgST9GKhNHiRQ==", + "dependencies": { + "d": "^1.0.1", + "es5-ext": "^0.10.61", + "es6-iterator": "^2.0.3", + "memoizee": "^0.4.15", + "timers-ext": "^0.1.7" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/code-red": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/code-red/-/code-red-1.0.4.tgz", + "integrity": "sha512-7qJWqItLA8/VPVlKJlFXU+NBlo/qyfs39aJcuMT/2ere32ZqvF5OSxgdM5xOfJJ7O429gg2HM47y8v9P+9wrNw==", + "peer": true, + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.4.15", + "@types/estree": "^1.0.1", + "acorn": "^8.10.0", + "estree-walker": "^3.0.3", + "periscopic": "^3.1.0" + } + }, + "node_modules/css-tree": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.3.1.tgz", + "integrity": "sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw==", + "peer": true, + "dependencies": { + "mdn-data": "2.0.30", + "source-map-js": "^1.0.1" + }, + "engines": { + "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0" + } + }, + "node_modules/d": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/d/-/d-1.0.1.tgz", + "integrity": "sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA==", + "dependencies": { + "es5-ext": "^0.10.50", + "type": "^1.0.1" + } + }, + "node_modules/deepmerge": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", + "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/dequal": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", + "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", + "peer": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/es5-ext": { + "version": "0.10.62", + "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.62.tgz", + "integrity": "sha512-BHLqn0klhEpnOKSrzn/Xsz2UIW8j+cGmo9JLzr8BiUapV8hPL9+FliFqjwr9ngW7jWdnxv6eO+/LqyhJVqgrjA==", + "hasInstallScript": true, + "dependencies": { + "es6-iterator": "^2.0.3", + "es6-symbol": "^3.1.3", + "next-tick": "^1.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/es6-iterator": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz", + "integrity": "sha512-zw4SRzoUkd+cl+ZoE15A9o1oQd920Bb0iOJMQkQhl3jNc03YqVjAhG7scf9C5KWRU/R13Orf588uCC6525o02g==", + "dependencies": { + "d": "1", + "es5-ext": "^0.10.35", + "es6-symbol": "^3.1.1" + } + }, + "node_modules/es6-symbol": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.3.tgz", + "integrity": "sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA==", + "dependencies": { + "d": "^1.0.1", + "ext": "^1.1.2" + } + }, + "node_modules/es6-weak-map": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/es6-weak-map/-/es6-weak-map-2.0.3.tgz", + "integrity": "sha512-p5um32HOTO1kP+w7PRnB+5lQ43Z6muuMuIMffvDN8ZB4GcnjLBV6zGStpbASIMk4DCAvEaamhe2zhyCb/QXXsA==", + "dependencies": { + "d": "1", + "es5-ext": "^0.10.46", + "es6-iterator": "^2.0.3", + "es6-symbol": "^3.1.1" + } + }, + "node_modules/esbuild": { + "version": "0.19.10", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.19.10.tgz", + "integrity": "sha512-S1Y27QGt/snkNYrRcswgRFqZjaTG5a5xM3EQo97uNBnH505pdzSNe/HLBq1v0RO7iK/ngdbhJB6mDAp0OK+iUA==", + "hasInstallScript": true, + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.19.10", + "@esbuild/android-arm": "0.19.10", + "@esbuild/android-arm64": "0.19.10", + "@esbuild/android-x64": "0.19.10", + "@esbuild/darwin-arm64": "0.19.10", + "@esbuild/darwin-x64": "0.19.10", + "@esbuild/freebsd-arm64": "0.19.10", + "@esbuild/freebsd-x64": "0.19.10", + "@esbuild/linux-arm": "0.19.10", + "@esbuild/linux-arm64": "0.19.10", + "@esbuild/linux-ia32": "0.19.10", + "@esbuild/linux-loong64": "0.19.10", + "@esbuild/linux-mips64el": "0.19.10", + "@esbuild/linux-ppc64": "0.19.10", + "@esbuild/linux-riscv64": "0.19.10", + "@esbuild/linux-s390x": "0.19.10", + "@esbuild/linux-x64": "0.19.10", + "@esbuild/netbsd-x64": "0.19.10", + "@esbuild/openbsd-x64": "0.19.10", + "@esbuild/sunos-x64": "0.19.10", + "@esbuild/win32-arm64": "0.19.10", + "@esbuild/win32-ia32": "0.19.10", + "@esbuild/win32-x64": "0.19.10" + } + }, + "node_modules/estree-walker": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", + "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", + "peer": true, + "dependencies": { + "@types/estree": "^1.0.0" + } + }, + "node_modules/event-emitter": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/event-emitter/-/event-emitter-0.3.5.tgz", + "integrity": "sha512-D9rRn9y7kLPnJ+hMq7S/nhvoKwwvVJahBi2BPmx3bvbsEdK3W9ii8cBSGjP+72/LnM4n6fo3+dkCX5FeTQruXA==", + "dependencies": { + "d": "1", + "es5-ext": "~0.10.14" + } + }, + "node_modules/ext": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/ext/-/ext-1.7.0.tgz", + "integrity": "sha512-6hxeJYaL110a9b5TEJSj0gojyHQAmA2ch5Os+ySCiA1QGdS697XWY1pzsrSjqA9LDEEgdB/KypIlR59RcLuHYw==", + "dependencies": { + "type": "^2.7.2" + } + }, + "node_modules/ext/node_modules/type": { + "version": "2.7.2", + "resolved": "https://registry.npmjs.org/type/-/type-2.7.2.tgz", + "integrity": "sha512-dzlvlNlt6AXU7EBSfpAscydQ7gXB+pPGsPnfJnZpiNJBDj7IaJzQlBZYGdEi4R9HmPdBv2XmWJ6YUtoTa7lmCw==" + }, + "node_modules/globalyzer": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/globalyzer/-/globalyzer-0.1.0.tgz", + "integrity": "sha512-40oNTM9UfG6aBmuKxk/giHn5nQ8RVz/SS4Ir6zgzOv9/qC3kKZ9v4etGTcJbEl/NyVQH7FGU7d+X1egr57Md2Q==" + }, + "node_modules/globrex": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/globrex/-/globrex-0.1.2.tgz", + "integrity": "sha512-uHJgbwAMwNFf5mLst7IWLNg14x1CkeqglJb/K3doi4dw6q2IvAAmM/Y81kevy83wP+Sst+nutFTYOGg3d1lsxg==" + }, + "node_modules/intl-messageformat": { + "version": "9.13.0", + "resolved": "https://registry.npmjs.org/intl-messageformat/-/intl-messageformat-9.13.0.tgz", + "integrity": "sha512-7sGC7QnSQGa5LZP7bXLDhVDtQOeKGeBFGHF2Y8LVBwYZoQZCgWeKoPGTa5GMG8g/TzDgeXuYJQis7Ggiw2xTOw==", + "dependencies": { + "@formatjs/ecma402-abstract": "1.11.4", + "@formatjs/fast-memoize": "1.2.1", + "@formatjs/icu-messageformat-parser": "2.1.0", + "tslib": "^2.1.0" + } + }, + "node_modules/is-promise": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.2.2.tgz", + "integrity": "sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ==" + }, + "node_modules/is-reference": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/is-reference/-/is-reference-3.0.2.tgz", + "integrity": "sha512-v3rht/LgVcsdZa3O2Nqs+NMowLOxeOm7Ay9+/ARQ2F+qEoANRcqrjAZKGN0v8ymUetZGgkp26LTnGT7H0Qo9Pg==", + "peer": true, + "dependencies": { + "@types/estree": "*" + } + }, + "node_modules/locate-character": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-character/-/locate-character-3.0.0.tgz", + "integrity": "sha512-SW13ws7BjaeJ6p7Q6CO2nchbYEc3X3J6WrmTTDto7yMPqVSZTUyY5Tjbid+Ab8gLnATtygYtiDIJGQRRn2ZOiA==", + "peer": true + }, + "node_modules/lru-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/lru-queue/-/lru-queue-0.1.0.tgz", + "integrity": "sha512-BpdYkt9EvGl8OfWHDQPISVpcl5xZthb+XPsbELj5AQXxIC8IriDZIQYjBJPEm5rS420sjZ0TLEzRcq5KdBhYrQ==", + "dependencies": { + "es5-ext": "~0.10.2" + } + }, + "node_modules/magic-string": { + "version": "0.30.5", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.5.tgz", + "integrity": "sha512-7xlpfBaQaP/T6Vh8MO/EqXSW5En6INHEvEXQiuff7Gku0PWjU3uf6w/j9o7O+SpB5fOAkrI5HeoNgwjEO0pFsA==", + "peer": true, + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.4.15" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/mdn-data": { + "version": "2.0.30", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.30.tgz", + "integrity": "sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==", + "peer": true + }, + "node_modules/memoizee": { + "version": "0.4.15", + "resolved": "https://registry.npmjs.org/memoizee/-/memoizee-0.4.15.tgz", + "integrity": "sha512-UBWmJpLZd5STPm7PMUlOw/TSy972M+z8gcyQ5veOnSDRREz/0bmpyTfKt3/51DhEBqCZQn1udM/5flcSPYhkdQ==", + "dependencies": { + "d": "^1.0.1", + "es5-ext": "^0.10.53", + "es6-weak-map": "^2.0.3", + "event-emitter": "^0.3.5", + "is-promise": "^2.2.2", + "lru-queue": "^0.1.0", + "next-tick": "^1.1.0", + "timers-ext": "^0.1.7" + } + }, + "node_modules/mri": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/mri/-/mri-1.2.0.tgz", + "integrity": "sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==", + "engines": { + "node": ">=4" + } + }, + "node_modules/next-tick": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.1.0.tgz", + "integrity": "sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ==" + }, + "node_modules/periscopic": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/periscopic/-/periscopic-3.1.0.tgz", + "integrity": "sha512-vKiQ8RRtkl9P+r/+oefh25C3fhybptkHKCZSPlcXiJux2tJF55GnEj3BVn4A5gKfq9NWWXXrxkHBwVPUfH0opw==", + "peer": true, + "dependencies": { + "@types/estree": "^1.0.0", + "estree-walker": "^3.0.0", + "is-reference": "^3.0.0" + } + }, + "node_modules/sade": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/sade/-/sade-1.8.1.tgz", + "integrity": "sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A==", + "dependencies": { + "mri": "^1.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/source-map-js": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", + "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==", + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/svelte": { + "version": "4.2.8", + "resolved": "https://registry.npmjs.org/svelte/-/svelte-4.2.8.tgz", + "integrity": "sha512-hU6dh1MPl8gh6klQZwK/n73GiAHiR95IkFsesLPbMeEZi36ydaXL/ZAb4g9sayT0MXzpxyZjR28yderJHxcmYA==", + "peer": true, + "dependencies": { + "@ampproject/remapping": "^2.2.1", + "@jridgewell/sourcemap-codec": "^1.4.15", + "@jridgewell/trace-mapping": "^0.3.18", + "acorn": "^8.9.0", + "aria-query": "^5.3.0", + "axobject-query": "^3.2.1", + "code-red": "^1.0.3", + "css-tree": "^2.3.1", + "estree-walker": "^3.0.3", + "is-reference": "^3.0.1", + "locate-character": "^3.0.0", + "magic-string": "^0.30.4", + "periscopic": "^3.1.0" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/svelte-i18n": { + "version": "3.7.4", + "resolved": "https://registry.npmjs.org/svelte-i18n/-/svelte-i18n-3.7.4.tgz", + "integrity": "sha512-yGRCNo+eBT4cPuU7IVsYTYjxB7I2V8qgUZPlHnNctJj5IgbJgV78flsRzpjZ/8iUYZrS49oCt7uxlU3AZv/N5Q==", + "dependencies": { + "cli-color": "^2.0.3", + "deepmerge": "^4.2.2", + "esbuild": "^0.19.2", + "estree-walker": "^2", + "intl-messageformat": "^9.13.0", + "sade": "^1.8.1", + "tiny-glob": "^0.2.9" + }, + "bin": { + "svelte-i18n": "dist/cli.js" + }, + "engines": { + "node": ">= 16" + }, + "peerDependencies": { + "svelte": "^3 || ^4" + } + }, + "node_modules/svelte-i18n/node_modules/estree-walker": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", + "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==" + }, + "node_modules/timers-ext": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/timers-ext/-/timers-ext-0.1.7.tgz", + "integrity": "sha512-b85NUNzTSdodShTIbky6ZF02e8STtVVfD+fu4aXXShEELpozH+bCpJLYMPZbsABN2wDH7fJpqIoXxJpzbf0NqQ==", + "dependencies": { + "es5-ext": "~0.10.46", + "next-tick": "1" + } + }, + "node_modules/tiny-glob": { + "version": "0.2.9", + "resolved": "https://registry.npmjs.org/tiny-glob/-/tiny-glob-0.2.9.tgz", + "integrity": "sha512-g/55ssRPUjShh+xkfx9UPDXqhckHEsHr4Vd9zX55oSdGZc/MD0m3sferOkwWtp98bv+kcVfEHtRJgBVJzelrzg==", + "dependencies": { + "globalyzer": "0.1.0", + "globrex": "^0.1.2" + } + }, + "node_modules/tslib": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", + "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==" + }, + "node_modules/type": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/type/-/type-1.2.0.tgz", + "integrity": "sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg==" + } + } +} diff --git a/components/iframe/frontend/package.json b/components/iframe/frontend/package.json new file mode 100644 index 0000000000000000000000000000000000000000..745d32fe5a64130697bcd7e670e1c35894dce305 --- /dev/null +++ b/components/iframe/frontend/package.json @@ -0,0 +1,20 @@ +{ + "name": "gradio_iframe", + "version": "0.1.3", + "description": "Gradio UI packages", + "type": "module", + "author": "", + "license": "ISC", + "private": false, + "main_changeset": true, + "dependencies": { + "@gradio/atoms": "0.3.0", + "@gradio/statustracker": "0.4.0", + "@gradio/utils": "0.2.0" + }, + "exports": { + ".": "./Index.svelte", + "./example": "./Example.svelte", + "./package.json": "./package.json" + } +} diff --git a/components/iframe/frontend/shared/HTML.svelte b/components/iframe/frontend/shared/HTML.svelte new file mode 100644 index 0000000000000000000000000000000000000000..461a3c9579d100c327ca0eed49d65bc11c852cb2 --- /dev/null +++ b/components/iframe/frontend/shared/HTML.svelte @@ -0,0 +1,28 @@ + + +
+ {@html value} +
+ + diff --git a/components/iframe/pyproject.toml b/components/iframe/pyproject.toml new file mode 100644 index 0000000000000000000000000000000000000000..fbf1d6cb8282074bb264e961e031f2557106ea4a --- /dev/null +++ b/components/iframe/pyproject.toml @@ -0,0 +1,42 @@ +[build-system] +requires = [ + "hatchling", + "hatch-requirements-txt", + "hatch-fancy-pypi-readme>=22.5.0", +] +build-backend = "hatchling.build" + +[project] +name = "gradio_iframe" +version = "0.0.1" +description = "iFrame components that wraps html and js code to make them interactive." +readme = "README.md" +license = "MIT" +requires-python = ">=3.8" +authors = [{ name = "YOUR NAME", email = "YOUREMAIL@domain.com" }] +keywords = ["gradio-custom-component", "gradio-template-HTML", "HTML", "iFrame"] +# Add dependencies here +dependencies = ["gradio>=4.0,<5.0"] +classifiers = [ + 'Development Status :: 3 - Alpha', + 'License :: OSI Approved :: Apache Software License', + 'Operating System :: OS Independent', + 'Programming Language :: Python :: 3', + 'Programming Language :: Python :: 3 :: Only', + 'Programming Language :: Python :: 3.8', + 'Programming Language :: Python :: 3.9', + 'Programming Language :: Python :: 3.10', + 'Programming Language :: Python :: 3.11', + 'Topic :: Scientific/Engineering', + 'Topic :: Scientific/Engineering :: Artificial Intelligence', + 'Topic :: Scientific/Engineering :: Visualization', +] + +[project.optional-dependencies] +dev = ["build", "twine"] + +[tool.hatch.build] +artifacts = ["/backend/gradio_iframe/templates", "*.pyi", "backend/gradio_iframe/templates"] + +[tool.hatch.build.targets.wheel] +packages = ["/backend/gradio_iframe"] diff --git a/entrypoint.sh b/entrypoint.sh index 2ebc689891a3603e786081f78144d03979d93e56..ba86ceb589f05d54cd064854cf93a28155355452 100644 --- a/entrypoint.sh +++ b/entrypoint.sh @@ -1,7 +1,8 @@ #!/bin/bash +# entrypoint script for the docker container to run at start # installing all the dependencies pip install --no-cache-dir --upgrade -r requirements.txt # running the fastapi app -uvicorn main:app --host 0.0.0.0 --port 8080 \ No newline at end of file +uvicorn main:app --host 0.0.0.0 --port 8080 diff --git a/explanation/__init__.py b/explanation/__init__.py index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..7d8ca1294b578f33d8e7daf450212ba1e8befa7c 100644 --- a/explanation/__init__.py +++ b/explanation/__init__.py @@ -0,0 +1,2 @@ +# empty init file for the package +# for fastapi to recognize the module diff --git a/explanation/interpret.py b/explanation/interpret.py index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..82366a7276e1f304951c6c54ad6fdb7c0865a437 100644 --- a/explanation/interpret.py +++ b/explanation/interpret.py @@ -0,0 +1,122 @@ +# interpret module that implements the interpretability method +# external imports +import seaborn as sns +import matplotlib.pyplot as plt +import numpy as np +from shap import models, maskers, plots, PartitionExplainer +import torch + +# internal imports +from utils import formatting as fmt + +# global variables +TEACHER_FORCING = None +TEXT_MASKER = None + + +# main explain function that returns a chat with explanations +def chat_explained(model, prompt): + model.set_config() + + # create the shap explainer + shap_explainer = PartitionExplainer(model.MODEL, model.TOKENIZER) + # get the shap values for the prompt + shap_values = shap_explainer([prompt]) + + # create the explanation graphic and plot + graphic = create_graphic(shap_values) + plot = create_plot(shap_values) + + # create the response text + response_text = fmt.format_output_text(shap_values.output_names) + return response_text, graphic, plot + + +def wrap_shap(model): + global TEXT_MASKER, TEACHER_FORCING + + # set the device to cuda if gpu is available + device = torch.device("cuda" if torch.cuda.is_available() else "cpu") + + # updating the model settings again + model.set_config() + + # (re)initialize the shap models and masker + text_generation = models.TextGeneration(model.MODEL, model.TOKENIZER) + TEACHER_FORCING = models.TeacherForcing( + text_generation, + model.TOKENIZER, + device=str(device), + similarity_model=model.MODEL, + similarity_tokenizer=model.TOKENIZER, + ) + TEXT_MASKER = maskers.Text(model.TOKENIZER, " ", collapse_mask_token=True) + + +# graphic plotting function that creates a html graphic (as string) for the explanation +def create_graphic(shap_values): + # create the html graphic using shap text plot function + graphic_html = plots.text(shap_values, display=False) + + # return the html graphic as string + return str(graphic_html) + + +# plotting function that creates a heatmap style explanation plot +def create_plot(shap_values): + values = shap_values.values[0] + output_names = shap_values.output_names + input_names = shap_values.data[0] + + # Transpose the values for horizontal input names + transposed_values = np.transpose(values) + + # Set seaborn style to dark + sns.set(style="dark") + + fig, ax = plt.subplots() + + # Making background transparent + ax.set_alpha(0) + fig.patch.set_alpha(0) + + # Setting figure size + fig.set_size_inches( + max(transposed_values.shape[1] * 2, 10), + max(transposed_values.shape[0] / 1.5, 5), + ) + + # Plotting the heatmap with Seaborn's color palette + im = ax.imshow( + transposed_values, + vmax=transposed_values.max(), + vmin=-transposed_values.min(), + cmap=sns.color_palette("vlag_r", as_cmap=True), + aspect="auto", + ) + + # Creating colorbar + cbar = ax.figure.colorbar(im, ax=ax) + cbar.ax.set_ylabel("Token Attribution", rotation=-90, va="bottom") + cbar.ax.yaxis.set_tick_params(color="white") + plt.setp(plt.getp(cbar.ax.axes, "yticklabels"), color="white") + + # Setting ticks and labels with white color for visibility + ax.set_xticks(np.arange(len(input_names)), labels=input_names) + ax.set_yticks(np.arange(len(output_names)), labels=output_names) + plt.setp(ax.get_xticklabels(), color="white", rotation=45, ha="right") + plt.setp(ax.get_yticklabels(), color="white") + + # Adjusting tick labels + ax.tick_params( + top=True, bottom=False, labeltop=False, labelbottom=True, color="white" + ) + + # Adding text annotations - not used for readability + # for i in range(transposed_values.shape[0]): + # for j in range(transposed_values.shape[1]): + # val = transposed_values[i, j] + # color = "black" if 0.2 < im.norm(val) < 0.8 else "white" + # ax.text(j, i, f"{val:.4f}", ha="center", va="center", color=color) + + return plt diff --git a/explanation/visualize.py b/explanation/visualize.py index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..9ac0567bc2c61a39cfea03ef0d4266fbd0918a0d 100644 --- a/explanation/visualize.py +++ b/explanation/visualize.py @@ -0,0 +1,110 @@ +# visualization module that creates an attention visualization using BERTViz + +# external imports +from bertviz import head_view +import matplotlib.pyplot as plt +import seaborn as sns +import numpy as np + +# internal imports +from utils import formatting as fmt + + +# plotting function that plots the attention values in a heatmap +def chat_explained(model, prompt): + + model.set_config() + + # get encoded input and output vectors + encoder_input_ids = model.TOKENIZER( + prompt, return_tensors="pt", add_special_tokens=True + ).input_ids + decoder_input_ids = model.MODEL.generate(encoder_input_ids, output_attentions=True) + encoder_text = fmt.format_tokens( + model.TOKENIZER.convert_ids_to_tokens(encoder_input_ids[0]) + ) + decoder_text = fmt.format_tokens( + model.TOKENIZER.convert_ids_to_tokens(decoder_input_ids[0]) + ) + + # get attention values for the input and output vectors + attention_output = model.MODEL( + input_ids=encoder_input_ids, + decoder_input_ids=decoder_input_ids, + output_attentions=True, + ) + + # create the response text, graphic and plot + response_text = fmt.format_output_text(decoder_text) + graphic = create_graphic(attention_output, (encoder_text, decoder_text)) + plot = create_plot(attention_output, (encoder_text, decoder_text)) + return response_text, graphic, plot + + +# creating a html graphic using BERTViz +def create_graphic(attention_output, enc_dec_texts: tuple): + + # calls the head_view function of BERTViz to return html graphic + hview = head_view( + encoder_attention=attention_output.encoder_attentions, + decoder_attention=attention_output.decoder_attentions, + cross_attention=attention_output.cross_attentions, + encoder_tokens=enc_dec_texts[0], + decoder_tokens=enc_dec_texts[1], + html_action="return", + ) + + return str(hview.data) + + +# creating an attention heatmap plot using seaborn +def create_plot(attention_output, enc_dec_texts: tuple): + # get the averaged attention weights + attention = attention_output.cross_attentions[0][0].detach().numpy() + averaged_attention_weights = np.mean(attention, axis=0) + + # get the encoder and decoder tokens + encoder_tokens = enc_dec_texts[0] + decoder_tokens = enc_dec_texts[1] + + # set seaborn style to dark and initialize figure and axis + sns.set(style="dark") + fig, ax = plt.subplots() + + # Making background transparent + ax.set_alpha(0) + fig.patch.set_alpha(0) + + # Setting figure size + fig.set_size_inches( + max(averaged_attention_weights.shape[1] * 2, 10), + max(averaged_attention_weights.shape[0] / 1.5, 5), + ) + + # Plotting the heatmap with seaborn's color palette + im = ax.imshow( + averaged_attention_weights, + vmax=averaged_attention_weights.max(), + vmin=-averaged_attention_weights.min(), + cmap=sns.color_palette("rocket", as_cmap=True), + aspect="auto", + ) + + # Creating colorbar + cbar = ax.figure.colorbar(im, ax=ax) + cbar.ax.set_ylabel("Token Attribution", rotation=-90, va="bottom") + cbar.ax.yaxis.set_tick_params(color="white") + plt.setp(plt.getp(cbar.ax.axes, "yticklabels"), color="white") + + # Setting ticks and labels with white color for visibility + ax.set_xticks(np.arange(len(encoder_tokens)), labels=encoder_tokens) + ax.set_yticks(np.arange(len(decoder_tokens)), labels=decoder_tokens) + plt.setp(ax.get_xticklabels(), color="white", rotation=45, ha="right") + plt.setp(ax.get_yticklabels(), color="white") + + # Adjusting tick labels + ax.tick_params( + top=True, bottom=False, labeltop=False, labelbottom=True, color="white" + ) + + return plt diff --git a/main.py b/main.py index 19f0797932c17e76fb6d2d203d8f22de70e7a4a9..9249ec0589b45a4e89ebabd7f8a1fdee139b40f9 100644 --- a/main.py +++ b/main.py @@ -1,109 +1,222 @@ -# main application file initializing the gradio based ui and calling other modules - -# external package imports -import gradio as gr -import markdown +# main application file initializing the gradio based ui and calling other +# external imports from fastapi import FastAPI +import markdown +import gradio as gr # internal imports -from model import mistral +from backend.controller import interference -# function to load md files in python as a string -def load_md(path): +# Global Variables and css +app = FastAPI() +css = "body {text-align: start !important;}" - # credit: official python-markdown documentation (https://python-markdown.github.io/reference/) - with open(path, "r") as file: - text = file.read() - # return markdown as a string +# different functions to provide frontend abilities +# function to load markdown files +def load_md(path): + # CREDIT: official python-markdown documentation + ## see https://python-markdown.github.io/reference/) + with open(path, "r", encoding="utf-8") as file: + text = file.read() return markdown.markdown(text) -# creation of FastAPI application -app = FastAPI() -# ui interface based on Gradio Blocks (see documentation: https://www.gradio.app/docs/interface) -with gr.Blocks() as ui: +# function to display the system prompt info +def system_prompt_info(sys_prompt_txt): + # display the system prompt using the Gradio Info component + gr.Info(f"The system prompt was set to:\n {sys_prompt_txt}") + + +# function to display the xai info +def xai_info(xai_radio): + # display the xai method using the Gradio Info component + if xai_radio != "None": + gr.Info(f"The XAI was set to:\n {xai_radio}") + else: + gr.Info("No XAI method was selected.") + + +# ui interface based on Gradio Blocks (see documentation: +# https://www.gradio.app/docs/interface) +with gr.Blocks( + css="text-align: start !important", + title="Thesis Webapp Showcase", + head="", +) as ui: # header row with markdown based text with gr.Row(): - gr.Markdown( - """ - # Thesis Demo - AI Chat Application with XAI + # markdown component to display the header + gr.Markdown(""" + # Thesis Demo - AI Chat Application with GODEL + ## XAI powered by SHAP and BERTVIZ ### Select between tabs below for the different views. """) # ChatBot tab used to chat with the AI chatbot with gr.Tab("AI ChatBot"): with gr.Row(): - gr.Markdown( - """ + # markdown component to display the header of the current tab + gr.Markdown(""" ### ChatBot Demo - Mitral AI 7B notebooks fine-tuned for instruction and fully open source (see at [HGF](https://huggingface.co/mistralai/Mistral-7B-v0.1)) + Chat with the AI ChatBot using the textbox below. + Manipulate the settings in the row above, + including the selection of the model, + the system prompt and the XAI method. + """) - # row with chatbot ui displaying "conversation" with the model (see documentation: https://www.gradio.app/docs/chatbot) - with gr.Row(): - chatbot = gr.Chatbot(layout="panel", show_copy_button=True,avatar_images=("./public/human.jpg","./public/bot.jpg")) - # disclaimer information row - data is recorded for shap dashboard and model explanability + # row with columns for the different settings + with gr.Row(equal_height=True): + # column that takes up 3/5 of the row + with gr.Column(scale=3): + # textbox to enter the system prompt + system_prompt = gr.Textbox( + label="System Prompt", + info="Set the models system prompt, dictating how it answers.", + placeholder=( + "You are a helpful, respectful and honest assistant. Always" + " answer as helpfully as possible, while being safe." + ), + ) + with gr.Column(scale=1): + # checkbox group to select the xai method + xai_selection = gr.Radio( + ["None", "SHAP", "Visualizer"], + label="XAI Settings", + info="Select a XAI Implementation to use.", + value="None", + interactive=True, + show_label=True, + ) + + # calling info functions on inputs for different settings + system_prompt.submit(system_prompt_info, [system_prompt]) + xai_selection.input(xai_info, [xai_selection]) + + # row with chatbot ui displaying "conversation" with the model + with gr.Row(equal_height=True): + # out of the box chatbot component + # see documentation: https://www.gradio.app/docs/chatbot + chatbot = gr.Chatbot( + layout="panel", + show_copy_button=True, + avatar_images=("./public/human.jpg", "./public/bot.jpg"), + ) + # rows with input textboxes with gr.Row(): - gr.Markdown( - """ - ##### โš ๏ธ All Conversations are recorded for qa assurance and explanation functionality! - """) - # row with input textbox + # textbox to enter the knowledge + with gr.Accordion(label="Additional Knowledge", open=False): + knowledge_input = gr.Textbox( + value="", + label="Knowledge", + max_lines=5, + info="Add additional context knowledge.", + show_label=True, + ) with gr.Row(): - prompt = gr.Textbox(label="Input Message") + # textbox to enter the user prompt + user_prompt = gr.Textbox( + label="Input Message", + max_lines=5, + info=""" + Ask the ChatBot a question. + Hint: More complicated question give better explanation insights! + """, + show_label=True, + ) # row with columns for buttons to submit and clear content with gr.Row(): with gr.Column(scale=1): - # default clear button which clearn the given components (see documentation: https://www.gradio.app/docs/clearbutton) - clear_btn = gr.ClearButton([prompt, chatbot]) + # out of the box clear button which clearn the given components (see + # documentation: https://www.gradio.app/docs/clearbutton) + clear_btn = gr.ClearButton([user_prompt, chatbot]) with gr.Column(scale=1): - submit_btn = gr.Button("Submit") - - # two functions performing the same action (triggered the model response), when the button is used or the textbox submit function is used (clicking enter). - submit_btn.click(mistral.chat, [prompt, chatbot], [prompt, chatbot]) - prompt.submit(mistral.chat, [prompt, chatbot], [prompt, chatbot]) + submit_btn = gr.Button("Submit", variant="primary") + with gr.Row(): + gr.Examples( + label="Example Questions", + examples=[ + [ + "How does a black hole form in space?", + ( + "Black holes are created when a massive star's core" + " collapses after a supernova, forming an object with" + " gravity so intense that even light cannot escape." + ), + ], + [ + ( + "Explain the importance of the Rosetta Stone in" + " understanding ancient languages." + ), + ( + "The Rosetta Stone, an ancient Egyptian artifact, was key" + " in decoding hieroglyphs, featuring the same text in three" + " scripts: hieroglyphs, Demotic, and Greek." + ), + ], + ], + inputs=[user_prompt, knowledge_input], + ) # explanations tab used to provide explanations for a specific conversation with gr.Tab("Explanations"): + # row with markdown component to display the header of the current tab with gr.Row(): - gr.Markdown( - """ - ### Get Explanations for - SHAP Visualization Dashboard adopted from [shapash](https://github.com/MAIF/shapash) + gr.Markdown(""" + ### Get Explanations for Conversations + Using your selected XAI method, you can get explanations for + the conversation you had with the AI ChatBot. The explanations are + based on the last message you sent to the AI ChatBot (see text) """) - - # shap dashboard tab for shapash inspired dashboard - with gr.Tab("SHAP Dashboard"): + # row that displays the generated explanation of the model (if applicable) + with gr.Row(variant="panel"): + # wraps the explanation html in an iframe to display it interactively + xai_interactive = gr.HTML( + label="Interactive Explanation", + value=( + '

No Graphic to Display' + " (Yet)

" + ), + show_label=True, + ) + # row and accordion to display an explanation plot (if applicable) with gr.Row(): - gr.Markdown( - """ - ### SHAP Dashboard - SHAP Visualization Dashboard adopted from [shapash](https://github.com/MAIF/shapash) + with gr.Accordion("Token Explanation Plot", open=False): + gr.Markdown(""" + #### Plotted Values + Values have been excluded for readability. See colorbar for value indication. """) + # plot component that takes a matplotlib figure as input + xai_plot = gr.Plot(label="Token Level Explanation", scale=3) - # visualize dashboard to display global visualization provided by the BERTViz adoption - with gr.Tab("Visualize Dashboard"): - with gr.Row(): - gr.Markdown( - """ - ### Visualization Dashboard - Visualization Dashboard adopted from [BERTViz](https://github.com/jessevig/bertviz) - """) + # functions to trigger the controller + ## takes information for the chat and the xai selection + ## returns prompt, history and xai data + ## see backend/controller.py for more information + submit_btn.click( + interference, + [user_prompt, chatbot, knowledge_input, system_prompt, xai_selection], + [user_prompt, chatbot, xai_interactive, xai_plot], + ) + # function triggered by the enter key + user_prompt.submit( + interference, + [user_prompt, chatbot, knowledge_input, system_prompt, xai_selection], + [user_prompt, chatbot, xai_interactive, xai_plot], + ) - # model overview tab for transparency - with gr.Tab("notebooks Overview"): - with gr.Tab("Mistral 7B Instruct"): - gr.Markdown(value=load_md("./model/mistral.md")) - with gr.Tab("LlaMa 2 7B Chat"): - gr.Markdown(value=load_md("./model/llama2.md")) + # final row to show legal information + ## - credits, data protection and link to the License + with gr.Tab(label="Credits, Data Protection and License"): + gr.Markdown(value=load_md("public/credits_dataprotection_license.md")) - # final row to show legal information - credits, data protection and link to the LICENSE on GitHub - with gr.Row(): - with gr.Accordion("Credits, Data Protection and License", open=False): - gr.Markdown(value=load_md("public/credits_dataprotection_license.md")) - -# launch function for fastAPI Application +# mount function for fastAPI Application app = gr.mount_gradio_app(app, ui, path="/") -# launch function for Gradio Interface on hgf spaces +# launch function using uvicorn to launch the fastAPI application if __name__ == "__main__": - ui.launch(share=False) \ No newline at end of file + from uvicorn import run + + # run the application on port 8080 in reload mode + ## for local development, uses Docker for Prod deployment + run("main:app", port=8080, reload=True) diff --git a/memory/controller.py b/memory/controller.py deleted file mode 100644 index 5a09b9181b3be8f661af2366204fe6456f7d081a..0000000000000000000000000000000000000000 --- a/memory/controller.py +++ /dev/null @@ -1,29 +0,0 @@ -# minimal memory module for saving and loading converstations - -# package imports -from tinydb import TinyDB, Query -from tinydb.storages import MemoryStorage - -#temporary json db setup -db = TinyDB('db.json',storage=MemoryStorage) -query = Query() - -def conversation_mapper(data): - mapping = { - { - 'user': 'Hello, how are you?', - 'bot': 'I am good, thank you.' - }, - } - return mapping - -# function to dump json data into the db -def dump (data): - mapping = conversation_mapper(data) - doc_id = db.insert(data) - return doc_id, mapping - -# function to query data from the db -def get (doc_id:int): - data = db.get(doc_id=doc_id) - return data diff --git a/memory/db.json b/memory/db.json deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/model/__init__.py b/model/__init__.py index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..7d8ca1294b578f33d8e7daf450212ba1e8befa7c 100644 --- a/model/__init__.py +++ b/model/__init__.py @@ -0,0 +1,2 @@ +# empty init file for the package +# for fastapi to recognize the module diff --git a/model/godel.py b/model/godel.py new file mode 100644 index 0000000000000000000000000000000000000000..cd0fcc6b47fdd20f6c33d1616c8c5afae1ec8891 --- /dev/null +++ b/model/godel.py @@ -0,0 +1,63 @@ +# GODEL model module for chat interaction and model instance control + +# external imports +from transformers import AutoTokenizer, AutoModelForSeq2SeqLM + +# internal imports +from utils import modelling as mdl + +# model and tokenizer instance +TOKENIZER = AutoTokenizer.from_pretrained("microsoft/GODEL-v1_1-large-seq2seq") +MODEL = AutoModelForSeq2SeqLM.from_pretrained("microsoft/GODEL-v1_1-large-seq2seq") +CONFIG = {"max_new_tokens": 50, "min_length": 8, "top_p": 0.9, "do_sample": True} + + +# TODO: Make config variable +def set_config(config: dict = None): + if config is None: + config = {} + + MODEL.config.max_new_tokens = 50 + MODEL.config.min_length = 8 + MODEL.config.top_p = 0.9 + MODEL.config.do_sample = True + + +# formatting class to formatting input for the model +# CREDIT: Adapted from official interference example on Huggingface +## see https://huggingface.co/microsoft/GODEL-v1_1-large-seq2seq +def format_prompt(message: str, history: list, system_prompt: str, knowledge: str = ""): + # user input prompt initialization + prompt = "" + + # limits the prompt elements to the maximum token count + message, history, system_prompt, knowledge = mdl.prompt_limiter( + TOKENIZER, message, history, system_prompt, knowledge + ) + + # adds knowledge text if not empty + if knowledge != "": + knowledge = "[KNOWLEDGE] " + knowledge + + # adds conversation history to the prompt + for conversation in history: + prompt += f"EOS {conversation[0]} EOS {conversation[1]}" + + # adds the message to the prompt + prompt += f" {message}" + # combines the entire prompt + full_prompt = f"{system_prompt} [CONTEXT] {prompt} {knowledge}" + + # returns the formatted prompt + return full_prompt + + +# response class calling the model and returning the model output message +# CREDIT: Copied from official interference example on Huggingface +## see https://huggingface.co/microsoft/GODEL-v1_1-large-seq2seq +def respond(prompt): + input_ids = TOKENIZER(f"{prompt}", return_tensors="pt").input_ids + outputs = MODEL.generate(input_ids, **CONFIG) + output = TOKENIZER.decode(outputs[0], skip_special_tokens=True) + + return output diff --git a/model/llama2.md b/model/llama2.md deleted file mode 100644 index 77d596d8ab74cd8bdf083c8616365e698d54e4ae..0000000000000000000000000000000000000000 --- a/model/llama2.md +++ /dev/null @@ -1,6 +0,0 @@ -### Credits - -### Data Protection - -### License -This Product is licensed under the MIT license. \ No newline at end of file diff --git a/model/llama2.py b/model/llama2.py deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/model/mistral.md b/model/mistral.md deleted file mode 100644 index 77d596d8ab74cd8bdf083c8616365e698d54e4ae..0000000000000000000000000000000000000000 --- a/model/mistral.md +++ /dev/null @@ -1,6 +0,0 @@ -### Credits - -### Data Protection - -### License -This Product is licensed under the MIT license. \ No newline at end of file diff --git a/model/mistral.py b/model/mistral.py deleted file mode 100644 index 3c883150f55c235dfb44196d382f1ff08025fea8..0000000000000000000000000000000000000000 --- a/model/mistral.py +++ /dev/null @@ -1,66 +0,0 @@ -from huggingface_hub import InferenceClient -import os - -# huggingface token used to load closed off models -token = os.environ.get("HGFTOKEN") - -# interference client created from mistral 7b instruction fine tuned model -# credit: copied 1:1 from Hugging Face, Inc/ Omar Sanseviero (see https://huggingface.co/spaces/osanseviero/mistral-super-fast/) -interference = InferenceClient( - "mistralai/Mistral-7B-Instruct-v0.1" -) - -# default model settings -model_temperature = 0.7 -model_max_new_tokens = 320 -model_top_p = 0.95 -model_repetition_penalty = 1.1 - -# chat function - basically the main function calling other functions and returning a response to showcase in chatbot ui -def chat (prompt, history,): - - # creating formatted prompt and calling for an answer from the model - formatted_prompt = format_prompt(prompt, history) - answer=respond(formatted_prompt) - - # updating the chat history with the new answer - history.append((prompt, answer)) - - # returning the chat history to be displayed in the chatbot ui - return "",history - -# function to format prompt in a way that is understandable for the text generation model -# credit: copied 1:1 from Hugging Face, Inc/ Omar Sanseviero (see https://huggingface.co/spaces/osanseviero/mistral-super-fast/) -def format_prompt(message, history): - prompt = "" - - # labeling each message in the history as bot or user - for user_prompt, bot_response in history: - prompt += f"[INST] {user_prompt} [/INST]" - prompt += f" {bot_response} " - prompt += f"[INST] {message} [/INST]" - return prompt - -# function to get the response -# credit: minimally changed from Hugging Face, Inc/ Omar Sanseviero (see https://huggingface.co/spaces/osanseviero/mistral-super-fast/) -def respond(formatted_prompt): - - # setting model temperature and - temperature = float(model_temperature) - if temperature < 1e-2: - temperature = 1e-2 - top_p = float(model_top_p) - - # creating model arguments/settings - generate_kwargs = dict( - temperature=temperature, - max_new_tokens=model_max_new_tokens, - top_p=top_p, - repetition_penalty=model_repetition_penalty, - do_sample=True, - seed=42, - ) - - # calling for model output and returning it - output = interference.text_generation(formatted_prompt, **generate_kwargs, stream=False, details=True, return_full_text=False).generated_text - return output \ No newline at end of file diff --git a/public/credits_dataprotection_license.md b/public/credits_dataprotection_license.md index 77d596d8ab74cd8bdf083c8616365e698d54e4ae..eee6ddeaa72ba1787d8bf83cb11763705985a557 100644 --- a/public/credits_dataprotection_license.md +++ b/public/credits_dataprotection_license.md @@ -1,6 +1,47 @@ -### Credits +# Links -### Data Protection +- [GitHub Repository](https://github.com/LennardZuendorf/thesis-webapp) - The GitHub repository of this project. +- [HTW Berlin](https://www.htw-berlin.de/) - The University I have built this project for, as part of my thesis. +- [Thesis Print]() - Link to the thesis pdf (in English), containing more information about the project. And a full list of sources for this work as well as additional evaluations and fundamental information for the project. -### License -This Product is licensed under the MIT license. \ No newline at end of file + +# Credits +For full credits, please refer to the [thesis print]() + +### Models +This implementation is build on GODEL by Microsoft, Inc. + +##### GODEL +GODEL is an open source model by Microsoft. See [offical paper](https://arxiv.org/abs/2206.11309) for more information. + +- the version used in this project is GODEL Large, see [huggingface model hub](https://huggingface.co/microsoft/GODEL-v1_1-large-seq2seq?text=Hey+my+name+is+Thomas%21+How+are+you%3F) +- the model as is a generative seq2seq transformer fine tuned for goal directed dialog +- it supports context and knowledge base inputs + +### Libraries +This project uses a number of open source libraries, only the most important ones are listed below. + +##### Shap +This application uses a custom version of the shap library, which is available at [GitHub](https://github.com/shap/shap). + +- please refer to the [thesis-custom-shap](https://github.com/LennardZuendorf/thesis-custom-shap) repository for more information about the changes made to the library, specifically the README and CHANGES files +- the shap library and the used partition SHAP explainer are based on work by Lundberg et al. (2017), see [offical paper](https://arxiv.org/pdf/1705.07874.pdf) for more information + +##### BertViz +This application uses a slightly customized version of the bertviz library, which is available at [GitHub](https://github.com/jessevig/bertviz) + +- the bertviz was introduced by Vig et al. (2019), see [offical paper](https://arxiv.org/pdf/1906.05714.pdf) for more information +- there are no changes to the library itself, only to the way it is used in this project (adapted to use Mistral/LlaMa 2 instead of BERT) + + +# Data Protection +This is a non-commercial research project, which does not collect any personal data. The only data collected is the data you enter into the application. This data is only used to generate the explanations and is not stored anywhere. + +> However, the application may be hosted with an external service (i.e. Huggingface Spaces), which may collect data. + +Please refer to the data protection policies of the respective service for more information. If you use the "flag" feature, the data you enter will be stored in *publicly available* csv file. + + +# License +This Product is licensed under the MIT license. See [LICENSE](https://github.com/LennardZuendorf/thesis-webapp/blob/main/LICENSE.md) at GitHub for more information. +Please credit the original authors of this project (Lennard Zรผndorf) and the credits listed above if you use this project or parts of it in your own work. diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000000000000000000000000000000000000..60d83d6e66a90e7783820f766a07fcb0709e9bed --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,61 @@ +# configuration for formatting & linting tools +[tool.black] +line-length = 88 +include = '\.pyi?$' +preview = true +exclude = ''' +/( + \.eggs + | \.git + | \.hg + | \.mypy_cache + | \.tox + | \.venv + | _build + | buck-out + | build + | dist + | components +)/ +''' + +[tool.pylint.messages_control] +disable = [ + "arguments-differ", + "attribute-defined-outside-init", + "blacklisted-name", + "duplicate-code", + "fixme", + "import-error", + "invalid-name", + "no-member", + "no-name-in-module", + "protected-access", + "stop-iteration-return", + "too-few-public-methods", + "too-many-arguments", + "too-many-branches", + "too-many-instance-attributes", + "too-many-lines", + "too-many-locals", + "too-many-return-statements", + "too-many-statements", + "abstract-method", + "chained-comparison", + "eval-used", + "exec-used", + "expression-not-assigned", + "global-statement", + "missing-docstring", + "redefined-argument-from-local", + "redefined-outer-name", + "reimported", + "too-many-ancestors", + "unexpected-special-method-signature", +] + +[tool.pylint.format] +max-line-length = "88" + +[tool.pylint.MASTER] +ignore = "components" diff --git a/railway.json b/railway.json deleted file mode 100644 index 153eb3b5bc4c8f3e474db4bd4cbb2a78e436c0b3..0000000000000000000000000000000000000000 --- a/railway.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "$schema": "https://railway.app/railway.schema.json", - "build": { - "builder": "DOCKERFILE", - "dockerfilePath": "Dockerfile" - }, - "deploy": { - "numReplicas": 1, - "sleepApplication": false, - "restartPolicyType": "ON_FAILURE", - "restartPolicyMaxRetries": 10 - } -} \ No newline at end of file diff --git a/requirements.txt b/requirements.txt index 4877269892fb55a046415fc2155ea37da7cfccfe..9a1a2da19ce9aafcf870fe534c49afa026c90eff 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,10 +1,18 @@ gradio~=4.7.1 transformers~=4.35.2 torch~=2.1.1 -shap~=0.43.0 +shap~=0.44.0 +bertviz~=1.4.0 accelerate~=0.24.1 markdown~=3.5.1 huggingface_hub~=0.19.4 fastapi~=0.104.1 uvicorn~=0.24.0 tinydb~=4.8.0 +black~=23.12.0 +pylint~=3.0.0 +seaborn~=0.13.0 +numpy +matplotlib +pre-commit +#./components/iframe/dist/gradio_iframe-0.0.1-py3-none-any.whl diff --git a/components/shap_explanation.py b/utils/__init__.py similarity index 100% rename from components/shap_explanation.py rename to utils/__init__.py diff --git a/utils/formatting.py b/utils/formatting.py new file mode 100644 index 0000000000000000000000000000000000000000..1dc2d19d2227718e68e470ada741c27e19733a3e --- /dev/null +++ b/utils/formatting.py @@ -0,0 +1,53 @@ +# formatting util module providing formatting functions for the model input and output + +# external imports +import re + + +# function to format the model reponse nicely +def format_output_text(output: list): + # remove special tokens from list + formatted_output = format_tokens(output) + + # start string with first list item if it is not empty + if formatted_output[0] != "": + output_str = formatted_output[0] + else: + # alternatively start with second list item + output_str = formatted_output[1] + + # add all other list items with a space in between + for txt in formatted_output[1:]: + # check if the token is a punctuation mark + if txt in [".", ",", "!", "?"]: + # add punctuation mark without space + output_str += txt + # add token with space if not empty + elif txt != "": + output_str += " " + txt + + # return the combined string with multiple spaces removed + return re.sub(" +", " ", output_str) + + +# format the tokens by removing special tokens and special characters +def format_tokens(tokens: list): + # define special tokens to remove and initialize empty list + special_tokens = ["[CLS]", "[SEP]", "[PAD]", "[UNK]", "[MASK]", "โ–", "ฤ ", ""] + updated_tokens = [] + + # loop through tokens + for t in tokens: + # remove special token from start of token if found + if t.startswith("โ–"): + t = t.lstrip("โ–") + + # loop through special tokens and remove them if found + for s in special_tokens: + t = t.replace(s, "") + + # add token to list + updated_tokens.append(t) + + # return the list of tokens + return updated_tokens diff --git a/utils/modelling.py b/utils/modelling.py new file mode 100644 index 0000000000000000000000000000000000000000..7a430855196d4e852e9170bfc3570e414eab0b2f --- /dev/null +++ b/utils/modelling.py @@ -0,0 +1,69 @@ +# module for modelling utilities + +# external imports +import gradio as gr + + +def prompt_limiter( + tokenizer, message: str, history: list, system_prompt: str, knowledge: str = "" +): + # initializing the prompt history empty + prompt_history = [] + # getting the token count for the message, system prompt, and knowledge + pre_count = ( + token_counter(tokenizer, message) + + token_counter(tokenizer, system_prompt) + + token_counter(tokenizer, knowledge) + ) + + # validating the token count + # check if token count already too high + if pre_count > 1024: + + # check if token count too high even without knowledge + if ( + token_counter(tokenizer, message) + token_counter(tokenizer, system_prompt) + > 1024 + ): + + # show warning and raise error + gr.Warning("Message and system prompt are too long. Please shorten them.") + raise RuntimeError( + "Message and system prompt are too long. Please shorten them." + ) + + # show warning and remove knowledge + gr.Warning("Knowledge is too long. It has been removed to keep model running.") + return message, prompt_history, system_prompt, "" + + # if token count small enough, add history + if pre_count < 800: + # setting the count to the precount + count = pre_count + # reversing the history to prioritize recent conversations + history.reverse() + + # iterating through the history + for conversation in history: + + # checking the token count with the current conversation + count += token_counter(tokenizer, conversation[0]) + token_counter( + tokenizer, conversation[1] + ) + + # add conversation or break loop depending on token count + if count < 1024: + prompt_history.append(conversation) + else: + break + + # return the message, prompt history, system prompt, and knowledge + return message, prompt_history, system_prompt, knowledge + + +# token counter function using the model tokenizer +def token_counter(tokenizer, text: str): + # tokenize the text + tokens = tokenizer(text, return_tensors="pt").input_ids + # return the token count + return len(tokens[0])