github-actions
commited on
Commit
·
6ca4b94
0
Parent(s):
Sync from GitHub (CI)
Browse filesThis view is limited to 50 files because it contains too many changes.
See raw diff
- .aidigestignore +9 -0
- .devcontainer/Dockerfile +58 -0
- .devcontainer/devcontainer.json +119 -0
- .dockerignore +12 -0
- .gitattributes +19 -0
- .github/ISSUE_TEMPLATE/data_donation.yml +65 -0
- .github/workflows/push-to-hf-space.yml +49 -0
- .gitignore +215 -0
- .vscode/launch.json +42 -0
- .vscode/settings.json +52 -0
- Dockerfile +58 -0
- LICENSE +5 -0
- README.md +43 -0
- notebooks/layouts/marimo-demo.grid.json +57 -0
- notebooks/marimo-demo.py +206 -0
- notebooks/theme.marimo.css +4 -0
- poetry.lock +0 -0
- public/bib/references.bib +42 -0
- public/favicon-128x128.png +3 -0
- public/favicon-16x16.png +3 -0
- public/favicon-256x256.png +3 -0
- public/favicon-32x32.png +3 -0
- public/favicon-48x48.png +3 -0
- public/favicon-64x64.png +3 -0
- public/fonts/TitilliumWeb-Black.ttf +3 -0
- public/fonts/TitilliumWeb-Bold.ttf +3 -0
- public/fonts/TitilliumWeb-BoldItalic.ttf +3 -0
- public/fonts/TitilliumWeb-ExtraLight.ttf +3 -0
- public/fonts/TitilliumWeb-ExtraLightItalic.ttf +3 -0
- public/fonts/TitilliumWeb-Italic.ttf +3 -0
- public/fonts/TitilliumWeb-Light.ttf +3 -0
- public/fonts/TitilliumWeb-LightItalic.ttf +3 -0
- public/fonts/TitilliumWeb-Regular.ttf +3 -0
- public/fonts/TitilliumWeb-SemiBold.ttf +3 -0
- public/fonts/TitilliumWeb-SemiBoldItalic.ttf +3 -0
- public/img/logo-dark.svg +3 -0
- public/img/logo.svg +3 -0
- public/img/logotype.svg +3 -0
- public/img/osf-logo.svg +3 -0
- public/img/synth-net-inline.svg +3 -0
- public/img/synth-net-stacked.svg +3 -0
- public/img/synthnet-logo.svg +3 -0
- public/img/team-arslan.jpg +3 -0
- public/img/team-clarke.jpg +3 -0
- public/img/team-cummins.jpg +3 -0
- public/img/team-elson.png +3 -0
- public/img/team-hommel.jpg +3 -0
- public/img/team-hussey.jpg +3 -0
- public/img/team-kuelpmann.jpg +3 -0
- public/libs/alpinejs@3.14.8/alpine.collapse.min.js +1 -0
.aidigestignore
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
codebase.md
|
| 2 |
+
poetry.lock
|
| 3 |
+
public/libs/**
|
| 4 |
+
__marimo__
|
| 5 |
+
public/styles/output.css
|
| 6 |
+
.venv
|
| 7 |
+
cache
|
| 8 |
+
**.parquet
|
| 9 |
+
.env
|
.devcontainer/Dockerfile
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
FROM ubuntu:24.04
|
| 2 |
+
|
| 3 |
+
ARG DEV_MODE
|
| 4 |
+
|
| 5 |
+
ENV DEV_MODE=${DEV_MODE:-false}
|
| 6 |
+
|
| 7 |
+
ENV DEBIAN_FRONTEND=noninteractive
|
| 8 |
+
ENV PYTHONUNBUFFERED=1
|
| 9 |
+
ENV PYTHONDONTWRITEBYTECODE=1
|
| 10 |
+
|
| 11 |
+
RUN apt update
|
| 12 |
+
|
| 13 |
+
RUN apt install -y \
|
| 14 |
+
python3.12 \
|
| 15 |
+
python3.12-dev \
|
| 16 |
+
python3.12-venv \
|
| 17 |
+
python3-pip
|
| 18 |
+
|
| 19 |
+
RUN ln -sf /usr/bin/python3 /usr/bin/python && ln -sf /usr/bin/pip3 /usr/bin/pip
|
| 20 |
+
|
| 21 |
+
RUN apt install -y \
|
| 22 |
+
curl \
|
| 23 |
+
git \
|
| 24 |
+
git-lfs \
|
| 25 |
+
locales && \
|
| 26 |
+
git lfs install && \
|
| 27 |
+
sed -i 's/# \(en_US.UTF-8 UTF-8\)/\1/' /etc/locale.gen && \
|
| 28 |
+
locale-gen && \
|
| 29 |
+
rm -rf /var/lib/apt/lists/*
|
| 30 |
+
|
| 31 |
+
RUN apt update && \
|
| 32 |
+
apt install -y nodejs npm && \
|
| 33 |
+
rm -rf /var/lib/apt/lists/*
|
| 34 |
+
|
| 35 |
+
ENV LANG=en_US.UTF-8 \
|
| 36 |
+
LC_ALL=en_US.UTF-8
|
| 37 |
+
|
| 38 |
+
RUN curl -sSL https://install.python-poetry.org | python - && \
|
| 39 |
+
ln -sf ~/.local/bin/poetry /usr/local/bin/poetry
|
| 40 |
+
|
| 41 |
+
RUN poetry config virtualenvs.in-project true
|
| 42 |
+
|
| 43 |
+
WORKDIR /app
|
| 44 |
+
|
| 45 |
+
EXPOSE 80 7860
|
| 46 |
+
|
| 47 |
+
COPY pyproject.toml poetry.lock* ./
|
| 48 |
+
|
| 49 |
+
RUN if [ "$DEV_MODE" = "false" ]; then \
|
| 50 |
+
echo "🏭 Production mode: Clean build without cache"; \
|
| 51 |
+
poetry install --no-root --no-interaction --no-ansi --with data,ml,dev; \
|
| 52 |
+
fi
|
| 53 |
+
|
| 54 |
+
COPY . /app
|
| 55 |
+
|
| 56 |
+
RUN chmod +x /app/scripts/*.sh || true
|
| 57 |
+
|
| 58 |
+
ENTRYPOINT ["/app/scripts/entrypoint.sh"]
|
.devcontainer/devcontainer.json
ADDED
|
@@ -0,0 +1,119 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"name": "Data Science Web App",
|
| 3 |
+
"build": {
|
| 4 |
+
"dockerfile": "Dockerfile",
|
| 5 |
+
"context": "..",
|
| 6 |
+
"args": {
|
| 7 |
+
"INSTALL_R": "true",
|
| 8 |
+
"INSTALL_OPENCPU": "true",
|
| 9 |
+
"DEV_MODE": "true"
|
| 10 |
+
}
|
| 11 |
+
},
|
| 12 |
+
"mounts": [
|
| 13 |
+
"source=poetry-cache,target=/app/.venv,type=volume"
|
| 14 |
+
],
|
| 15 |
+
"forwardPorts": [
|
| 16 |
+
7860
|
| 17 |
+
],
|
| 18 |
+
"containerEnv": {
|
| 19 |
+
"DEV_MODE": "true"
|
| 20 |
+
},
|
| 21 |
+
"postCreateCommand": "poetry lock && poetry install --no-interaction --no-ansi --with dev,data,ml,demo",
|
| 22 |
+
"postStartCommand": "scripts/entrypoint.sh && mkdir -p ~/.vscode-server/data/Machine",
|
| 23 |
+
"customizations": {
|
| 24 |
+
"vscode": {
|
| 25 |
+
"extensions": [
|
| 26 |
+
"ms-python.python",
|
| 27 |
+
"ms-python.vscode-pylance",
|
| 28 |
+
"adrianwilczynski.alpine-js-intellisense",
|
| 29 |
+
"bradlc.vscode-tailwindcss",
|
| 30 |
+
"tamasfe.even-better-toml",
|
| 31 |
+
"reditorsupport.r",
|
| 32 |
+
"wholroyd.jinja",
|
| 33 |
+
"formulahendry.code-runner",
|
| 34 |
+
"ms-azuretools.vscode-docker",
|
| 35 |
+
"eamodio.gitlens",
|
| 36 |
+
"otovo-oss.htmx-tags",
|
| 37 |
+
"csstools.postcss",
|
| 38 |
+
"dbaeumer.vscode-eslint",
|
| 39 |
+
"esbenp.prettier-vscode",
|
| 40 |
+
"samuelcolvin.jinjahtml",
|
| 41 |
+
"monosans.djlint",
|
| 42 |
+
"ms-toolsai.jupyter",
|
| 43 |
+
"ms-python.black-formatter",
|
| 44 |
+
"naumovs.color-highlight"
|
| 45 |
+
],
|
| 46 |
+
"settings": {
|
| 47 |
+
"python.defaultInterpreterPath": "/app/.venv/bin/python",
|
| 48 |
+
"terminal.integrated.shell.linux": "/bin/bash",
|
| 49 |
+
"python.linting.enabled": true,
|
| 50 |
+
"python.linting.pylintEnabled": true,
|
| 51 |
+
"python.formatting.provider": "black",
|
| 52 |
+
"editor.formatOnSave": true,
|
| 53 |
+
"editor.defaultFormatter": "esbenp.prettier-vscode",
|
| 54 |
+
"[python]": {
|
| 55 |
+
"editor.defaultFormatter": "ms-python.python"
|
| 56 |
+
},
|
| 57 |
+
"editor.codeActionsOnSave": {
|
| 58 |
+
"source.sortImports": "explicit"
|
| 59 |
+
},
|
| 60 |
+
"terminal.integrated.defaultProfile.linux": "bash",
|
| 61 |
+
"terminal.integrated.profiles.linux": {
|
| 62 |
+
"Apache Server": {
|
| 63 |
+
"path": "apachectl",
|
| 64 |
+
"args": [
|
| 65 |
+
"-DFOREGROUND"
|
| 66 |
+
]
|
| 67 |
+
},
|
| 68 |
+
"Uvicorn Server": {
|
| 69 |
+
"path": "poetry run uvicorn",
|
| 70 |
+
"args": [
|
| 71 |
+
"src.main:app",
|
| 72 |
+
"--host",
|
| 73 |
+
"0.0.0.0",
|
| 74 |
+
"--port",
|
| 75 |
+
"7860",
|
| 76 |
+
"--reload",
|
| 77 |
+
"--reload-include",
|
| 78 |
+
"./src/",
|
| 79 |
+
"--reload-exclude",
|
| 80 |
+
"*.db"
|
| 81 |
+
]
|
| 82 |
+
},
|
| 83 |
+
"Edit Demo Marimo Notebook": {
|
| 84 |
+
"path": "poetry run marimo",
|
| 85 |
+
"args": [
|
| 86 |
+
"edit",
|
| 87 |
+
"/app/notebooks/marimo-demo.py",
|
| 88 |
+
"--host",
|
| 89 |
+
"0.0.0.0",
|
| 90 |
+
"--port",
|
| 91 |
+
"8080",
|
| 92 |
+
"--headless"
|
| 93 |
+
]
|
| 94 |
+
},
|
| 95 |
+
"Tailwind CSS": {
|
| 96 |
+
"path": "/app/bin/tailwindcss",
|
| 97 |
+
"args": [
|
| 98 |
+
"-i",
|
| 99 |
+
"/app/public/styles/input.css",
|
| 100 |
+
"-o",
|
| 101 |
+
"/app/public/styles/output.css",
|
| 102 |
+
"--watch=always",
|
| 103 |
+
"--poll"
|
| 104 |
+
]
|
| 105 |
+
},
|
| 106 |
+
"AI Digest": {
|
| 107 |
+
"path": "npx",
|
| 108 |
+
"args": [
|
| 109 |
+
"--yes",
|
| 110 |
+
"ai-digest"
|
| 111 |
+
]
|
| 112 |
+
}
|
| 113 |
+
}
|
| 114 |
+
}
|
| 115 |
+
}
|
| 116 |
+
},
|
| 117 |
+
"workspaceMount": "source=${localWorkspaceFolder},target=/app,type=bind,consistency=delegated",
|
| 118 |
+
"workspaceFolder": "/app"
|
| 119 |
+
}
|
.dockerignore
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
node_modules
|
| 2 |
+
.git
|
| 3 |
+
*.log
|
| 4 |
+
*.tmp
|
| 5 |
+
.venv
|
| 6 |
+
.git
|
| 7 |
+
__pycache__
|
| 8 |
+
__marimo__
|
| 9 |
+
*.pyc
|
| 10 |
+
.env
|
| 11 |
+
cache
|
| 12 |
+
cache/processed_data/
|
.gitattributes
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
* text=auto eol=lf
|
| 2 |
+
|
| 3 |
+
# Git LFS - Images
|
| 4 |
+
*.png filter=lfs diff=lfs merge=lfs -text
|
| 5 |
+
*.jpg filter=lfs diff=lfs merge=lfs -text
|
| 6 |
+
*.jpeg filter=lfs diff=lfs merge=lfs -text
|
| 7 |
+
*.gif filter=lfs diff=lfs merge=lfs -text
|
| 8 |
+
*.webp filter=lfs diff=lfs merge=lfs -text
|
| 9 |
+
*.svg filter=lfs diff=lfs merge=lfs -text
|
| 10 |
+
|
| 11 |
+
# Git LFS - Fonts
|
| 12 |
+
*.ttf filter=lfs diff=lfs merge=lfs -text
|
| 13 |
+
*.otf filter=lfs diff=lfs merge=lfs -text
|
| 14 |
+
*.woff filter=lfs diff=lfs merge=lfs -text
|
| 15 |
+
*.woff2 filter=lfs diff=lfs merge=lfs -text
|
| 16 |
+
|
| 17 |
+
# Git LFS - Other binary files
|
| 18 |
+
*.pdf filter=lfs diff=lfs merge=lfs -text
|
| 19 |
+
*.zip filter=lfs diff=lfs merge=lfs -text
|
.github/ISSUE_TEMPLATE/data_donation.yml
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
name: "Data Donation"
|
| 2 |
+
description: "Contribute a questionnaire, scale, survey or test to the project."
|
| 3 |
+
title: "Data Donation: [Instrument Name]"
|
| 4 |
+
labels: ["data-donation", "triage"]
|
| 5 |
+
body:
|
| 6 |
+
- type: markdown
|
| 7 |
+
attributes:
|
| 8 |
+
value: |
|
| 9 |
+
Thanks for your interest in contributing data! Please fill out the details below.
|
| 10 |
+
|
| 11 |
+
- type: input
|
| 12 |
+
id: contact
|
| 13 |
+
attributes:
|
| 14 |
+
label: Contact Email
|
| 15 |
+
description: How can we reach you?
|
| 16 |
+
placeholder: researcher@university.edu
|
| 17 |
+
validations:
|
| 18 |
+
required: true
|
| 19 |
+
|
| 20 |
+
- type: input
|
| 21 |
+
id: instrument_name
|
| 22 |
+
attributes:
|
| 23 |
+
label: Instrument Name
|
| 24 |
+
description: A short, descriptive name for the instrument
|
| 25 |
+
placeholder: "e.g., Revised Attitudes Towards Horses Scale (R-ATHS)"
|
| 26 |
+
validations:
|
| 27 |
+
required: false
|
| 28 |
+
|
| 29 |
+
- type: textarea
|
| 30 |
+
id: description
|
| 31 |
+
attributes:
|
| 32 |
+
label: Instrument Description
|
| 33 |
+
description: What does this dataset contain? What constructs/scales were measured?
|
| 34 |
+
placeholder: |
|
| 35 |
+
- Constructs measured: ...
|
| 36 |
+
- Target population: ...
|
| 37 |
+
- Collection context: ...
|
| 38 |
+
validations:
|
| 39 |
+
required: true
|
| 40 |
+
|
| 41 |
+
- type: input
|
| 42 |
+
id: sample_size
|
| 43 |
+
attributes:
|
| 44 |
+
label: Sample Size
|
| 45 |
+
description: Approximate number of participants/observations
|
| 46 |
+
placeholder: "N = 500"
|
| 47 |
+
validations:
|
| 48 |
+
required: false
|
| 49 |
+
|
| 50 |
+
- type: textarea
|
| 51 |
+
id: publications
|
| 52 |
+
attributes:
|
| 53 |
+
label: Related Publications
|
| 54 |
+
description: Any papers or reports using this data? (Optional)
|
| 55 |
+
placeholder: "Author et al. (2023). Title. Journal. https://doi.org/..."
|
| 56 |
+
validations:
|
| 57 |
+
required: false
|
| 58 |
+
|
| 59 |
+
- type: textarea
|
| 60 |
+
id: additional
|
| 61 |
+
attributes:
|
| 62 |
+
label: Additional Information
|
| 63 |
+
description: Anything else we should know?
|
| 64 |
+
validations:
|
| 65 |
+
required: false
|
.github/workflows/push-to-hf-space.yml
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
name: Push to Hugging Face Space
|
| 2 |
+
on:
|
| 3 |
+
push:
|
| 4 |
+
branches: [ main ]
|
| 5 |
+
workflow_dispatch:
|
| 6 |
+
|
| 7 |
+
jobs:
|
| 8 |
+
to-hf:
|
| 9 |
+
runs-on: ubuntu-latest
|
| 10 |
+
steps:
|
| 11 |
+
- uses: actions/checkout@v4
|
| 12 |
+
with:
|
| 13 |
+
lfs: true
|
| 14 |
+
fetch-depth: 0
|
| 15 |
+
|
| 16 |
+
- name: Prepare staging dir for HF Space
|
| 17 |
+
run: |
|
| 18 |
+
rm -rf hf_staging
|
| 19 |
+
mkdir -p hf_staging
|
| 20 |
+
# copy repo contents (excluding Git metadata)
|
| 21 |
+
rsync -a --exclude '.git' ./ hf_staging/
|
| 22 |
+
|
| 23 |
+
cd hf_staging
|
| 24 |
+
|
| 25 |
+
# 1) Ensure README.md is the HF one (but keep your normal README in GitHub)
|
| 26 |
+
if [ -f README_HF.md ]; then
|
| 27 |
+
mv -f README_HF.md README.md
|
| 28 |
+
fi
|
| 29 |
+
|
| 30 |
+
# 2) Promote Dockerfile from .devcontainer to root for HF build
|
| 31 |
+
if [ -f .devcontainer/Dockerfile ]; then
|
| 32 |
+
cp .devcontainer/Dockerfile ./Dockerfile
|
| 33 |
+
fi
|
| 34 |
+
|
| 35 |
+
- name: Push to HuggingFace Space
|
| 36 |
+
env:
|
| 37 |
+
HF_TOKEN: ${{ secrets.HF_TOKEN }} # GitHub repo secret
|
| 38 |
+
HF_SPACE: magnolia-psychometrics/synth-net
|
| 39 |
+
run: |
|
| 40 |
+
cd hf_staging
|
| 41 |
+
git init
|
| 42 |
+
git lfs install
|
| 43 |
+
git config user.email "actions@github.com"
|
| 44 |
+
git config user.name "github-actions"
|
| 45 |
+
git remote add origin https://huggingface.co/spaces/${HF_SPACE}
|
| 46 |
+
git add .
|
| 47 |
+
git commit -m "Sync from GitHub (CI)"
|
| 48 |
+
# Use token to authenticate
|
| 49 |
+
git push --force https://user:${HF_TOKEN}@huggingface.co/spaces/${HF_SPACE} HEAD:main
|
.gitignore
ADDED
|
@@ -0,0 +1,215 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
cache
|
| 2 |
+
bin/tailwindcss
|
| 3 |
+
codebase.md
|
| 4 |
+
__marimo__
|
| 5 |
+
public/styles/output.css
|
| 6 |
+
*:Zone.Identifier
|
| 7 |
+
src/data/**
|
| 8 |
+
|
| 9 |
+
# Byte-compiled / optimized / DLL files
|
| 10 |
+
__pycache__/
|
| 11 |
+
*.py[codz]
|
| 12 |
+
*$py.class
|
| 13 |
+
|
| 14 |
+
# C extensions
|
| 15 |
+
*.so
|
| 16 |
+
|
| 17 |
+
# Distribution / packaging
|
| 18 |
+
.Python
|
| 19 |
+
build/
|
| 20 |
+
develop-eggs/
|
| 21 |
+
dist/
|
| 22 |
+
downloads/
|
| 23 |
+
eggs/
|
| 24 |
+
.eggs/
|
| 25 |
+
lib/
|
| 26 |
+
lib64/
|
| 27 |
+
parts/
|
| 28 |
+
sdist/
|
| 29 |
+
var/
|
| 30 |
+
wheels/
|
| 31 |
+
share/python-wheels/
|
| 32 |
+
*.egg-info/
|
| 33 |
+
.installed.cfg
|
| 34 |
+
*.egg
|
| 35 |
+
MANIFEST
|
| 36 |
+
|
| 37 |
+
# PyInstaller
|
| 38 |
+
# Usually these files are written by a python script from a template
|
| 39 |
+
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
| 40 |
+
*.manifest
|
| 41 |
+
*.spec
|
| 42 |
+
|
| 43 |
+
# Installer logs
|
| 44 |
+
pip-log.txt
|
| 45 |
+
pip-delete-this-directory.txt
|
| 46 |
+
|
| 47 |
+
# Unit test / coverage reports
|
| 48 |
+
htmlcov/
|
| 49 |
+
.tox/
|
| 50 |
+
.nox/
|
| 51 |
+
.coverage
|
| 52 |
+
.coverage.*
|
| 53 |
+
.cache
|
| 54 |
+
nosetests.xml
|
| 55 |
+
coverage.xml
|
| 56 |
+
*.cover
|
| 57 |
+
*.py.cover
|
| 58 |
+
.hypothesis/
|
| 59 |
+
.pytest_cache/
|
| 60 |
+
cover/
|
| 61 |
+
|
| 62 |
+
# Translations
|
| 63 |
+
*.mo
|
| 64 |
+
*.pot
|
| 65 |
+
|
| 66 |
+
# Django stuff:
|
| 67 |
+
*.log
|
| 68 |
+
local_settings.py
|
| 69 |
+
db.sqlite3
|
| 70 |
+
db.sqlite3-journal
|
| 71 |
+
|
| 72 |
+
# Flask stuff:
|
| 73 |
+
instance/
|
| 74 |
+
.webassets-cache
|
| 75 |
+
|
| 76 |
+
# Scrapy stuff:
|
| 77 |
+
.scrapy
|
| 78 |
+
|
| 79 |
+
# Sphinx documentation
|
| 80 |
+
docs/_build/
|
| 81 |
+
|
| 82 |
+
# PyBuilder
|
| 83 |
+
.pybuilder/
|
| 84 |
+
target/
|
| 85 |
+
|
| 86 |
+
# Jupyter Notebook
|
| 87 |
+
.ipynb_checkpoints
|
| 88 |
+
|
| 89 |
+
# IPython
|
| 90 |
+
profile_default/
|
| 91 |
+
ipython_config.py
|
| 92 |
+
|
| 93 |
+
# pyenv
|
| 94 |
+
# For a library or package, you might want to ignore these files since the code is
|
| 95 |
+
# intended to run in multiple environments; otherwise, check them in:
|
| 96 |
+
# .python-version
|
| 97 |
+
|
| 98 |
+
# pipenv
|
| 99 |
+
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
|
| 100 |
+
# However, in case of collaboration, if having platform-specific dependencies or dependencies
|
| 101 |
+
# having no cross-platform support, pipenv may install dependencies that don't work, or not
|
| 102 |
+
# install all needed dependencies.
|
| 103 |
+
#Pipfile.lock
|
| 104 |
+
|
| 105 |
+
# UV
|
| 106 |
+
# Similar to Pipfile.lock, it is generally recommended to include uv.lock in version control.
|
| 107 |
+
# This is especially recommended for binary packages to ensure reproducibility, and is more
|
| 108 |
+
# commonly ignored for libraries.
|
| 109 |
+
#uv.lock
|
| 110 |
+
|
| 111 |
+
# poetry
|
| 112 |
+
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
|
| 113 |
+
# This is especially recommended for binary packages to ensure reproducibility, and is more
|
| 114 |
+
# commonly ignored for libraries.
|
| 115 |
+
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
|
| 116 |
+
#poetry.lock
|
| 117 |
+
#poetry.toml
|
| 118 |
+
|
| 119 |
+
# pdm
|
| 120 |
+
# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
|
| 121 |
+
# pdm recommends including project-wide configuration in pdm.toml, but excluding .pdm-python.
|
| 122 |
+
# https://pdm-project.org/en/latest/usage/project/#working-with-version-control
|
| 123 |
+
#pdm.lock
|
| 124 |
+
#pdm.toml
|
| 125 |
+
.pdm-python
|
| 126 |
+
.pdm-build/
|
| 127 |
+
|
| 128 |
+
# pixi
|
| 129 |
+
# Similar to Pipfile.lock, it is generally recommended to include pixi.lock in version control.
|
| 130 |
+
#pixi.lock
|
| 131 |
+
# Pixi creates a virtual environment in the .pixi directory, just like venv module creates one
|
| 132 |
+
# in the .venv directory. It is recommended not to include this directory in version control.
|
| 133 |
+
.pixi
|
| 134 |
+
|
| 135 |
+
# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
|
| 136 |
+
__pypackages__/
|
| 137 |
+
|
| 138 |
+
# Celery stuff
|
| 139 |
+
celerybeat-schedule
|
| 140 |
+
celerybeat.pid
|
| 141 |
+
|
| 142 |
+
# SageMath parsed files
|
| 143 |
+
*.sage.py
|
| 144 |
+
|
| 145 |
+
# Environments
|
| 146 |
+
.env
|
| 147 |
+
.envrc
|
| 148 |
+
.venv
|
| 149 |
+
env/
|
| 150 |
+
venv/
|
| 151 |
+
ENV/
|
| 152 |
+
env.bak/
|
| 153 |
+
venv.bak/
|
| 154 |
+
|
| 155 |
+
# Spyder project settings
|
| 156 |
+
.spyderproject
|
| 157 |
+
.spyproject
|
| 158 |
+
|
| 159 |
+
# Rope project settings
|
| 160 |
+
.ropeproject
|
| 161 |
+
|
| 162 |
+
# mkdocs documentation
|
| 163 |
+
/site
|
| 164 |
+
|
| 165 |
+
# mypy
|
| 166 |
+
.mypy_cache/
|
| 167 |
+
.dmypy.json
|
| 168 |
+
dmypy.json
|
| 169 |
+
|
| 170 |
+
# Pyre type checker
|
| 171 |
+
.pyre/
|
| 172 |
+
|
| 173 |
+
# pytype static type analyzer
|
| 174 |
+
.pytype/
|
| 175 |
+
|
| 176 |
+
# Cython debug symbols
|
| 177 |
+
cython_debug/
|
| 178 |
+
|
| 179 |
+
# PyCharm
|
| 180 |
+
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
|
| 181 |
+
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
|
| 182 |
+
# and can be added to the global gitignore or merged into this file. For a more nuclear
|
| 183 |
+
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
|
| 184 |
+
#.idea/
|
| 185 |
+
|
| 186 |
+
# Abstra
|
| 187 |
+
# Abstra is an AI-powered process automation framework.
|
| 188 |
+
# Ignore directories containing user credentials, local state, and settings.
|
| 189 |
+
# Learn more at https://abstra.io/docs
|
| 190 |
+
.abstra/
|
| 191 |
+
|
| 192 |
+
# Visual Studio Code
|
| 193 |
+
# Visual Studio Code specific template is maintained in a separate VisualStudioCode.gitignore
|
| 194 |
+
# that can be found at https://github.com/github/gitignore/blob/main/Global/VisualStudioCode.gitignore
|
| 195 |
+
# and can be added to the global gitignore or merged into this file. However, if you prefer,
|
| 196 |
+
# you could uncomment the following to ignore the entire vscode folder
|
| 197 |
+
# .vscode/
|
| 198 |
+
|
| 199 |
+
# Ruff stuff:
|
| 200 |
+
.ruff_cache/
|
| 201 |
+
|
| 202 |
+
# PyPI configuration file
|
| 203 |
+
.pypirc
|
| 204 |
+
|
| 205 |
+
# Cursor
|
| 206 |
+
# Cursor is an AI-powered code editor. `.cursorignore` specifies files/directories to
|
| 207 |
+
# exclude from AI features like autocomplete and code analysis. Recommended for sensitive data
|
| 208 |
+
# refer to https://docs.cursor.com/context/ignore-files
|
| 209 |
+
.cursorignore
|
| 210 |
+
.cursorindexingignore
|
| 211 |
+
|
| 212 |
+
# Marimo
|
| 213 |
+
marimo/_static/
|
| 214 |
+
marimo/_lsp/
|
| 215 |
+
__marimo__/
|
.vscode/launch.json
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"version": "0.2.0",
|
| 3 |
+
"configurations": [
|
| 4 |
+
{
|
| 5 |
+
"name": "FastAPI: Uvicorn",
|
| 6 |
+
"type": "debugpy",
|
| 7 |
+
"request": "launch",
|
| 8 |
+
"module": "uvicorn",
|
| 9 |
+
"args": [
|
| 10 |
+
"src.main:app",
|
| 11 |
+
"--host",
|
| 12 |
+
"0.0.0.0",
|
| 13 |
+
"--port",
|
| 14 |
+
"7860",
|
| 15 |
+
"--reload",
|
| 16 |
+
"--reload-include",
|
| 17 |
+
"./src/",
|
| 18 |
+
"--reload-exclude",
|
| 19 |
+
"*.db"
|
| 20 |
+
],
|
| 21 |
+
"jinja": true,
|
| 22 |
+
"justMyCode": false,
|
| 23 |
+
"console": "integratedTerminal",
|
| 24 |
+
},
|
| 25 |
+
{
|
| 26 |
+
"name": "Model Server (FastAPI: Uvicorn)",
|
| 27 |
+
"type": "debugpy",
|
| 28 |
+
"request": "launch",
|
| 29 |
+
"module": "uvicorn",
|
| 30 |
+
"args": [
|
| 31 |
+
"src.servers.model_server:app",
|
| 32 |
+
"--host",
|
| 33 |
+
"0.0.0.0",
|
| 34 |
+
"--port",
|
| 35 |
+
"8001"
|
| 36 |
+
],
|
| 37 |
+
"jinja": true,
|
| 38 |
+
"justMyCode": false,
|
| 39 |
+
"console": "integratedTerminal",
|
| 40 |
+
},
|
| 41 |
+
]
|
| 42 |
+
}
|
.vscode/settings.json
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"remote.autoForwardPorts": false,
|
| 3 |
+
"remote.WSL.useShellEnvironment": true,
|
| 4 |
+
"remote.WSL.defaultDistro": "Ubuntu",
|
| 5 |
+
"remote.restoreForwardedPorts": true,
|
| 6 |
+
"remote.WSL.server.connectThroughLocalhost": false,
|
| 7 |
+
"python.analysis.exclude": [
|
| 8 |
+
"**/.cache/**",
|
| 9 |
+
"**/site-packages/**",
|
| 10 |
+
"**/virtualenvs/**"
|
| 11 |
+
],
|
| 12 |
+
"djlint.showInstallError": false,
|
| 13 |
+
"python.defaultInterpreterPath": "/app/.venv/bin/python",
|
| 14 |
+
"tailwindCSS.experimental.configFile": "./public/styles/input.css",
|
| 15 |
+
"tailwindCSS.includeLanguages": {
|
| 16 |
+
"html": "html",
|
| 17 |
+
"javascript": "javascript",
|
| 18 |
+
"css": "css",
|
| 19 |
+
"jinja": "html",
|
| 20 |
+
"jinja2": "html"
|
| 21 |
+
},
|
| 22 |
+
"editor.quickSuggestions": {
|
| 23 |
+
"strings": true
|
| 24 |
+
},
|
| 25 |
+
"tailwindCSS.emmetCompletions": true,
|
| 26 |
+
"editor.formatOnSave": false,
|
| 27 |
+
"files.associations": {
|
| 28 |
+
"*.jinja": "jinja-html",
|
| 29 |
+
"*.jinja2": "jinja-html",
|
| 30 |
+
"*.j2": "jinja-html"
|
| 31 |
+
},
|
| 32 |
+
"emmet.includeLanguages": {
|
| 33 |
+
"jinja-html": "html",
|
| 34 |
+
"jinja2": "html",
|
| 35 |
+
"django-html": "html"
|
| 36 |
+
},
|
| 37 |
+
"[jinja]": {
|
| 38 |
+
"editor.defaultFormatter": "monosans.djlint",
|
| 39 |
+
"editor.detectIndentation": false,
|
| 40 |
+
"editor.tabSize": 2,
|
| 41 |
+
"editor.formatOnSave": false
|
| 42 |
+
},
|
| 43 |
+
"[jinja-html]": {
|
| 44 |
+
"editor.defaultFormatter": "monosans.djlint",
|
| 45 |
+
"editor.detectIndentation": false,
|
| 46 |
+
"editor.tabSize": 2,
|
| 47 |
+
"editor.formatOnSave": false
|
| 48 |
+
},
|
| 49 |
+
"djlint.profile": "jinja",
|
| 50 |
+
"djlint.useVenv": true,
|
| 51 |
+
"alpine-intellisense.settings.languageScopes": "html,jinja-html,django-html",
|
| 52 |
+
}
|
Dockerfile
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
FROM ubuntu:24.04
|
| 2 |
+
|
| 3 |
+
ARG DEV_MODE
|
| 4 |
+
|
| 5 |
+
ENV DEV_MODE=${DEV_MODE:-false}
|
| 6 |
+
|
| 7 |
+
ENV DEBIAN_FRONTEND=noninteractive
|
| 8 |
+
ENV PYTHONUNBUFFERED=1
|
| 9 |
+
ENV PYTHONDONTWRITEBYTECODE=1
|
| 10 |
+
|
| 11 |
+
RUN apt update
|
| 12 |
+
|
| 13 |
+
RUN apt install -y \
|
| 14 |
+
python3.12 \
|
| 15 |
+
python3.12-dev \
|
| 16 |
+
python3.12-venv \
|
| 17 |
+
python3-pip
|
| 18 |
+
|
| 19 |
+
RUN ln -sf /usr/bin/python3 /usr/bin/python && ln -sf /usr/bin/pip3 /usr/bin/pip
|
| 20 |
+
|
| 21 |
+
RUN apt install -y \
|
| 22 |
+
curl \
|
| 23 |
+
git \
|
| 24 |
+
git-lfs \
|
| 25 |
+
locales && \
|
| 26 |
+
git lfs install && \
|
| 27 |
+
sed -i 's/# \(en_US.UTF-8 UTF-8\)/\1/' /etc/locale.gen && \
|
| 28 |
+
locale-gen && \
|
| 29 |
+
rm -rf /var/lib/apt/lists/*
|
| 30 |
+
|
| 31 |
+
RUN apt update && \
|
| 32 |
+
apt install -y nodejs npm && \
|
| 33 |
+
rm -rf /var/lib/apt/lists/*
|
| 34 |
+
|
| 35 |
+
ENV LANG=en_US.UTF-8 \
|
| 36 |
+
LC_ALL=en_US.UTF-8
|
| 37 |
+
|
| 38 |
+
RUN curl -sSL https://install.python-poetry.org | python - && \
|
| 39 |
+
ln -sf ~/.local/bin/poetry /usr/local/bin/poetry
|
| 40 |
+
|
| 41 |
+
RUN poetry config virtualenvs.in-project true
|
| 42 |
+
|
| 43 |
+
WORKDIR /app
|
| 44 |
+
|
| 45 |
+
EXPOSE 80 7860
|
| 46 |
+
|
| 47 |
+
COPY pyproject.toml poetry.lock* ./
|
| 48 |
+
|
| 49 |
+
RUN if [ "$DEV_MODE" = "false" ]; then \
|
| 50 |
+
echo "🏭 Production mode: Clean build without cache"; \
|
| 51 |
+
poetry install --no-root --no-interaction --no-ansi --with data,ml,dev; \
|
| 52 |
+
fi
|
| 53 |
+
|
| 54 |
+
COPY . /app
|
| 55 |
+
|
| 56 |
+
RUN chmod +x /app/scripts/*.sh || true
|
| 57 |
+
|
| 58 |
+
ENTRYPOINT ["/app/scripts/entrypoint.sh"]
|
LICENSE
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
Copyright (c) 2025 magnolia psychometrics GmbH. All rights reserved.
|
| 2 |
+
|
| 3 |
+
This software is proprietary and confidential. Unauthorized copying of this file, via any medium is strictly prohibited.
|
| 4 |
+
|
| 5 |
+
This repository is provided as a template and is the property of the **magnolia psychometrics GmbH**. For internal use only.
|
README.md
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
---
|
| 2 |
+
title: The Synthetic Nomological Net
|
| 3 |
+
emoji: 🔍
|
| 4 |
+
colorFrom: purple
|
| 5 |
+
colorTo: blue
|
| 6 |
+
sdk: docker
|
| 7 |
+
suggested_hardware: "cpu-basic"
|
| 8 |
+
app_port: 7860
|
| 9 |
+
pinned: true
|
| 10 |
+
models:
|
| 11 |
+
- "magnolia-psychometrics/surveybot3000"
|
| 12 |
+
- "sentence-transformers/all-mpnet-base-v2"
|
| 13 |
+
license: mit
|
| 14 |
+
---
|
| 15 |
+
|
| 16 |
+
# SynthNet Search
|
| 17 |
+
|
| 18 |
+
Mapping over 74,000 scales from more than 31,500 APA PsycTests Questionnaires, Surveys, and Tests.
|
| 19 |
+
|
| 20 |
+
## Setup
|
| 21 |
+
|
| 22 |
+
This application requires the following environment variables:
|
| 23 |
+
|
| 24 |
+
- `MODEL__ITEM_MODEL_PATH`: HuggingFace model respository path
|
| 25 |
+
- `MODEL__ITEM_MODEL_ACCESS_TOKEN`: Access token for private HuggingFace model
|
| 26 |
+
- `MODEL__SCALE_MODEL_PATH`: HuggingFace model respository path
|
| 27 |
+
- `MODEL__SCALE_MODEL_ACCESS_TOKEN`: Access token for private HuggingFace model
|
| 28 |
+
- `DATA__DATASET_PATH`: HuggingFace dataset respository path
|
| 29 |
+
- `DATA__ENCRYPTION_KEY`: Encryption key for database
|
| 30 |
+
- `TRACKING_DB__API_ENDPOINT`: Usage tracking database endpoint
|
| 31 |
+
- `TRACKING_DB__ANON_KEY`: Anonymous key for usage tracking database endpoint
|
| 32 |
+
- `TRACKING_DB__JWT_TOKEN`: Access token for usage tracking database endpoint
|
| 33 |
+
|
| 34 |
+
Configure these in the Space settings under "Repository secrets".
|
| 35 |
+
|
| 36 |
+
## Citation
|
| 37 |
+
```
|
| 38 |
+
Hommel, B. E., Külpmann, A. I., & Arslan, R. C. (2025). The Synthetic Nomological Net: A search engine to identify conceptual overlap in measures in the behavioral sciences. PsyArXiv. Manuscript in preparation. https://osf.io/preprints/psyarxiv/nfgmv_v1/
|
| 39 |
+
```
|
| 40 |
+
|
| 41 |
+
## About
|
| 42 |
+
|
| 43 |
+
This research is part of the [SYNTH research project (#546323839)](https://gepris.dfg.de/gepris/projekt/546323839?language=en), which is conducted as part of the [META-REP Priority Program](https://gepris.dfg.de/gepris/projekt/441890184) aiming to improve the replicability, reproducibility, and generalizability of empirical research in the behavioral sciences. SYNTH contributes to these goals by integrating large language models into current research workflows to reduce burdens on scientists while improving transparency and replicability.
|
notebooks/layouts/marimo-demo.grid.json
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"type": "grid",
|
| 3 |
+
"data": {
|
| 4 |
+
"columns": 24,
|
| 5 |
+
"rowHeight": 20,
|
| 6 |
+
"maxWidth": 300,
|
| 7 |
+
"bordered": true,
|
| 8 |
+
"cells": [
|
| 9 |
+
{
|
| 10 |
+
"position": null
|
| 11 |
+
},
|
| 12 |
+
{
|
| 13 |
+
"position": null
|
| 14 |
+
},
|
| 15 |
+
{
|
| 16 |
+
"position": null
|
| 17 |
+
},
|
| 18 |
+
{
|
| 19 |
+
"position": null
|
| 20 |
+
},
|
| 21 |
+
{
|
| 22 |
+
"position": null
|
| 23 |
+
},
|
| 24 |
+
{
|
| 25 |
+
"position": null
|
| 26 |
+
},
|
| 27 |
+
{
|
| 28 |
+
"position": null
|
| 29 |
+
},
|
| 30 |
+
{
|
| 31 |
+
"position": null
|
| 32 |
+
},
|
| 33 |
+
{
|
| 34 |
+
"position": null
|
| 35 |
+
},
|
| 36 |
+
{
|
| 37 |
+
"position": null
|
| 38 |
+
},
|
| 39 |
+
{
|
| 40 |
+
"position": [
|
| 41 |
+
0,
|
| 42 |
+
0,
|
| 43 |
+
24,
|
| 44 |
+
15
|
| 45 |
+
]
|
| 46 |
+
},
|
| 47 |
+
{
|
| 48 |
+
"position": [
|
| 49 |
+
0,
|
| 50 |
+
15,
|
| 51 |
+
24,
|
| 52 |
+
15
|
| 53 |
+
]
|
| 54 |
+
}
|
| 55 |
+
]
|
| 56 |
+
}
|
| 57 |
+
}
|
notebooks/marimo-demo.py
ADDED
|
@@ -0,0 +1,206 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# /// script
|
| 2 |
+
# requires-python = ">=3.12"
|
| 3 |
+
# dependencies = [
|
| 4 |
+
# "marimo",
|
| 5 |
+
# "matplotlib==3.10.1",
|
| 6 |
+
# "numpy==2.2.4",
|
| 7 |
+
# ]
|
| 8 |
+
# ///
|
| 9 |
+
|
| 10 |
+
import marimo
|
| 11 |
+
|
| 12 |
+
__generated_with = "0.14.10"
|
| 13 |
+
app = marimo.App(css_file="theme.marimo.css", html_head_file="")
|
| 14 |
+
|
| 15 |
+
|
| 16 |
+
@app.cell
|
| 17 |
+
def _():
|
| 18 |
+
import marimo as mo
|
| 19 |
+
return (mo,)
|
| 20 |
+
|
| 21 |
+
|
| 22 |
+
@app.cell
|
| 23 |
+
def _(mo):
|
| 24 |
+
get_applicant_count, set_applicant_count = mo.state(500)
|
| 25 |
+
return get_applicant_count, set_applicant_count
|
| 26 |
+
|
| 27 |
+
|
| 28 |
+
@app.cell
|
| 29 |
+
def _(get_applicant_count, mo, set_applicant_count):
|
| 30 |
+
applicant_count = mo.ui.number(
|
| 31 |
+
start=1,
|
| 32 |
+
step=1,
|
| 33 |
+
value=get_applicant_count(),
|
| 34 |
+
full_width=True,
|
| 35 |
+
label="Number of applicants",
|
| 36 |
+
on_change=set_applicant_count,
|
| 37 |
+
)
|
| 38 |
+
return (applicant_count,)
|
| 39 |
+
|
| 40 |
+
|
| 41 |
+
@app.cell
|
| 42 |
+
def _(get_applicant_count, mo):
|
| 43 |
+
hire_count = mo.ui.number(
|
| 44 |
+
start=1,
|
| 45 |
+
stop=get_applicant_count() - 1,
|
| 46 |
+
step=1,
|
| 47 |
+
value=75,
|
| 48 |
+
full_width=True,
|
| 49 |
+
label="Hire count",
|
| 50 |
+
)
|
| 51 |
+
return (hire_count,)
|
| 52 |
+
|
| 53 |
+
|
| 54 |
+
@app.cell
|
| 55 |
+
def _(mo):
|
| 56 |
+
base_rate = mo.ui.slider(
|
| 57 |
+
value=40, start=1, stop=100, step=1, full_width=True, label="Base rate"
|
| 58 |
+
)
|
| 59 |
+
return (base_rate,)
|
| 60 |
+
|
| 61 |
+
|
| 62 |
+
@app.cell
|
| 63 |
+
def _(mo):
|
| 64 |
+
validity = mo.ui.slider(
|
| 65 |
+
value=0.18, start=0.01, stop=1.00, step=0.01, full_width=True, label="Validity"
|
| 66 |
+
)
|
| 67 |
+
return (validity,)
|
| 68 |
+
|
| 69 |
+
|
| 70 |
+
@app.cell
|
| 71 |
+
def _(applicant_count, base_rate, hire_count, validity):
|
| 72 |
+
import requests
|
| 73 |
+
|
| 74 |
+
url = "http://localhost:7860/api/v1/demo/r/demo"
|
| 75 |
+
params = {
|
| 76 |
+
"applicant_count": applicant_count.value,
|
| 77 |
+
"hire_count": hire_count.value,
|
| 78 |
+
"base_rate": base_rate.value,
|
| 79 |
+
"validity": validity.value,
|
| 80 |
+
}
|
| 81 |
+
headers = {"accept": "application/json"}
|
| 82 |
+
|
| 83 |
+
response = requests.post(url, params=params, headers=headers)
|
| 84 |
+
|
| 85 |
+
return (response,)
|
| 86 |
+
|
| 87 |
+
|
| 88 |
+
@app.cell
|
| 89 |
+
def _(response):
|
| 90 |
+
import pandas as pd
|
| 91 |
+
import plotly.graph_objects as go
|
| 92 |
+
from plotly.subplots import make_subplots
|
| 93 |
+
|
| 94 |
+
json_data = response.json()
|
| 95 |
+
|
| 96 |
+
data = pd.DataFrame(
|
| 97 |
+
{
|
| 98 |
+
"var": list(json_data.keys()),
|
| 99 |
+
"label": [
|
| 100 |
+
"Rightfully hired",
|
| 101 |
+
"Incorrectly hired",
|
| 102 |
+
"Rightfully rejected",
|
| 103 |
+
"Incorrectly rejected",
|
| 104 |
+
],
|
| 105 |
+
"value": list(json_data.values()),
|
| 106 |
+
}
|
| 107 |
+
)
|
| 108 |
+
|
| 109 |
+
data["label_with_value"] = data["label"] + " (" + data["value"].astype(str) + ")"
|
| 110 |
+
|
| 111 |
+
fig = make_subplots(
|
| 112 |
+
rows=1,
|
| 113 |
+
cols=2,
|
| 114 |
+
specs=[[{"type": "pie"}, {"type": "pie"}]],
|
| 115 |
+
subplot_titles=("Hiring Outcome", "Rejection Outcome"),
|
| 116 |
+
horizontal_spacing=0.1,
|
| 117 |
+
vertical_spacing=0.15,
|
| 118 |
+
)
|
| 119 |
+
|
| 120 |
+
hired_data = data[data["var"].isin(["true_positives", "false_positives"])]
|
| 121 |
+
hired_values = hired_data["value"].tolist()
|
| 122 |
+
hired_labels = hired_data["label_with_value"].tolist()
|
| 123 |
+
|
| 124 |
+
rejected_data = data[data["var"].isin(["true_negatives", "false_negatives"])]
|
| 125 |
+
rejected_values = rejected_data["value"].tolist()
|
| 126 |
+
rejected_labels = rejected_data["label_with_value"].tolist()
|
| 127 |
+
|
| 128 |
+
fig.add_trace(
|
| 129 |
+
go.Pie(
|
| 130 |
+
values=hired_values,
|
| 131 |
+
labels=hired_labels,
|
| 132 |
+
hole=0.5,
|
| 133 |
+
marker_colors=["#6b71ed", "#403c5d"],
|
| 134 |
+
name="Hiring",
|
| 135 |
+
legendgroup="hiring",
|
| 136 |
+
showlegend=True,
|
| 137 |
+
hoverinfo="none",
|
| 138 |
+
),
|
| 139 |
+
row=1,
|
| 140 |
+
col=1,
|
| 141 |
+
)
|
| 142 |
+
|
| 143 |
+
fig.add_trace(
|
| 144 |
+
go.Pie(
|
| 145 |
+
values=rejected_values,
|
| 146 |
+
labels=rejected_labels,
|
| 147 |
+
hole=0.5,
|
| 148 |
+
marker_colors=["#6b71ed", "#403c5d"],
|
| 149 |
+
name="Rejection",
|
| 150 |
+
legendgroup="rejection",
|
| 151 |
+
showlegend=True,
|
| 152 |
+
hoverinfo="none",
|
| 153 |
+
),
|
| 154 |
+
row=1,
|
| 155 |
+
col=2,
|
| 156 |
+
)
|
| 157 |
+
|
| 158 |
+
fig.update_layout(
|
| 159 |
+
autosize=True,
|
| 160 |
+
margin=dict(l=0, r=0, t=60, b=20),
|
| 161 |
+
legend=dict(
|
| 162 |
+
orientation="h",
|
| 163 |
+
yanchor="top",
|
| 164 |
+
y=-0.1,
|
| 165 |
+
xanchor="center",
|
| 166 |
+
x=0.5,
|
| 167 |
+
font=dict(size=12),
|
| 168 |
+
),
|
| 169 |
+
title=dict(text=None, x=0.5, font=dict(size=16)),
|
| 170 |
+
height=400,
|
| 171 |
+
paper_bgcolor="rgba(0,0,0,0)",
|
| 172 |
+
plot_bgcolor="rgba(0,0,0,0)",
|
| 173 |
+
)
|
| 174 |
+
|
| 175 |
+
fig.update_annotations(font_size=14, y=1.08)
|
| 176 |
+
|
| 177 |
+
return (fig,)
|
| 178 |
+
|
| 179 |
+
|
| 180 |
+
@app.cell
|
| 181 |
+
def _(applicant_count, base_rate, hire_count, mo, validity):
|
| 182 |
+
with mo.status.spinner(subtitle="Loading data ...") as _spinner:
|
| 183 |
+
mo.vstack([applicant_count, hire_count, base_rate, validity])
|
| 184 |
+
return
|
| 185 |
+
|
| 186 |
+
|
| 187 |
+
@app.cell
|
| 188 |
+
def _(applicant_count, base_rate, hire_count, mo, validity):
|
| 189 |
+
mo.vstack([applicant_count, hire_count, base_rate, validity])
|
| 190 |
+
return
|
| 191 |
+
|
| 192 |
+
|
| 193 |
+
@app.cell
|
| 194 |
+
def _(fig, mo, response):
|
| 195 |
+
if response.status_code == 200:
|
| 196 |
+
fig.show(
|
| 197 |
+
config={"displayModeBar": False, "staticPlot": True, "responsive": True}
|
| 198 |
+
)
|
| 199 |
+
else:
|
| 200 |
+
error_msg = mo.md(f"{mo.icon('lucide:ban')} Error in server response")
|
| 201 |
+
mo.output.append(error_msg)
|
| 202 |
+
return
|
| 203 |
+
|
| 204 |
+
|
| 205 |
+
if __name__ == "__main__":
|
| 206 |
+
app.run()
|
notebooks/theme.marimo.css
ADDED
|
@@ -0,0 +1,4 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
:root {
|
| 2 |
+
--background: transparent;
|
| 3 |
+
--background-darker: transparent;
|
| 4 |
+
}
|
poetry.lock
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
public/bib/references.bib
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
@UNPUBLISHED{HommelArslan2025,
|
| 2 |
+
title = "Language models accurately infer correlations between
|
| 3 |
+
psychological items and scales from text alone",
|
| 4 |
+
author = "Hommel, Bj{\"o}rn E and Arslan, Ruben C",
|
| 5 |
+
abstract = "Many behavioural scientists do not agree on core constructs and
|
| 6 |
+
how they should be measured. Different literatures measure
|
| 7 |
+
related constructs, but the connections are not always obvious to
|
| 8 |
+
readers and meta-analysts. Many measures in behavioural science
|
| 9 |
+
are based on agreement with survey items. Because these items are
|
| 10 |
+
sentences, computerised language models can make connections
|
| 11 |
+
between disparate measures and constructs and help researchers
|
| 12 |
+
regain an overview over the rapidly growing, fragmented
|
| 13 |
+
literature. Our fine-tuned language model, the SurveyBot3000,
|
| 14 |
+
accurately predicts the correlations between survey items, the
|
| 15 |
+
reliability of aggregated measurement scales, and
|
| 16 |
+
intercorrelations between scales from item positions in semantic
|
| 17 |
+
vector space. In our pilot study, the out-of-sample accuracy for
|
| 18 |
+
item correlations was .71, .89 for reliabilities, and .89 for
|
| 19 |
+
scale correlations. In our preregistered validation study using
|
| 20 |
+
novel items, the out-of-sample accuracy was slightly reduced to
|
| 21 |
+
.59 for item correlations, .84 for reliabilities, and .84 for
|
| 22 |
+
scale correlations. The synthetic item correlations showed an
|
| 23 |
+
average prediction error of .17, with larger errors for middling
|
| 24 |
+
correlations. Predictions exhibited generalizability beyond the
|
| 25 |
+
training data and across various domains, with some variability
|
| 26 |
+
in accuracy. Our work shows language models can reliably predict
|
| 27 |
+
psychometric relationships between survey items, enabling
|
| 28 |
+
researchers to evaluate new measures against existing scales,
|
| 29 |
+
reduce redundancy in measurement, and work towards a more unified
|
| 30 |
+
behavioural science taxonomy.",
|
| 31 |
+
journal = "PsyArXiv",
|
| 32 |
+
note = "Manuscript submitted for publication",
|
| 33 |
+
year = 2025
|
| 34 |
+
}
|
| 35 |
+
|
| 36 |
+
@UNPUBLISHED{HommelKuelpmannArslan,
|
| 37 |
+
title = "The Synthetic Nomological Net: A search engine to identify conceptual overlap in measures in the behavioral sciences",
|
| 38 |
+
author = "Hommel, Bj{\"o}rn E and K{\"u}lpmann, Annika I and Arslan, Ruben C",
|
| 39 |
+
journal = "PsyArXiv",
|
| 40 |
+
note = "Manuscript in preparation",
|
| 41 |
+
year = 2025
|
| 42 |
+
}
|
public/favicon-128x128.png
ADDED
|
|
Git LFS Details
|
public/favicon-16x16.png
ADDED
|
|
Git LFS Details
|
public/favicon-256x256.png
ADDED
|
|
Git LFS Details
|
public/favicon-32x32.png
ADDED
|
|
Git LFS Details
|
public/favicon-48x48.png
ADDED
|
|
Git LFS Details
|
public/favicon-64x64.png
ADDED
|
|
Git LFS Details
|
public/fonts/TitilliumWeb-Black.ttf
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:09c98a384ee96f6b4e9cc2206cfb8d74b2bbc1fc337877503bb8f381891ae132
|
| 3 |
+
size 43664
|
public/fonts/TitilliumWeb-Bold.ttf
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:fe3d6895510631f14e0bff85e487b32be20972364a457e7df4047b58f41559c2
|
| 3 |
+
size 53896
|
public/fonts/TitilliumWeb-BoldItalic.ttf
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:b0aa4933862f69af4126f2db8d71eb32d72051e2f312f3ab9a9241aa6969daeb
|
| 3 |
+
size 62924
|
public/fonts/TitilliumWeb-ExtraLight.ttf
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:96db1f9f826461d9132e116f1537edd99cc0121a6148d933646bb8a5f4fb0e7d
|
| 3 |
+
size 56724
|
public/fonts/TitilliumWeb-ExtraLightItalic.ttf
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:2aef09f80d400021cff9b3b836c41800cf29f40da711dbcd2cd7dc3e7f39d88f
|
| 3 |
+
size 60848
|
public/fonts/TitilliumWeb-Italic.ttf
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:d2bb5f00f1b7ff1265c88872e37e3859b5a7fc5e9492c3d8a556fc2db571fcce
|
| 3 |
+
size 65284
|
public/fonts/TitilliumWeb-Light.ttf
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:10606c76bb84cbc0c6fda46cb9c57ae6da49cae2312245f333a8a46db19b6f46
|
| 3 |
+
size 57600
|
public/fonts/TitilliumWeb-LightItalic.ttf
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:885f3206c0c3419400340d3a5de1617f80e16cfaf407ce138227098f46108917
|
| 3 |
+
size 64560
|
public/fonts/TitilliumWeb-Regular.ttf
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:486e78be7ca7596376418b5120443ee1a359e95488da17f7a88282d82f34d51c
|
| 3 |
+
size 57392
|
public/fonts/TitilliumWeb-SemiBold.ttf
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:3a285881faadbb793538867d008dc972ec70a7244099b6ed84bb5691c519be28
|
| 3 |
+
size 56752
|
public/fonts/TitilliumWeb-SemiBoldItalic.ttf
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:f9a81b17cca11ea77793751ad4d2d4c863bb7b3ccf6d554f8ff39b81d44e6fde
|
| 3 |
+
size 64816
|
public/img/logo-dark.svg
ADDED
|
|
Git LFS Details
|
public/img/logo.svg
ADDED
|
|
Git LFS Details
|
public/img/logotype.svg
ADDED
|
|
Git LFS Details
|
public/img/osf-logo.svg
ADDED
|
|
Git LFS Details
|
public/img/synth-net-inline.svg
ADDED
|
|
Git LFS Details
|
public/img/synth-net-stacked.svg
ADDED
|
|
Git LFS Details
|
public/img/synthnet-logo.svg
ADDED
|
|
Git LFS Details
|
public/img/team-arslan.jpg
ADDED
|
Git LFS Details
|
public/img/team-clarke.jpg
ADDED
|
Git LFS Details
|
public/img/team-cummins.jpg
ADDED
|
Git LFS Details
|
public/img/team-elson.png
ADDED
|
Git LFS Details
|
public/img/team-hommel.jpg
ADDED
|
Git LFS Details
|
public/img/team-hussey.jpg
ADDED
|
Git LFS Details
|
public/img/team-kuelpmann.jpg
ADDED
|
Git LFS Details
|
public/libs/alpinejs@3.14.8/alpine.collapse.min.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
(()=>{function g(n){n.directive("collapse",e),e.inline=(t,{modifiers:i})=>{i.includes("min")&&(t._x_doShow=()=>{},t._x_doHide=()=>{})};function e(t,{modifiers:i}){let r=l(i,"duration",250)/1e3,h=l(i,"min",0),u=!i.includes("min");t._x_isShown||(t.style.height=`${h}px`),!t._x_isShown&&u&&(t.hidden=!0),t._x_isShown||(t.style.overflow="hidden");let c=(d,s)=>{let o=n.setStyles(d,s);return s.height?()=>{}:o},f={transitionProperty:"height",transitionDuration:`${r}s`,transitionTimingFunction:"cubic-bezier(0.4, 0.0, 0.2, 1)"};t._x_transition={in(d=()=>{},s=()=>{}){u&&(t.hidden=!1),u&&(t.style.display=null);let o=t.getBoundingClientRect().height;t.style.height="auto";let a=t.getBoundingClientRect().height;o===a&&(o=h),n.transition(t,n.setStyles,{during:f,start:{height:o+"px"},end:{height:a+"px"}},()=>t._x_isShown=!0,()=>{Math.abs(t.getBoundingClientRect().height-a)<1&&(t.style.overflow=null)})},out(d=()=>{},s=()=>{}){let o=t.getBoundingClientRect().height;n.transition(t,c,{during:f,start:{height:o+"px"},end:{height:h+"px"}},()=>t.style.overflow="hidden",()=>{t._x_isShown=!1,t.style.height==`${h}px`&&u&&(t.style.display="none",t.hidden=!0)})}}}}function l(n,e,t){if(n.indexOf(e)===-1)return t;let i=n[n.indexOf(e)+1];if(!i)return t;if(e==="duration"){let r=i.match(/([0-9]+)ms/);if(r)return r[1]}if(e==="min"){let r=i.match(/([0-9]+)px/);if(r)return r[1]}return i}document.addEventListener("alpine:init",()=>{window.Alpine.plugin(g)});})();
|