diff --git a/charts/lightcurve/Chart.yaml b/charts/lightcurve/Chart.yaml index c58c10b23..a489fabba 100644 --- a/charts/lightcurve/Chart.yaml +++ b/charts/lightcurve/Chart.yaml @@ -1,5 +1,5 @@ -appVersion: 24.9.1-rc123 +appVersion: 24.10.1-rc127 description: Lightcurve API for ALeRCE Clients name: lightcurve type: application -version: 24.9.156 +version: 24.10.160 diff --git a/lightcurve/Dockerfile b/lightcurve/Dockerfile index 8eac978bc..270f89517 100644 --- a/lightcurve/Dockerfile +++ b/lightcurve/Dockerfile @@ -1,3 +1,31 @@ +FROM python:3.11 as python-base +LABEL org.opencontainers.image.authors="ALeRCE" +ENV PYTHONDONTWRITEBYTECODE=1 \ + PYTHONUNBUFFERED=1 \ + PYTHONFAULTHANDLER=1 \ + PIP_NO_CACHE_DIR=off \ + PIP_DISABLE_PIP_VERSION_CHECK=on \ + PIP_DEFAULT_TIMEOUT=100 \ + POETRY_VIRTUALENVS_IN_PROJECT=true \ + POETRY_NO_INTERACTION=1 + + +FROM python-base as builder +RUN pip install poetry +WORKDIR /app +COPY ./lightcurve/poetry.lock ./lightcurve/pyproject.toml /app +COPY ./libs/ralidator-core /libs/ralidator-core +COPY ./libs/ralidator-fastapi /libs/ralidator-fastapi +RUN poetry install --no-root --without=test + +FROM node:22-alpine as tailwindcss_lightcurve +COPY ./lightcurve/ /lightcurve/ +WORKDIR /lightcurve +RUN \ + wget -nc https://github.com/tailwindlabs/tailwindcss/releases/download/v3.4.14/tailwindcss-linux-x64 -O tailwindcss && \ + chmod +x tailwindcss && \ + ./tailwindcss -i /lightcurve/src/lightcurve_api/templates/main.css -o /compiled/main.css + FROM node:22-alpine as tailwindcss_object COPY ./lightcurve/ /lightcurve/ WORKDIR /lightcurve @@ -14,6 +42,15 @@ RUN \ chmod +x tailwindcss && \ ./tailwindcss -i /lightcurve/src/magstats_api/templates/magstats.css -o /compiled/magstats.css +FROM node:22-alpine as tailwindcss_probability +COPY ./lightcurve/ /lightcurve/ +WORKDIR /lightcurve +RUN \ + wget -nc https://github.com/tailwindlabs/tailwindcss/releases/download/v3.4.13/tailwindcss-linux-x64 -O tailwindcss && \ + chmod +x tailwindcss && \ + ./tailwindcss -i /lightcurve/src/probability_api/templates/probability.css -o /compiled/probability.css + + FROM node:22-alpine as tailwindcss_crossmatch COPY ./lightcurve/ /lightcurve/ WORKDIR /lightcurve @@ -34,6 +71,7 @@ COPY ./lightcurve/src /app/src COPY --from=tailwindcss_lightcurve /compiled/main.css /app/src/api/static COPY --from=tailwindcss_magstats /compiled/magstats.css /app/src/magstats_api/static COPY --from=tailwindcss_object /compiled/object.css /app/src/object_api/static +COPY --from=tailwindcss_probability /compiled/probability.css /app/src/probability_api/static COPY --from=tailwindcss_crossmatch /compiled/crossmatch.css /app/src/crossmatch_api/static RUN poetry install --only-root CMD ["bash", "scripts/entrypoint.sh"] \ No newline at end of file diff --git a/lightcurve/docker-compose.yaml b/lightcurve/docker-compose.yaml index 38ae051f7..57a50b87b 100644 --- a/lightcurve/docker-compose.yaml +++ b/lightcurve/docker-compose.yaml @@ -28,6 +28,18 @@ services: environment: SERVICE: lightcurve_api API_URL: http://localhost:8001 + + object: + build: + context: ../ + dockerfile: lightcurve/Dockerfile + ports: + - 8002:8000 + env_file: + - variables.env + environment: + SERVICE: object_api + API_URL: http://localhost:8002 magstats: build: @@ -40,18 +52,18 @@ services: environment: SERVICE: magstats_api API_URL: http://localhost:8003 - - object: + + probability: build: context: ../ dockerfile: lightcurve/Dockerfile ports: - - 8002:8000 + - 8004:8000 env_file: - variables.env environment: - SERVICE: object_api - API_URL: http://localhost:8002 + SERVICE: probability_api + API_URL: http://localhost:8004 crossmatch: build: diff --git a/lightcurve/pyproject.toml b/lightcurve/pyproject.toml index 0ae3e0576..e2242a986 100644 --- a/lightcurve/pyproject.toml +++ b/lightcurve/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "lightcurve" -version = "24.9.1-rc123" +version = "24.10.1-rc127" description = "Get lightcurve of objects from ZTF and ATLAS surveys" authors = ["Diego Rodriguez Mancini"] readme = "README.md" @@ -10,6 +10,7 @@ packages = [ { include = "lightcurve_api", from = "src" }, { include = "magstats_api", from = "src" }, { include = "object_api", from = "src" }, + { include = "probability_api", from = "src" }, { include = "database", from = "src" }, ] @@ -71,4 +72,5 @@ dev = "scripts.run_dev:run" lightcurve = "scripts.run_dev:run_lightcurve" magstats = "scripts.run_dev:run_magstats" object = "scripts.run_dev:run_object" +probability = "scripts.run_dev:run_probability" tunnel = "scripts.sshproxy:run_tunnel" diff --git a/lightcurve/scripts/run_dev.py b/lightcurve/scripts/run_dev.py index bde1e4471..4dd8c7949 100644 --- a/lightcurve/scripts/run_dev.py +++ b/lightcurve/scripts/run_dev.py @@ -33,10 +33,17 @@ def run_object(): port = int(os.getenv("PORT", default=8000)) asyncio.run(run_service("object_api", port)) + def run_crossmatch(): port = int(os.getenv("PORT", default=8000)) asyncio.run(run_service("crossmatch_api", port)) + +def run_probability(): + port = int(os.getenv("PORT", default=8000)) + asyncio.run(run_service("probability_api", port)) + + async def run_services(services, port): tasks = [] for i, service in enumerate(services): diff --git a/lightcurve/scripts/run_probability_dev.py b/lightcurve/scripts/run_probability_dev.py new file mode 100644 index 000000000..00c971873 --- /dev/null +++ b/lightcurve/scripts/run_probability_dev.py @@ -0,0 +1,12 @@ +import os + +import uvicorn + + +def run(): + port = os.getenv("PORT", default=8000) + uvicorn.run("probability_api.api:app", port=int(port), reload=True, reload_dirs=[".", "../libs"]) + + +if __name__ == "__main__": + run() \ No newline at end of file diff --git a/lightcurve/src/lightcurve_api/static/lc-apparent.js b/lightcurve/src/lightcurve_api/static/lc-apparent.js index 4f23076fb..3124fe1b5 100644 --- a/lightcurve/src/lightcurve_api/static/lc-apparent.js +++ b/lightcurve/src/lightcurve_api/static/lc-apparent.js @@ -3,7 +3,7 @@ import { LightCurveOptions } from "./lc-utils.js"; export class ApparentLightCurveOptions extends LightCurveOptions { constructor(detections, forcedPhotometry, fontColor, flux = false) { - super(detections, [], forcedPhotometry, fontColor, "Apparent Magnitude"); + super(fontColor, "Apparent Magnitude"); this.detections = detections; this.forcedPhotometry = forcedPhotometry; this.getSeries(flux); diff --git a/lightcurve/src/lightcurve_api/static/lc-difference.js b/lightcurve/src/lightcurve_api/static/lc-difference.js index d948fd42e..692dda614 100644 --- a/lightcurve/src/lightcurve_api/static/lc-difference.js +++ b/lightcurve/src/lightcurve_api/static/lc-difference.js @@ -10,9 +10,6 @@ export class DifferenceLightCurveOptions extends LightCurveOptions { flux = false, ) { super( - detections, - nonDetections, - forcedPhotometry, fontColor, "Difference Magnitude", ); diff --git a/lightcurve/src/lightcurve_api/static/lc-folded.js b/lightcurve/src/lightcurve_api/static/lc-folded.js index 790252824..c88df50a3 100644 --- a/lightcurve/src/lightcurve_api/static/lc-folded.js +++ b/lightcurve/src/lightcurve_api/static/lc-folded.js @@ -3,7 +3,7 @@ import { jdToDate } from "./astro-dates.js"; export class FoldedLightCurveOptions extends LightCurveOptions { constructor(detections, forcedPhotometry, fontColor, period, flux) { - super(detections, [], forcedPhotometry, fontColor, "Folded Light Curve"); + super(fontColor, "Folded Light Curve"); this.detections = detections; this.forcedPhotometry = forcedPhotometry; this.period = period; diff --git a/lightcurve/src/lightcurve_api/static/lc-utils.js b/lightcurve/src/lightcurve_api/static/lc-utils.js index e36141d71..d5ed01dab 100644 --- a/lightcurve/src/lightcurve_api/static/lc-utils.js +++ b/lightcurve/src/lightcurve_api/static/lc-utils.js @@ -12,6 +12,7 @@ export class LightCurveOptions { 4: { name: "c", color: "#00FFFF" }, 5: { name: "o", color: "#FFA500" }, }; + this.fontColor = fontColor; this.options = { grid: { diff --git a/lightcurve/src/lightcurve_api/static/main.css b/lightcurve/src/lightcurve_api/static/main.css index 6f4ceb356..270cdd86c 100644 --- a/lightcurve/src/lightcurve_api/static/main.css +++ b/lightcurve/src/lightcurve_api/static/main.css @@ -1,3 +1,18 @@ +.indicator { + opacity: 0; +} + +@keyframes tw-pulse { + 50% { + opacity: .5; + } +} + +.htmx-request.indicator { + animation: tw-pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite; + opacity: 1; +} + .tw-preflight :is(.tw-pointer-events-none) { pointer-events: none; } @@ -22,10 +37,22 @@ right: 0px; } +.tw-preflight :is(.tw-top-1) { + top: 0.25rem; +} + .tw-preflight :is(.tw-top-1\/2) { top: 50%; } +.tw-preflight :is(.tw-z-10) { + z-index: 10; +} + +.tw-preflight :is(.tw-z-\[10\]) { + z-index: 10; +} + .tw-preflight :is(.tw-z-\[9999\]) { z-index: 9999; } @@ -46,6 +73,10 @@ grid-column: span 5 / span 5; } +.tw-preflight :is(.tw-m-0) { + margin: 0px; +} + .tw-preflight :is(.tw-m-auto) { margin: auto; } @@ -60,8 +91,14 @@ margin-right: auto; } -.tw-preflight :is(.tw-mb-\[20px\]) { - margin-bottom: 20px; +.tw-preflight :is(.tw-my-1) { + margin-top: 0.25rem; + margin-bottom: 0.25rem; +} + +.tw-preflight :is(.tw-my-4) { + margin-top: 1rem; + margin-bottom: 1rem; } .tw-preflight :is(.tw-me-2) { @@ -80,8 +117,8 @@ margin-top: 0.75rem; } -.tw-preflight :is(.tw-mt-\[10px\]) { - margin-top: 10px; +.tw-preflight :is(.tw-inline-block) { + display: inline-block; } .tw-preflight :is(.tw-inline) { @@ -112,6 +149,18 @@ height: 1.5rem; } +.tw-preflight :is(.tw-h-8) { + height: 2rem; +} + +.tw-preflight :is(.tw-h-auto) { + height: auto; +} + +.tw-preflight :is(.tw-w-1\/3) { + width: 33.333333%; +} + .tw-preflight :is(.tw-w-12) { width: 3rem; } @@ -120,6 +169,10 @@ width: 8rem; } +.tw-preflight :is(.tw-w-48) { + width: 12rem; +} + .tw-preflight :is(.tw-w-5) { width: 1.25rem; } @@ -128,6 +181,18 @@ width: 1.5rem; } +.tw-preflight :is(.tw-w-80) { + width: 20rem; +} + +.tw-preflight :is(.tw-w-\[400px\]) { + width: 400px; +} + +.tw-preflight :is(.tw-w-\[50\%\]) { + width: 50%; +} + .tw-preflight :is(.tw-w-\[95\%\]) { width: 95%; } @@ -140,17 +205,32 @@ min-width: 100%; } +.tw-preflight :is(.tw-max-w-\[40\%\]) { + max-width: 40%; +} + +.tw-preflight :is(.-tw-translate-y-1) { + --tw-translate-y: -0.25rem; + transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); +} + .tw-preflight :is(.-tw-translate-y-1\/2) { --tw-translate-y: -50%; - transform: translate(var(--tw-translate-x), var(--tw-translate-y)) - rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) - scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); + transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); } .tw-preflight :is(.tw-transform) { - transform: translate(var(--tw-translate-x), var(--tw-translate-y)) - rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) - scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); + transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); +} + +@keyframes tw-pulse { + 50% { + opacity: .5; + } +} + +.tw-preflight :is(.tw-animate-pulse) { + animation: tw-pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite; } @keyframes tw-spin { @@ -163,10 +243,14 @@ animation: tw-spin 1s linear infinite; } +.tw-preflight :is(.tw-cursor-pointer) { + cursor: pointer; +} + .tw-preflight :is(.tw-appearance-none) { -webkit-appearance: none; - -moz-appearance: none; - appearance: none; + -moz-appearance: none; + appearance: none; } .tw-preflight :is(.tw-grid-cols-10) { @@ -211,6 +295,12 @@ margin-left: calc(0.5rem * calc(1 - var(--tw-space-x-reverse))); } +.tw-preflight :is(.tw-space-x-4 > :not([hidden]) ~ :not([hidden])) { + --tw-space-x-reverse: 0; + margin-right: calc(1rem * var(--tw-space-x-reverse)); + margin-left: calc(1rem * calc(1 - var(--tw-space-x-reverse))); +} + .tw-preflight :is(.tw-space-y-2 > :not([hidden]) ~ :not([hidden])) { --tw-space-y-reverse: 0; margin-top: calc(0.5rem * calc(1 - var(--tw-space-y-reverse))); @@ -236,6 +326,16 @@ overflow: auto; } +.tw-preflight :is(.tw-truncate) { + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} + +.tw-preflight :is(.tw-text-wrap) { + text-wrap: wrap; +} + .tw-preflight :is(.tw-rounded) { border-radius: 0.25rem; } @@ -268,10 +368,19 @@ border-bottom-width: 1px; } +.tw-preflight :is(.tw-border-t) { + border-top-width: 1px; +} + .tw-preflight :is(.tw-border-solid) { border-style: solid; } +.tw-preflight :is(.tw-border-\[\#1e1e1e\]) { + --tw-border-opacity: 1; + border-color: rgb(30 30 30 / var(--tw-border-opacity)); +} + .tw-preflight :is(.tw-border-blue-400) { --tw-border-opacity: 1; border-color: rgb(96 165 250 / var(--tw-border-opacity)); @@ -295,11 +404,25 @@ --tw-border-opacity: 0.2; } +.tw-preflight :is(.tw-bg-\[\#757575\]\/60) { + background-color: rgb(117 117 117 / 0.6); +} + .tw-preflight :is(.tw-bg-blue-500) { --tw-bg-opacity: 1; background-color: rgb(59 130 246 / var(--tw-bg-opacity)); } +.tw-preflight :is(.tw-bg-blue-700) { + --tw-bg-opacity: 1; + background-color: rgb(29 78 216 / var(--tw-bg-opacity)); +} + +.tw-preflight :is(.tw-bg-cyan-700) { + --tw-bg-opacity: 1; + background-color: rgb(14 116 144 / var(--tw-bg-opacity)); +} + .tw-preflight :is(.tw-bg-gray-100) { --tw-bg-opacity: 1; background-color: rgb(243 244 246 / var(--tw-bg-opacity)); @@ -328,6 +451,10 @@ padding: 0.5rem; } +.tw-preflight :is(.tw-p-4) { + padding: 1rem; +} + .tw-preflight :is(.tw-px-2) { padding-left: 0.5rem; padding-right: 0.5rem; @@ -348,6 +475,11 @@ padding-bottom: 0.5rem; } +.tw-preflight :is(.tw-py-3) { + padding-top: 0.75rem; + padding-bottom: 0.75rem; +} + .tw-preflight :is(.tw-py-4) { padding-top: 1rem; padding-bottom: 1rem; @@ -357,10 +489,6 @@ padding-left: 10px; } -.tw-preflight :is(.tw-pl-\[5px\]) { - padding-left: 5px; -} - .tw-preflight :is(.tw-pr-2) { padding-right: 0.5rem; } @@ -377,8 +505,8 @@ padding-top: 25px; } -.tw-preflight :is(.tw-pt-\[30px\]) { - padding-top: 30px; +.tw-preflight :is(.tw-text-left) { + text-align: left; } .tw-preflight :is(.tw-text-center) { @@ -408,11 +536,13 @@ font-weight: 700; } +.tw-preflight :is(.tw-font-light) { + font-weight: 300; +} + .tw-preflight :is(.tw-ordinal) { --tw-ordinal: ordinal; - font-variant-numeric: var(--tw-ordinal) var(--tw-slashed-zero) - var(--tw-numeric-figure) var(--tw-numeric-spacing) - var(--tw-numeric-fraction); + font-variant-numeric: var(--tw-ordinal) var(--tw-slashed-zero) var(--tw-numeric-figure) var(--tw-numeric-spacing) var(--tw-numeric-fraction); } .tw-preflight :is(.tw-text-\[\#1e1e1e\]) { @@ -420,11 +550,36 @@ color: rgb(30 30 30 / var(--tw-text-opacity)); } +.tw-preflight :is(.tw-text-\[\#BDBDBD\]) { + --tw-text-opacity: 1; + color: rgb(189 189 189 / var(--tw-text-opacity)); +} + +.tw-preflight :is(.tw-text-\[\#FAFAFA\]) { + --tw-text-opacity: 1; + color: rgb(250 250 250 / var(--tw-text-opacity)); +} + .tw-preflight :is(.tw-text-black) { --tw-text-opacity: 1; color: rgb(0 0 0 / var(--tw-text-opacity)); } +.tw-preflight :is(.tw-text-blue-50) { + --tw-text-opacity: 1; + color: rgb(239 246 255 / var(--tw-text-opacity)); +} + +.tw-preflight :is(.tw-text-blue-600) { + --tw-text-opacity: 1; + color: rgb(37 99 235 / var(--tw-text-opacity)); +} + +.tw-preflight :is(.tw-text-cyan-50) { + --tw-text-opacity: 1; + color: rgb(236 254 255 / var(--tw-text-opacity)); +} + .tw-preflight :is(.tw-text-gray-400) { --tw-text-opacity: 1; color: rgb(156 163 175 / var(--tw-text-opacity)); @@ -440,11 +595,24 @@ color: rgb(239 68 68 / var(--tw-text-opacity)); } +.tw-preflight :is(.tw-text-red-900) { + --tw-text-opacity: 1; + color: rgb(127 29 29 / var(--tw-text-opacity)); +} + .tw-preflight :is(.tw-text-white) { --tw-text-opacity: 1; color: rgb(255 255 255 / var(--tw-text-opacity)); } +.tw-preflight :is(.tw-underline) { + text-decoration-line: underline; +} + +.tw-preflight :is(.tw-opacity-100) { + opacity: 1; +} + .tw-preflight :is(.tw-opacity-50) { opacity: 0.5; } @@ -452,8 +620,11 @@ .tw-preflight :is(.tw-shadow-2xl) { --tw-shadow: 0 25px 50px -12px rgb(0 0 0 / 0.25); --tw-shadow-colored: 0 25px 50px -12px var(--tw-shadow-color); - box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), - var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); + box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); +} + +.tw-preflight :is(.tw-duration-200) { + transition-duration: 200ms; } .disabled\:bg-transparent { @@ -885,8 +1056,7 @@ Prevent resizing textareas horizontally by default. /* 2 */ } -.tw-preflight input::-moz-placeholder, -.tw-preflight textarea::-moz-placeholder { +.tw-preflight input::-moz-placeholder, .tw-preflight textarea::-moz-placeholder { opacity: 1; /* 1 */ color: #9ca3af; @@ -1065,6 +1235,11 @@ Constrain images and videos to the parent width and preserve their intrinsic asp background-color: rgb(117 117 117 / var(--tw-bg-opacity)); } +.tw-preflight :is(.hover\:tw-bg-\[\#e5e4e2\]:hover) { + --tw-bg-opacity: 1; + background-color: rgb(229 228 226 / var(--tw-bg-opacity)); +} + .tw-preflight :is(.hover\:tw-bg-blue-700:hover) { --tw-bg-opacity: 1; background-color: rgb(29 78 216 / var(--tw-bg-opacity)); @@ -1090,10 +1265,6 @@ Constrain images and videos to the parent width and preserve their intrinsic asp color: rgb(75 85 99 / var(--tw-text-opacity)); } -.tw-preflight :is(.hover\:tw-opacity-70:hover) { - opacity: 0.7; -} - .tw-preflight :is(.disabled\:tw-bg-transparent:disabled) { background-color: transparent; } @@ -1106,20 +1277,19 @@ Constrain images and videos to the parent width and preserve their intrinsic asp outline-style: solid; } +.tw-preflight :is(.tw-group:hover .group-hover\:tw-block) { + display: block; +} + .tw-preflight :is(.tw-group:hover .group-hover\:tw-flex) { display: flex; } -.tw-preflight :is(.tw-group:hover .group-hover\:tw-opacity-60) { - opacity: 0.6; +.tw-preflight :is(.tw-group:hover .group-hover\:tw-flex-col) { + flex-direction: column; } -.tw-preflight - :is( - :is(.tw-dark .dark\:tw-divide-\[\#404040\]) - > :not([hidden]) - ~ :not([hidden]) - ) { +.tw-preflight :is(:is(.tw-dark .dark\:tw-divide-\[\#404040\]) > :not([hidden]) ~ :not([hidden])) { --tw-divide-opacity: 1; border-color: rgb(64 64 64 / var(--tw-divide-opacity)); } @@ -1129,9 +1299,9 @@ Constrain images and videos to the parent width and preserve their intrinsic asp border-color: rgb(64 64 64 / var(--tw-border-opacity)); } -.tw-preflight :is(.tw-dark .dark\:tw-border-b-white) { +.tw-preflight :is(.tw-dark .dark\:tw-border-white) { --tw-border-opacity: 1; - border-bottom-color: rgb(255 255 255 / var(--tw-border-opacity)); + border-color: rgb(255 255 255 / var(--tw-border-opacity)); } .tw-preflight :is(.tw-dark .dark\:tw-border-opacity-20) { @@ -1148,11 +1318,20 @@ Constrain images and videos to the parent width and preserve their intrinsic asp background-color: rgb(37 37 37 / var(--tw-bg-opacity)); } +.tw-preflight :is(.tw-dark .dark\:tw-bg-\[\#757575\]\/60) { + background-color: rgb(117 117 117 / 0.6); +} + .tw-preflight :is(.tw-dark .dark\:tw-bg-green-700) { --tw-bg-opacity: 1; background-color: rgb(21 128 61 / var(--tw-bg-opacity)); } +.tw-preflight :is(.tw-dark .dark\:tw-text-\[\#FAFAFA\]) { + --tw-text-opacity: 1; + color: rgb(250 250 250 / var(--tw-text-opacity)); +} + .tw-preflight :is(.tw-dark .dark\:tw-text-white) { --tw-text-opacity: 1; color: rgb(255 255 255 / var(--tw-text-opacity)); @@ -1162,3 +1341,8 @@ Constrain images and videos to the parent width and preserve their intrinsic asp --tw-bg-opacity: 1; background-color: rgb(53 53 53 / var(--tw-bg-opacity)); } + +.tw-preflight :is(.tw-dark .dark\:hover\:tw-bg-\[\#3b3939\]:hover) { + --tw-bg-opacity: 1; + background-color: rgb(59 57 57 / var(--tw-bg-opacity)); +} diff --git a/lightcurve/src/lightcurve_api/static/periodogram.js b/lightcurve/src/lightcurve_api/static/periodogram.js index b7e4aeb98..9ec5c98bb 100644 --- a/lightcurve/src/lightcurve_api/static/periodogram.js +++ b/lightcurve/src/lightcurve_api/static/periodogram.js @@ -51,8 +51,11 @@ export class Periodogram { legend: { textStyle: { color } }, }; - if (this.isPeriodogramBuilt) this.periodogram_plot.setOption(options); - else this.chartOptions = new PeriodogramOptions(color); + if (this.isPeriodogramBuilt){ + this.periodogram_plot.setOption(options); + } else { + this.chartOptions = new PeriodogramOptions(color); + } } load() { diff --git a/lightcurve/src/lightcurve_api/templates/lightcurve_app.html.jinja b/lightcurve/src/lightcurve_api/templates/lightcurve_app.html.jinja index 85d7aa08e..dc8641edf 100644 --- a/lightcurve/src/lightcurve_api/templates/lightcurve_app.html.jinja +++ b/lightcurve/src/lightcurve_api/templates/lightcurve_app.html.jinja @@ -20,7 +20,7 @@ class="tw-preflight tw-bg-white dark:tw-bg-[#1e1e1e] dark:tw-text-white" style="height: 100%">
-

