diff --git a/.dockerignore b/.dockerignore index cd1eb0cb7..42846592a 100644 --- a/.dockerignore +++ b/.dockerignore @@ -1,17 +1,32 @@ +# Git +.git +.gitignore + +# Docker +Dockerfile* +.dockerignore + +# Python +__pycache__/ +*.pyo +*.pyd .venv venv -node_modules *.sqlite3 -**/__pycache__ *.egg-info +# IDE / OS specific +.idea/ +.vscode/ +*.swp +.DS_Store + # Other files and folders /coverage.lcov /media/ /static/ /db/ -/extras/docker/open-food-facts/dump/*.tar.gz -/extras/docker/open-food-facts/dump/off/* +/extras/open-food-facts/dump/ /extras/authors/commits_cache/ /extras/authors/*.md /extras/scripts/*.json diff --git a/extras/docker/base/Dockerfile b/extras/docker/base/Dockerfile index e784fb045..b0a8e3a18 100644 --- a/extras/docker/base/Dockerfile +++ b/extras/docker/base/Dockerfile @@ -10,7 +10,7 @@ FROM ubuntu:24.04 -LABEL maintainer="Roland Geider " +LABEL org.opencontainers.image.authors="wger team " # Install dependencies ENV DEBIAN_FRONTEND=noninteractive diff --git a/extras/docker/demo/Dockerfile b/extras/docker/demo/Dockerfile index 89345b5e1..9466c5ecb 100644 --- a/extras/docker/demo/Dockerfile +++ b/extras/docker/demo/Dockerfile @@ -20,7 +20,8 @@ FROM wger/base:latest AS builder ARG DEBIAN_FRONTEND=noninteractive -RUN apt update \ +RUN wget -O- https://deb.nodesource.com/setup_22.x | bash - \ + && apt update \ && apt install --no-install-recommends -y \ build-essential \ python3-dev \ @@ -32,31 +33,33 @@ RUN apt update \ libpq-dev \ rustc \ cargo \ - yarnpkg \ sassc \ - && ln -s /usr/bin/yarnpkg /usr/bin/yarn \ - && ln -s /usr/bin/sassc /usr/bin/sass + nodejs \ + && ln -s /usr/bin/sassc /usr/bin/sass \ + && rm -rf /var/lib/apt/lists/* \ + && corepack enable # Build the necessary python wheels # Note that the --mount is a workaround for https://github.com/rust-lang/cargo/issues/8719 -COPY pyproject.toml . -COPY wger/version.py ./wger/version.py -COPY wger/__init__.py ./wger/__init__.py -COPY README.md ./README.md -RUN --mount=type=tmpfs,target=/root/.cargo pip3 wheel --no-cache-dir --wheel-dir /wheels --group docker . \ - && pip3 install --break-system-packages --user --no-cache-dir /wheels/* - -COPY . /home/wger/src WORKDIR /home/wger/src -RUN yarn install \ - && yarn build:css:sass + +COPY pyproject.toml /home/wger/src +COPY wger/version.py /home/wger/src/wger/ +COPY wger/__init__.py /home/wger/src/wger/ +COPY README.md /home/wger/src +COPY package.json /home/wger/src +COPY yarn.lock /home/wger/src +COPY wger/core/static /home/wger/src/wger/core/static +RUN --mount=type=tmpfs,target=/root/.cargo pip3 wheel --no-cache-dir --wheel-dir /wheels --group docker . \ + && yarn install \ + && yarn build:css:sass ######## # Final ######## FROM wger/base:latest AS final -LABEL maintainer="Roland Geider " +LABEL org.opencontainers.image.authors="wger team " ENV TERM=xterm ARG DOCKER_DIR=./extras/docker/demo EXPOSE 80 @@ -90,7 +93,6 @@ RUN chmod 0644 /etc/cron.d/wger \ && chmod +x /home/wger/venvwrapper \ && touch /var/log/cron.log -COPY --from=builder /wheels /wheels COPY --chown=wger:www-data . /home/wger/src COPY --from=builder --chown=wger:wger /home/wger/src/wger/core/static/yarn /home/wger/src/wger/core/static/yarn @@ -107,7 +109,7 @@ RUN mkdir -p ~/static/CACHE ~/media \ && ln -s /home/wger/static/CACHE /home/wger/src/CACHE \ && chmod g+w /home/wger/static/CACHE -RUN . /home/wger/venv/bin/activate \ +RUN --mount=type=bind,from=builder,source=/wheels,target=/wheels . /home/wger/venv/bin/activate \ && pip install --upgrade pip \ && pip install --no-cache /wheels/* \ && pip install -e . \ diff --git a/extras/docker/production/Dockerfile b/extras/docker/production/Dockerfile index 34aecdf0f..5d7aca114 100644 --- a/extras/docker/production/Dockerfile +++ b/extras/docker/production/Dockerfile @@ -14,7 +14,9 @@ FROM wger/base:latest AS builder ARG DEBIAN_FRONTEND=noninteractive -RUN apt update \ +# Need a newer node than what's in ubuntu +RUN wget -O- https://deb.nodesource.com/setup_22.x | bash - \ + && apt update \ && apt install --no-install-recommends -y \ build-essential \ python3-dev \ @@ -25,61 +27,67 @@ RUN apt update \ libwebp-dev \ libpq-dev \ rustc \ - yarnpkg \ sassc \ - cargo + cargo \ + unzip \ + nodejs \ + && rm -rf /var/lib/apt/lists/* \ + && corepack enable \ + && mkdir -p /root/src/wger/core/static -# Build the necessary python wheels -# -# PS: the --mount tmpfs is a workaround for https://github.com/rust-lang/cargo/issues/8719 -# -# PPS: actually only pyproject.toml is needed here, but it seems there is no way -# to tell pip to only build the dependencies and not the project itself as well, -# so we copy enough to make this is possible -COPY pyproject.toml . -COPY wger/version.py ./wger/version.py -COPY wger/__init__.py ./wger/__init__.py -COPY README.md ./README.md +# +# Build the python wheels +# +WORKDIR /root/src + +# Copy necessary files to build the application +COPY pyproject.toml /root/src +COPY wger/version.py /root/src/wger/ +COPY wger/__init__.py /root/src/wger/ +COPY README.md /root/src +COPY package.json /root/src +COPY yarn.lock /root/src +COPY wger/core/static /root/src/wger/core/static + +# NB: the --mount tmpfs is a workaround for https://github.com/rust-lang/cargo/issues/8719 RUN --mount=type=tmpfs,target=/root/.cargo \ pip3 wheel \ --no-cache-dir \ --wheel-dir /wheels \ --group docker . \ - && pip3 install \ - --break-system-packages \ - --no-warn-script-location \ - --root-user-action ignore \ - --user \ - --no-cache-dir /wheels/* \ - && ln -s /usr/bin/yarnpkg /usr/bin/yarn \ && ln -s /usr/bin/sassc /usr/bin/sass - -# Download and copy js and css files -COPY . /home/wger/src -WORKDIR /home/wger/src -RUN yarn install \ - && yarn build:css:sass +# +# Build the JS and CSS files +# +RUN yarn config set nodeLinker node-modules \ + && yarn install \ + && yarn build:css:sass \ + && cd .. \ + && wget https://github.com/wger-project/react/archive/refs/heads/master.zip \ + && unzip master.zip \ + && cd react-master \ + && yarn config set --home enableTelemetry 0 \ + && yarn config set nodeLinker node-modules \ + && yarn install \ + && WGER_STATIC_FOLDER="/root/src/wger/core/static/react" yarn build ######## # Final ######## FROM wger/base:latest AS final -LABEL maintainer="Roland Geider " +LABEL org.opencontainers.image.authors="wger team " ARG DOCKER_DIR=./extras/docker/production ENV PATH="/home/wger/.local/bin:$PATH" - +WORKDIR /home/wger/src EXPOSE 8000 - # Set up the application -COPY --from=builder --chown=wger:wger /root/.local /home/wger/.local - -WORKDIR /home/wger/src COPY --chown=wger:wger . /home/wger/src -COPY --from=builder --chown=wger:wger /home/wger/src/wger/core/static/yarn /home/wger/src/wger/core/static/yarn +COPY --chown=wger:wger --from=builder /root/src/wger/core/static/yarn /home/wger/src/wger/core/static/yarn +COPY --chown=wger:wger --from=builder /root/src/wger/core/static/react /home/wger/src/wger/core/static/react COPY ${DOCKER_DIR}/settings.py /home/wger/src COPY ${DOCKER_DIR}/settings.py /tmp/ COPY ${DOCKER_DIR}/entrypoint.sh /home/wger/entrypoint.sh @@ -93,10 +101,11 @@ RUN chmod +x /home/wger/entrypoint.sh \ && chown wger:wger /home/wger/src USER wger -RUN pip3 install --break-system-packages --user --editable . \ - && mkdir ~/media \ - && mkdir ~/static \ - && mkdir ~/beat \ - && mkdir ~/db +RUN --mount=type=bind,from=builder,source=/wheels,target=/wheels \ + pip3 install --break-system-packages --no-cache-dir --user /wheels/* \ + && pip3 install --break-system-packages --user . \ + && mkdir -p ~/media ~/static ~/beat ~/db \ + && cd wger \ + && django-admin compilemessages CMD ["/home/wger/entrypoint.sh"] diff --git a/package.json b/package.json index 228d30ff5..7e861fd89 100644 --- a/package.json +++ b/package.json @@ -10,11 +10,12 @@ }, "homepage": "https://github.com/wger-project/wger", "dependencies": { - "htmx.org": "^2.0.5", + "@popperjs/core": "^2.11.8", "bootstrap": "5.3.7", "components-font-awesome": "5.9.0", "datatables.net-bs5": "^2.3.1", "devbridge-autocomplete": "^1.4.11", + "htmx.org": "^2.0.5", "jquery": "^3.7.1", "masonry-layout": "^4.2.2", "popper.js": "^1.16.1", @@ -25,5 +26,6 @@ }, "engines": { "yarn": ">= 1.0.0" - } + }, + "packageManager": "yarn@4.9.2" } diff --git a/yarn.lock b/yarn.lock index 9a9f9a643..17823b669 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1,100 +1,164 @@ -# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. -# yarn lockfile v1 +# This file is generated by running "yarn install" inside your project. +# Manual changes might be lost - proceed with caution! +__metadata: + version: 8 + cacheKey: 10c0 -"@types/jquery@^2.0.32": - version "2.0.54" - resolved "https://registry.yarnpkg.com/@types/jquery/-/jquery-2.0.54.tgz#d7999245f77c3fab5d84e7d32b8a6c20bfd1f072" - integrity sha512-D/PomKwNkDfSKD13DEVQT/pq2TUjN54c6uB341fEZanIzkjfGe7UaFuuaLZbpEiS5j7Wk2MUHAZqZIoECw29lg== +"@popperjs/core@npm:^2.11.8": + version: 2.11.8 + resolution: "@popperjs/core@npm:2.11.8" + checksum: 10c0/4681e682abc006d25eb380d0cf3efc7557043f53b6aea7a5057d0d1e7df849a00e281cd8ea79c902a35a414d7919621fc2ba293ecec05f413598e0b23d5a1e63 + languageName: node + linkType: hard -bootstrap@5.3.7: - version "5.3.7" - resolved "https://registry.yarnpkg.com/bootstrap/-/bootstrap-5.3.7.tgz#8640065036124d961d885d80b5945745e1154d90" - integrity sha512-7KgiD8UHjfcPBHEpDNg+zGz8L3LqR3GVwqZiBRFX04a1BCArZOz1r2kjly2HQ0WokqTO0v1nF+QAt8dsW4lKlw== +"@types/jquery@npm:^2.0.32": + version: 2.0.54 + resolution: "@types/jquery@npm:2.0.54" + checksum: 10c0/8fc70e33a313c50224cd929a428c728a6f700cc5ec66dec5028d817f0c34ba8388d472f1bc0fb07f424c8c67314a8d8d19dfbc96b24cde0e317b59a0ab67ca0c + languageName: node + linkType: hard -components-font-awesome@5.9.0: - version "5.9.0" - resolved "https://registry.yarnpkg.com/components-font-awesome/-/components-font-awesome-5.9.0.tgz#02242f85946f0a6ab46870547f4c54d11e94ef75" - integrity sha512-AjY5WwmKripvroQ1oYpCC4eK8efavSKUGN/ATgwcbyz/kRmojslH8l6Mrlxq071bdzBrZvCxi+RKgU5ao3bU+A== +"bootstrap@npm:5.3.7": + version: 5.3.7 + resolution: "bootstrap@npm:5.3.7" + peerDependencies: + "@popperjs/core": ^2.11.8 + checksum: 10c0/019f0d683aec843b9fc0592ae78560cfe286bc8e31e706d40d8c15d390dcca7ab2ffa193a489a74f65ed5596800b9b79da867545ce3bbafca945b630fe0055af + languageName: node + linkType: hard -datatables.net-bs5@^2.3.1: - version "2.3.1" - resolved "https://registry.yarnpkg.com/datatables.net-bs5/-/datatables.net-bs5-2.3.1.tgz#167a86c4ab138fe6eb7f653fb4c64e3ade0d3d7a" - integrity sha512-bUwsW7cIR8EDyiedQv6OKGF5ouxkFjaODmtEd7NRtpoZixAZDScmIrxe9cddjS0EybpC2gYslKs+o03E8tkCEA== +"components-font-awesome@npm:5.9.0": + version: 5.9.0 + resolution: "components-font-awesome@npm:5.9.0" + checksum: 10c0/f2db52e788844bdb1bbf0eebc8f4ef233c04fb52e64b2ce3f6871922f43708379518cf0aa5c599b895633d063c6d8f44ea687a06f82f7be522ee081c31480536 + languageName: node + linkType: hard + +"datatables.net-bs5@npm:^2.3.1": + version: 2.3.1 + resolution: "datatables.net-bs5@npm:2.3.1" dependencies: - datatables.net "2.3.1" - jquery ">=1.7" + datatables.net: "npm:2.3.1" + jquery: "npm:>=1.7" + checksum: 10c0/5c6b0af1002dc4125506cd7b7de7b0bfdc01aff9e7aec0329b58fb91b471a27390968c16434607abd30d15e025d26a689e06ce7ac8c3310ba495c682f436ae01 + languageName: node + linkType: hard -datatables.net@2.3.1: - version "2.3.1" - resolved "https://registry.yarnpkg.com/datatables.net/-/datatables.net-2.3.1.tgz#fcb61efd42fe64627fb9042637f1d93872268e70" - integrity sha512-pRXZuk3oR7P5kTl/CRvopcTihlvmZiY+xSBjbNI6e8MjYtgZQodWEqLUUOrIZeLH8CfxapPR/Bmb0NKAvILP5g== +"datatables.net@npm:2.3.1": + version: 2.3.1 + resolution: "datatables.net@npm:2.3.1" dependencies: - jquery ">=1.7" + jquery: "npm:>=1.7" + checksum: 10c0/a44625d67621176b2acd108a1541b56f548af67e99364fcf05356f0d5d191a4930fe4f26bc87bfb2e7ffd18d79ab055b0ebca6149b7e2d4df23b7230a8f6909c + languageName: node + linkType: hard -desandro-matches-selector@^2.0.0: - version "2.0.2" - resolved "https://registry.yarnpkg.com/desandro-matches-selector/-/desandro-matches-selector-2.0.2.tgz#717beed4dc13e7d8f3762f707a6d58a6774218e1" - integrity sha1-cXvu1NwT59jzdi9wem1YpndCGOE= +"desandro-matches-selector@npm:^2.0.0": + version: 2.0.2 + resolution: "desandro-matches-selector@npm:2.0.2" + checksum: 10c0/f4b1f42e6ccd6c97e93e3f99a64461eef2722075b03d8a9e349e31766436f8b385d1fd50802b024dae951dc69399f13de20a139c1187000fd5e2fcf11cb5eb00 + languageName: node + linkType: hard -devbridge-autocomplete@^1.4.11: - version "1.4.11" - resolved "https://registry.yarnpkg.com/devbridge-autocomplete/-/devbridge-autocomplete-1.4.11.tgz#05424a675711a9c3ad118c98de0a22180944b00f" - integrity sha512-lRU1y9IKyPm45NKDMcujszJoftw+wqxKbtcNJoMx+LywJQJdDwjg/s4lwLYR4vyQQ6VTcUaIeveLMkZTqorBIA== +"devbridge-autocomplete@npm:^1.4.11": + version: 1.4.11 + resolution: "devbridge-autocomplete@npm:1.4.11" dependencies: - "@types/jquery" "^2.0.32" - jquery ">=1.7" + "@types/jquery": "npm:^2.0.32" + jquery: "npm:>=1.7" + checksum: 10c0/2ec2d14d9060ca58d54b13b5582c3c87ede9d527c7f3b17e76f6492a35ef5cc66318b748cf8111839a7690a2e612f6c42667c2e8c72ab7129fc679ec3e74ed00 + languageName: node + linkType: hard -ev-emitter@^1.0.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/ev-emitter/-/ev-emitter-1.1.1.tgz#8f18b0ce5c76a5d18017f71c0a795c65b9138f2a" - integrity sha512-ipiDYhdQSCZ4hSbX4rMW+XzNKMD1prg/sTvoVmSLkuQ1MVlwjJQQA+sW8tMYR3BLUr9KjodFV4pvzunvRhd33Q== +"ev-emitter@npm:^1.0.0": + version: 1.1.1 + resolution: "ev-emitter@npm:1.1.1" + checksum: 10c0/332dcb444de2b1d81035fb22a10dd33926311baa7ea6fc24f1de7b60c6eff5b7e133611000fce740471f0c8f95259d3914d49b4201af2d85a51f0aeb8cb1ceda + languageName: node + linkType: hard -fizzy-ui-utils@^2.0.0: - version "2.0.7" - resolved "https://registry.yarnpkg.com/fizzy-ui-utils/-/fizzy-ui-utils-2.0.7.tgz#7df45dcc4eb374a08b65d39bb9a4beedf7330505" - integrity sha512-CZXDVXQ1If3/r8s0T+v+qVeMshhfcuq0rqIFgJnrtd+Bu8GmDmqMjntjUePypVtjHXKJ6V4sw9zeyox34n9aCg== +"fizzy-ui-utils@npm:^2.0.0": + version: 2.0.7 + resolution: "fizzy-ui-utils@npm:2.0.7" dependencies: - desandro-matches-selector "^2.0.0" + desandro-matches-selector: "npm:^2.0.0" + checksum: 10c0/4c36d45db4e2e0cf1507aa9633af6710a12bdc047146fa89505e10aedc5bfb16cbfb0da686d5dfd89a37e1da4bce86bbee365e22be88705ab4ffccd530b4902a + languageName: node + linkType: hard -get-size@^2.0.2: - version "2.0.3" - resolved "https://registry.yarnpkg.com/get-size/-/get-size-2.0.3.tgz#54a1d0256b20ea7ac646516756202769941ad2ef" - integrity sha512-lXNzT/h/dTjTxRbm9BXb+SGxxzkm97h/PCIKtlN/CBCxxmkkIVV21udumMS93MuVTDX583gqc94v3RjuHmI+2Q== +"get-size@npm:^2.0.2": + version: 2.0.3 + resolution: "get-size@npm:2.0.3" + checksum: 10c0/c9703caa61b4d38385eab34aa5068f3a25ab40f6d9cda6dac3f0dc4dcd8da38f7b0283035e71c9f52a47b670b9315372cae46f58d66ad709a4939e57c1fdc6cc + languageName: node + linkType: hard -htmx.org@^2.0.5: - version "2.0.5" - resolved "https://registry.yarnpkg.com/htmx.org/-/htmx.org-2.0.5.tgz#88e8d89078b3059d74ac4eb653d80451c144820c" - integrity sha512-ocgvtHCShWFW0DvSV1NbJC7Y5EzUMy2eo5zeWvGj2Ac4LOr7sv9YKg4jzCZJdXN21fXACmCViwKSy+cm6i2dWQ== +"htmx.org@npm:^2.0.5": + version: 2.0.5 + resolution: "htmx.org@npm:2.0.5" + checksum: 10c0/c09dbb1396599129f36ae7286a4f89a4f9988c1eb6b4a562f0e7c591c781257ece08408e414a34f48c4c311af52762d945154c35c5b68e24411da6b47a8284b0 + languageName: node + linkType: hard -jquery@>=1.7, jquery@^3.7.1: - version "3.7.1" - resolved "https://registry.yarnpkg.com/jquery/-/jquery-3.7.1.tgz#083ef98927c9a6a74d05a6af02806566d16274de" - integrity sha512-m4avr8yL8kmFN8psrbFFFmB/If14iN5o9nw/NgnnM+kybDJpRsAynV2BsfpTYrTRysYUdADVD7CkUUizgkpLfg== +"jquery@npm:>=1.7, jquery@npm:^3.7.1": + version: 3.7.1 + resolution: "jquery@npm:3.7.1" + checksum: 10c0/808cfbfb758438560224bf26e17fcd5afc7419170230c810dd11f5c1792e2263e2970cca8d659eb84fcd9acc301edb6d310096e450277d54be4f57071b0c82d9 + languageName: node + linkType: hard -masonry-layout@^4.2.2: - version "4.2.2" - resolved "https://registry.yarnpkg.com/masonry-layout/-/masonry-layout-4.2.2.tgz#d57b44af13e601bfcdc423f1dd8348b5524de348" - integrity sha512-iGtAlrpHNyxaR19CvKC3npnEcAwszXoyJiI8ARV2ePi7fmYhIud25MHK8Zx4P0LCC4d3TNO9+rFa1KoK1OEOaA== +"masonry-layout@npm:^4.2.2": + version: 4.2.2 + resolution: "masonry-layout@npm:4.2.2" dependencies: - get-size "^2.0.2" - outlayer "^2.1.0" + get-size: "npm:^2.0.2" + outlayer: "npm:^2.1.0" + checksum: 10c0/991044cf7c22acbbb1135690314d68f9f237ef17315494c9dd25ed00fa0c526a8eb27d6bcf99a141a9d049bd62c5c251f66f9c8a4c201ca9c0944d8e44c0f09f + languageName: node + linkType: hard -outlayer@^2.1.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/outlayer/-/outlayer-2.1.1.tgz#29863b6de10ea5dadfffcadfa0d728907387e9a2" - integrity sha1-KYY7beEOpdrf/8rfoNcokHOH6aI= +"outlayer@npm:^2.1.0": + version: 2.1.1 + resolution: "outlayer@npm:2.1.1" dependencies: - ev-emitter "^1.0.0" - fizzy-ui-utils "^2.0.0" - get-size "^2.0.2" + ev-emitter: "npm:^1.0.0" + fizzy-ui-utils: "npm:^2.0.0" + get-size: "npm:^2.0.2" + checksum: 10c0/863f5568e16833d11d048a760ddd92395a9e1e49b51b669d863ff4ffda4cf8f6d91ebb2c4c20e26ca30175cb295f8f436075772a56c7e17ae40d3f095d449a53 + languageName: node + linkType: hard -popper.js@^1.16.1: - version "1.16.1" - resolved "https://registry.yarnpkg.com/popper.js/-/popper.js-1.16.1.tgz#2a223cb3dc7b6213d740e40372be40de43e65b1b" - integrity sha512-Wb4p1J4zyFTbM+u6WuO4XstYx4Ky9Cewe4DWrel7B0w6VVICvPwdOpotjzcf6eD8TsckVnIMNONQyPIUFOUbCQ== +"popper.js@npm:^1.16.1": + version: 1.16.1 + resolution: "popper.js@npm:1.16.1" + checksum: 10c0/1c1a826f757edb5b8c2049dfd7a9febf6ae1e9d0e51342fc715b49a0c1020fced250d26484619883651e097c5764bbcacd2f31496e3646027f079dd83e072681 + languageName: node + linkType: hard -yarn@^1.22.22: - version "1.22.22" - resolved "https://registry.yarnpkg.com/yarn/-/yarn-1.22.22.tgz#ac34549e6aa8e7ead463a7407e1c7390f61a6610" - integrity sha512-prL3kGtyG7o9Z9Sv8IPfBNrWTDmXB4Qbes8A9rEzt6wkJV8mUvoirjU0Mp3GGAU06Y0XQyA3/2/RQFVuK7MTfg== +"wger@workspace:.": + version: 0.0.0-use.local + resolution: "wger@workspace:." + dependencies: + "@popperjs/core": "npm:^2.11.8" + bootstrap: "npm:5.3.7" + components-font-awesome: "npm:5.9.0" + datatables.net-bs5: "npm:^2.3.1" + devbridge-autocomplete: "npm:^1.4.11" + htmx.org: "npm:^2.0.5" + jquery: "npm:^3.7.1" + masonry-layout: "npm:^4.2.2" + popper.js: "npm:^1.16.1" + yarn: "npm:^1.22.22" + languageName: unknown + linkType: soft + +"yarn@npm:^1.22.22": + version: 1.22.22 + resolution: "yarn@npm:1.22.22" + bin: + yarn: bin/yarn.js + yarnpkg: bin/yarn.js + checksum: 10c0/8c77198c93d7542e7f4e131c63b66de357b7076ecfbcfe709ec0d674115c2dd9edaa45196e5510e6e9366d368707a802579e3402071002e1c9d9a99d491478de + languageName: node + linkType: hard