Loading...

+

Loading...

{% import 'radio_button.html.jinja' as radio %} @@ -51,7 +51,7 @@ hx-trigger="click" hx-target="#lightcurve-app" hx-swap="outerHTML" - hx-indicator="#plot-indicator"> + hx-indicator="#spot-loader"> Filter DR @@ -86,14 +86,13 @@ let current_plot = "{{ plot_type }}"; let period = {{ period | float }}; const apiUrl = "{{ API_URL }}" - + const setPlot = () => { let flux = document.getElementById("lc-check-flux").checked; const all_detections = getDetectionsWithDR(); const periodogram = document.getElementById("lc-periodogram"); const periodogram_check = document.getElementById("lc-check-row-periodogram"); - const diffOptions = new DifferenceLightCurveOptions( JSON.parse(JSON.stringify(detections)), non_detections, @@ -262,6 +261,7 @@ updateRadioButtons(); }); }); + let check_dr = document.getElementById("lc-check-dr"); {% if show_dr %} check_dr.checked = true; @@ -295,6 +295,7 @@ setPlot(); }; + // Update color scheme function setColorSchemeWrapper(container) { function setColorScheme() { diff --git a/lightcurve/src/lightcurve_api/templates/main.css b/lightcurve/src/lightcurve_api/templates/main.css index 1693169f6..24a861e91 100644 --- a/lightcurve/src/lightcurve_api/templates/main.css +++ b/lightcurve/src/lightcurve_api/templates/main.css @@ -1,6 +1,16 @@ @tailwind components; @tailwind utilities; +@layer components{ + .indicator{ + @apply tw-opacity-0; + } + + .htmx-request.indicator{ + @apply tw-opacity-100 tw-animate-pulse; + } +} + .disabled\:bg-transparent { background-color: transparent; } diff --git a/lightcurve/src/magstats_api/routes/rest.py b/lightcurve/src/magstats_api/routes/rest.py index a1f55cef6..004a5dc3e 100644 --- a/lightcurve/src/magstats_api/routes/rest.py +++ b/lightcurve/src/magstats_api/routes/rest.py @@ -10,20 +10,11 @@ directory="src/object_api/templates", autoescape=True, auto_reload=True ) +@router.get("/") +def root(): + return "this is the magstats module" -@router.get("/mag/{oid}", response_class=HTMLResponse) -async def object_mag_app(request: Request, oid: str): - try: - mag_stats = get_mag_stats( - oid, session_factory=request.app.state.psql_session - ) - except ObjectNotFound: - raise HTTPException(status_code=404, detail="Object not found") - mag_stats_dict = {} - for i, mag_stat in enumerate(mag_stats): - mag_stats_dict[f"band_{i+1}"] = ( - mag_stat.__dict__ - ) ## Es necesario cambiar el nombre de las keys por los fid y trabajar con el conversor que esta en probability en alerts-api - - return {"request": request, "stat_r": mag_stats_dict} +@router.get("/healthcheck") +def healthcheck(): + return "OK" diff --git a/lightcurve/src/magstats_api/static/magstats.css b/lightcurve/src/magstats_api/static/magstats.css index 7091bc1e5..dcf4ca529 100644 --- a/lightcurve/src/magstats_api/static/magstats.css +++ b/lightcurve/src/magstats_api/static/magstats.css @@ -22,6 +22,642 @@ right: 0px; } +.tw-preflight :is(.tw-top-1) { + top: 0.25rem; +} + +.tw-preflight :is(.tw-top-1\/2) { + top: 50%; +} + +.tw-preflight :is(.tw-z-10) { + z-index: 10; +} + +.tw-preflight :is(.tw-z-\[10\]) { + z-index: 10; +} + +.tw-preflight :is(.tw-z-\[9999\]) { + z-index: 9999; +} + +.tw-preflight :is(.tw-col-span-1) { + grid-column: span 1 / span 1; +} + +.tw-preflight :is(.tw-col-span-2) { + grid-column: span 2 / span 2; +} + +.tw-preflight :is(.tw-col-span-4) { + grid-column: span 4 / span 4; +} + +.tw-preflight :is(.tw-col-span-5) { + grid-column: span 5 / span 5; +} + +.tw-preflight :is(.tw-m-0) { + margin: 0px; +} + +.tw-preflight :is(.tw-m-auto) { + margin: auto; +} + +.tw-preflight :is(.tw-mx-0) { + margin-left: 0px; + margin-right: 0px; +} + +.tw-preflight :is(.tw-mx-2) { + margin-left: 0.5rem; + margin-right: 0.5rem; +} + +.tw-preflight :is(.tw-mx-auto) { + margin-left: auto; + margin-right: auto; +} + +.tw-preflight :is(.tw-my-1) { + margin-top: 0.25rem; + margin-bottom: 0.25rem; +} + +.tw-preflight :is(.tw-my-4) { + margin-top: 1rem; + margin-bottom: 1rem; +} + +.tw-preflight :is(.tw-me-2) { + margin-inline-end: 0.5rem; +} + +.tw-preflight :is(.tw-ml-2) { + margin-left: 0.5rem; +} + +.tw-preflight :is(.tw-mt-2) { + margin-top: 0.5rem; +} + +.tw-preflight :is(.tw-mt-3) { + margin-top: 0.75rem; +} + +.tw-preflight :is(.tw-block) { + display: block; +} + +.tw-preflight :is(.tw-inline-block) { + display: inline-block; +} + +.tw-preflight :is(.tw-inline) { + display: inline; +} + +.tw-preflight :is(.tw-flex) { + display: flex; +} + +.tw-preflight :is(.tw-grid) { + display: grid; +} + +.tw-preflight :is(.tw-hidden) { + display: none; +} + +.tw-preflight :is(.tw-h-32) { + height: 8rem; +} + +.tw-preflight :is(.tw-h-5) { + height: 1.25rem; +} + +.tw-preflight :is(.tw-h-6) { + height: 1.5rem; +} + +.tw-preflight :is(.tw-h-8) { + height: 2rem; +} + +.tw-preflight :is(.tw-h-auto) { + height: auto; +} + +.tw-preflight :is(.tw-w-1\/3) { + width: 33.333333%; +} + +.tw-preflight :is(.tw-w-12) { + width: 3rem; +} + +.tw-preflight :is(.tw-w-32) { + width: 8rem; +} + +.tw-preflight :is(.tw-w-48) { + width: 12rem; +} + +.tw-preflight :is(.tw-w-5) { + width: 1.25rem; +} + +.tw-preflight :is(.tw-w-6) { + width: 1.5rem; +} + +.tw-preflight :is(.tw-w-80) { + width: 20rem; +} + +.tw-preflight :is(.tw-w-\[400px\]) { + width: 400px; +} + +.tw-preflight :is(.tw-w-\[50\%\]) { + width: 50%; +} + +.tw-preflight :is(.tw-w-\[95\%\]) { + width: 95%; +} + +.tw-preflight :is(.tw-w-full) { + width: 100%; +} + +.tw-preflight :is(.tw-min-w-full) { + min-width: 100%; +} + +.tw-preflight :is(.tw-max-w-\[40\%\]) { + max-width: 40%; +} + +.tw-preflight :is(.-tw-translate-y-1) { + --tw-translate-y: -0.25rem; + transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); +} + +.tw-preflight :is(.-tw-translate-y-1\/2) { + --tw-translate-y: -50%; + transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); +} + +.tw-preflight :is(.tw-transform) { + transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); +} + +@keyframes tw-pulse { + 50% { + opacity: .5; + } +} + +.tw-preflight :is(.tw-animate-pulse) { + animation: tw-pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite; +} + +@keyframes tw-spin { + to { + transform: rotate(360deg); + } +} + +.tw-preflight :is(.tw-animate-spin) { + animation: tw-spin 1s linear infinite; +} + +.tw-preflight :is(.tw-cursor-pointer) { + cursor: pointer; +} + +.tw-preflight :is(.tw-appearance-none) { + -webkit-appearance: none; + -moz-appearance: none; + appearance: none; +} + +.tw-preflight :is(.tw-grid-cols-10) { + grid-template-columns: repeat(10, minmax(0, 1fr)); +} + +.tw-preflight :is(.tw-grid-cols-6) { + grid-template-columns: repeat(6, minmax(0, 1fr)); +} + +.tw-preflight :is(.tw-flex-col) { + flex-direction: column; +} + +.tw-preflight :is(.tw-place-content-center) { + place-content: center; +} + +.tw-preflight :is(.tw-place-items-center) { + place-items: center; +} + +.tw-preflight :is(.tw-items-center) { + align-items: center; +} + +.tw-preflight :is(.tw-justify-center) { + justify-content: center; +} + +.tw-preflight :is(.tw-justify-between) { + justify-content: space-between; +} + +.tw-preflight :is(.tw-gap-1) { + gap: 0.25rem; +} + +.tw-preflight :is(.tw-space-x-2 > :not([hidden]) ~ :not([hidden])) { + --tw-space-x-reverse: 0; + margin-right: calc(0.5rem * var(--tw-space-x-reverse)); + margin-left: calc(0.5rem * calc(1 - var(--tw-space-x-reverse))); +} + +.tw-preflight :is(.tw-space-x-4 > :not([hidden]) ~ :not([hidden])) { + --tw-space-x-reverse: 0; + margin-right: calc(1rem * var(--tw-space-x-reverse)); + margin-left: calc(1rem * calc(1 - var(--tw-space-x-reverse))); +} + +.tw-preflight :is(.tw-space-y-2 > :not([hidden]) ~ :not([hidden])) { + --tw-space-y-reverse: 0; + margin-top: calc(0.5rem * calc(1 - var(--tw-space-y-reverse))); + margin-bottom: calc(0.5rem * var(--tw-space-y-reverse)); +} + +.tw-preflight :is(.tw-divide-y > :not([hidden]) ~ :not([hidden])) { + --tw-divide-y-reverse: 0; + border-top-width: calc(1px * calc(1 - var(--tw-divide-y-reverse))); + border-bottom-width: calc(1px * var(--tw-divide-y-reverse)); +} + +.tw-preflight :is(.tw-divide-gray-200 > :not([hidden]) ~ :not([hidden])) { + --tw-divide-opacity: 1; + border-color: rgb(229 231 235 / var(--tw-divide-opacity)); +} + +.tw-preflight :is(.tw-place-self-center) { + place-self: center; +} + +.tw-preflight :is(.tw-overflow-auto) { + overflow: auto; +} + +.tw-preflight :is(.tw-truncate) { + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} + +.tw-preflight :is(.tw-text-wrap) { + text-wrap: wrap; +} + +.tw-preflight :is(.tw-rounded) { + border-radius: 0.25rem; +} + +.tw-preflight :is(.tw-rounded-\[6px\]) { + border-radius: 6px; +} + +.tw-preflight :is(.tw-rounded-full) { + border-radius: 9999px; +} + +.tw-preflight :is(.tw-rounded-md) { + border-radius: 0.375rem; +} + +.tw-preflight :is(.tw-border) { + border-width: 1px; +} + +.tw-preflight :is(.tw-border-8) { + border-width: 8px; +} + +.tw-preflight :is(.tw-border-b) { + border-bottom-width: 1px; +} + +.tw-preflight :is(.tw-border-b-\[1px\]) { + border-bottom-width: 1px; +} + +.tw-preflight :is(.tw-border-t) { + border-top-width: 1px; +} + +.tw-preflight :is(.tw-border-solid) { + border-style: solid; +} + +.tw-preflight :is(.tw-border-\[\#1e1e1e\]) { + --tw-border-opacity: 1; + border-color: rgb(30 30 30 / var(--tw-border-opacity)); +} + +.tw-preflight :is(.tw-border-blue-400) { + --tw-border-opacity: 1; + border-color: rgb(96 165 250 / var(--tw-border-opacity)); +} + +.tw-preflight :is(.tw-border-gray-300) { + --tw-border-opacity: 1; + border-color: rgb(209 213 219 / var(--tw-border-opacity)); +} + +.tw-preflight :is(.tw-border-b-black) { + --tw-border-opacity: 1; + border-bottom-color: rgb(0 0 0 / var(--tw-border-opacity)); +} + +.tw-preflight :is(.tw-border-t-transparent) { + border-top-color: transparent; +} + +.tw-preflight :is(.tw-border-opacity-20) { + --tw-border-opacity: 0.2; +} + +.tw-preflight :is(.tw-bg-\[\#0097A7\]) { + --tw-bg-opacity: 1; + background-color: rgb(0 151 167 / var(--tw-bg-opacity)); +} + +.tw-preflight :is(.tw-bg-\[\#2196f3\]) { + --tw-bg-opacity: 1; + background-color: rgb(33 150 243 / var(--tw-bg-opacity)); +} + +.tw-preflight :is(.tw-bg-\[\#757575\]\/60) { + background-color: rgb(117 117 117 / 0.6); +} + +.tw-preflight :is(.tw-bg-blue-500) { + --tw-bg-opacity: 1; + background-color: rgb(59 130 246 / var(--tw-bg-opacity)); +} + +.tw-preflight :is(.tw-bg-gray-100) { + --tw-bg-opacity: 1; + background-color: rgb(243 244 246 / var(--tw-bg-opacity)); +} + +.tw-preflight :is(.tw-bg-gray-900) { + --tw-bg-opacity: 1; + background-color: rgb(17 24 39 / var(--tw-bg-opacity)); +} + +.tw-preflight :is(.tw-bg-green-500) { + --tw-bg-opacity: 1; + background-color: rgb(34 197 94 / var(--tw-bg-opacity)); +} + +.tw-preflight :is(.tw-bg-transparent) { + background-color: transparent; +} + +.tw-preflight :is(.tw-bg-white) { + --tw-bg-opacity: 1; + background-color: rgb(255 255 255 / var(--tw-bg-opacity)); +} + +.tw-preflight :is(.tw-p-2) { + padding: 0.5rem; +} + +.tw-preflight :is(.tw-p-4) { + padding: 1rem; +} + +.tw-preflight :is(.tw-px-2) { + padding-left: 0.5rem; + padding-right: 0.5rem; +} + +.tw-preflight :is(.tw-px-4) { + padding-left: 1rem; + padding-right: 1rem; +} + +.tw-preflight :is(.tw-px-\[8px\]) { + padding-left: 8px; + padding-right: 8px; +} + +.tw-preflight :is(.tw-py-1) { + padding-top: 0.25rem; + padding-bottom: 0.25rem; +} + +.tw-preflight :is(.tw-py-2) { + padding-top: 0.5rem; + padding-bottom: 0.5rem; +} + +.tw-preflight :is(.tw-py-3) { + padding-top: 0.75rem; + padding-bottom: 0.75rem; +} + +.tw-preflight :is(.tw-py-4) { + padding-top: 1rem; + padding-bottom: 1rem; +} + +.tw-preflight :is(.tw-py-\[2px\]) { + padding-top: 2px; + padding-bottom: 2px; +} + +.tw-preflight :is(.tw-pl-\[10px\]) { + padding-left: 10px; +} + +.tw-preflight :is(.tw-pr-2) { + padding-right: 0.5rem; +} + +.tw-preflight :is(.tw-pr-\[10px\]) { + padding-right: 10px; +} + +.tw-preflight :is(.tw-ps-2) { + padding-inline-start: 0.5rem; +} + +.tw-preflight :is(.tw-pt-\[25px\]) { + padding-top: 25px; +} + +.tw-preflight :is(.tw-text-left) { + text-align: left; +} + +.tw-preflight :is(.tw-text-center) { + text-align: center; +} + +.tw-preflight :is(.tw-text-right) { + text-align: right; +} + +.tw-preflight :is(.tw-font-roboto) { + font-family: Roboto, sans-serif; +} + +.tw-preflight :is(.tw-text-2xl) { + font-size: 1.5rem; + line-height: 2rem; +} + +.tw-preflight :is(.tw-text-sm) { + font-size: 0.875rem; + line-height: 1.25rem; +} + +.tw-preflight :is(.tw-text-xs) { + font-size: 0.75rem; + line-height: 1rem; +} + +.tw-preflight :is(.tw-font-bold) { + font-weight: 700; +} + +.tw-preflight :is(.tw-font-light) { + font-weight: 300; +} + +.tw-preflight :is(.tw-font-medium) { + font-weight: 500; +} + +.tw-preflight :is(.tw-ordinal) { + --tw-ordinal: ordinal; + font-variant-numeric: var(--tw-ordinal) var(--tw-slashed-zero) var(--tw-numeric-figure) var(--tw-numeric-spacing) var(--tw-numeric-fraction); +} + +.tw-preflight :is(.tw-text-\[\#1e1e1e\]) { + --tw-text-opacity: 1; + color: rgb(30 30 30 / var(--tw-text-opacity)); +} + +.tw-preflight :is(.tw-text-\[\#BDBDBD\]) { + --tw-text-opacity: 1; + color: rgb(189 189 189 / var(--tw-text-opacity)); +} + +.tw-preflight :is(.tw-text-\[\#FAFAFA\]) { + --tw-text-opacity: 1; + color: rgb(250 250 250 / var(--tw-text-opacity)); +} + +.tw-preflight :is(.tw-text-black) { + --tw-text-opacity: 1; + color: rgb(0 0 0 / var(--tw-text-opacity)); +} + +.tw-preflight :is(.tw-text-blue-50) { + --tw-text-opacity: 1; + color: rgb(239 246 255 / var(--tw-text-opacity)); +} + +.tw-preflight :is(.tw-text-blue-600) { + --tw-text-opacity: 1; + color: rgb(37 99 235 / var(--tw-text-opacity)); +} + +.tw-preflight :is(.tw-text-cyan-50) { + --tw-text-opacity: 1; + color: rgb(236 254 255 / var(--tw-text-opacity)); +} + +.tw-preflight :is(.tw-text-gray-400) { + --tw-text-opacity: 1; + color: rgb(156 163 175 / var(--tw-text-opacity)); +} + +.tw-preflight :is(.tw-text-gray-900) { + --tw-text-opacity: 1; + color: rgb(17 24 39 / var(--tw-text-opacity)); +} + +.tw-preflight :is(.tw-text-red-500) { + --tw-text-opacity: 1; + color: rgb(239 68 68 / var(--tw-text-opacity)); +} + +.tw-preflight :is(.tw-text-white) { + --tw-text-opacity: 1; + color: rgb(255 255 255 / var(--tw-text-opacity)); +} + +.tw-preflight :is(.tw-underline) { + text-decoration-line: underline; +} + +.tw-preflight :is(.tw-opacity-100) { + opacity: 1; +} + +.tw-preflight :is(.tw-opacity-50) { + opacity: 0.5; +} + +.tw-preflight :is(.tw-shadow-2xl) { + --tw-shadow: 0 25px 50px -12px rgb(0 0 0 / 0.25); + --tw-shadow-colored: 0 25px 50px -12px var(--tw-shadow-color); + box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); +} + +.tw-preflight :is(.tw-duration-200) { + transition-duration: 200ms; +} + +.tw-preflight :is(.tw-pointer-events-none) { + pointer-events: none; +} + +.tw-preflight :is(.tw-pointer-events-auto) { + pointer-events: auto; +} + +.tw-preflight :is(.tw-absolute) { + position: absolute; +} + +.tw-preflight :is(.tw-relative) { + position: relative; +} + +.tw-preflight :is(.tw-left-10) { + left: 2.5rem; +} + +.tw-preflight :is(.tw-right-0) { + right: 0px; +} + .tw-preflight :is(.tw-top-1\/2) { top: 50%; } @@ -1277,3 +1913,124 @@ th { --tw-bg-opacity: 1; background-color: rgb(53 53 53 / var(--tw-bg-opacity)); } + +.tw-preflight :is(.hover\:tw-cursor-pointer:hover) { + cursor: pointer; +} + +.tw-preflight :is(.hover\:tw-bg-\[\#757575\]:hover) { + --tw-bg-opacity: 1; + background-color: rgb(117 117 117 / var(--tw-bg-opacity)); +} + +.tw-preflight :is(.hover\:tw-bg-\[\#e5e4e2\]:hover) { + --tw-bg-opacity: 1; + background-color: rgb(229 228 226 / var(--tw-bg-opacity)); +} + +.tw-preflight :is(.hover\:tw-bg-blue-700:hover) { + --tw-bg-opacity: 1; + background-color: rgb(29 78 216 / var(--tw-bg-opacity)); +} + +.tw-preflight :is(.hover\:tw-bg-gray-200:hover) { + --tw-bg-opacity: 1; + background-color: rgb(229 231 235 / var(--tw-bg-opacity)); +} + +.tw-preflight :is(.hover\:tw-bg-green-600:hover) { + --tw-bg-opacity: 1; + background-color: rgb(22 163 74 / var(--tw-bg-opacity)); +} + +.tw-preflight :is(.hover\:tw-bg-green-700:hover) { + --tw-bg-opacity: 1; + background-color: rgb(21 128 61 / var(--tw-bg-opacity)); +} + +.tw-preflight :is(.hover\:tw-text-gray-600:hover) { + --tw-text-opacity: 1; + color: rgb(75 85 99 / var(--tw-text-opacity)); +} + +.tw-preflight :is(.disabled\:tw-bg-transparent:disabled) { + background-color: transparent; +} + +.tw-preflight :is(.disabled\:tw-opacity-50:disabled) { + opacity: 0.5; +} + +.tw-preflight :is(.disabled\:tw-outline:disabled) { + outline-style: solid; +} + +.tw-preflight :is(.tw-group:hover .group-hover\:tw-block) { + display: block; +} + +.tw-preflight :is(.tw-group:hover .group-hover\:tw-flex) { + display: flex; +} + +.tw-preflight :is(.tw-group:hover .group-hover\:tw-flex-col) { + flex-direction: column; +} + +.tw-preflight :is(:is(.tw-dark .dark\:tw-divide-\[\#404040\]) > :not([hidden]) ~ :not([hidden])) { + --tw-divide-opacity: 1; + border-color: rgb(64 64 64 / var(--tw-divide-opacity)); +} + +.tw-preflight :is(.tw-dark .dark\:tw-border-\[\#404040\]) { + --tw-border-opacity: 1; + border-color: rgb(64 64 64 / var(--tw-border-opacity)); +} + +.tw-preflight :is(.tw-dark .dark\:tw-border-white) { + --tw-border-opacity: 1; + border-color: rgb(255 255 255 / var(--tw-border-opacity)); +} + +.tw-preflight :is(.tw-dark .dark\:tw-border-opacity-20) { + --tw-border-opacity: 0.2; +} + +.tw-preflight :is(.tw-dark .dark\:tw-bg-\[\#1e1e1e\]) { + --tw-bg-opacity: 1; + background-color: rgb(30 30 30 / var(--tw-bg-opacity)); +} + +.tw-preflight :is(.tw-dark .dark\:tw-bg-\[\#252525\]) { + --tw-bg-opacity: 1; + background-color: rgb(37 37 37 / var(--tw-bg-opacity)); +} + +.tw-preflight :is(.tw-dark .dark\:tw-bg-\[\#757575\]\/60) { + background-color: rgb(117 117 117 / 0.6); +} + +.tw-preflight :is(.tw-dark .dark\:tw-bg-green-700) { + --tw-bg-opacity: 1; + background-color: rgb(21 128 61 / var(--tw-bg-opacity)); +} + +.tw-preflight :is(.tw-dark .dark\:tw-text-\[\#FAFAFA\]) { + --tw-text-opacity: 1; + color: rgb(250 250 250 / var(--tw-text-opacity)); +} + +.tw-preflight :is(.tw-dark .dark\:tw-text-white) { + --tw-text-opacity: 1; + color: rgb(255 255 255 / var(--tw-text-opacity)); +} + +.tw-preflight :is(.tw-dark .dark\:hover\:tw-bg-\[\#353535\]:hover) { + --tw-bg-opacity: 1; + background-color: rgb(53 53 53 / var(--tw-bg-opacity)); +} + +.tw-preflight :is(.tw-dark .dark\:hover\:tw-bg-\[\#3b3939\]:hover) { + --tw-bg-opacity: 1; + background-color: rgb(59 57 57 / var(--tw-bg-opacity)); +} diff --git a/lightcurve/src/magstats_api/static/magstats.js b/lightcurve/src/magstats_api/static/magstats.js index 7f91b59b5..ecc72ba76 100644 --- a/lightcurve/src/magstats_api/static/magstats.js +++ b/lightcurve/src/magstats_api/static/magstats.js @@ -30,7 +30,7 @@ export function initMagstats() { boolColumns = 0; rowsToShow = 5; - const rawDb = JSON.parse(document.getElementById("magstats-data").text); + let rawDb = JSON.parse(document.getElementById("magstats-data").text); db = []; parseStatR(rawDb); @@ -38,10 +38,6 @@ export function initMagstats() { numColumns = db.length + 1; // Esto es numero de bandas + 1 numRows = Object.keys(db[0]).length; - for (let i = 0; i < db.length; i++) { - numBands.push(db[i]["fid"]); - delete db[i]["fid"]; - } for (let i = 0; i < numBands.length; i++) { realBands.push(bandMapping[numBands[i]]); @@ -116,21 +112,22 @@ function parseStatR(dict) { Object.keys(dict).forEach((key) => { let auxJson = {}; auxJson = { - stellar: dict[key]["stellar"], - corrected: dict[key]["corrected"], - ndet: dict[key]["ndet"], - ndubious: dict[key]["ndubious"], - magmean: dict[key]["magmean"], - magmedian: dict[key]["magmedian"], - magmax: dict[key]["magmax"], - magmin: dict[key]["magmin"], - magsigma: dict[key]["magsigma"], - maglast: dict[key]["maglast"], - magfirst: dict[key]["magfirst"], - firstmjd: dict[key]["firstmjd"], - lastmjd: dict[key]["lastmjd"], - step_id_corr: dict[key]["step_id_corr"], + stellar: dict[key]["stellar"] != null ? dict[key]["stellar"] : "-", + corrected: dict[key]["corrected"] != null ? dict[key]["corrected"] : "-", + ndet: dict[key]["ndet"] != null ? dict[key]["ndet"]: "-", + ndubious: dict[key]["ndubious"] != null ? dict[key]["ndubious"] : "-", + magmean: dict[key]["magmean"] != null ? dict[key]["magmean"].toFixed(3) : "-" , + magmedian: dict[key]["magmedian"] != null ? dict[key]["magmedian"].toFixed(3) : "-", + magmax: dict[key]["magmax"] != null ? dict[key]["magmax"].toFixed(3) : "-" , + magmin: dict[key]["magmin"] != null ? dict[key]["magmin"].toFixed(3) : "-" , + magsigma: dict[key]["magsigma"] != null ? dict[key]["magsigma"].toFixed(3) : "-" , + maglast: dict[key]["maglast"] != null ? dict[key]["maglast"].toFixed(3) : "-" , + magfirst: dict[key]["magfirst"] != null ? dict[key]["magfirst"].toFixed(3) : "-" , + firstmjd: dict[key]["firstmjd"] != null ? dict[key]["firstmjd"].toFixed(3) : "-" , + lastmjd: dict[key]["lastmjd"] != null ? dict[key]["lastmjd"].toFixed(3) : "-" , + step_id_corr: dict[key]["step_id_corr"] != null ? dict[key]["step_id_corr"] : "-", }; + numBands.push(dict[key]["fid"]); db.push(auxJson); }); } @@ -148,7 +145,7 @@ function createTable() { // Create the table element const table = document.createElement("table"); table.classList = - "tw-overflow-auto tw-w-full tw-text-sm"; + "tw-overflow-auto tw-w-full tw-text-sm tw-font-roboto "; // Create the table header row const headerRow = document.createElement("tr"); @@ -173,7 +170,7 @@ function createTable() { for (let i = 0; i < numRows; i++) { const dataRow = document.createElement("tr"); dataRow.classList = - "tw-w-full tw-preflight hover:tw-bg-[#757575] dark:tw-text-white tw-text-black tw-border-b-[1px] tw-border-b-solid tw-border-b-black dark:tw-border-b-white tw-border-opacity-20 dark:tw-border-opacity-20"; + "tw-w-full hover:tw-bg-[#757575] dark:tw-text-white tw-text-black tw-border-b-[1px] tw-border-b-solid tw-border-b-black dark:tw-border-b-white tw-border-opacity-20 dark:tw-border-opacity-20"; for (let j = 0; j < numColumns; j++) { const td = document.createElement("td"); diff --git a/lightcurve/src/magstats_api/templates/magstatRebuild.html.jinja b/lightcurve/src/magstats_api/templates/magstatRebuild.html.jinja index b69b155c5..9470c6cb4 100644 --- a/lightcurve/src/magstats_api/templates/magstatRebuild.html.jinja +++ b/lightcurve/src/magstats_api/templates/magstatRebuild.html.jinja @@ -3,14 +3,14 @@ - +
-
+
-

Magnitude Statistics

+

Magnitude Statistics

diff --git a/lightcurve/src/magstats_api/templates/magstats.css b/lightcurve/src/magstats_api/templates/magstats.css index 2ace5646e..1c1387882 100644 --- a/lightcurve/src/magstats_api/templates/magstats.css +++ b/lightcurve/src/magstats_api/templates/magstats.css @@ -1,3 +1,9 @@ +@tailwind components; +@tailwind utilities; + + +@import url('https://fonts.googleapis.com/css2?family=Roboto:ital,wght@0,100;0,300;0,400;0,500;0,700;0,900;1,100;1,300;1,400;1,500;1,700;1,900&display=swap'); + .tw-preflight :is(.tw-pointer-events-none) { pointer-events: none; } diff --git a/lightcurve/src/object_api/routes/htmx.py b/lightcurve/src/object_api/routes/htmx.py index f1c32d89d..7bae4bfcc 100644 --- a/lightcurve/src/object_api/routes/htmx.py +++ b/lightcurve/src/object_api/routes/htmx.py @@ -5,7 +5,6 @@ from fastapi import APIRouter, HTTPException, Request from fastapi.responses import HTMLResponse from fastapi.templating import Jinja2Templates - from core.exceptions import ObjectNotFound from core.services.object import ( get_count_ndet, @@ -21,34 +20,48 @@ "API_URL", "http://localhost:8001" ) +def add_tns_link(data): + + if data["object_name"] != '-': + return 'https://www.wis-tns.org/object/' + data["object_name"] + else: + return 'https://www.wis-tns.org/' -def last_information(data): - informationDict = { - "typeInput": "", - "name": "", - "redshift": "", - "tnsLink": "https://www.wis-tns.org/" - } +def check_data(data): - if data == True: - informationDict["typeInput"] = "-" - informationDict["name"] = "-" - informationDict["redshift"] = "-" - elif isinstance(data, dict) and data: - if len(data["object_data"]) > 25: - informationDict["typeInput"] = data["object_type"] - informationDict["name"] = data["object_name"] - informationDict["redshift"] = data["object_data"]["redshift"] - else: - informationDict["typeInput"] = "-" - informationDict["name"] = "-" - informationDict["redshift"] = "-" + if "object_data" in data and len(data["object_data"]) > 25: + if data["object_data"]["redshift"] == None: + data["object_data"]["redshift"] = '-' else: - informationDict["typeInput"] = "Unexpected response" - informationDict["name"] = "Unexpected response" - informationDict["redshift"] = "Unexpected response" - - return informationDict + raise ValueError("Data does not meet the required condition") + + if "object_name" in data: + if data["object_name"] == None: + data["object_name"] = '-' + else: + raise ValueError("Data does not meet the required condition") + + if "object_type" in data: + if data["object_type"] == None: + data["object_type"] = '-' + else: + raise ValueError("Data does not meet the required condition") + + return data + +def error_data(): + tns_data = { + "object_data": { + "discoverer": "-", + "discovery_data_source": { "group_name": "-"}, + "redshift": "-", + }, + "object_name": "-", + "object_type": "-" + } + tns_link = 'https://www.wis-tns.org/' + + return tns_data, tns_link def get_tns(ra, dec): @@ -63,24 +76,23 @@ def get_tns(ra, dec): response = requests.post("https://tns.alerce.online/search", data=payload_dump, headers=headersSend) - text = response.text - - if "Error message" in text: - raise requests.exceptions.RequestException("Error found in response: " + text) - - try: - data = response.json() - except ValueError: - raise requests.exceptions.RequestException("Error found in response: " + text) + data = response.json() - tns_data = last_information(data) + check_data(data) + tns_link = add_tns_link(data) - return tns_data + return data, tns_link except requests.exceptions.RequestException as error: - tns_data = last_information(True) + print(f"Error: {error}") + tns = error_data() + return tns + + except ValueError as e: + print(f"Error: {e}") - return tns_data + tns = error_data() + return tns @router.get("/object/{oid}", response_class=HTMLResponse) async def object_info_app(request: Request, oid: str): @@ -88,6 +100,9 @@ async def object_info_app(request: Request, oid: str): object_data = get_object(oid, request.app.state.psql_session) candid = get_first_det_candid(oid, request.app.state.psql_session) count_ndet = get_count_ndet(oid, request.app.state.psql_session) + + other_archives = ['DESI Legacy Survey DR10', 'NED', 'PanSTARRS', 'SDSS DR18', 'SIMBAD', 'TNS', 'Vizier', 'VSX'] + except ObjectNotFound: raise HTTPException(status_code=404, detail="Object ID not found") @@ -105,18 +120,29 @@ async def object_info_app(request: Request, oid: str): "lastDetectionMJD": object_data.lastmjd, "ra": object_data.meanra, "dec": object_data.meandec, - "candid": candid, + "candid": str(candid), + "otherArchives": other_archives, }, ) @router.get("/tns/", response_class=HTMLResponse) async def tns_info(request: Request, ra: float, dec:float): try: - tns_data = get_tns(ra, dec) + tns_data, tns_link = get_tns(ra, dec) + except ObjectNotFound: raise HTTPException(status_code=404, detail="Object ID not found") return templates.TemplateResponse( name="tnsInformation.html.jinja", - context={"request": request}|tns_data - ) + context={ + "request": request, + "tns_data": tns_data, + "tns_link": tns_link, + "object_name": tns_data["object_name"], + "object_type": tns_data["object_type"], + "redshift": tns_data["object_data"]["redshift"], + "discoverer": tns_data["object_data"]["discoverer"], + "discovery_data_source": tns_data["object_data"]["discovery_data_source"] + } + ) \ No newline at end of file diff --git a/lightcurve/src/object_api/routes/rest.py b/lightcurve/src/object_api/routes/rest.py index 18a52c780..43a624957 100644 --- a/lightcurve/src/object_api/routes/rest.py +++ b/lightcurve/src/object_api/routes/rest.py @@ -10,27 +10,11 @@ directory="src/object_api/templates", autoescape=True, auto_reload=True ) +@router.get("/") +def root(): + return "this is the object module" -@router.get("/object/{oid}", response_class=HTMLResponse) -async def object_info_app(request: Request, oid: str): - link = "https://acortar.link/ba5kba" - try: - object_data = get_object( - oid, session_factory=request.app.state.psql_session - ) - except ObjectNotFound: - raise HTTPException(status_code=404, detail="Object ID not found") - - return { - "request": request, - "object": object_data.oid, - "corrected": object_data.corrected, - "stellar": object_data.stellar, - "detections": object_data.ndet, - "discoveryDateMJD": object_data.firstmjd, - "lastDetectionMJD": object_data.lastmjd, - "ra": object_data.meanra, - "dec": object_data.meandec, - "link": link, - } +@router.get("/healthcheck") +def healthcheck(): + return "OK" diff --git a/lightcurve/src/object_api/static/basicInformation.js b/lightcurve/src/object_api/static/basicInformation.js index 9697d8a4b..7b7be2912 100644 --- a/lightcurve/src/object_api/static/basicInformation.js +++ b/lightcurve/src/object_api/static/basicInformation.js @@ -117,19 +117,37 @@ export function transformRa(degrees, precision=3) { } export function setMenuUrl(ra, dec, candid, object, raTime, decTime) { + + let raNed = encodeCoordinates(raTime) + let decNed = encodeCoordinates(decTime) + const urlDict = { - "desi-button": `https://www.legacysurvey.org/viewer/jpeg-cutout/?ra=${ra}&dec=${dec}&layer=ls-dr10&pixscale=0.1&bands=grz`, - "ned-button": `https://ned.ipac.caltech.edu/conesearch?search_type=Near+Position+Search&iau_style=liberal&objname=&coordinates=${raTime}d,${decTime}d&iau_name=&radius=0.17&in_csys=Equatorial&in_equinox=J2000&in_csys_IAU=Equatorial&in_equinox_IAU=B1950&z_constraint=Unconstrained&z_value1=&z_value2=&z_unit=z&ot_include=ANY&nmp_op=ANY&hconst=67.8&omegam=0.308&omegav=0.692&wmap=4&corr_z=1&out_csys=Same+as+Input&out_equinox=Same+as+Input&obj_sort=Distance+to+search+center&op=Go&form_build_id=form-a28snc2SSIQl3faGUe4otq7_NcjnMwxxxPoVxw5LHzg&form_id=conesearch`, - "pan-button": `https://ps1images.stsci.edu/cgi-bin/ps1cutouts?pos=${ra}+${dec}&filter=color`, - "sdss-button": `https://skyserver.sdss.org/dr18/en/tools/chart/navi.aspx?ra=${ra}8&dec=${dec}`, - "simbad-button": `https://simbad.u-strasbg.fr/simbad/sim-coo?Coord=${ra}%20${dec}&Radius.unit=arcsec&Radius=10`, - "tns-button": `https://www.wis-tns.org/search?ra=${ra}&decl=${dec}&radius=10&coords_unit=arcsec`, - "viz-button": `https://vizier.cds.unistra.fr/viz-bin/VizieR-4?-c=${ra}+${dec}&-c.rs=10&-out.add=_r&-sort=_r&-out.max=$4`, - "vsx-button": `https://www.aavso.org/vsx/index.php?view=results.get&coords=${ra}+${dec}&format=d&size=10&geom=r&unit=3&order=9`, - "find-button": `https://findingchart.alerce.online/get_chart?oid=${object}&candid=${candid}`, + "DESI Legacy Survey DR10": `https://www.legacysurvey.org/viewer/jpeg-cutout/?ra=${ra}&dec=${dec}&layer=ls-dr10&pixscale=0.1&bands=grz`, + + "NED": `https://ned.ipac.caltech.edu/conesearch?search_type=Near%20Position%20Search&in_csys=Equatorial&in_equinox=J2000&ra=${raNed}&dec=${decNed}&radius=0.17`, + + "PanSTARRS": `https://ps1images.stsci.edu/cgi-bin/ps1cutouts?pos=${ra}+${dec}&filter=color`, + + "SDSS DR18": `https://skyserver.sdss.org/dr18/en/tools/chart/navi.aspx?ra=${ra}8&dec=${dec}`, + + "SIMBAD": `https://simbad.u-strasbg.fr/simbad/sim-coo?Coord=${ra}%20${dec}&Radius.unit=arcsec&Radius=10`, + + "TNS": `https://www.wis-tns.org/search?ra=${ra}&decl=${dec}&radius=10&coords_unit=arcsec`, + + "Vizier": `https://vizier.cds.unistra.fr/viz-bin/VizieR-4?-c=${ra}+${dec}&-c.rs=10&-out.add=_r&-sort=_r&-out.max=$4`, + + "VSX": `https://www.aavso.org/vsx/index.php?view=results.get&coords=${ra}+${dec}&format=d&size=10&geom=r&unit=3&order=9`, + + "find-button-object": `https://findingchart.alerce.online/get_chart?oid=${object}&candid=${candid}`, }; + for (let button in urlDict) { document.getElementById(button).href = urlDict[button]; } } + + +function encodeCoordinates(coordinate){ + return coordinate.replaceAll(":", "%3A") +} diff --git a/lightcurve/src/object_api/static/object.css b/lightcurve/src/object_api/static/object.css index c85c5137e..8d583250d 100644 --- a/lightcurve/src/object_api/static/object.css +++ b/lightcurve/src/object_api/static/object.css @@ -1,3 +1,15 @@ +.htmx-indicator { + opacity: 0; +} + +.htmx-request .htmx-indicator { + opacity: 1; +} + +.htmx-request.htmx-indicator { + opacity: 1; +} + .tw-preflight :is(.tw-pointer-events-none) { pointer-events: none; } @@ -14,10 +26,6 @@ position: relative; } -.tw-preflight :is(.tw-bottom-0) { - bottom: 0px; -} - .tw-preflight :is(.tw-left-10) { left: 2.5rem; } @@ -34,6 +42,14 @@ top: 50%; } +.tw-preflight :is(.tw-z-10) { + z-index: 10; +} + +.tw-preflight :is(.tw-z-\[10\]) { + z-index: 10; +} + .tw-preflight :is(.tw-z-\[9999\]) { z-index: 9999; } @@ -62,6 +78,11 @@ margin: auto; } +.tw-preflight :is(.tw-mx-0) { + margin-left: 0px; + margin-right: 0px; +} + .tw-preflight :is(.tw-mx-2) { margin-left: 0.5rem; margin-right: 0.5rem; @@ -72,15 +93,16 @@ margin-right: auto; } +.tw-preflight :is(.tw-my-1) { + margin-top: 0.25rem; + margin-bottom: 0.25rem; +} + .tw-preflight :is(.tw-my-4) { margin-top: 1rem; margin-bottom: 1rem; } -.tw-preflight :is(.tw-mb-\[20px\]) { - margin-bottom: 20px; -} - .tw-preflight :is(.tw-me-2) { margin-inline-end: 0.5rem; } @@ -89,10 +111,6 @@ margin-left: 0.5rem; } -.tw-preflight :is(.tw-ml-\[50\%\]) { - margin-left: 50%; -} - .tw-preflight :is(.tw-mt-2) { margin-top: 0.5rem; } @@ -101,24 +119,12 @@ margin-top: 0.75rem; } -.tw-preflight :is(.tw-mt-\[10px\]) { - margin-top: 10px; -} - -.tw-preflight :is(.tw-mt-\[30px\]) { - margin-top: 30px; -} - -.tw-preflight :is(.tw-mt-4) { - margin-top: 1rem; -} - -.tw-preflight :is(.tw-mr-4) { - margin-right: 1rem; +.tw-preflight :is(.tw-block) { + display: block; } -.tw-preflight :is(.tw-box-content) { - box-sizing: content-box; +.tw-preflight :is(.tw-inline-block) { + display: inline-block; } .tw-preflight :is(.tw-inline) { @@ -137,10 +143,6 @@ display: none; } -.tw-preflight :is(.tw-h-11) { - height: 2.75rem; -} - .tw-preflight :is(.tw-h-32) { height: 8rem; } @@ -153,36 +155,12 @@ height: 1.5rem; } -.tw-preflight :is(.tw-h-\[100\%\]) { - height: 100%; -} - -.tw-preflight :is(.tw-h-\[12\.5\%\]) { - height: 12.5%; -} - -.tw-preflight :is(.tw-h-\[500px\]) { - height: 500px; -} - -.tw-preflight :is(.tw-h-auto) { - height: auto; -} - -.tw-preflight :is(.tw-h-10) { - height: 2.5rem; -} - -.tw-preflight :is(.tw-h-9) { - height: 2.25rem; -} - .tw-preflight :is(.tw-h-8) { height: 2rem; } -.tw-preflight :is(.tw-h-1) { - height: 0.25rem; +.tw-preflight :is(.tw-h-auto) { + height: auto; } .tw-preflight :is(.tw-w-1\/3) { @@ -205,22 +183,22 @@ width: 1.25rem; } -.tw-preflight :is(.tw-w-52) { - width: 13rem; -} - .tw-preflight :is(.tw-w-6) { width: 1.5rem; } -.tw-preflight :is(.tw-w-\[100\%\]) { - width: 100%; +.tw-preflight :is(.tw-w-80) { + width: 20rem; } .tw-preflight :is(.tw-w-\[400px\]) { width: 400px; } +.tw-preflight :is(.tw-w-\[50\%\]) { + width: 50%; +} + .tw-preflight :is(.tw-w-\[95\%\]) { width: 95%; } @@ -239,22 +217,26 @@ .tw-preflight :is(.-tw-translate-y-1) { --tw-translate-y: -0.25rem; - transform: translate(var(--tw-translate-x), var(--tw-translate-y)) - rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) - scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); + transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); } .tw-preflight :is(.-tw-translate-y-1\/2) { --tw-translate-y: -50%; - transform: translate(var(--tw-translate-x), var(--tw-translate-y)) - rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) - scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); + transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); } .tw-preflight :is(.tw-transform) { - transform: translate(var(--tw-translate-x), var(--tw-translate-y)) - rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) - scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); + transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); +} + +@keyframes tw-pulse { + 50% { + opacity: .5; + } +} + +.tw-preflight :is(.tw-animate-pulse) { + animation: tw-pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite; } @keyframes tw-spin { @@ -273,8 +255,8 @@ .tw-preflight :is(.tw-appearance-none) { -webkit-appearance: none; - -moz-appearance: none; - appearance: none; + -moz-appearance: none; + appearance: none; } .tw-preflight :is(.tw-grid-cols-10) { @@ -297,18 +279,10 @@ place-items: center; } -.tw-preflight :is(.tw-content-end) { - align-content: flex-end; -} - .tw-preflight :is(.tw-items-center) { align-items: center; } -.tw-preflight :is(.tw-justify-end) { - justify-content: flex-end; -} - .tw-preflight :is(.tw-justify-center) { justify-content: center; } @@ -354,14 +328,6 @@ place-self: center; } -.tw-preflight :is(.tw-self-end) { - align-self: flex-end; -} - -.tw-preflight :is(.tw-self-center) { - align-self: center; -} - .tw-preflight :is(.tw-overflow-auto) { overflow: auto; } @@ -380,10 +346,6 @@ border-radius: 0.25rem; } -.tw-preflight :is(.tw-rounded-\[50px\]) { - border-radius: 50px; -} - .tw-preflight :is(.tw-rounded-\[6px\]) { border-radius: 6px; } @@ -396,22 +358,6 @@ border-radius: 0.375rem; } -.tw-preflight :is(.tw-rounded-bl-\[10px\]) { - border-bottom-left-radius: 10px; -} - -.tw-preflight :is(.tw-rounded-br-\[10px\]) { - border-bottom-right-radius: 10px; -} - -.tw-preflight :is(.tw-rounded-tl-\[10px\]) { - border-top-left-radius: 10px; -} - -.tw-preflight :is(.tw-rounded-tr-\[10px\]) { - border-top-right-radius: 10px; -} - .tw-preflight :is(.tw-border) { border-width: 1px; } @@ -464,23 +410,23 @@ --tw-border-opacity: 0.2; } -.tw-preflight :is(.tw-bg-\[\#757575\]\/60) { - background-color: rgb(117 117 117 / 0.6); +.tw-preflight :is(.tw-bg-\[\#0097A7\]) { + --tw-bg-opacity: 1; + background-color: rgb(0 151 167 / var(--tw-bg-opacity)); } -.tw-preflight :is(.tw-bg-blue-500) { +.tw-preflight :is(.tw-bg-\[\#2196f3\]) { --tw-bg-opacity: 1; - background-color: rgb(59 130 246 / var(--tw-bg-opacity)); + background-color: rgb(33 150 243 / var(--tw-bg-opacity)); } -.tw-preflight :is(.tw-bg-blue-700) { - --tw-bg-opacity: 1; - background-color: rgb(29 78 216 / var(--tw-bg-opacity)); +.tw-preflight :is(.tw-bg-\[\#757575\]\/60) { + background-color: rgb(117 117 117 / 0.6); } -.tw-preflight :is(.tw-bg-cyan-700) { +.tw-preflight :is(.tw-bg-blue-500) { --tw-bg-opacity: 1; - background-color: rgb(14 116 144 / var(--tw-bg-opacity)); + background-color: rgb(59 130 246 / var(--tw-bg-opacity)); } .tw-preflight :is(.tw-bg-gray-100) { @@ -511,6 +457,10 @@ padding: 0.5rem; } +.tw-preflight :is(.tw-p-4) { + padding: 1rem; +} + .tw-preflight :is(.tw-px-2) { padding-left: 0.5rem; padding-right: 0.5rem; @@ -521,6 +471,11 @@ padding-right: 1rem; } +.tw-preflight :is(.tw-px-\[8px\]) { + padding-left: 8px; + padding-right: 8px; +} + .tw-preflight :is(.tw-py-1) { padding-top: 0.25rem; padding-bottom: 0.25rem; @@ -531,17 +486,23 @@ padding-bottom: 0.5rem; } +.tw-preflight :is(.tw-py-3) { + padding-top: 0.75rem; + padding-bottom: 0.75rem; +} + .tw-preflight :is(.tw-py-4) { padding-top: 1rem; padding-bottom: 1rem; } -.tw-preflight :is(.tw-pl-\[10px\]) { - padding-left: 10px; +.tw-preflight :is(.tw-py-\[2px\]) { + padding-top: 2px; + padding-bottom: 2px; } -.tw-preflight :is(.tw-pl-\[5px\]) { - padding-left: 5px; +.tw-preflight :is(.tw-pl-\[10px\]) { + padding-left: 10px; } .tw-preflight :is(.tw-pr-2) { @@ -560,10 +521,6 @@ padding-top: 25px; } -.tw-preflight :is(.tw-pt-\[30px\]) { - padding-top: 30px; -} - .tw-preflight :is(.tw-text-left) { text-align: left; } @@ -576,20 +533,15 @@ text-align: right; } +.tw-preflight :is(.tw-font-roboto) { + font-family: Roboto, sans-serif; +} + .tw-preflight :is(.tw-text-2xl) { font-size: 1.5rem; line-height: 2rem; } -.tw-preflight :is(.tw-text-\[17px\]) { - font-size: 17px; -} - -.tw-preflight :is(.tw-text-lg) { - font-size: 1.125rem; - line-height: 1.75rem; -} - .tw-preflight :is(.tw-text-sm) { font-size: 0.875rem; line-height: 1.25rem; @@ -604,11 +556,17 @@ font-weight: 700; } +.tw-preflight :is(.tw-font-light) { + font-weight: 300; +} + +.tw-preflight :is(.tw-font-medium) { + font-weight: 500; +} + .tw-preflight :is(.tw-ordinal) { --tw-ordinal: ordinal; - font-variant-numeric: var(--tw-ordinal) var(--tw-slashed-zero) - var(--tw-numeric-figure) var(--tw-numeric-spacing) - var(--tw-numeric-fraction); + font-variant-numeric: var(--tw-ordinal) var(--tw-slashed-zero) var(--tw-numeric-figure) var(--tw-numeric-spacing) var(--tw-numeric-fraction); } .tw-preflight :is(.tw-text-\[\#1e1e1e\]) { @@ -616,6 +574,11 @@ color: rgb(30 30 30 / var(--tw-text-opacity)); } +.tw-preflight :is(.tw-text-\[\#BDBDBD\]) { + --tw-text-opacity: 1; + color: rgb(189 189 189 / var(--tw-text-opacity)); +} + .tw-preflight :is(.tw-text-\[\#FAFAFA\]) { --tw-text-opacity: 1; color: rgb(250 250 250 / var(--tw-text-opacity)); @@ -626,11 +589,21 @@ color: rgb(0 0 0 / var(--tw-text-opacity)); } +.tw-preflight :is(.tw-text-blue-50) { + --tw-text-opacity: 1; + color: rgb(239 246 255 / var(--tw-text-opacity)); +} + .tw-preflight :is(.tw-text-blue-600) { --tw-text-opacity: 1; color: rgb(37 99 235 / var(--tw-text-opacity)); } +.tw-preflight :is(.tw-text-cyan-50) { + --tw-text-opacity: 1; + color: rgb(236 254 255 / var(--tw-text-opacity)); +} + .tw-preflight :is(.tw-text-gray-400) { --tw-text-opacity: 1; color: rgb(156 163 175 / var(--tw-text-opacity)); @@ -666,14 +639,17 @@ .tw-preflight :is(.tw-shadow-2xl) { --tw-shadow: 0 25px 50px -12px rgb(0 0 0 / 0.25); --tw-shadow-colored: 0 25px 50px -12px var(--tw-shadow-color); - box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), - var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); + box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); } .tw-preflight :is(.tw-duration-200) { transition-duration: 200ms; } +/* roboto font */ + +/*loader*/ + .disabled\:bg-transparent { background-color: transparent; } @@ -1103,8 +1079,7 @@ Prevent resizing textareas horizontally by default. /* 2 */ } -.tw-preflight input::-moz-placeholder, -.tw-preflight textarea::-moz-placeholder { +.tw-preflight input::-moz-placeholder, .tw-preflight textarea::-moz-placeholder { opacity: 1; /* 1 */ color: #9ca3af; @@ -1325,10 +1300,6 @@ Constrain images and videos to the parent width and preserve their intrinsic asp color: rgb(75 85 99 / var(--tw-text-opacity)); } -.tw-preflight :is(.hover\:tw-opacity-70:hover) { - opacity: 0.7; -} - .tw-preflight :is(.disabled\:tw-bg-transparent:disabled) { background-color: transparent; } @@ -1341,20 +1312,19 @@ Constrain images and videos to the parent width and preserve their intrinsic asp outline-style: solid; } +.tw-preflight :is(.tw-group:hover .group-hover\:tw-block) { + display: block; +} + .tw-preflight :is(.tw-group:hover .group-hover\:tw-flex) { display: flex; } -.tw-preflight :is(.tw-group:hover .group-hover\:tw-opacity-60) { - opacity: 0.6; +.tw-preflight :is(.tw-group:hover .group-hover\:tw-flex-col) { + flex-direction: column; } -.tw-preflight - :is( - :is(.tw-dark .dark\:tw-divide-\[\#404040\]) - > :not([hidden]) - ~ :not([hidden]) - ) { +.tw-preflight :is(:is(.tw-dark .dark\:tw-divide-\[\#404040\]) > :not([hidden]) ~ :not([hidden])) { --tw-divide-opacity: 1; border-color: rgb(64 64 64 / var(--tw-divide-opacity)); } @@ -1369,11 +1339,6 @@ Constrain images and videos to the parent width and preserve their intrinsic asp border-color: rgb(255 255 255 / var(--tw-border-opacity)); } -.tw-preflight :is(.tw-dark .dark\:tw-border-b-white) { - --tw-border-opacity: 1; - border-bottom-color: rgb(255 255 255 / var(--tw-border-opacity)); -} - .tw-preflight :is(.tw-dark .dark\:tw-border-opacity-20) { --tw-border-opacity: 0.2; } diff --git a/lightcurve/src/object_api/static/object.js b/lightcurve/src/object_api/static/object.js index 37b2fec9b..f4a3c2170 100644 --- a/lightcurve/src/object_api/static/object.js +++ b/lightcurve/src/object_api/static/object.js @@ -14,15 +14,15 @@ const FIXED_PRECISION = 7; export function init() { - const objectInfo = JSON.parse(document.getElementById("object-data").text); + let objectInfo = JSON.parse(document.getElementById("object-data").text); - const object = objectInfo.object; - const corrected = objectInfo.corrected; - const stellar = objectInfo.stellar; - const detections = objectInfo.detections; + let object = objectInfo.object; + let corrected = objectInfo.corrected; + let stellar = objectInfo.stellar; + let detections = objectInfo.detections; let discoveryDateMJD = objectInfo.discoveryDateMJD; let lastDetectionMJD = objectInfo.lastDetectionMJD; - const nonDetections = objectInfo.nonDetections; + let nonDetections = objectInfo.nonDetections; let ra = objectInfo.ra; let dec = objectInfo.dec; let candid = objectInfo.candid; @@ -57,9 +57,8 @@ export function init() { document.getElementById("changeRaDec").addEventListener("click", () => { changeRaDec(raDec, raDecTime); }); - document - .getElementById("menu-button") - .addEventListener("click", () => display_menu()); + document.getElementById("menu-button-object").addEventListener("click", () => display_menu()); + document.getElementById("menu-box-object").addEventListener("click", () => display_menu()); setMenuUrl(ra, dec, candid, object, raTime, decTime); } @@ -85,26 +84,21 @@ export function elementReady(selector) { }); } -// En vez de usar variables binarias, podemos preguntar si es que esta en block o none y cambiar por el contrario. -// Tambien, si se ocupa la variable binaria, declararla antes. -let click = 0; +let click = 0 function display_menu() { - if (click === 0) { - document.getElementById("menu-box").style.display = "block"; - click = 1; + let menu = document.getElementById("menu-box-object") + if(menu.classList.contains("tw-hidden")){ + menu.classList.remove("tw-hidden") } else { - document.getElementById("menu-box").style.display = "none"; - click = 0; + menu.classList.add("tw-hidden") } } function handleOutsideClick(event) { - let myClick = document.getElementById("menu-button"); + let myClick = document.getElementById("menu-button-object"); if (myClick && !myClick.contains(event.target)) { click = 1; display_menu(); } } - -document.addEventListener("click", handleOutsideClick); diff --git a/lightcurve/src/object_api/templates/basicInformationPreview.html.jinja b/lightcurve/src/object_api/templates/basicInformationPreview.html.jinja index 4e5cdb764..9aa6e5505 100644 --- a/lightcurve/src/object_api/templates/basicInformationPreview.html.jinja +++ b/lightcurve/src/object_api/templates/basicInformationPreview.html.jinja @@ -5,8 +5,8 @@ href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@24,400,0,0"> -
- +
+
@@ -139,93 +139,38 @@
-
- +
+ FINDING CHART - + + - -
- - - - - - - - - - - - - -
TypeNameRedshift
---
- +
+ + + + + + +
TypeNameRedshift
+
Loading...
diff --git a/lightcurve/src/object_api/templates/object.css b/lightcurve/src/object_api/templates/object.css index 7f8a1894f..dd8378229 100644 --- a/lightcurve/src/object_api/templates/object.css +++ b/lightcurve/src/object_api/templates/object.css @@ -1,6 +1,25 @@ @tailwind components; @tailwind utilities; +/* roboto font */ +@import url('https://fonts.googleapis.com/css2?family=Roboto:ital,wght@0,100;0,300;0,400;0,500;0,700;0,900;1,100;1,300;1,400;1,500;1,700;1,900&display=swap'); + +/*loader*/ + +@layer components{ + .htmx-indicator{ + @apply tw-opacity-0; + } + + .htmx-request .htmx-indicator{ + @apply tw-opacity-100; + } + + .htmx-request.htmx-indicator{ + @apply tw-opacity-100; + } +} + .disabled\:bg-transparent { background-color: transparent; } diff --git a/lightcurve/src/object_api/templates/tnsInformation.html.jinja b/lightcurve/src/object_api/templates/tnsInformation.html.jinja index 9a4d04278..d4fdd1d4c 100644 --- a/lightcurve/src/object_api/templates/tnsInformation.html.jinja +++ b/lightcurve/src/object_api/templates/tnsInformation.html.jinja @@ -2,25 +2,39 @@ href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@24,400,0,0"> +
- - - - - +
TypeNameRedshift
+ + + + - - + +
TypeNameRedshift
{{typeInput}}{{name}}{{object_type}}{{object_name}} {{redshift}}
-
-
-
- Provided by - TNS -
+
+
+ {% if "reporter" in tns_data["object_data"] and tns_data["object_data"]["reporter"] == "ALeRCE"%} +

Discovered by {{discovery_data_source["group_name"]}}

+ +
+ Reported by ALeRCE +
+ +

{{discoverer}}

+
+
+ {% endif %} +
+

+ Provided by + TNS +

+
diff --git a/lightcurve/src/probability_api/__init__.py b/lightcurve/src/probability_api/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/lightcurve/src/probability_api/api.py b/lightcurve/src/probability_api/api.py new file mode 100644 index 000000000..0023e1190 --- /dev/null +++ b/lightcurve/src/probability_api/api.py @@ -0,0 +1,35 @@ + +from fastapi import FastAPI +from fastapi.middleware.cors import CORSMiddleware +from fastapi.staticfiles import StaticFiles +from prometheus_fastapi_instrumentator import Instrumentator + +from .routes import htmx, rest +from database.mongo import connect as connect_mongo +from database.sql import connect as connect_sql, session_wrapper + +app = FastAPI(openapi_url="/v2/object/openapi.json") +app.state.mongo_db = None +psql_engine = connect_sql() +app.state.psql_session = session_wrapper(psql_engine) +instrumentator = Instrumentator().instrument(app).expose(app) + +app.add_middleware( + CORSMiddleware, + allow_origins=["*"], + allow_credentials=True, + allow_methods=["*"], + allow_headers=["*"], +) + + +app.include_router(rest.router) +app.include_router(prefix="/htmx", router=htmx.router) + +app.mount("/static", StaticFiles(directory="src/probability_api/static"), name="static") + + +@app.get("/openapi.json") +def custom_swagger_route(): + return app.openapi() + diff --git a/lightcurve/src/probability_api/filters.py b/lightcurve/src/probability_api/filters.py new file mode 100644 index 000000000..876a12da6 --- /dev/null +++ b/lightcurve/src/probability_api/filters.py @@ -0,0 +1,47 @@ +import re + + +def update_config_dict(config_dict): + config_dict["FILTERS_MAP"] = { + "filter_atlas_detections": filter_atlas_detection_non_detection, + "filter_atlas_non_detections": filter_atlas_detection_non_detection, + "filter_atlas_lightcurve": filter_atlas_lightcurve, + "filter_atlas_forced_photometry": filter_atlas_detection_non_detection, + } + + +def get_filters_map(): + return { + "filter_atlas_detections": filter_atlas_detection_non_detection, + "filter_atlas_non_detections": filter_atlas_detection_non_detection, + "filter_atlas_lightcurve": filter_atlas_lightcurve, + "filter_atlas_forced_photometry": filter_atlas_detection_non_detection, + } + + +def filter_atlas_detection_non_detection(lc_object): + pattern = re.compile("atlas*", re.IGNORECASE) + if pattern.match(lc_object["tid"]): + return False + return True + + +def filter_atlas_lightcurve(lc_object): + non_filtered_detections = [] + non_filtered_non_detections = [] + non_filtered_forced_photometry = [] + + for detection in lc_object["detections"]: + if filter_atlas_detection_non_detection(detection): + non_filtered_detections.append(detection) + for non_detecton in lc_object["non_detections"]: + if filter_atlas_detection_non_detection(non_detecton): + non_filtered_non_detections.append(non_detecton) + for forced_photometry in lc_object["forced_photometry"]: + if filter_atlas_detection_non_detection(forced_photometry): + non_filtered_forced_photometry.append(forced_photometry) + + lc_object["detections"] = non_filtered_detections + lc_object["non_detections"] = non_filtered_non_detections + lc_object["forced_photometry"] = non_filtered_forced_photometry + return True \ No newline at end of file diff --git a/lightcurve/src/probability_api/result_handler.py b/lightcurve/src/probability_api/result_handler.py new file mode 100644 index 000000000..8e873734c --- /dev/null +++ b/lightcurve/src/probability_api/result_handler.py @@ -0,0 +1,37 @@ +import traceback +import logging + +from fastapi import HTTPException + +from core.exceptions import ( + AtlasNonDetectionError, + DatabaseError, + ObjectNotFound, + SurveyIdError, +) + + +def handle_success(result): + return result + + +def _handle_client_error(err: BaseException, code=400): + raise HTTPException(status_code=code, detail=str(err)) + + +def _handle_server_error(err: BaseException): + if err.__traceback__: + traceback.print_exception(err) + logging.error(err) + raise HTTPException(status_code=500, detail=str(err)) + + +def handle_error(err: BaseException): + if isinstance(err, DatabaseError): + _handle_server_error(err) + if isinstance(err, SurveyIdError): + _handle_client_error(err) + if isinstance(err, AtlasNonDetectionError): + _handle_client_error(err) + if isinstance(err, ObjectNotFound): + _handle_client_error(err, code=404) \ No newline at end of file diff --git a/lightcurve/src/probability_api/routes/__init__.py b/lightcurve/src/probability_api/routes/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/lightcurve/src/probability_api/routes/htmx.py b/lightcurve/src/probability_api/routes/htmx.py new file mode 100644 index 000000000..5dd02baa7 --- /dev/null +++ b/lightcurve/src/probability_api/routes/htmx.py @@ -0,0 +1,118 @@ +import os +import pprint +from fastapi import FastAPI, Request, Query + +from core.services.object import get_probabilities,get_taxonomies +from fastapi import APIRouter, Request, HTTPException +from fastapi.templating import Jinja2Templates +from fastapi.responses import HTMLResponse, JSONResponse + +router = APIRouter() +templates = Jinja2Templates( + directory="src/probability_api/templates", autoescape=True, auto_reload=True +) +templates.env.globals["API_URL"] = os.getenv( + "API_URL", "http://localhost:8004" +) + + +def taxonomy_data(taxonomy_list): + """ + dict example: {classifier_name:{class_name:[],classifier_version:''}} + """ + + taxonomy_dict = {} + + for n in range(len(taxonomy_list)): + taxonomy_dict[taxonomy_list[n].classifier_name] = taxonomy_list[n].__dict__ + + return taxonomy_dict + + +def filter_data_by_higher_version(prob_dict): + + """ + Dictionary format: {'classifier_name': {'classifier_version: [{},{},{}]}} + """ + data_by_higher_version = {} + + for itemKey, itemValue in prob_dict.items(): + if len(itemValue) > 1 : + lastest_version = max(itemValue.keys()) + if itemKey not in data_by_higher_version: + data_by_higher_version[itemKey] = {lastest_version: itemValue[lastest_version]} + else: + if itemKey not in data_by_higher_version: + data_by_higher_version[itemKey] = itemValue + + return data_by_higher_version + + +def group_data_by_classifier_dict(prob_lis): + group_data_by_classifier = {} + + for item in prob_lis: + aux_dict = { + 'classifier_name': item.classifier_name, + 'classifier_version': item.classifier_version, + 'class_name': item.class_name, + 'probability': item.probability, + 'ranking': item.ranking, + } + classifier_name = item.classifier_name + classifier_version = item.classifier_version + + if item.classifier_name not in group_data_by_classifier: + group_data_by_classifier[classifier_name] = {} + + if classifier_version not in group_data_by_classifier[classifier_name]: + group_data_by_classifier[classifier_name][classifier_version]= [] + + group_data_by_classifier[classifier_name][classifier_version].append(aux_dict) + + return group_data_by_classifier + +def classifiers_options(group_prob_by_version): + class_dict = [] + priorities = { + 'lc_classifier': 0, + 'lc_classifier_top': 1, + 'stamp_classifier': 2, + 'LC_classifier_ATAT_forced_phot(beta)': 3, + 'LC_classifier_BHRF_forced_phot(beta)': 4, + } + + for key, value in priorities.items(): + if key in group_prob_by_version: + class_dict.append({ key : format_classifiers_name(key) }) + + return class_dict + +def format_classifiers_name(classifier_name): + return classifier_name.replace('_',' ').title() + + +@router.get("/probabilities/{oid}", response_class=HTMLResponse) +async def object_probability_app( + request: Request, + oid: str, +): + + prob_list = get_probabilities(oid,session_factory = request.app.state.psql_session) + taxonomy_list = get_taxonomies(session_factory = request.app.state.psql_session) + + taxonomy_dict = taxonomy_data(taxonomy_list) + + group_prob = group_data_by_classifier_dict(prob_list) + group_prob_by_version = filter_data_by_higher_version(group_prob) + + class_options = classifiers_options(group_prob_by_version) + + return templates.TemplateResponse( + name='prob.html.jinja', + context={'request': request, + 'taxonomy_dict': taxonomy_dict, + 'group_prob_dict': group_prob_by_version, + 'class_dict': class_options + }, + ) diff --git a/lightcurve/src/probability_api/routes/rest.py b/lightcurve/src/probability_api/routes/rest.py new file mode 100644 index 000000000..df5347a9f --- /dev/null +++ b/lightcurve/src/probability_api/routes/rest.py @@ -0,0 +1,26 @@ +import re +import os +from typing import Annotated +from fastapi import Query + +from fastapi import APIRouter +from fastapi.templating import Jinja2Templates +from ..result_handler import handle_error, handle_success + +router = APIRouter() +templates = Jinja2Templates( + directory="src/api/templates", autoescape=True, auto_reload=True +) +templates.env.globals["API_URL"] = os.getenv( + "API_URL", "http://localhost:8000" +) + +@router.get("/") +def root(): + return "this is the probability module" + + +@router.get("/healthcheck") +def healthcheck(): + return "OK" + diff --git a/lightcurve/src/probability_api/static/probability.css b/lightcurve/src/probability_api/static/probability.css new file mode 100644 index 000000000..39a66ade4 --- /dev/null +++ b/lightcurve/src/probability_api/static/probability.css @@ -0,0 +1,1553 @@ +.select-wrapper { + position: relative; + margin-left: 1rem; + margin-right: 1rem; + height: 40px; + width: 100%; + -webkit-user-select: none; + -moz-user-select: none; + user-select: none; +} + +.select { + position: relative; + display: flex; + flex-direction: column; + border-left-width: 0px; + border-right-width: 0px; + border-top-width: 0px; + border-bottom-width: 1px; + border-style: solid; + --tw-border-opacity: 1; + border-bottom-color: rgb(30 30 30 / var(--tw-border-opacity)); +} + +.select:hover { + --tw-bg-opacity: 1; + background-color: rgb(178 178 178 / var(--tw-bg-opacity)); +} + +:is(.tw-dark .select) { + --tw-border-opacity: 1; + border-bottom-color: rgb(255 255 255 / var(--tw-border-opacity)); +} + +.select__trigger { + position: relative; + display: flex; + cursor: pointer; + align-items: center; + justify-content: space-between; + background-color: transparent; + padding-left: 1rem; + padding-right: 1rem; + line-height: 2.25rem; +} + +:is(.tw-dark .select__trigger) { + --tw-text-opacity: 1; + color: rgb(238 238 238 / var(--tw-text-opacity)); +} + +.custom-options { + pointer-events: none; + visibility: hidden; + position: absolute; + top: 100%; + left: 0px; + right: 0px; + z-index: 2; + display: block; + --tw-bg-opacity: 1; + background-color: rgb(255 255 255 / var(--tw-bg-opacity)); + opacity: 0; + transition-property: all; + transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); + transition-duration: 150ms; +} + +:is(.tw-dark .custom-options) { + --tw-bg-opacity: 1; + background-color: rgb(30 30 30 / var(--tw-bg-opacity)); +} + +.select.open .custom-options { + pointer-events: auto; + visibility: visible; + opacity: 1; +} + +.custom-option { + position: relative; + display: block; + cursor: pointer; + padding-left: 1rem; + padding-right: 1rem; + line-height: 2.25rem; + --tw-text-opacity: 1; + color: rgb(0 0 0 / var(--tw-text-opacity)); + transition-property: all; + transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); + transition-duration: 150ms; +} + +.custom-option:hover { + --tw-bg-opacity: 1; + background-color: rgb(178 178 178 / var(--tw-bg-opacity)); +} + +:is(.tw-dark .custom-option) { + --tw-text-opacity: 1; + color: rgb(238 238 238 / var(--tw-text-opacity)); +} + +.custom-option.selected { + background-color: rgb(25 118 210 / 0.3); + --tw-text-opacity: 1; + color: rgb(25 118 210 / var(--tw-text-opacity)); +} + +.tw-preflight :is(.tw-pointer-events-none) { + pointer-events: none; +} + +.tw-preflight :is(.tw-pointer-events-auto) { + pointer-events: auto; +} + +.tw-preflight :is(.tw-visible) { + visibility: visible; +} + +.tw-preflight :is(.tw-invisible) { + visibility: hidden; +} + +.tw-preflight :is(.tw-absolute) { + position: absolute; +} + +.tw-preflight :is(.tw-relative) { + position: relative; +} + +.tw-preflight :is(.tw-left-0) { + left: 0px; +} + +.tw-preflight :is(.tw-left-10) { + left: 2.5rem; +} + +.tw-preflight :is(.tw-right-0) { + right: 0px; +} + +.tw-preflight :is(.tw-top-1) { + top: 0.25rem; +} + +.tw-preflight :is(.tw-top-1\/2) { + top: 50%; +} + +.tw-preflight :is(.tw-top-\[100\%\]) { + top: 100%; +} + +.tw-preflight :is(.tw-z-\[2\]) { + z-index: 2; +} + +.tw-preflight :is(.tw-z-\[9999\]) { + z-index: 9999; +} + +.tw-preflight :is(.tw-col-span-1) { + grid-column: span 1 / span 1; +} + +.tw-preflight :is(.tw-col-span-2) { + grid-column: span 2 / span 2; +} + +.tw-preflight :is(.tw-col-span-4) { + grid-column: span 4 / span 4; +} + +.tw-preflight :is(.tw-col-span-5) { + grid-column: span 5 / span 5; +} + +.tw-preflight :is(.tw-m-0) { + margin: 0px; +} + +.tw-preflight :is(.tw-m-auto) { + margin: auto; +} + +.tw-preflight :is(.tw-mx-2) { + margin-left: 0.5rem; + margin-right: 0.5rem; +} + +.tw-preflight :is(.tw-mx-4) { + margin-left: 1rem; + margin-right: 1rem; +} + +.tw-preflight :is(.tw-mx-auto) { + margin-left: auto; + margin-right: auto; +} + +.tw-preflight :is(.tw-my-4) { + margin-top: 1rem; + margin-bottom: 1rem; +} + +.tw-preflight :is(.tw-me-2) { + margin-inline-end: 0.5rem; +} + +.tw-preflight :is(.tw-ml-2) { + margin-left: 0.5rem; +} + +.tw-preflight :is(.tw-ml-4) { + margin-left: 1rem; +} + +.tw-preflight :is(.tw-ml-\[50\%\]) { + margin-left: 50%; +} + +.tw-preflight :is(.tw-mr-4) { + margin-right: 1rem; +} + +.tw-preflight :is(.tw-mt-2) { + margin-top: 0.5rem; +} + +.tw-preflight :is(.tw-mt-3) { + margin-top: 0.75rem; +} + +.tw-preflight :is(.tw-mt-4) { + margin-top: 1rem; +} + +.tw-preflight :is(.tw-mt-\[30px\]) { + margin-top: 30px; +} + +.tw-preflight :is(.tw-box-content) { + box-sizing: content-box; +} + +.tw-preflight :is(.tw-block) { + display: block; +} + +.tw-preflight :is(.tw-inline) { + display: inline; +} + +.tw-preflight :is(.tw-flex) { + display: flex; +} + +.tw-preflight :is(.tw-grid) { + display: grid; +} + +.tw-preflight :is(.tw-hidden) { + display: none; +} + +.tw-preflight :is(.tw-h-32) { + height: 8rem; +} + +.tw-preflight :is(.tw-h-5) { + height: 1.25rem; +} + +.tw-preflight :is(.tw-h-6) { + height: 1.5rem; +} + +.tw-preflight :is(.tw-h-8) { + height: 2rem; +} + +.tw-preflight :is(.tw-h-\[100\%\]) { + height: 100%; +} + +.tw-preflight :is(.tw-h-\[12\.5\%\]) { + height: 12.5%; +} + +.tw-preflight :is(.tw-h-\[30px\]) { + height: 30px; +} + +.tw-preflight :is(.tw-h-\[40px\]) { + height: 40px; +} + +.tw-preflight :is(.tw-h-\[500px\]) { + height: 500px; +} + +.tw-preflight :is(.tw-h-auto) { + height: auto; +} + +.tw-preflight :is(.tw-w-1\/3) { + width: 33.333333%; +} + +.tw-preflight :is(.tw-w-12) { + width: 3rem; +} + +.tw-preflight :is(.tw-w-32) { + width: 8rem; +} + +.tw-preflight :is(.tw-w-48) { + width: 12rem; +} + +.tw-preflight :is(.tw-w-5) { + width: 1.25rem; +} + +.tw-preflight :is(.tw-w-52) { + width: 13rem; +} + +.tw-preflight :is(.tw-w-6) { + width: 1.5rem; +} + +.tw-preflight :is(.tw-w-\[100\%\]) { + width: 100%; +} + +.tw-preflight :is(.tw-w-\[30px\]) { + width: 30px; +} + +.tw-preflight :is(.tw-w-\[400px\]) { + width: 400px; +} + +.tw-preflight :is(.tw-w-\[95\%\]) { + width: 95%; +} + +.tw-preflight :is(.tw-w-full) { + width: 100%; +} + +.tw-preflight :is(.tw-min-w-full) { + min-width: 100%; +} + +.tw-preflight :is(.tw-max-w-\[40\%\]) { + max-width: 40%; +} + +.tw-preflight :is(.-tw-translate-y-1) { + --tw-translate-y: -0.25rem; + transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); +} + +.tw-preflight :is(.-tw-translate-y-1\/2) { + --tw-translate-y: -50%; + transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); +} + +.tw-preflight :is(.tw-transform) { + transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); +} + +@keyframes tw-spin { + to { + transform: rotate(360deg); + } +} + +.tw-preflight :is(.tw-animate-spin) { + animation: tw-spin 1s linear infinite; +} + +.tw-preflight :is(.tw-cursor-pointer) { + cursor: pointer; +} + +.tw-preflight :is(.tw-appearance-none) { + -webkit-appearance: none; + -moz-appearance: none; + appearance: none; +} + +.tw-preflight :is(.tw-grid-cols-10) { + grid-template-columns: repeat(10, minmax(0, 1fr)); +} + +.tw-preflight :is(.tw-grid-cols-6) { + grid-template-columns: repeat(6, minmax(0, 1fr)); +} + +.tw-preflight :is(.tw-flex-col) { + flex-direction: column; +} + +.tw-preflight :is(.tw-place-content-center) { + place-content: center; +} + +.tw-preflight :is(.tw-place-items-center) { + place-items: center; +} + +.tw-preflight :is(.tw-items-center) { + align-items: center; +} + +.tw-preflight :is(.tw-justify-end) { + justify-content: flex-end; +} + +.tw-preflight :is(.tw-justify-center) { + justify-content: center; +} + +.tw-preflight :is(.tw-justify-between) { + justify-content: space-between; +} + +.tw-preflight :is(.tw-gap-1) { + gap: 0.25rem; +} + +.tw-preflight :is(.tw-space-x-2 > :not([hidden]) ~ :not([hidden])) { + --tw-space-x-reverse: 0; + margin-right: calc(0.5rem * var(--tw-space-x-reverse)); + margin-left: calc(0.5rem * calc(1 - var(--tw-space-x-reverse))); +} + +.tw-preflight :is(.tw-space-x-4 > :not([hidden]) ~ :not([hidden])) { + --tw-space-x-reverse: 0; + margin-right: calc(1rem * var(--tw-space-x-reverse)); + margin-left: calc(1rem * calc(1 - var(--tw-space-x-reverse))); +} + +.tw-preflight :is(.tw-space-y-2 > :not([hidden]) ~ :not([hidden])) { + --tw-space-y-reverse: 0; + margin-top: calc(0.5rem * calc(1 - var(--tw-space-y-reverse))); + margin-bottom: calc(0.5rem * var(--tw-space-y-reverse)); +} + +.tw-preflight :is(.tw-divide-y > :not([hidden]) ~ :not([hidden])) { + --tw-divide-y-reverse: 0; + border-top-width: calc(1px * calc(1 - var(--tw-divide-y-reverse))); + border-bottom-width: calc(1px * var(--tw-divide-y-reverse)); +} + +.tw-preflight :is(.tw-divide-gray-200 > :not([hidden]) ~ :not([hidden])) { + --tw-divide-opacity: 1; + border-color: rgb(229 231 235 / var(--tw-divide-opacity)); +} + +.tw-preflight :is(.tw-place-self-center) { + place-self: center; +} + +.tw-preflight :is(.tw-overflow-auto) { + overflow: auto; +} + +.tw-preflight :is(.tw-truncate) { + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} + +.tw-preflight :is(.tw-text-wrap) { + text-wrap: wrap; +} + +.tw-preflight :is(.tw-rounded) { + border-radius: 0.25rem; +} + +.tw-preflight :is(.tw-rounded-\[50px\]) { + border-radius: 50px; +} + +.tw-preflight :is(.tw-rounded-\[6px\]) { + border-radius: 6px; +} + +.tw-preflight :is(.tw-rounded-full) { + border-radius: 9999px; +} + +.tw-preflight :is(.tw-rounded-md) { + border-radius: 0.375rem; +} + +.tw-preflight :is(.tw-rounded-bl-\[10px\]) { + border-bottom-left-radius: 10px; +} + +.tw-preflight :is(.tw-rounded-br-\[10px\]) { + border-bottom-right-radius: 10px; +} + +.tw-preflight :is(.tw-rounded-tl-\[10px\]) { + border-top-left-radius: 10px; +} + +.tw-preflight :is(.tw-rounded-tr-\[10px\]) { + border-top-right-radius: 10px; +} + +.tw-preflight :is(.tw-border) { + border-width: 1px; +} + +.tw-preflight :is(.tw-border-8) { + border-width: 8px; +} + +.tw-preflight :is(.tw-border-x-0) { + border-left-width: 0px; + border-right-width: 0px; +} + +.tw-preflight :is(.tw-border-y-0) { + border-top-width: 0px; + border-bottom-width: 0px; +} + +.tw-preflight :is(.tw-border-b) { + border-bottom-width: 1px; +} + +.tw-preflight :is(.tw-border-b-\[1px\]) { + border-bottom-width: 1px; +} + +.tw-preflight :is(.tw-border-t) { + border-top-width: 1px; +} + +.tw-preflight :is(.tw-border-solid) { + border-style: solid; +} + +.tw-preflight :is(.tw-border-\[\#1e1e1e\]) { + --tw-border-opacity: 1; + border-color: rgb(30 30 30 / var(--tw-border-opacity)); +} + +.tw-preflight :is(.tw-border-blue-400) { + --tw-border-opacity: 1; + border-color: rgb(96 165 250 / var(--tw-border-opacity)); +} + +.tw-preflight :is(.tw-border-gray-300) { + --tw-border-opacity: 1; + border-color: rgb(209 213 219 / var(--tw-border-opacity)); +} + +.tw-preflight :is(.tw-border-b-\[\#1e1e1e\]) { + --tw-border-opacity: 1; + border-bottom-color: rgb(30 30 30 / var(--tw-border-opacity)); +} + +.tw-preflight :is(.tw-border-b-black) { + --tw-border-opacity: 1; + border-bottom-color: rgb(0 0 0 / var(--tw-border-opacity)); +} + +.tw-preflight :is(.tw-border-t-transparent) { + border-top-color: transparent; +} + +.tw-preflight :is(.tw-border-opacity-20) { + --tw-border-opacity: 0.2; +} + +.tw-preflight :is(.tw-bg-\[\#1976D2\]\/30) { + background-color: rgb(25 118 210 / 0.3); +} + +.tw-preflight :is(.tw-bg-\[\#757575\]\/60) { + background-color: rgb(117 117 117 / 0.6); +} + +.tw-preflight :is(.tw-bg-blue-500) { + --tw-bg-opacity: 1; + background-color: rgb(59 130 246 / var(--tw-bg-opacity)); +} + +.tw-preflight :is(.tw-bg-blue-700) { + --tw-bg-opacity: 1; + background-color: rgb(29 78 216 / var(--tw-bg-opacity)); +} + +.tw-preflight :is(.tw-bg-cyan-700) { + --tw-bg-opacity: 1; + background-color: rgb(14 116 144 / var(--tw-bg-opacity)); +} + +.tw-preflight :is(.tw-bg-gray-100) { + --tw-bg-opacity: 1; + background-color: rgb(243 244 246 / var(--tw-bg-opacity)); +} + +.tw-preflight :is(.tw-bg-gray-900) { + --tw-bg-opacity: 1; + background-color: rgb(17 24 39 / var(--tw-bg-opacity)); +} + +.tw-preflight :is(.tw-bg-green-500) { + --tw-bg-opacity: 1; + background-color: rgb(34 197 94 / var(--tw-bg-opacity)); +} + +.tw-preflight :is(.tw-bg-transparent) { + background-color: transparent; +} + +.tw-preflight :is(.tw-bg-white) { + --tw-bg-opacity: 1; + background-color: rgb(255 255 255 / var(--tw-bg-opacity)); +} + +.tw-preflight :is(.tw-p-2) { + padding: 0.5rem; +} + +.tw-preflight :is(.tw-px-2) { + padding-left: 0.5rem; + padding-right: 0.5rem; +} + +.tw-preflight :is(.tw-px-4) { + padding-left: 1rem; + padding-right: 1rem; +} + +.tw-preflight :is(.tw-py-1) { + padding-top: 0.25rem; + padding-bottom: 0.25rem; +} + +.tw-preflight :is(.tw-py-2) { + padding-top: 0.5rem; + padding-bottom: 0.5rem; +} + +.tw-preflight :is(.tw-py-4) { + padding-top: 1rem; + padding-bottom: 1rem; +} + +.tw-preflight :is(.tw-pl-\[10px\]) { + padding-left: 10px; +} + +.tw-preflight :is(.tw-pr-2) { + padding-right: 0.5rem; +} + +.tw-preflight :is(.tw-pr-\[10px\]) { + padding-right: 10px; +} + +.tw-preflight :is(.tw-ps-2) { + padding-inline-start: 0.5rem; +} + +.tw-preflight :is(.tw-pt-\[25px\]) { + padding-top: 25px; +} + +.tw-preflight :is(.tw-text-left) { + text-align: left; +} + +.tw-preflight :is(.tw-text-center) { + text-align: center; +} + +.tw-preflight :is(.tw-text-right) { + text-align: right; +} + +.tw-preflight :is(.tw-text-2xl) { + font-size: 1.5rem; + line-height: 2rem; +} + +.tw-preflight :is(.tw-text-\[17px\]) { + font-size: 17px; +} + +.tw-preflight :is(.tw-text-lg) { + font-size: 1.125rem; + line-height: 1.75rem; +} + +.tw-preflight :is(.tw-text-sm) { + font-size: 0.875rem; + line-height: 1.25rem; +} + +.tw-preflight :is(.tw-text-xs) { + font-size: 0.75rem; + line-height: 1rem; +} + +.tw-preflight :is(.tw-font-bold) { + font-weight: 700; +} + +.tw-preflight :is(.tw-ordinal) { + --tw-ordinal: ordinal; + font-variant-numeric: var(--tw-ordinal) var(--tw-slashed-zero) var(--tw-numeric-figure) var(--tw-numeric-spacing) var(--tw-numeric-fraction); +} + +.tw-preflight :is(.tw-leading-9) { + line-height: 2.25rem; +} + +.tw-preflight :is(.tw-text-\[\#1976D2\]) { + --tw-text-opacity: 1; + color: rgb(25 118 210 / var(--tw-text-opacity)); +} + +.tw-preflight :is(.tw-text-\[\#1e1e1e\]) { + --tw-text-opacity: 1; + color: rgb(30 30 30 / var(--tw-text-opacity)); +} + +.tw-preflight :is(.tw-text-\[\#FAFAFA\]) { + --tw-text-opacity: 1; + color: rgb(250 250 250 / var(--tw-text-opacity)); +} + +.tw-preflight :is(.tw-text-black) { + --tw-text-opacity: 1; + color: rgb(0 0 0 / var(--tw-text-opacity)); +} + +.tw-preflight :is(.tw-text-blue-600) { + --tw-text-opacity: 1; + color: rgb(37 99 235 / var(--tw-text-opacity)); +} + +.tw-preflight :is(.tw-text-gray-400) { + --tw-text-opacity: 1; + color: rgb(156 163 175 / var(--tw-text-opacity)); +} + +.tw-preflight :is(.tw-text-gray-900) { + --tw-text-opacity: 1; + color: rgb(17 24 39 / var(--tw-text-opacity)); +} + +.tw-preflight :is(.tw-text-red-500) { + --tw-text-opacity: 1; + color: rgb(239 68 68 / var(--tw-text-opacity)); +} + +.tw-preflight :is(.tw-text-white) { + --tw-text-opacity: 1; + color: rgb(255 255 255 / var(--tw-text-opacity)); +} + +.tw-preflight :is(.tw-underline) { + text-decoration-line: underline; +} + +.tw-preflight :is(.tw-opacity-0) { + opacity: 0; +} + +.tw-preflight :is(.tw-opacity-100) { + opacity: 1; +} + +.tw-preflight :is(.tw-opacity-50) { + opacity: 0.5; +} + +.tw-preflight :is(.tw-shadow-2xl) { + --tw-shadow: 0 25px 50px -12px rgb(0 0 0 / 0.25); + --tw-shadow-colored: 0 25px 50px -12px var(--tw-shadow-color); + box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); +} + +.tw-preflight :is(.tw-transition-all) { + transition-property: all; + transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); + transition-duration: 150ms; +} + +.tw-preflight :is(.tw-duration-200) { + transition-duration: 200ms; +} + +/*inicio custom select*/ + +/*fin custom select*/ + +.disabled\:bg-transparent { + background-color: transparent; +} + +/* Optionally, adjust the opacity for a more subdued appearance */ + +.disabled\:opacity-50 { + opacity: 0.5; + /* Adjust the opacity as needed */ +} + +.disabled\:outline { + outline-style: solid; +} + +.tooltip { + position: relative; +} + +.tooltip .fa-question-circle { + cursor: pointer; +} + +.tooltip-text { + visibility: hidden; + width: -moz-max-content; + width: max-content; + max-width: 500px; + background-color: #000; + color: #fff; + text-align: center; + border-radius: 4px; + padding: 4px 8px; + position: absolute; + font-size: 12px; + z-index: 999; + top: -50px; + left: 50%; + transform: translateX(-50%); + opacity: 0; + transition: opacity 0.3s; +} + +.tooltip:hover .tooltip-text { + visibility: visible; + opacity: 1; +} + +.tw-preflight *, +::before, +::after { + box-sizing: border-box; + /* 1 */ +} + +/* + border-width: 0; + 2 + border-style: solid; + 2 + border-color: #e5e7eb; + 2 +*/ + +.tw-preflight ::before, +.tw-preflight ::after { + --tw-content: ""; +} + +/* +1. Use a consistent sensible line-height in all browsers. +2. Prevent adjustments of font size after orientation changes in iOS. +3. Use a more readable tab size. +4. Use the user's configured `sans` font-family by default. +5. Use the user's configured `sans` font-feature-settings by default. +6. Use the user's configured `sans` font-variation-settings by default. +*/ + +.tw-preflight { + line-height: 1.5; + /* 1 */ + -webkit-text-size-adjust: 100%; + /* 2 */ + -moz-tab-size: 4; + /* 3 */ + -o-tab-size: 4; + tab-size: 4; + /* 3 */ + font-family: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, + "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, + "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", + "Noto Color Emoji"; + /* 4 */ + font-feature-settings: normal; + /* 5 */ + font-variation-settings: normal; + /* 6 */ + margin: 0; +} + +input::-webkit-outer-spin-button, +input::-webkit-inner-spin-button { + -webkit-appearance: none; + margin: 0; +} + +input[type=number] { + -moz-appearance: textfield; +} + +/* +1. Add the correct height in Firefox. +2. Correct the inheritance of border color in Firefox. (https://bugzilla.mozilla.org/show_bug.cgi?id=190655) +3. Ensure horizontal rules are visible by default. +*/ + +.tw-preflight hr { + height: 0; + /* 1 */ + color: inherit; + /* 2 */ + border-top-width: 1px; + /* 3 */ +} + +/* +Add the correct text decoration in Chrome, Edge, and Safari. +*/ + +.tw-preflight abbr:where([title]) { + -webkit-text-decoration: underline dotted; + text-decoration: underline dotted; +} + +/* +Remove the default font size and weight for headings. +*/ + +.tw-preflight h1, +.tw-preflight h2, +.tw-preflight h3, +.tw-preflight h4, +.tw-preflight h5, +.tw-preflight h6 { + font-size: inherit; + font-weight: inherit; +} + +/* +Reset links to optimize for opt-in styling instead of opt-out. +*/ + +.tw-preflight a { + color: inherit; + text-decoration: inherit; +} + +/* +Add the correct font weight in Edge and Safari. +*/ + +.tw-preflight b, +.tw-preflight strong { + font-weight: bolder; +} + +/* +1. Use the user's configured `mono` font family by default. +2. Correct the odd `em` font sizing in all browsers. +*/ + +.tw-preflight code, +.tw-preflight kbd, +.tw-preflight samp, +.tw-preflight pre { + font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, + "Liberation Mono", "Courier New", monospace; + /* 1 */ + font-size: 1em; + /* 2 */ +} + +/* +Add the correct font size in all browsers. +*/ + +.tw-preflight small { + font-size: 80%; +} + +/* +Prevent `sub` and `sup` elements from affecting the line height in all browsers. +*/ + +.tw-preflight sub, +.tw-preflight sup { + font-size: 75%; + line-height: 0; + position: relative; + vertical-align: baseline; +} + +.tw-preflight sub { + bottom: -0.25em; +} + +.tw-preflight sup { + top: -0.5em; +} + +/* +1. Remove text indentation from table contents in Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=999088, https://bugs.webkit.org/show_bug.cgi?id=201297) +2. Correct table border color inheritance in all Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=935729, https://bugs.webkit.org/show_bug.cgi?id=195016) +3. Remove gaps between table borders by default. +*/ + +.tw-preflight table { + text-indent: 0; + /* 1 */ + border-color: inherit; + /* 2 */ + border-collapse: collapse; + /* 3 */ +} + +/* +1. Change the font styles in all browsers. +2. Remove the margin in Firefox and Safari. +3. Remove default padding in all browsers. +*/ + +.tw-preflight button, +.tw-preflight input, +.tw-preflight optgroup, +.tw-preflight select, +.tw-preflight textarea { + font-family: inherit; + /* 1 */ + font-feature-settings: inherit; + /* 1 */ + font-variation-settings: inherit; + /* 1 */ + font-size: 100%; + /* 1 */ + font-weight: inherit; + /* 1 */ + line-height: inherit; + /* 1 */ + color: inherit; + /* 1 */ + margin: 0; + /* 2 */ + padding: 0; + /* 3 */ +} + +/* +Remove the inheritance of text transform in Edge and Firefox. +*/ + +.tw-preflight button, +.tw-preflight select { + text-transform: none; +} + +/* +1. Correct the inability to style clickable types in iOS and Safari. +2. Remove default button styles. +*/ + +.tw-preflight button, +.tw-preflight [type="button"], +.tw-preflight [type="reset"], +.tw-preflight [type="submit"] { + -webkit-appearance: button; + /* 1 */ + background-color: transparent; + /* 2 */ + background-image: none; + /* 2 */ +} + +/* +Use the modern Firefox focus style for all focusable elements. +*/ + +.tw-preflight :-moz-focusring { + outline: auto; +} + +/* +Remove the additional `:invalid` styles in Firefox. (https://github.com/mozilla/gecko-dev/blob/2f9eacd9d3d995c937b4251a5557d95d494c9be1/layout/style/res/forms.css#L728-L737) +*/ + +.tw-preflight :-moz-ui-invalid { + box-shadow: none; +} + +/* +Add the correct vertical alignment in Chrome and Firefox. +*/ + +.tw-preflight progress { + vertical-align: baseline; +} + +/* +Correct the cursor style of increment and decrement buttons in Safari. +*/ + +.tw-preflight ::-webkit-inner-spin-button, +.tw-preflight ::-webkit-outer-spin-button { + height: auto; +} + +/* +1. Correct the odd appearance in Chrome and Safari. +2. Correct the outline style in Safari. +*/ + +.tw-preflight [type="search"] { + -webkit-appearance: textfield; + /* 1 */ + outline-offset: -2px; + /* 2 */ +} + +/* +Remove the inner padding in Chrome and Safari on macOS. +*/ + +.tw-preflight ::-webkit-search-decoration { + -webkit-appearance: none; +} + +/* +1. Correct the inability to style clickable types in iOS and Safari. +2. Change font properties to `inherit` in Safari. +*/ + +.tw-preflight ::-webkit-file-upload-button { + -webkit-appearance: button; + /* 1 */ + font: inherit; + /* 2 */ +} + +/* +Add the correct display in Chrome and Safari. +*/ + +.tw-preflight summary { + display: list-item; +} + +/* +Removes the default spacing and border for appropriate elements. +*/ + +.tw-preflight blockquote, +.tw-preflight dl, +.tw-preflight dd, +.tw-preflight h1, +.tw-preflight h2, +.tw-preflight h3, +.tw-preflight h4, +.tw-preflight h5, +.tw-preflight h6, +.tw-preflight hr, +.tw-preflight figure, +.tw-preflight p, +.tw-preflight pre { + margin: 0; +} + +.tw-preflight fieldset { + margin: 0; + padding: 0; +} + +.tw-preflight legend { + padding: 0; +} + +.tw-preflight ol, +.tw-preflight ul, +.tw-preflight menu { + list-style: none; + margin: 0; + padding: 0; +} + +/* +Reset default styling for dialogs. +*/ + +.tw-preflight dialog { + padding: 0; +} + +/* +Prevent resizing textareas horizontally by default. +*/ + +.tw-preflight textarea { + resize: vertical; +} + +/* +1. Reset the default placeholder opacity in Firefox. (https://github.com/tailwindlabs/tailwindcss/issues/3300) +2. Set the default placeholder color to the user's configured gray 400 color. +*/ + +.tw-preflight input::-moz-placeholder, +.tw-preflight textarea::-moz-placeholder { + opacity: 1; + /* 1 */ + color: #9ca3af; + /* 2 */ +} + +.tw-preflight input::-moz-placeholder, .tw-preflight textarea::-moz-placeholder { + opacity: 1; + /* 1 */ + color: #9ca3af; + /* 2 */ +} + +.tw-preflight input::placeholder, +.tw-preflight textarea::placeholder { + opacity: 1; + /* 1 */ + color: #9ca3af; + /* 2 */ +} + +/* +Set the default cursor for buttons. +*/ + +.tw-preflight button, +[role="button"] { + cursor: pointer; +} + +/* +Make sure disabled buttons don't get the pointer cursor. +*/ + +.tw-preflight :disabled { + cursor: default; +} + +/* +1. Make replaced elements `display: block` by default. (https://github.com/mozdevs/cssremedy/issues/14) +2. Add `vertical-align: middle` to align replaced elements more sensibly by default. (https://github.com/jensimmons/cssremedy/issues/14#issuecomment-634934210) + This can trigger a poorly considered lint error in some tools but is included by design. +*/ + +.tw-preflight img, +.tw-preflight svg, +.tw-preflight, +.tw-preflight canvas, +.tw-preflight, +.tw-preflight iframe, +.tw-preflight embed, +.tw-preflight object { + display: block; + /* 1 */ + vertical-align: middle; + /* 2 */ +} + +/* +Constrain images and videos to the parent width and preserve their intrinsic aspect ratio. (https://github.com/mozdevs/cssremedy/issues/14) +*/ + +.tw-preflight img, +.tw-preflight video { + max-width: 100%; + height: auto; +} + +/* Make elements with the HTML hidden attribute stay hidden by default */ + +.tw-preflight [hidden] { + display: none; +} + +.tw-preflight *, +.tw-preflight ::before, +.tw-preflight ::after { + --tw-border-spacing-x: 0; + --tw-border-spacing-y: 0; + --tw-translate-x: 0; + --tw-translate-y: 0; + --tw-rotate: 0; + --tw-skew-x: 0; + --tw-skew-y: 0; + --tw-scale-x: 1; + --tw-scale-y: 1; + --tw-pan-x: ; + --tw-pan-y: ; + --tw-pinch-zoom: ; + --tw-scroll-snap-strictness: proximity; + --tw-gradient-from-position: ; + --tw-gradient-via-position: ; + --tw-gradient-to-position: ; + --tw-ordinal: ; + --tw-slashed-zero: ; + --tw-numeric-figure: ; + --tw-numeric-spacing: ; + --tw-numeric-fraction: ; + --tw-ring-inset: ; + --tw-ring-offset-width: 0px; + --tw-ring-offset-color: #fff; + --tw-ring-color: rgb(59 130 246 / 0.5); + --tw-ring-offset-shadow: 0 0 #0000; + --tw-ring-shadow: 0 0 #0000; + --tw-shadow: 0 0 #0000; + --tw-shadow-colored: 0 0 #0000; + --tw-blur: ; + --tw-brightness: ; + --tw-contrast: ; + --tw-grayscale: ; + --tw-hue-rotate: ; + --tw-invert: ; + --tw-saturate: ; + --tw-sepia: ; + --tw-drop-shadow: ; + --tw-backdrop-blur: ; + --tw-backdrop-brightness: ; + --tw-backdrop-contrast: ; + --tw-backdrop-grayscale: ; + --tw-backdrop-hue-rotate: ; + --tw-backdrop-invert: ; + --tw-backdrop-opacity: ; + --tw-backdrop-saturate: ; + --tw-backdrop-sepia: ; +} + +.tw-preflight ::backdrop { + --tw-border-spacing-x: 0; + --tw-border-spacing-y: 0; + --tw-translate-x: 0; + --tw-translate-y: 0; + --tw-rotate: 0; + --tw-skew-x: 0; + --tw-skew-y: 0; + --tw-scale-x: 1; + --tw-scale-y: 1; + --tw-pan-x: ; + --tw-pan-y: ; + --tw-pinch-zoom: ; + --tw-scroll-snap-strictness: proximity; + --tw-gradient-from-position: ; + --tw-gradient-via-position: ; + --tw-gradient-to-position: ; + --tw-ordinal: ; + --tw-slashed-zero: ; + --tw-numeric-figure: ; + --tw-numeric-spacing: ; + --tw-numeric-fraction: ; + --tw-ring-inset: ; + --tw-ring-offset-width: 0px; + --tw-ring-offset-color: #fff; + --tw-ring-color: rgb(59 130 246 / 0.5); + --tw-ring-offset-shadow: 0 0 #0000; + --tw-ring-shadow: 0 0 #0000; + --tw-shadow: 0 0 #0000; + --tw-shadow-colored: 0 0 #0000; + --tw-blur: ; + --tw-brightness: ; + --tw-contrast: ; + --tw-grayscale: ; + --tw-hue-rotate: ; + --tw-invert: ; + --tw-saturate: ; + --tw-sepia: ; + --tw-drop-shadow: ; + --tw-backdrop-blur: ; + --tw-backdrop-brightness: ; + --tw-backdrop-contrast: ; + --tw-backdrop-grayscale: ; + --tw-backdrop-hue-rotate: ; + --tw-backdrop-invert: ; + --tw-backdrop-opacity: ; + --tw-backdrop-saturate: ; + --tw-backdrop-sepia: ; +} + +.tw-preflight :is(.hover\:tw-cursor-pointer:hover) { + cursor: pointer; +} + +.tw-preflight :is(.hover\:tw-bg-\[\#757575\]:hover) { + --tw-bg-opacity: 1; + background-color: rgb(117 117 117 / var(--tw-bg-opacity)); +} + +.tw-preflight :is(.hover\:tw-bg-\[\#b2b2b2\]:hover) { + --tw-bg-opacity: 1; + background-color: rgb(178 178 178 / var(--tw-bg-opacity)); +} + +.tw-preflight :is(.hover\:tw-bg-\[\#e5e4e2\]:hover) { + --tw-bg-opacity: 1; + background-color: rgb(229 228 226 / var(--tw-bg-opacity)); +} + +.tw-preflight :is(.hover\:tw-bg-blue-700:hover) { + --tw-bg-opacity: 1; + background-color: rgb(29 78 216 / var(--tw-bg-opacity)); +} + +.tw-preflight :is(.hover\:tw-bg-gray-200:hover) { + --tw-bg-opacity: 1; + background-color: rgb(229 231 235 / var(--tw-bg-opacity)); +} + +.tw-preflight :is(.hover\:tw-bg-green-600:hover) { + --tw-bg-opacity: 1; + background-color: rgb(22 163 74 / var(--tw-bg-opacity)); +} + +.tw-preflight :is(.hover\:tw-bg-green-700:hover) { + --tw-bg-opacity: 1; + background-color: rgb(21 128 61 / var(--tw-bg-opacity)); +} + +.tw-preflight :is(.hover\:tw-text-gray-600:hover) { + --tw-text-opacity: 1; + color: rgb(75 85 99 / var(--tw-text-opacity)); +} + +.tw-preflight :is(.disabled\:tw-bg-transparent:disabled) { + background-color: transparent; +} + +.tw-preflight :is(.disabled\:tw-opacity-50:disabled) { + opacity: 0.5; +} + +.tw-preflight :is(.disabled\:tw-outline:disabled) { + outline-style: solid; +} + +.tw-preflight :is(.tw-group:hover .group-hover\:tw-flex) { + display: flex; +} + +.tw-preflight :is(:is(.tw-dark .dark\:tw-divide-\[\#404040\]) > :not([hidden]) ~ :not([hidden])) { + --tw-divide-opacity: 1; + border-color: rgb(64 64 64 / var(--tw-divide-opacity)); +} + +.tw-preflight :is(.tw-dark .dark\:tw-border-\[\#404040\]) { + --tw-border-opacity: 1; + border-color: rgb(64 64 64 / var(--tw-border-opacity)); +} + +.tw-preflight :is(.tw-dark .dark\:tw-border-white) { + --tw-border-opacity: 1; + border-color: rgb(255 255 255 / var(--tw-border-opacity)); +} + +.tw-preflight :is(.tw-dark .dark\:tw-border-b-white) { + --tw-border-opacity: 1; + border-bottom-color: rgb(255 255 255 / var(--tw-border-opacity)); +} + +.tw-preflight :is(.tw-dark .dark\:tw-border-opacity-20) { + --tw-border-opacity: 0.2; +} + +.tw-preflight :is(.tw-dark .dark\:tw-bg-\[\#1e1e1e\]) { + --tw-bg-opacity: 1; + background-color: rgb(30 30 30 / var(--tw-bg-opacity)); +} + +.tw-preflight :is(.tw-dark .dark\:tw-bg-\[\#252525\]) { + --tw-bg-opacity: 1; + background-color: rgb(37 37 37 / var(--tw-bg-opacity)); +} + +.tw-preflight :is(.tw-dark .dark\:tw-bg-\[\#757575\]\/60) { + background-color: rgb(117 117 117 / 0.6); +} + +.tw-preflight :is(.tw-dark .dark\:tw-bg-green-700) { + --tw-bg-opacity: 1; + background-color: rgb(21 128 61 / var(--tw-bg-opacity)); +} + +.tw-preflight :is(.tw-dark .dark\:tw-text-\[\#EEEEEE\]) { + --tw-text-opacity: 1; + color: rgb(238 238 238 / var(--tw-text-opacity)); +} + +.tw-preflight :is(.tw-dark .dark\:tw-text-\[\#FAFAFA\]) { + --tw-text-opacity: 1; + color: rgb(250 250 250 / var(--tw-text-opacity)); +} + +.tw-preflight :is(.tw-dark .dark\:tw-text-white) { + --tw-text-opacity: 1; + color: rgb(255 255 255 / var(--tw-text-opacity)); +} + +.tw-preflight :is(.tw-dark .dark\:hover\:tw-bg-\[\#353535\]:hover) { + --tw-bg-opacity: 1; + background-color: rgb(53 53 53 / var(--tw-bg-opacity)); +} + +.tw-preflight :is(.tw-dark .dark\:hover\:tw-bg-\[\#3b3939\]:hover) { + --tw-bg-opacity: 1; + background-color: rgb(59 57 57 / var(--tw-bg-opacity)); +} + +@media (min-width: 640px) { + .tw-preflight :is(.sm\:tw-h-\[100\%\]) { + height: 100%; + } + + .tw-preflight :is(.sm\:tw-w-\[100\%\]) { + width: 100%; + } +} + +@media (min-width: 768px) { + .tw-preflight :is(.md\:tw-h-\[80\%\]) { + height: 80%; + } + + .tw-preflight :is(.md\:tw-w-\[80\%\]) { + width: 80%; + } +} \ No newline at end of file diff --git a/lightcurve/src/probability_api/static/probability.js b/lightcurve/src/probability_api/static/probability.js new file mode 100644 index 000000000..fa5875fe9 --- /dev/null +++ b/lightcurve/src/probability_api/static/probability.js @@ -0,0 +1,210 @@ +let probability_data_aux +let mychart + +let data = { + labels: [], + datasets: [{ + label: 'Probabilities', + data: [], + fill: true, + backgroundColor: 'rgba(255, 0, 54, 0.7)', + borderColor: 'rgb(255, 0, 54)', + pointBackgroundColor: 'rgb(255, 0, 54)', + pointBorderColor: '#fff', + pointHoverBackgroundColor: '#fff', + pointHoverBorderColor: 'rgb(255, 0, 54)', + }] +}; + + +let config = { + type: 'radar', + data: data, + options: { + responsive: true, + maintainAspectRatio: false, + pointRadius: 5, + elements: { + line: { + borderWidth: 1, + fill: true, + } + }, + scales: { + r: { + backgroundColor: 'white', + ticks: { + display: false, + stepSize: 0.33, + }, + angleLines: { + color: '#000000' + }, + grid: { + color: '#000000', + }, + pointLabels: { + color: '#000000', + font: { + size: 14 + } + }, + beginAtZero: true, + max: 1 + }, + }, + plugins: { + legend: { + display: false + }, + tooltip: { + enabled: true, + mode: 'index', + position: 'nearest', + titleFont: { + weight: 'bold' + }, + displayColors: false, + callbacks: { + title: function(){ + return "Probabilities (score)" + }, + label: function(context){ + let tooltipText = []; + let length = context.dataset.data.length - 1 + let data = context.dataset.data + let labels = context.chart.data.labels + + tooltipText.push(`${labels[0]}: ${data[0]}`) + + for (let index = length; index >= 1; index--){ + tooltipText.push(`${labels[index]}: ${data[index]}`) + } + + return tooltipText + } + } + } + }, + + } +} + +export function init(){ + let raw_data = JSON.parse(document.getElementById("probabilities-data").text); + let raw_tax = raw_data.taxonomy_dict + let raw_group_prob_dict = raw_data.group_prob_dict + + let ctx = document.getElementById('myChart'); + let custom_select = document.querySelector(".select-wrapper") + let initial_value = document.querySelector('.custom-option.selected').getAttribute("data-value") + + reverseData(raw_tax) + + probability_data_aux = [] + mychart = new Chart(ctx, config); + + updateMyChart(initial_value, raw_tax, raw_group_prob_dict) + + custom_select.addEventListener('click', () => { + custom_select.querySelector('.select').classList.toggle('open'); + }) + + for(const option of document.querySelectorAll(".custom-option")){ + option.addEventListener('click', () => { + if(!option.classList.contains('selected')){ + option.parentNode.querySelector('.custom-option.selected').classList.remove('selected'); + option.classList.add('selected'); + option.closest('.select').querySelector('.select__trigger span').textContent = option.textContent; + + updateMyChart(option.getAttribute("data-value"), raw_tax, raw_group_prob_dict) + } + }) + } +} + +function reverseData(raw_tax){ + let aux_arr = [] + + Object.keys(raw_tax).forEach((key) => { + aux_arr= raw_tax[key].classes.map((item, idx) => { + if (idx == 0) { + return item + } else { + return raw_tax[key].classes[raw_tax[key].classes.length - idx] + } + }) + raw_tax[key].classes = aux_arr + }) +} + + +function orderDataByTagNew(labels_tags, classifier_data){ + probability_data_aux.length = 0 + + labels_tags.forEach((e) => { + classifier_data.forEach((element) => { + if(element.class_name == e){ + probability_data_aux.push(element.probability) + } + }) + }) +} + +function maxValue(classifier_data){ + let maxVal = Math.max.apply(Math, classifier_data.map((e) => e.probability)) + + return maxVal +} + +function getScale(max_value){ + return (max_value/3) +} + +function updateMyChart(classifier_name, raw_tax, raw_group_prob_dict){ + let max_value + let classes_arr = raw_tax[classifier_name].classes + let classifier_data = Object.values(raw_group_prob_dict[classifier_name])[0] + + orderDataByTagNew(classes_arr, classifier_data) + + max_value = maxValue(classifier_data) + + removeDataChart() + updateDataChart(classes_arr, max_value) + + isDark(); +} + +function removeDataChart(){ + mychart.data.labels.length = 0; + mychart.data.datasets.forEach((dataset) => { + dataset.data.length = 0; + + }); + + mychart.update(); +} + +function updateDataChart(labels, max_value){ + mychart.data.labels.push(...labels); + mychart.data.datasets.forEach((dataset) => { + dataset.data.push(...probability_data_aux); + }); + + mychart.config.options.scales.r.ticks.stepSize = getScale(max_value) + mychart.config.options.scales.r.max = max_value + + mychart.update(); +} + +function isDark(){ + if(document.getElementById("probabilities-app").classList.contains("tw-dark")){ + mychart.config.options.scales.r.backgroundColor = 'rgba(245, 245, 245, 0.2)' + mychart.config.options.scales.r.angleLines.color = '#F5F5F5' + mychart.config.options.scales.r.grid.color = '#F5F5F5' + mychart.config.options.scales.r.pointLabels.color = '#F5F5F5' + + mychart.update(); + } +} \ No newline at end of file diff --git a/lightcurve/src/probability_api/templates/prob.html.jinja b/lightcurve/src/probability_api/templates/prob.html.jinja new file mode 100644 index 000000000..222a66cd8 --- /dev/null +++ b/lightcurve/src/probability_api/templates/prob.html.jinja @@ -0,0 +1,59 @@ + + + + + +
+
+ +
+ +
+ + + +
+ +
+
+
+ {% for value in class_dict[0].values()%} + {{value}} + {% endfor %} +
+
+ {% for y in class_dict %} + {% if loop.first %} + {% for key, value in y.items() %} + {{value}} + {% endfor %} + {% else %} + {% for key, value in y.items() %} + {{value}} + {% endfor %} + {% endif %} + {% endfor %} +
+
+
+ +
+ +
+ +
+
+
+ + + + + \ No newline at end of file diff --git a/lightcurve/src/probability_api/templates/probability.css b/lightcurve/src/probability_api/templates/probability.css new file mode 100644 index 000000000..3ca29c377 --- /dev/null +++ b/lightcurve/src/probability_api/templates/probability.css @@ -0,0 +1,610 @@ +@tailwind components; +@tailwind utilities; + +/*inicio custom select*/ +@layer components { + + .select-wrapper{ + @apply tw-relative tw-w-full tw-h-[40px] tw-mx-4 tw-select-none; + } + + .select{ + @apply tw-relative tw-flex tw-flex-col tw-border-solid tw-border-x-0 tw-border-y-0 tw-border-b tw-border-b-[#1e1e1e] dark:tw-border-b-white hover:tw-bg-[#b2b2b2] + } + .select__trigger{ + @apply tw-relative tw-flex tw-items-center tw-justify-between tw-px-4 tw-leading-9 tw-bg-transparent tw-cursor-pointer dark:tw-text-[#EEEEEE] + } + + .custom-options{ + @apply tw-absolute tw-block tw-top-[100%] tw-left-0 tw-right-0 tw-bg-white tw-transition-all tw-pointer-events-none tw-z-[2] tw-opacity-0 tw-invisible dark:tw-bg-[#1e1e1e] + } + + .select.open .custom-options{ + @apply tw-opacity-100 tw-visible tw-pointer-events-auto + } + + .custom-option{ + @apply tw-relative tw-block tw-px-4 tw-leading-9 tw-text-black tw-cursor-pointer tw-transition-all dark:tw-text-[#EEEEEE] hover:tw-bg-[#b2b2b2] + } + + .custom-option.selected{ + @apply tw-text-[#1976D2] tw-bg-[#1976D2]/30 + } +} +/*fin custom select*/ + + +.disabled\:bg-transparent { + background-color: transparent; + } + +/* Optionally, adjust the opacity for a more subdued appearance */ +.disabled\:opacity-50 { + opacity: 0.5; /* Adjust the opacity as needed */ +} + +.disabled\:outline { + outline-style: solid; +} + +.tooltip { + position: relative; +} + +.tooltip .fa-question-circle { + cursor: pointer; +} + +.tooltip-text { + visibility: hidden; + width: max-content; + max-width: 500px; + background-color: #000; + color: #fff; + text-align: center; + border-radius: 4px; + padding: 4px 8px; + position: absolute; + font-size: 12px; + z-index: 999; + top: -50px; + left: 50%; + transform: translateX(-50%); + opacity: 0; + transition: opacity 0.3s; +} + +.tooltip:hover .tooltip-text { + visibility: visible; + opacity: 1; +} + +.tw-preflight *, +::before, +::after { + box-sizing: border-box; + /* 1 */ + +} + + +.tw-preflight ::before, +.tw-preflight ::after { + --tw-content: ""; +} + +/* +1. Use a consistent sensible line-height in all browsers. +2. Prevent adjustments of font size after orientation changes in iOS. +3. Use a more readable tab size. +4. Use the user's configured `sans` font-family by default. +5. Use the user's configured `sans` font-feature-settings by default. +6. Use the user's configured `sans` font-variation-settings by default. +*/ + +.tw-preflight { + line-height: 1.5; + /* 1 */ + -webkit-text-size-adjust: 100%; + /* 2 */ + -moz-tab-size: 4; + /* 3 */ + -o-tab-size: 4; + tab-size: 4; + /* 3 */ + font-family: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, + "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, + "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", + "Noto Color Emoji"; + /* 4 */ + font-feature-settings: normal; + /* 5 */ + font-variation-settings: normal; + /* 6 */ + margin: 0; +} + +input::-webkit-outer-spin-button, +input::-webkit-inner-spin-button { + -webkit-appearance: none; + margin: 0; +} + + +input[type=number] { + -moz-appearance: textfield; +} + +/* +1. Add the correct height in Firefox. +2. Correct the inheritance of border color in Firefox. (https://bugzilla.mozilla.org/show_bug.cgi?id=190655) +3. Ensure horizontal rules are visible by default. +*/ + +.tw-preflight hr { + height: 0; + /* 1 */ + color: inherit; + /* 2 */ + border-top-width: 1px; + /* 3 */ +} + +/* +Add the correct text decoration in Chrome, Edge, and Safari. +*/ + +.tw-preflight abbr:where([title]) { + -webkit-text-decoration: underline dotted; + text-decoration: underline dotted; +} + +/* +Remove the default font size and weight for headings. +*/ + +.tw-preflight h1, +.tw-preflight h2, +.tw-preflight h3, +.tw-preflight h4, +.tw-preflight h5, +.tw-preflight h6 { + font-size: inherit; + font-weight: inherit; +} + +/* +Reset links to optimize for opt-in styling instead of opt-out. +*/ + +.tw-preflight a { + color: inherit; + text-decoration: inherit; +} + +/* +Add the correct font weight in Edge and Safari. +*/ + +.tw-preflight b, +.tw-preflight strong { + font-weight: bolder; +} + +/* +1. Use the user's configured `mono` font family by default. +2. Correct the odd `em` font sizing in all browsers. +*/ + +.tw-preflight code, +.tw-preflight kbd, +.tw-preflight samp, +.tw-preflight pre { + font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, + "Liberation Mono", "Courier New", monospace; + /* 1 */ + font-size: 1em; + /* 2 */ +} + +/* +Add the correct font size in all browsers. +*/ + +.tw-preflight small { + font-size: 80%; +} + +/* +Prevent `sub` and `sup` elements from affecting the line height in all browsers. +*/ + +.tw-preflight sub, +.tw-preflight sup { + font-size: 75%; + line-height: 0; + position: relative; + vertical-align: baseline; +} + +.tw-preflight sub { + bottom: -0.25em; +} + +.tw-preflight sup { + top: -0.5em; +} + +/* +1. Remove text indentation from table contents in Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=999088, https://bugs.webkit.org/show_bug.cgi?id=201297) +2. Correct table border color inheritance in all Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=935729, https://bugs.webkit.org/show_bug.cgi?id=195016) +3. Remove gaps between table borders by default. +*/ + +.tw-preflight table { + text-indent: 0; + /* 1 */ + border-color: inherit; + /* 2 */ + border-collapse: collapse; + /* 3 */ +} + +/* +1. Change the font styles in all browsers. +2. Remove the margin in Firefox and Safari. +3. Remove default padding in all browsers. +*/ + +.tw-preflight button, +.tw-preflight input, +.tw-preflight optgroup, +.tw-preflight select, +.tw-preflight textarea { + font-family: inherit; + /* 1 */ + font-feature-settings: inherit; + /* 1 */ + font-variation-settings: inherit; + /* 1 */ + font-size: 100%; + /* 1 */ + font-weight: inherit; + /* 1 */ + line-height: inherit; + /* 1 */ + color: inherit; + /* 1 */ + margin: 0; + /* 2 */ + padding: 0; + /* 3 */ +} + +/* +Remove the inheritance of text transform in Edge and Firefox. +*/ + +.tw-preflight button, +.tw-preflight select { + text-transform: none; +} + +/* +1. Correct the inability to style clickable types in iOS and Safari. +2. Remove default button styles. +*/ + +.tw-preflight button, +.tw-preflight [type="button"], +.tw-preflight [type="reset"], +.tw-preflight [type="submit"] { + -webkit-appearance: button; + /* 1 */ + background-color: transparent; + /* 2 */ + background-image: none; + /* 2 */ +} + +/* +Use the modern Firefox focus style for all focusable elements. +*/ + +.tw-preflight :-moz-focusring { + outline: auto; +} + +/* +Remove the additional `:invalid` styles in Firefox. (https://github.com/mozilla/gecko-dev/blob/2f9eacd9d3d995c937b4251a5557d95d494c9be1/layout/style/res/forms.css#L728-L737) +*/ + +.tw-preflight :-moz-ui-invalid { + box-shadow: none; +} + +/* +Add the correct vertical alignment in Chrome and Firefox. +*/ + +.tw-preflight progress { + vertical-align: baseline; +} + +/* +Correct the cursor style of increment and decrement buttons in Safari. +*/ + +.tw-preflight ::-webkit-inner-spin-button, +.tw-preflight ::-webkit-outer-spin-button { + height: auto; +} + +/* +1. Correct the odd appearance in Chrome and Safari. +2. Correct the outline style in Safari. +*/ + +.tw-preflight [type="search"] { + -webkit-appearance: textfield; + /* 1 */ + outline-offset: -2px; + /* 2 */ +} + +/* +Remove the inner padding in Chrome and Safari on macOS. +*/ + +.tw-preflight ::-webkit-search-decoration { + -webkit-appearance: none; +} + +/* +1. Correct the inability to style clickable types in iOS and Safari. +2. Change font properties to `inherit` in Safari. +*/ + +.tw-preflight ::-webkit-file-upload-button { + -webkit-appearance: button; + /* 1 */ + font: inherit; + /* 2 */ +} + +/* +Add the correct display in Chrome and Safari. +*/ + +.tw-preflight summary { + display: list-item; +} + +/* +Removes the default spacing and border for appropriate elements. +*/ + +.tw-preflight blockquote, +.tw-preflight dl, +.tw-preflight dd, +.tw-preflight h1, +.tw-preflight h2, +.tw-preflight h3, +.tw-preflight h4, +.tw-preflight h5, +.tw-preflight h6, +.tw-preflight hr, +.tw-preflight figure, +.tw-preflight p, +.tw-preflight pre { + margin: 0; +} + +.tw-preflight fieldset { + margin: 0; + padding: 0; +} + +.tw-preflight legend { + padding: 0; +} + +.tw-preflight ol, +.tw-preflight ul, +.tw-preflight menu { + list-style: none; + margin: 0; + padding: 0; +} + +/* +Reset default styling for dialogs. +*/ + +.tw-preflight dialog { + padding: 0; +} + +/* +Prevent resizing textareas horizontally by default. +*/ + +.tw-preflight textarea { + resize: vertical; +} + +/* +1. Reset the default placeholder opacity in Firefox. (https://github.com/tailwindlabs/tailwindcss/issues/3300) +2. Set the default placeholder color to the user's configured gray 400 color. +*/ + +.tw-preflight input::-moz-placeholder, +.tw-preflight textarea::-moz-placeholder { + opacity: 1; + /* 1 */ + color: #9ca3af; + /* 2 */ +} + +.tw-preflight input::placeholder, +.tw-preflight textarea::placeholder { + opacity: 1; + /* 1 */ + color: #9ca3af; + /* 2 */ +} + +/* +Set the default cursor for buttons. +*/ + +.tw-preflight button, +[role="button"] { + cursor: pointer; +} + +/* +Make sure disabled buttons don't get the pointer cursor. +*/ + +.tw-preflight :disabled { + cursor: default; +} + +/* +1. Make replaced elements `display: block` by default. (https://github.com/mozdevs/cssremedy/issues/14) +2. Add `vertical-align: middle` to align replaced elements more sensibly by default. (https://github.com/jensimmons/cssremedy/issues/14#issuecomment-634934210) + This can trigger a poorly considered lint error in some tools but is included by design. +*/ + +.tw-preflight img, +.tw-preflight svg, +.tw-preflight, +.tw-preflight canvas, +.tw-preflight, +.tw-preflight iframe, +.tw-preflight embed, +.tw-preflight object { + display: block; + /* 1 */ + vertical-align: middle; + /* 2 */ +} + +/* +Constrain images and videos to the parent width and preserve their intrinsic aspect ratio. (https://github.com/mozdevs/cssremedy/issues/14) +*/ + +.tw-preflight img, +.tw-preflight video { + max-width: 100%; + height: auto; +} + +/* Make elements with the HTML hidden attribute stay hidden by default */ + +.tw-preflight [hidden] { + display: none; +} + +.tw-preflight *, +.tw-preflight ::before, +.tw-preflight ::after { + --tw-border-spacing-x: 0; + --tw-border-spacing-y: 0; + --tw-translate-x: 0; + --tw-translate-y: 0; + --tw-rotate: 0; + --tw-skew-x: 0; + --tw-skew-y: 0; + --tw-scale-x: 1; + --tw-scale-y: 1; + --tw-pan-x: ; + --tw-pan-y: ; + --tw-pinch-zoom: ; + --tw-scroll-snap-strictness: proximity; + --tw-gradient-from-position: ; + --tw-gradient-via-position: ; + --tw-gradient-to-position: ; + --tw-ordinal: ; + --tw-slashed-zero: ; + --tw-numeric-figure: ; + --tw-numeric-spacing: ; + --tw-numeric-fraction: ; + --tw-ring-inset: ; + --tw-ring-offset-width: 0px; + --tw-ring-offset-color: #fff; + --tw-ring-color: rgb(59 130 246 / 0.5); + --tw-ring-offset-shadow: 0 0 #0000; + --tw-ring-shadow: 0 0 #0000; + --tw-shadow: 0 0 #0000; + --tw-shadow-colored: 0 0 #0000; + --tw-blur: ; + --tw-brightness: ; + --tw-contrast: ; + --tw-grayscale: ; + --tw-hue-rotate: ; + --tw-invert: ; + --tw-saturate: ; + --tw-sepia: ; + --tw-drop-shadow: ; + --tw-backdrop-blur: ; + --tw-backdrop-brightness: ; + --tw-backdrop-contrast: ; + --tw-backdrop-grayscale: ; + --tw-backdrop-hue-rotate: ; + --tw-backdrop-invert: ; + --tw-backdrop-opacity: ; + --tw-backdrop-saturate: ; + --tw-backdrop-sepia: ; +} + +.tw-preflight ::backdrop { + --tw-border-spacing-x: 0; + --tw-border-spacing-y: 0; + --tw-translate-x: 0; + --tw-translate-y: 0; + --tw-rotate: 0; + --tw-skew-x: 0; + --tw-skew-y: 0; + --tw-scale-x: 1; + --tw-scale-y: 1; + --tw-pan-x: ; + --tw-pan-y: ; + --tw-pinch-zoom: ; + --tw-scroll-snap-strictness: proximity; + --tw-gradient-from-position: ; + --tw-gradient-via-position: ; + --tw-gradient-to-position: ; + --tw-ordinal: ; + --tw-slashed-zero: ; + --tw-numeric-figure: ; + --tw-numeric-spacing: ; + --tw-numeric-fraction: ; + --tw-ring-inset: ; + --tw-ring-offset-width: 0px; + --tw-ring-offset-color: #fff; + --tw-ring-color: rgb(59 130 246 / 0.5); + --tw-ring-offset-shadow: 0 0 #0000; + --tw-ring-shadow: 0 0 #0000; + --tw-shadow: 0 0 #0000; + --tw-shadow-colored: 0 0 #0000; + --tw-blur: ; + --tw-brightness: ; + --tw-contrast: ; + --tw-grayscale: ; + --tw-hue-rotate: ; + --tw-invert: ; + --tw-saturate: ; + --tw-sepia: ; + --tw-drop-shadow: ; + --tw-backdrop-blur: ; + --tw-backdrop-brightness: ; + --tw-backdrop-contrast: ; + --tw-backdrop-grayscale: ; + --tw-backdrop-hue-rotate: ; + --tw-backdrop-invert: ; + --tw-backdrop-opacity: ; + --tw-backdrop-saturate: ; + --tw-backdrop-sepia: ; +} \ No newline at end of file diff --git a/lightcurve/tailwind.config.js b/lightcurve/tailwind.config.js index b250d56e7..31d950da0 100644 --- a/lightcurve/tailwind.config.js +++ b/lightcurve/tailwind.config.js @@ -8,9 +8,15 @@ module.exports = { "./src/magstats_api/templates//*.{html.jinja,html,css}", "./src/object_api/templates//*.{html.jinja,html,css}", "./src/crossmatch_api/templates//*.{html.jinja,html,css}", + "./src/probability_api/templates//*.{html.jinja,html,css}", + ], theme: { - extend: {}, + extend: { + fontFamily: { + roboto: ['Roboto', 'sans-serif'], + } + }, }, plugins: [], corePlugins: {