diff --git a/.gitignore b/.gitignore index 699dd1d..40cd709 100644 --- a/.gitignore +++ b/.gitignore @@ -3,4 +3,5 @@ bin gridCertificate.p12 data **/__debug* -.vscode \ No newline at end of file +.vscode +docker-for-azure/activate \ No newline at end of file diff --git a/Dockerfile b/Dockerfile index 2c474de..cbfab1a 100644 --- a/Dockerfile +++ b/Dockerfile @@ -10,7 +10,7 @@ COPY go.mod go.sum ./ RUN go mod download # install tailwind CLI -ENV TAILWIND_VERSION=v3.3.2 +ENV TAILWIND_VERSION=v3.4.10 RUN curl -L "https://github.com/tailwindlabs/tailwindcss/releases/download/$TAILWIND_VERSION/tailwindcss-linux-x64" -o /usr/local/bin/tailwindcss RUN chmod +x /usr/local/bin/tailwindcss @@ -47,13 +47,15 @@ RUN mkdir ~/.globus RUN openssl pkcs12 -clcerts -nokeys -in ./gridCertificate.p12 -out ~/.globus/usercert.pem -password pass: RUN openssl pkcs12 -nocerts -nodes -in ./gridCertificate.p12 -out ~/.globus/userkey.pem -password pass: RUN chmod 0400 ~/.globus/userkey.pem +ENV CCDB_SSL_CERT_PATH=/root/.globus/usercert.pem +ENV CCDB_SSL_KEY_PATH=/root/.globus/userkey.pem WORKDIR /app RUN alien.py getCAcerts -# for some reason first execution of ls is returning nil - from second and then on it works great +# for some reason first execution of ls is returning nil - from second and on it works as expected RUN alien_ls / -COPY --from=builder /app/.env /app/AliceTraINT . +COPY --from=builder /app/.env /app/AliceTraINT ./ COPY --from=builder /app/web ./web COPY --from=builder /app/static/ ./static/ diff --git a/docker-for-azure/Dockerfile b/docker-for-azure/Dockerfile new file mode 100644 index 0000000..b4d48f5 --- /dev/null +++ b/docker-for-azure/Dockerfile @@ -0,0 +1,5 @@ +# run build.sh from docker-for-azure container +FROM mytkom/alicetraint + +WORKDIR /app +COPY root.crt . diff --git a/docker-for-azure/build.sh b/docker-for-azure/build.sh new file mode 100755 index 0000000..77a23c8 --- /dev/null +++ b/docker-for-azure/build.sh @@ -0,0 +1,6 @@ +#!/usr/bin/env bash + +# Run only from docker-for-azure subdir +docker build -t mytkom/alicetraint ../ +docker build -t mytkom/alicetraint-for-azure . +docker tag mytkom/alicetraint-for-azure $IMAGE_NAME \ No newline at end of file diff --git a/docker-for-azure/deploy_container.sh b/docker-for-azure/deploy_container.sh new file mode 100755 index 0000000..3083b8a --- /dev/null +++ b/docker-for-azure/deploy_container.sh @@ -0,0 +1,51 @@ +#!/usr/bin/env bash + +# ENVs to fill +# RESOURCE_GROUP= +# STORAGE_ACCOUNT_NAME= +# LOCATION= +# SHARE_NAME= +# ALICETRAINT_ACR_NAME= +# ALICETRAINT_ACR_URL= +# IMAGE_NAME= +# STORAGE_KEY=$(az storage account keys list --resource-group $RESOURCE_GROUP --account-name $STORAGE_ACCOUNT_NAME --query "[0].value" --output tsv) +# SERVICE_PRINCIPAL_USERNAME= +# SERVICE_PRINCIPAL_PASSWORD= +# PGHOST= +# PGUSER= +# PGPORT= +# PGDATABASE= +# PGPASSWORD= +# CERN_REDIRECT_URL= +# SSL_ROOT_CERT_PATH= + +# Before this script +# 1. Log In to acr +# 2. Set all envs +# 3. Run build.sh + +# Deploy container +az container create --resource-group $RESOURCE_GROUP \ + --name alicetraint \ + --image $IMAGE_NAME \ + --dns-name-label alicetraint \ + --ports 80 \ + --cpu 1 \ + --memory 1 \ + --registry-username $SERVICE_PRINCIPAL_USERNAME \ + --registry-password $SERVICE_PRINCIPAL_PASSWORD \ + --azure-file-volume-account-name $STORAGE_ACCOUNT_NAME \ + --azure-file-volume-account-key $STORAGE_KEY \ + --azure-file-volume-share-name $SHARE_NAME \ + --azure-file-volume-mount-path /app/data/ \ + --secure-environment-variables \ + 'DB_PASSWORD'=$PGPASSWORD \ + --environment-variables \ + 'DB_HOST'=$PGHOST \ + 'DB_PORT'=$PGPORT \ + 'DB_USER'=$PGUSER \ + 'DB_NAME'=$PGDATABASE \ + 'CERN_REDIRECT_URL'=$CERN_REDIRECT_URL \ + 'ALICETRAINT_PORT'='80' \ + 'DB_SSL_CERT_PATH'=$SSL_ROOT_CERT_PATH \ + 'DB_SSLMODE'='verify-full' diff --git a/docker-for-azure/root.crt b/docker-for-azure/root.crt new file mode 100644 index 0000000..3bdfb23 --- /dev/null +++ b/docker-for-azure/root.crt @@ -0,0 +1,33 @@ +-----BEGIN CERTIFICATE----- +MIIFqDCCA5CgAwIBAgIQHtOXCV/YtLNHcB6qvn9FszANBgkqhkiG9w0BAQwFADBl +MQswCQYDVQQGEwJVUzEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMTYw +NAYDVQQDEy1NaWNyb3NvZnQgUlNBIFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5 +IDIwMTcwHhcNMTkxMjE4MjI1MTIyWhcNNDIwNzE4MjMwMDIzWjBlMQswCQYDVQQG +EwJVUzEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMTYwNAYDVQQDEy1N +aWNyb3NvZnQgUlNBIFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IDIwMTcwggIi +MA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDKW76UM4wplZEWCpW9R2LBifOZ +Nt9GkMml7Xhqb0eRaPgnZ1AzHaGm++DlQ6OEAlcBXZxIQIJTELy/xztokLaCLeX0 +ZdDMbRnMlfl7rEqUrQ7eS0MdhweSE5CAg2Q1OQT85elss7YfUJQ4ZVBcF0a5toW1 +HLUX6NZFndiyJrDKxHBKrmCk3bPZ7Pw71VdyvD/IybLeS2v4I2wDwAW9lcfNcztm +gGTjGqwu+UcF8ga2m3P1eDNbx6H7JyqhtJqRjJHTOoI+dkC0zVJhUXAoP8XFWvLJ +jEm7FFtNyP9nTUwSlq31/niol4fX/V4ggNyhSyL71Imtus5Hl0dVe49FyGcohJUc +aDDv70ngNXtk55iwlNpNhTs+VcQor1fznhPbRiefHqJeRIOkpcrVE7NLP8TjwuaG +YaRSMLl6IE9vDzhTyzMMEyuP1pq9KsgtsRx9S1HKR9FIJ3Jdh+vVReZIZZ2vUpC6 +W6IYZVcSn2i51BVrlMRpIpj0M+Dt+VGOQVDJNE92kKz8OMHY4Xu54+OU4UZpyw4K +UGsTuqwPN1q3ErWQgR5WrlcihtnJ0tHXUeOrO8ZV/R4O03QK0dqq6mm4lyiPSMQH ++FJDOvTKVTUssKZqwJz58oHhEmrARdlns87/I6KJClTUFLkqqNfs+avNJVgyeY+Q +W5g5xAgGwax/Dj0ApQIDAQABo1QwUjAOBgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/ +BAUwAwEB/zAdBgNVHQ4EFgQUCctZf4aycI8awznjwNnpv7tNsiMwEAYJKwYBBAGC +NxUBBAMCAQAwDQYJKoZIhvcNAQEMBQADggIBAKyvPl3CEZaJjqPnktaXFbgToqZC +LgLNFgVZJ8og6Lq46BrsTaiXVq5lQ7GPAJtSzVXNUzltYkyLDVt8LkS/gxCP81OC +gMNPOsduET/m4xaRhPtthH80dK2Jp86519efhGSSvpWhrQlTM93uCupKUY5vVau6 +tZRGrox/2KJQJWVggEbbMwSubLWYdFQl3JPk+ONVFT24bcMKpBLBaYVu32TxU5nh +SnUgnZUP5NbcA/FZGOhHibJXWpS2qdgXKxdJ5XbLwVaZOjex/2kskZGT4d9Mozd2 +TaGf+G0eHdP67Pv0RR0Tbc/3WeUiJ3IrhvNXuzDtJE3cfVa7o7P4NHmJweDyAmH3 +pvwPuxwXC65B2Xy9J6P9LjrRk5Sxcx0ki69bIImtt2dmefU6xqaWM/5TkshGsRGR +xpl/j8nWZjEgQRCHLQzWwa80mMpkg/sTV9HB8Dx6jKXB/ZUhoHHBk2dxEuqPiApp +GWSZI1b7rCoucL5mxAyE7+WL85MB+GqQk2dLsmijtWKP6T+MejteD+eMuMZ87zf9 +dOLITzNy4ZQ5bb0Sr74MTnB8G2+NszKTc0QWbej09+CVgI+WXTik9KveCjCHk9hN +AHFiRSdLOkKEW39lt2c0Ui2cFmuqqNh7o0JMcccMyj6D5KbvtwEwXlGjefVwaaZB +RA+GsCyRxj3qrg+E +-----END CERTIFICATE----- diff --git a/internal/config/config.go b/internal/config/config.go index 93c41a9..949c8db 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -22,12 +22,13 @@ type Config struct { } type DatabaseConfig struct { - Host string - Port uint - User string - Password string - DBName string - SSLMode string + Host string + Port uint + User string + Password string + DBName string + SSLMode string + SSLRootCertPath string } func LoadConfig() *Config { @@ -38,12 +39,13 @@ func LoadConfig() *Config { return &Config{ Database: DatabaseConfig{ - Host: getEnv("DB_HOST", "localhost"), - Port: getEnvAsUint("DB_PORT", 5432), - User: getEnv("DB_USER", "user"), - Password: getEnv("DB_PASSWORD", "password"), - DBName: getEnv("DB_NAME", "AliceTraINT_db"), - SSLMode: getEnv("DB_SSLMODE", "disable"), + Host: getEnv("DB_HOST", "localhost"), + Port: getEnvAsUint("DB_PORT", 5432), + User: getEnv("DB_USER", "user"), + Password: getEnv("DB_PASSWORD", "password"), + DBName: getEnv("DB_NAME", "AliceTraINT_db"), + SSLMode: getEnv("DB_SSLMODE", "disable"), + SSLRootCertPath: getEnv("DB_SSL_CERT_PATH", ""), }, Port: getEnv("ALICETRAINT_PORT", "8088"), JalienCacheMinutes: getEnvAsUint("ALICETRAINT_JALIEN_CACHE_MINUTES", 60), @@ -57,10 +59,17 @@ func LoadConfig() *Config { } func (dbConfig *DatabaseConfig) ConnectionString() string { - return fmt.Sprintf( - "host=%s port=%d user=%s password=%s dbname=%s sslmode=%s", - dbConfig.Host, dbConfig.Port, dbConfig.User, dbConfig.Password, dbConfig.DBName, dbConfig.SSLMode, - ) + if dbConfig.SSLMode == "disabled" { + return fmt.Sprintf( + "host=%s port=%d user=%s password=%s dbname=%s sslmode=%s", + dbConfig.Host, dbConfig.Port, dbConfig.User, dbConfig.Password, dbConfig.DBName, dbConfig.SSLMode, + ) + } else { + return fmt.Sprintf( + "host=%s port=%d user=%s password=%s dbname=%s sslmode=%s sslrootcert=%s", + dbConfig.Host, dbConfig.Port, dbConfig.User, dbConfig.Password, dbConfig.DBName, dbConfig.SSLMode, dbConfig.SSLRootCertPath, + ) + } } func getEnv(key, defaultValue string) string { diff --git a/internal/db/migrate/migrate.go b/internal/db/migrate/migrate.go index ae2093e..5a60f66 100644 --- a/internal/db/migrate/migrate.go +++ b/internal/db/migrate/migrate.go @@ -5,6 +5,7 @@ import ( "time" "github.com/mytkom/AliceTraINT/internal/db/models" + "github.com/mytkom/AliceTraINT/internal/hash" "github.com/mytkom/AliceTraINT/internal/jalien" "gorm.io/gorm" ) @@ -87,25 +88,25 @@ func SeedDB(db *gorm.DB) error { }, { Name: "AO2D.root", - Path: "/alice/sim/2023/LHC23e1/302002/AOD/013/AO2D.root", + Path: "/alice/sim/2023/LHC23d4/302005/AOD/013/AO2D.root", Size: 35403114, - LHCPeriod: "LHC23e1", + LHCPeriod: "LHC23d4", RunNumber: 302002, AODNumber: 13, }, { Name: "AO2D.root", - Path: "/alice/sim/2023/LHC23e1/302002/AOD/024/AO2D.root", + Path: "/alice/sim/2023/LHC23d4/302005/AOD/024/AO2D.root", Size: 97906832, - LHCPeriod: "LHC23e1", + LHCPeriod: "LHC23d4", RunNumber: 302002, AODNumber: 24, }, { Name: "AO2D.root", - Path: "/alice/sim/2023/LHC23e1/302002/AOD/030/AO2D.root", + Path: "/alice/sim/2023/LHC23d4/302005/AOD/030/AO2D.root", Size: 175726295, - LHCPeriod: "LHC23e1", + LHCPeriod: "LHC23d4", RunNumber: 302002, AODNumber: 30, }, @@ -120,9 +121,13 @@ func SeedDB(db *gorm.DB) error { return err } + secretHashed, err := hash.HashKey("secretkey_secretkey_secretkey_sk") + if err != nil { + return err + } trainingMachines := []models.TrainingMachine{ - {Name: "tm1", LastActivityAt: time.Now(), SecretKeyHashed: "salt:secret", UserId: users[0].ID}, - {Name: "tm2", LastActivityAt: time.Now(), SecretKeyHashed: "salt:secret2", UserId: users[1].ID}, + {Name: "tm1", LastActivityAt: time.Now(), SecretKeyHashed: secretHashed, UserId: users[0].ID}, + {Name: "tm2", LastActivityAt: time.Now(), SecretKeyHashed: secretHashed, UserId: users[1].ID}, } if err := db.Save(trainingMachines).Error; err != nil { diff --git a/internal/handler/queue_handler.go b/internal/handler/queue_handler.go index 59abe9a..f882f6e 100644 --- a/internal/handler/queue_handler.go +++ b/internal/handler/queue_handler.go @@ -109,12 +109,11 @@ func (qh *QueueHandler) QueryTask(w http.ResponseWriter, r *http.Request) { Configuration: tt.Configuration, } + w.WriteHeader(http.StatusOK) if err := json.NewEncoder(w).Encode(response); err != nil { http.Error(w, "cannot encode response", http.StatusInternalServerError) return } - - w.WriteHeader(http.StatusOK) } func (qh *QueueHandler) CreateTrainingTaskResult(w http.ResponseWriter, r *http.Request) { diff --git a/internal/service/training_task_service.go b/internal/service/training_task_service.go index febcf5f..1ed8626 100644 --- a/internal/service/training_task_service.go +++ b/internal/service/training_task_service.go @@ -117,7 +117,7 @@ func (s *TrainingTaskService) GetByID(id uint) (*TrainingTaskWithResults, error) } var imageFiles []models.TrainingTaskResult - if trainingTask.Status >= models.Completed { + if trainingTask.Status >= models.Training { imageFiles, err = s.TrainingTaskResult.GetByType(trainingTask.ID, models.Image) if err != nil { return nil, errInternalServerError diff --git a/static/css/output.css b/static/css/output.css index 2c8bc8d..1b39ee3 100644 --- a/static/css/output.css +++ b/static/css/output.css @@ -1,1617 +1 @@ -/* -! tailwindcss v3.4.10 | MIT License | https://tailwindcss.com -*/ - -/* -1. Prevent padding and border from affecting element width. (https://github.com/mozdevs/cssremedy/issues/4) -2. Allow adding a border to an element by just adding a border-width. (https://github.com/tailwindcss/tailwindcss/pull/116) -*/ - -*, -::before, -::after { - box-sizing: border-box; - /* 1 */ - border-width: 0; - /* 2 */ - border-style: solid; - /* 2 */ - border-color: #e5e7eb; - /* 2 */ -} - -::before, -::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. -7. Disable tap highlights on iOS -*/ - -html, -:host { - 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, 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 */ - -webkit-tap-highlight-color: transparent; - /* 7 */ -} - -/* -1. Remove the margin in all browsers. -2. Inherit line-height from `html` so users can set them as a class directly on the `html` element. -*/ - -body { - margin: 0; - /* 1 */ - line-height: inherit; - /* 2 */ -} - -/* -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. -*/ - -hr { - height: 0; - /* 1 */ - color: inherit; - /* 2 */ - border-top-width: 1px; - /* 3 */ -} - -/* -Add the correct text decoration in Chrome, Edge, and Safari. -*/ - -abbr:where([title]) { - -webkit-text-decoration: underline dotted; - text-decoration: underline dotted; -} - -/* -Remove the default font size and weight for headings. -*/ - -h1, -h2, -h3, -h4, -h5, -h6 { - font-size: inherit; - font-weight: inherit; -} - -/* -Reset links to optimize for opt-in styling instead of opt-out. -*/ - -a { - color: inherit; - text-decoration: inherit; -} - -/* -Add the correct font weight in Edge and Safari. -*/ - -b, -strong { - font-weight: bolder; -} - -/* -1. Use the user's configured `mono` font-family by default. -2. Use the user's configured `mono` font-feature-settings by default. -3. Use the user's configured `mono` font-variation-settings by default. -4. Correct the odd `em` font sizing in all browsers. -*/ - -code, -kbd, -samp, -pre { - font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace; - /* 1 */ - font-feature-settings: normal; - /* 2 */ - font-variation-settings: normal; - /* 3 */ - font-size: 1em; - /* 4 */ -} - -/* -Add the correct font size in all browsers. -*/ - -small { - font-size: 80%; -} - -/* -Prevent `sub` and `sup` elements from affecting the line height in all browsers. -*/ - -sub, -sup { - font-size: 75%; - line-height: 0; - position: relative; - vertical-align: baseline; -} - -sub { - bottom: -0.25em; -} - -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. -*/ - -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. -*/ - -button, -input, -optgroup, -select, -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 */ - letter-spacing: inherit; - /* 1 */ - color: inherit; - /* 1 */ - margin: 0; - /* 2 */ - padding: 0; - /* 3 */ -} - -/* -Remove the inheritance of text transform in Edge and Firefox. -*/ - -button, -select { - text-transform: none; -} - -/* -1. Correct the inability to style clickable types in iOS and Safari. -2. Remove default button styles. -*/ - -button, -input:where([type='button']), -input:where([type='reset']), -input:where([type='submit']) { - -webkit-appearance: button; - /* 1 */ - background-color: transparent; - /* 2 */ - background-image: none; - /* 2 */ -} - -/* -Use the modern Firefox focus style for all focusable elements. -*/ - -:-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) -*/ - -:-moz-ui-invalid { - box-shadow: none; -} - -/* -Add the correct vertical alignment in Chrome and Firefox. -*/ - -progress { - vertical-align: baseline; -} - -/* -Correct the cursor style of increment and decrement buttons in Safari. -*/ - -::-webkit-inner-spin-button, -::-webkit-outer-spin-button { - height: auto; -} - -/* -1. Correct the odd appearance in Chrome and Safari. -2. Correct the outline style in Safari. -*/ - -[type='search'] { - -webkit-appearance: textfield; - /* 1 */ - outline-offset: -2px; - /* 2 */ -} - -/* -Remove the inner padding in Chrome and Safari on macOS. -*/ - -::-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. -*/ - -::-webkit-file-upload-button { - -webkit-appearance: button; - /* 1 */ - font: inherit; - /* 2 */ -} - -/* -Add the correct display in Chrome and Safari. -*/ - -summary { - display: list-item; -} - -/* -Removes the default spacing and border for appropriate elements. -*/ - -blockquote, -dl, -dd, -h1, -h2, -h3, -h4, -h5, -h6, -hr, -figure, -p, -pre { - margin: 0; -} - -fieldset { - margin: 0; - padding: 0; -} - -legend { - padding: 0; -} - -ol, -ul, -menu { - list-style: none; - margin: 0; - padding: 0; -} - -/* -Reset default styling for dialogs. -*/ - -dialog { - padding: 0; -} - -/* -Prevent resizing textareas horizontally by default. -*/ - -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. -*/ - -input::-moz-placeholder, textarea::-moz-placeholder { - opacity: 1; - /* 1 */ - color: #9ca3af; - /* 2 */ -} - -input::placeholder, -textarea::placeholder { - opacity: 1; - /* 1 */ - color: #9ca3af; - /* 2 */ -} - -/* -Set the default cursor for buttons. -*/ - -button, -[role="button"] { - cursor: pointer; -} - -/* -Make sure disabled buttons don't get the pointer cursor. -*/ - -: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. -*/ - -img, -svg, -video, -canvas, -audio, -iframe, -embed, -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) -*/ - -img, -video { - max-width: 100%; - height: auto; -} - -/* Make elements with the HTML hidden attribute stay hidden by default */ - -[hidden] { - display: none; -} - -[type='text'],input:where(:not([type])),[type='email'],[type='url'],[type='password'],[type='number'],[type='date'],[type='datetime-local'],[type='month'],[type='search'],[type='tel'],[type='time'],[type='week'],[multiple],textarea,select { - -webkit-appearance: none; - -moz-appearance: none; - appearance: none; - background-color: #fff; - border-color: #6b7280; - border-width: 1px; - border-radius: 0px; - padding-top: 0.5rem; - padding-right: 0.75rem; - padding-bottom: 0.5rem; - padding-left: 0.75rem; - font-size: 1rem; - line-height: 1.5rem; - --tw-shadow: 0 0 #0000; -} - -[type='text']:focus, input:where(:not([type])):focus, [type='email']:focus, [type='url']:focus, [type='password']:focus, [type='number']:focus, [type='date']:focus, [type='datetime-local']:focus, [type='month']:focus, [type='search']:focus, [type='tel']:focus, [type='time']:focus, [type='week']:focus, [multiple]:focus, textarea:focus, select:focus { - outline: 2px solid transparent; - outline-offset: 2px; - --tw-ring-inset: var(--tw-empty,/*!*/ /*!*/); - --tw-ring-offset-width: 0px; - --tw-ring-offset-color: #fff; - --tw-ring-color: #2563eb; - --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color); - --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color); - box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow); - border-color: #2563eb; -} - -input::-moz-placeholder, textarea::-moz-placeholder { - color: #6b7280; - opacity: 1; -} - -input::placeholder,textarea::placeholder { - color: #6b7280; - opacity: 1; -} - -::-webkit-datetime-edit-fields-wrapper { - padding: 0; -} - -::-webkit-date-and-time-value { - min-height: 1.5em; - text-align: inherit; -} - -::-webkit-datetime-edit { - display: inline-flex; -} - -::-webkit-datetime-edit,::-webkit-datetime-edit-year-field,::-webkit-datetime-edit-month-field,::-webkit-datetime-edit-day-field,::-webkit-datetime-edit-hour-field,::-webkit-datetime-edit-minute-field,::-webkit-datetime-edit-second-field,::-webkit-datetime-edit-millisecond-field,::-webkit-datetime-edit-meridiem-field { - padding-top: 0; - padding-bottom: 0; -} - -select { - background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 20 20'%3e%3cpath stroke='%236b7280' stroke-linecap='round' stroke-linejoin='round' stroke-width='1.5' d='M6 8l4 4 4-4'/%3e%3c/svg%3e"); - background-position: right 0.5rem center; - background-repeat: no-repeat; - background-size: 1.5em 1.5em; - padding-right: 2.5rem; - -webkit-print-color-adjust: exact; - print-color-adjust: exact; -} - -[multiple],[size]:where(select:not([size="1"])) { - background-image: initial; - background-position: initial; - background-repeat: unset; - background-size: initial; - padding-right: 0.75rem; - -webkit-print-color-adjust: unset; - print-color-adjust: unset; -} - -[type='checkbox'],[type='radio'] { - -webkit-appearance: none; - -moz-appearance: none; - appearance: none; - padding: 0; - -webkit-print-color-adjust: exact; - print-color-adjust: exact; - display: inline-block; - vertical-align: middle; - background-origin: border-box; - -webkit-user-select: none; - -moz-user-select: none; - user-select: none; - flex-shrink: 0; - height: 1rem; - width: 1rem; - color: #2563eb; - background-color: #fff; - border-color: #6b7280; - border-width: 1px; - --tw-shadow: 0 0 #0000; -} - -[type='checkbox'] { - border-radius: 0px; -} - -[type='radio'] { - border-radius: 100%; -} - -[type='checkbox']:focus,[type='radio']:focus { - outline: 2px solid transparent; - outline-offset: 2px; - --tw-ring-inset: var(--tw-empty,/*!*/ /*!*/); - --tw-ring-offset-width: 2px; - --tw-ring-offset-color: #fff; - --tw-ring-color: #2563eb; - --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color); - --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color); - box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow); -} - -[type='checkbox']:checked,[type='radio']:checked { - border-color: transparent; - background-color: currentColor; - background-size: 100% 100%; - background-position: center; - background-repeat: no-repeat; -} - -[type='checkbox']:checked { - background-image: url("data:image/svg+xml,%3csvg viewBox='0 0 16 16' fill='white' xmlns='http://www.w3.org/2000/svg'%3e%3cpath d='M12.207 4.793a1 1 0 010 1.414l-5 5a1 1 0 01-1.414 0l-2-2a1 1 0 011.414-1.414L6.5 9.086l4.293-4.293a1 1 0 011.414 0z'/%3e%3c/svg%3e"); -} - -@media (forced-colors: active) { - [type='checkbox']:checked { - -webkit-appearance: auto; - -moz-appearance: auto; - appearance: auto; - } -} - -[type='radio']:checked { - background-image: url("data:image/svg+xml,%3csvg viewBox='0 0 16 16' fill='white' xmlns='http://www.w3.org/2000/svg'%3e%3ccircle cx='8' cy='8' r='3'/%3e%3c/svg%3e"); -} - -@media (forced-colors: active) { - [type='radio']:checked { - -webkit-appearance: auto; - -moz-appearance: auto; - appearance: auto; - } -} - -[type='checkbox']:checked:hover,[type='checkbox']:checked:focus,[type='radio']:checked:hover,[type='radio']:checked:focus { - border-color: transparent; - background-color: currentColor; -} - -[type='checkbox']:indeterminate { - background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 16 16'%3e%3cpath stroke='white' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M4 8h8'/%3e%3c/svg%3e"); - border-color: transparent; - background-color: currentColor; - background-size: 100% 100%; - background-position: center; - background-repeat: no-repeat; -} - -@media (forced-colors: active) { - [type='checkbox']:indeterminate { - -webkit-appearance: auto; - -moz-appearance: auto; - appearance: auto; - } -} - -[type='checkbox']:indeterminate:hover,[type='checkbox']:indeterminate:focus { - border-color: transparent; - background-color: currentColor; -} - -[type='file'] { - background: unset; - border-color: inherit; - border-width: 0; - border-radius: 0; - padding: 0; - font-size: unset; - line-height: inherit; -} - -[type='file']:focus { - outline: 1px solid ButtonText; - outline: 1px auto -webkit-focus-ring-color; -} - -*, ::before, ::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-contain-size: ; - --tw-contain-layout: ; - --tw-contain-paint: ; - --tw-contain-style: ; -} - -::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-contain-size: ; - --tw-contain-layout: ; - --tw-contain-paint: ; - --tw-contain-style: ; -} - -.container { - width: 100%; -} - -@media (min-width: 640px) { - .container { - max-width: 640px; - } -} - -@media (min-width: 768px) { - .container { - max-width: 768px; - } -} - -@media (min-width: 1024px) { - .container { - max-width: 1024px; - } -} - -@media (min-width: 1280px) { - .container { - max-width: 1280px; - } -} - -@media (min-width: 1536px) { - .container { - max-width: 1536px; - } -} - -.absolute { - position: absolute; -} - -.relative { - position: relative; -} - -.sticky { - position: sticky; -} - -.inset-0 { - inset: 0px; -} - -.left-4 { - left: 1rem; -} - -.right-4 { - right: 1rem; -} - -.top-0 { - top: 0px; -} - -.top-1\/2 { - top: 50%; -} - -.z-10 { - z-index: 10; -} - -.col-span-2 { - grid-column: span 2 / span 2; -} - -.col-start-1 { - grid-column-start: 1; -} - -.col-start-2 { - grid-column-start: 2; -} - -.row-start-2 { - grid-row-start: 2; -} - -.mx-auto { - margin-left: auto; - margin-right: auto; -} - -.my-4 { - margin-top: 1rem; - margin-bottom: 1rem; -} - -.mb-5 { - margin-bottom: 1.25rem; -} - -.mt-4 { - margin-top: 1rem; -} - -.mt-5 { - margin-top: 1.25rem; -} - -.block { - display: block; -} - -.flex { - display: flex; -} - -.table { - display: table; -} - -.grid { - display: grid; -} - -.hidden { - display: none; -} - -.size-14 { - width: 3.5rem; - height: 3.5rem; -} - -.size-4 { - width: 1rem; - height: 1rem; -} - -.h-12 { - height: 3rem; -} - -.h-3 { - height: 0.75rem; -} - -.h-5 { - height: 1.25rem; -} - -.h-8 { - height: 2rem; -} - -.h-full { - height: 100%; -} - -.max-h-96 { - max-height: 24rem; -} - -.max-h-full { - max-height: 100%; -} - -.max-h-screen { - max-height: 100vh; -} - -.min-h-48 { - min-height: 12rem; -} - -.min-h-96 { - min-height: 24rem; -} - -.min-h-screen { - min-height: 100vh; -} - -.w-16 { - width: 4rem; -} - -.w-3 { - width: 0.75rem; -} - -.w-40 { - width: 10rem; -} - -.w-5 { - width: 1.25rem; -} - -.w-8 { - width: 2rem; -} - -.w-full { - width: 100%; -} - -.flex-shrink { - flex-shrink: 1; -} - -.flex-grow { - flex-grow: 1; -} - -.border-collapse { - border-collapse: collapse; -} - -.-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 { - 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)); -} - -.cursor-pointer { - cursor: pointer; -} - -.auto-cols-auto { - grid-auto-columns: auto; -} - -.auto-rows-auto { - grid-auto-rows: auto; -} - -.grid-cols-1 { - grid-template-columns: repeat(1, minmax(0, 1fr)); -} - -.grid-cols-2 { - grid-template-columns: repeat(2, minmax(0, 1fr)); -} - -.grid-cols-3 { - grid-template-columns: repeat(3, minmax(0, 1fr)); -} - -.grid-cols-7 { - grid-template-columns: repeat(7, minmax(0, 1fr)); -} - -.grid-rows-2 { - grid-template-rows: repeat(2, minmax(0, 1fr)); -} - -.flex-row { - flex-direction: row; -} - -.flex-col { - flex-direction: column; -} - -.flex-wrap { - flex-wrap: wrap; -} - -.content-stretch { - align-content: stretch; -} - -.items-center { - align-items: center; -} - -.items-stretch { - align-items: stretch; -} - -.justify-start { - justify-content: flex-start; -} - -.justify-end { - justify-content: flex-end; -} - -.justify-center { - justify-content: center; -} - -.justify-between { - justify-content: space-between; -} - -.justify-stretch { - justify-content: stretch; -} - -.gap-0 { - gap: 0px; -} - -.gap-1 { - gap: 0.25rem; -} - -.gap-2 { - gap: 0.5rem; -} - -.gap-3 { - gap: 0.75rem; -} - -.gap-4 { - gap: 1rem; -} - -.gap-5 { - gap: 1.25rem; -} - -.self-end { - align-self: flex-end; -} - -.self-center { - align-self: center; -} - -.self-stretch { - align-self: stretch; -} - -.justify-self-end { - justify-self: end; -} - -.justify-self-stretch { - justify-self: stretch; -} - -.overflow-hidden { - overflow: hidden; -} - -.overflow-x-auto { - overflow-x: auto; -} - -.overflow-y-auto { - overflow-y: auto; -} - -.rounded { - border-radius: 0.25rem; -} - -.rounded-full { - border-radius: 9999px; -} - -.rounded-lg { - border-radius: 0.5rem; -} - -.rounded-md { - border-radius: 0.375rem; -} - -.border { - border-width: 1px; -} - -.border-b { - border-bottom-width: 1px; -} - -.border-b-2 { - border-bottom-width: 2px; -} - -.border-dotted { - border-style: dotted; -} - -.border-sky-200 { - --tw-border-opacity: 1; - border-color: rgb(186 230 253 / var(--tw-border-opacity)); -} - -.border-sky-900 { - --tw-border-opacity: 1; - border-color: rgb(12 74 110 / var(--tw-border-opacity)); -} - -.bg-emerald-600 { - --tw-bg-opacity: 1; - background-color: rgb(5 150 105 / var(--tw-bg-opacity)); -} - -.bg-gray-400 { - --tw-bg-opacity: 1; - background-color: rgb(156 163 175 / var(--tw-bg-opacity)); -} - -.bg-gray-700 { - --tw-bg-opacity: 1; - background-color: rgb(55 65 81 / var(--tw-bg-opacity)); -} - -.bg-green-400 { - --tw-bg-opacity: 1; - background-color: rgb(74 222 128 / var(--tw-bg-opacity)); -} - -.bg-green-600 { - --tw-bg-opacity: 1; - background-color: rgb(22 163 74 / var(--tw-bg-opacity)); -} - -.bg-red-400 { - --tw-bg-opacity: 1; - background-color: rgb(248 113 113 / var(--tw-bg-opacity)); -} - -.bg-red-600 { - --tw-bg-opacity: 1; - background-color: rgb(220 38 38 / var(--tw-bg-opacity)); -} - -.bg-sky-100 { - --tw-bg-opacity: 1; - background-color: rgb(224 242 254 / var(--tw-bg-opacity)); -} - -.bg-sky-200 { - --tw-bg-opacity: 1; - background-color: rgb(186 230 253 / var(--tw-bg-opacity)); -} - -.bg-sky-50 { - --tw-bg-opacity: 1; - background-color: rgb(240 249 255 / var(--tw-bg-opacity)); -} - -.bg-sky-800 { - --tw-bg-opacity: 1; - background-color: rgb(7 89 133 / var(--tw-bg-opacity)); -} - -.bg-sky-900 { - --tw-bg-opacity: 1; - background-color: rgb(12 74 110 / var(--tw-bg-opacity)); -} - -.bg-white { - --tw-bg-opacity: 1; - background-color: rgb(255 255 255 / var(--tw-bg-opacity)); -} - -.bg-yellow-200 { - --tw-bg-opacity: 1; - background-color: rgb(254 240 138 / var(--tw-bg-opacity)); -} - -.bg-yellow-600 { - --tw-bg-opacity: 1; - background-color: rgb(202 138 4 / var(--tw-bg-opacity)); -} - -.object-contain { - -o-object-fit: contain; - object-fit: contain; -} - -.object-cover { - -o-object-fit: cover; - object-fit: cover; -} - -.p-2 { - padding: 0.5rem; -} - -.p-3 { - padding: 0.75rem; -} - -.p-5 { - padding: 1.25rem; -} - -.p-6 { - padding: 1.5rem; -} - -.px-2 { - padding-left: 0.5rem; - padding-right: 0.5rem; -} - -.px-4 { - padding-left: 1rem; - padding-right: 1rem; -} - -.px-5 { - padding-left: 1.25rem; - padding-right: 1.25rem; -} - -.py-1 { - padding-top: 0.25rem; - padding-bottom: 0.25rem; -} - -.py-2 { - padding-top: 0.5rem; - padding-bottom: 0.5rem; -} - -.py-3 { - padding-top: 0.75rem; - padding-bottom: 0.75rem; -} - -.py-4 { - padding-top: 1rem; - padding-bottom: 1rem; -} - -.py-5 { - padding-top: 1.25rem; - padding-bottom: 1.25rem; -} - -.text-left { - text-align: left; -} - -.text-center { - text-align: center; -} - -.text-right { - text-align: right; -} - -.font-sans { - font-family: ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; -} - -.text-2xl { - font-size: 1.5rem; - line-height: 2rem; -} - -.text-3xl { - font-size: 1.875rem; - line-height: 2.25rem; -} - -.text-lg { - font-size: 1.125rem; - line-height: 1.75rem; -} - -.text-sm { - font-size: 0.875rem; - line-height: 1.25rem; -} - -.text-xl { - font-size: 1.25rem; - line-height: 1.75rem; -} - -.font-bold { - font-weight: 700; -} - -.font-extrabold { - font-weight: 800; -} - -.font-medium { - font-weight: 500; -} - -.font-normal { - font-weight: 400; -} - -.font-semibold { - font-weight: 600; -} - -.uppercase { - text-transform: uppercase; -} - -.leading-normal { - line-height: 1.5; -} - -.text-gray-50 { - --tw-text-opacity: 1; - color: rgb(249 250 251 / var(--tw-text-opacity)); -} - -.text-gray-800 { - --tw-text-opacity: 1; - color: rgb(31 41 55 / var(--tw-text-opacity)); -} - -.text-gray-900 { - --tw-text-opacity: 1; - color: rgb(17 24 39 / var(--tw-text-opacity)); -} - -.text-red-500 { - --tw-text-opacity: 1; - color: rgb(239 68 68 / var(--tw-text-opacity)); -} - -.text-red-700 { - --tw-text-opacity: 1; - color: rgb(185 28 28 / var(--tw-text-opacity)); -} - -.text-sky-50 { - --tw-text-opacity: 1; - color: rgb(240 249 255 / var(--tw-text-opacity)); -} - -.text-sky-900 { - --tw-text-opacity: 1; - color: rgb(12 74 110 / var(--tw-text-opacity)); -} - -.text-white { - --tw-text-opacity: 1; - color: rgb(255 255 255 / var(--tw-text-opacity)); -} - -.text-red-600 { - --tw-text-opacity: 1; - color: rgb(220 38 38 / var(--tw-text-opacity)); -} - -.opacity-50 { - opacity: 0.5; -} - -.shadow-lg { - --tw-shadow: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1); - --tw-shadow-colored: 0 10px 15px -3px var(--tw-shadow-color), 0 4px 6px -4px var(--tw-shadow-color); - box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); -} - -.shadow-md { - --tw-shadow: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1); - --tw-shadow-colored: 0 4px 6px -1px var(--tw-shadow-color), 0 2px 4px -2px var(--tw-shadow-color); - box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); -} - -.transition { - transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, -webkit-backdrop-filter; - transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter; - transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter, -webkit-backdrop-filter; - transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); - transition-duration: 150ms; -} - -.display-htmx-indicator { - display: none; -} - -.htmx-request .display-htmx-indicator { - display: inline; -} - -.htmx-request.display-htmx-indicator { - display: inline; -} - -.hover\:cursor-pointer:hover { - cursor: pointer; -} - -.hover\:bg-gray-600:hover { - --tw-bg-opacity: 1; - background-color: rgb(75 85 99 / var(--tw-bg-opacity)); -} - -.hover\:bg-red-400:hover { - --tw-bg-opacity: 1; - background-color: rgb(248 113 113 / var(--tw-bg-opacity)); -} - -.hover\:bg-sky-100:hover { - --tw-bg-opacity: 1; - background-color: rgb(224 242 254 / var(--tw-bg-opacity)); -} - -.hover\:bg-sky-200:hover { - --tw-bg-opacity: 1; - background-color: rgb(186 230 253 / var(--tw-bg-opacity)); -} - -.hover\:bg-sky-700:hover { - --tw-bg-opacity: 1; - background-color: rgb(3 105 161 / var(--tw-bg-opacity)); -} - -.hover\:bg-sky-800:hover { - --tw-bg-opacity: 1; - background-color: rgb(7 89 133 / var(--tw-bg-opacity)); -} - -.hover\:bg-white:hover { - --tw-bg-opacity: 1; - background-color: rgb(255 255 255 / var(--tw-bg-opacity)); -} - -.group:hover .group-hover\:border-blue-500 { - --tw-border-opacity: 1; - border-color: rgb(59 130 246 / var(--tw-border-opacity)); -} - -.group:hover .group-hover\:text-blue-500 { - --tw-text-opacity: 1; - color: rgb(59 130 246 / var(--tw-text-opacity)); -} - -@media (min-width: 768px) { - .md\:grid { - display: grid; - } - - .md\:auto-rows-auto { - grid-auto-rows: auto; - } - - .md\:grid-cols-2 { - grid-template-columns: repeat(2, minmax(0, 1fr)); - } - - .md\:justify-between { - justify-content: space-between; - } - - .md\:justify-self-end { - justify-self: end; - } - - .md\:text-lg { - font-size: 1.125rem; - line-height: 1.75rem; - } - - .md\:text-xl { - font-size: 1.25rem; - line-height: 1.75rem; - } -} - -@media (min-width: 1024px) { - .lg\:size-20 { - width: 5rem; - height: 5rem; - } - - .lg\:size-5 { - width: 1.25rem; - height: 1.25rem; - } - - .lg\:size-6 { - width: 1.5rem; - height: 1.5rem; - } - - .lg\:w-1\/2 { - width: 50%; - } - - .lg\:grid-cols-2 { - grid-template-columns: repeat(2, minmax(0, 1fr)); - } - - .lg\:flex-row { - flex-direction: row; - } -} - -@media (min-width: 1280px) { - .xl\:text-lg { - font-size: 1.125rem; - line-height: 1.75rem; - } -} - -@media (prefers-color-scheme: dark) { - .dark\:border-sky-700 { - --tw-border-opacity: 1; - border-color: rgb(3 105 161 / var(--tw-border-opacity)); - } - - .dark\:bg-sky-600 { - --tw-bg-opacity: 1; - background-color: rgb(2 132 199 / var(--tw-bg-opacity)); - } - - .dark\:bg-sky-700 { - --tw-bg-opacity: 1; - background-color: rgb(3 105 161 / var(--tw-bg-opacity)); - } - - .dark\:bg-sky-800 { - --tw-bg-opacity: 1; - background-color: rgb(7 89 133 / var(--tw-bg-opacity)); - } - - .dark\:bg-sky-900 { - --tw-bg-opacity: 1; - background-color: rgb(12 74 110 / var(--tw-bg-opacity)); - } - - .dark\:bg-sky-950 { - --tw-bg-opacity: 1; - background-color: rgb(8 47 73 / var(--tw-bg-opacity)); - } - - .dark\:text-gray-50 { - --tw-text-opacity: 1; - color: rgb(249 250 251 / var(--tw-text-opacity)); - } - - .dark\:text-sky-50 { - --tw-text-opacity: 1; - color: rgb(240 249 255 / var(--tw-text-opacity)); - } - - .dark\:shadow-none { - --tw-shadow: 0 0 #0000; - --tw-shadow-colored: 0 0 #0000; - box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); - } - - .dark\:hover\:bg-sky-700:hover { - --tw-bg-opacity: 1; - background-color: rgb(3 105 161 / var(--tw-bg-opacity)); - } - - .dark\:hover\:bg-sky-800:hover { - --tw-bg-opacity: 1; - background-color: rgb(7 89 133 / var(--tw-bg-opacity)); - } -} \ No newline at end of file +/*! tailwindcss v3.4.10 | MIT License | https://tailwindcss.com*/*,:after,:before{border:0 solid #e5e7eb;box-sizing:border-box}:after,:before{--tw-content:""}:host,html{line-height:1.5;-webkit-text-size-adjust:100%;font-family:ui-sans-serif,system-ui,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji;font-feature-settings:normal;font-variation-settings:normal;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-tap-highlight-color:transparent}body{line-height:inherit;margin:0}hr{border-top-width:1px;color:inherit;height:0}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,pre,samp{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-feature-settings:normal;font-size:1em;font-variation-settings:normal}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}table{border-collapse:collapse;border-color:inherit;text-indent:0}button,input,optgroup,select,textarea{color:inherit;font-family:inherit;font-feature-settings:inherit;font-size:100%;font-variation-settings:inherit;font-weight:inherit;letter-spacing:inherit;line-height:inherit;margin:0;padding:0}button,select{text-transform:none}button,input:where([type=button]),input:where([type=reset]),input:where([type=submit]){-webkit-appearance:button;background-color:transparent;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:baseline}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dd,dl,figure,h1,h2,h3,h4,h5,h6,hr,p,pre{margin:0}fieldset{margin:0}fieldset,legend{padding:0}menu,ol,ul{list-style:none;margin:0;padding:0}dialog{padding:0}textarea{resize:vertical}input::-moz-placeholder,textarea::-moz-placeholder{color:#9ca3af;opacity:1}input::placeholder,textarea::placeholder{color:#9ca3af;opacity:1}[role=button],button{cursor:pointer}:disabled{cursor:default}audio,canvas,embed,iframe,img,object,svg,video{display:block;vertical-align:middle}img,video{height:auto;max-width:100%}[hidden]{display:none}[multiple],[type=date],[type=datetime-local],[type=email],[type=month],[type=number],[type=password],[type=search],[type=tel],[type=text],[type=time],[type=url],[type=week],input:where(:not([type])),select,textarea{-webkit-appearance:none;-moz-appearance:none;appearance:none;background-color:#fff;border-color:#6b7280;border-radius:0;border-width:1px;font-size:1rem;line-height:1.5rem;padding:.5rem .75rem;--tw-shadow:0 0 #0000}[multiple]:focus,[type=date]:focus,[type=datetime-local]:focus,[type=email]:focus,[type=month]:focus,[type=number]:focus,[type=password]:focus,[type=search]:focus,[type=tel]:focus,[type=text]:focus,[type=time]:focus,[type=url]:focus,[type=week]:focus,input:where(:not([type])):focus,select:focus,textarea:focus{outline:2px solid transparent;outline-offset:2px;--tw-ring-inset:var(--tw-empty,/*!*/ /*!*/);--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:#2563eb;--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);border-color:#2563eb;box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}input::-moz-placeholder,textarea::-moz-placeholder{color:#6b7280;opacity:1}input::placeholder,textarea::placeholder{color:#6b7280;opacity:1}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-date-and-time-value{min-height:1.5em;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit,::-webkit-datetime-edit-day-field,::-webkit-datetime-edit-hour-field,::-webkit-datetime-edit-meridiem-field,::-webkit-datetime-edit-millisecond-field,::-webkit-datetime-edit-minute-field,::-webkit-datetime-edit-month-field,::-webkit-datetime-edit-second-field,::-webkit-datetime-edit-year-field{padding-bottom:0;padding-top:0}select{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 20 20'%3E%3Cpath stroke='%236b7280' stroke-linecap='round' stroke-linejoin='round' stroke-width='1.5' d='m6 8 4 4 4-4'/%3E%3C/svg%3E");background-position:right .5rem center;background-repeat:no-repeat;background-size:1.5em 1.5em;padding-right:2.5rem;-webkit-print-color-adjust:exact;print-color-adjust:exact}[multiple],[size]:where(select:not([size="1"])){background-image:none;background-position:0 0;background-repeat:unset;background-size:initial;padding-right:.75rem;-webkit-print-color-adjust:unset;print-color-adjust:unset}[type=checkbox],[type=radio]{-webkit-appearance:none;-moz-appearance:none;appearance:none;background-color:#fff;background-origin:border-box;border-color:#6b7280;border-width:1px;color:#2563eb;display:inline-block;flex-shrink:0;height:1rem;padding:0;-webkit-print-color-adjust:exact;print-color-adjust:exact;-webkit-user-select:none;-moz-user-select:none;user-select:none;vertical-align:middle;width:1rem;--tw-shadow:0 0 #0000}[type=checkbox]{border-radius:0}[type=radio]{border-radius:100%}[type=checkbox]:focus,[type=radio]:focus{outline:2px solid transparent;outline-offset:2px;--tw-ring-inset:var(--tw-empty,/*!*/ /*!*/);--tw-ring-offset-width:2px;--tw-ring-offset-color:#fff;--tw-ring-color:#2563eb;--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}[type=checkbox]:checked,[type=radio]:checked{background-color:currentColor;background-position:50%;background-repeat:no-repeat;background-size:100% 100%;border-color:transparent}[type=checkbox]:checked{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='%23fff' viewBox='0 0 16 16'%3E%3Cpath d='M12.207 4.793a1 1 0 0 1 0 1.414l-5 5a1 1 0 0 1-1.414 0l-2-2a1 1 0 0 1 1.414-1.414L6.5 9.086l4.293-4.293a1 1 0 0 1 1.414 0'/%3E%3C/svg%3E")}@media (forced-colors:active) {[type=checkbox]:checked{-webkit-appearance:auto;-moz-appearance:auto;appearance:auto}}[type=radio]:checked{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='%23fff' viewBox='0 0 16 16'%3E%3Ccircle cx='8' cy='8' r='3'/%3E%3C/svg%3E")}@media (forced-colors:active) {[type=radio]:checked{-webkit-appearance:auto;-moz-appearance:auto;appearance:auto}}[type=checkbox]:checked:focus,[type=checkbox]:checked:hover,[type=radio]:checked:focus,[type=radio]:checked:hover{background-color:currentColor;border-color:transparent}[type=checkbox]:indeterminate{background-color:currentColor;background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 16 16'%3E%3Cpath stroke='%23fff' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M4 8h8'/%3E%3C/svg%3E");background-position:50%;background-repeat:no-repeat;background-size:100% 100%;border-color:transparent}@media (forced-colors:active) {[type=checkbox]:indeterminate{-webkit-appearance:auto;-moz-appearance:auto;appearance:auto}}[type=checkbox]:indeterminate:focus,[type=checkbox]:indeterminate:hover{background-color:currentColor;border-color:transparent}[type=file]{background:unset;border-color:inherit;border-radius:0;border-width:0;font-size:unset;line-height:inherit;padding:0}[type=file]:focus{outline:1px solid ButtonText;outline:1px auto -webkit-focus-ring-color}*,:after,:before{--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:rgba(59,130,246,.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-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }::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:rgba(59,130,246,.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-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }.container{width:100%}@media (min-width:640px){.container{max-width:640px}}@media (min-width:768px){.container{max-width:768px}}@media (min-width:1024px){.container{max-width:1024px}}@media (min-width:1280px){.container{max-width:1280px}}@media (min-width:1536px){.container{max-width:1536px}}.absolute{position:absolute}.relative{position:relative}.sticky{position:sticky}.inset-0{inset:0}.left-4{left:1rem}.right-4{right:1rem}.top-0{top:0}.top-1\/2{top:50%}.z-10{z-index:10}.col-span-2{grid-column:span 2/span 2}.col-start-1{grid-column-start:1}.col-start-2{grid-column-start:2}.row-start-2{grid-row-start:2}.mx-auto{margin-left:auto;margin-right:auto}.my-4{margin-bottom:1rem;margin-top:1rem}.mb-5{margin-bottom:1.25rem}.mt-4{margin-top:1rem}.mt-5{margin-top:1.25rem}.block{display:block}.flex{display:flex}.table{display:table}.grid{display:grid}.hidden{display:none}.size-14{height:3.5rem;width:3.5rem}.size-4{height:1rem;width:1rem}.h-12{height:3rem}.h-3{height:.75rem}.h-5{height:1.25rem}.h-8{height:2rem}.h-full{height:100%}.max-h-96{max-height:24rem}.max-h-full{max-height:100%}.max-h-screen{max-height:100vh}.min-h-48{min-height:12rem}.min-h-96{min-height:24rem}.min-h-screen{min-height:100vh}.w-16{width:4rem}.w-3{width:.75rem}.w-40{width:10rem}.w-5{width:1.25rem}.w-8{width:2rem}.w-full{width:100%}.flex-shrink{flex-shrink:1}.flex-grow{flex-grow:1}.border-collapse{border-collapse:collapse}.-translate-y-1\/2{--tw-translate-y:-50%}.-translate-y-1\/2,.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))}.cursor-pointer{cursor:pointer}.auto-cols-auto{grid-auto-columns:auto}.auto-rows-auto{grid-auto-rows:auto}.grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.grid-cols-7{grid-template-columns:repeat(7,minmax(0,1fr))}.grid-rows-2{grid-template-rows:repeat(2,minmax(0,1fr))}.flex-row{flex-direction:row}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.content-stretch{align-content:stretch}.items-center{align-items:center}.items-stretch{align-items:stretch}.justify-start{justify-content:flex-start}.justify-end{justify-content:flex-end}.justify-center{justify-content:center}.justify-between{justify-content:space-between}.justify-stretch{justify-content:stretch}.gap-0{gap:0}.gap-1{gap:.25rem}.gap-2{gap:.5rem}.gap-3{gap:.75rem}.gap-4{gap:1rem}.gap-5{gap:1.25rem}.self-end{align-self:flex-end}.self-center{align-self:center}.self-stretch{align-self:stretch}.justify-self-end{justify-self:end}.justify-self-stretch{justify-self:stretch}.overflow-hidden{overflow:hidden}.overflow-x-auto{overflow-x:auto}.overflow-y-auto{overflow-y:auto}.rounded{border-radius:.25rem}.rounded-full{border-radius:9999px}.rounded-lg{border-radius:.5rem}.rounded-md{border-radius:.375rem}.border{border-width:1px}.border-b{border-bottom-width:1px}.border-b-2{border-bottom-width:2px}.border-dotted{border-style:dotted}.border-sky-200{--tw-border-opacity:1;border-color:rgb(186 230 253/var(--tw-border-opacity))}.border-sky-900{--tw-border-opacity:1;border-color:rgb(12 74 110/var(--tw-border-opacity))}.bg-emerald-600{--tw-bg-opacity:1;background-color:rgb(5 150 105/var(--tw-bg-opacity))}.bg-gray-400{--tw-bg-opacity:1;background-color:rgb(156 163 175/var(--tw-bg-opacity))}.bg-gray-700{--tw-bg-opacity:1;background-color:rgb(55 65 81/var(--tw-bg-opacity))}.bg-green-400{--tw-bg-opacity:1;background-color:rgb(74 222 128/var(--tw-bg-opacity))}.bg-green-600{--tw-bg-opacity:1;background-color:rgb(22 163 74/var(--tw-bg-opacity))}.bg-red-400{--tw-bg-opacity:1;background-color:rgb(248 113 113/var(--tw-bg-opacity))}.bg-red-600{--tw-bg-opacity:1;background-color:rgb(220 38 38/var(--tw-bg-opacity))}.bg-sky-100{--tw-bg-opacity:1;background-color:rgb(224 242 254/var(--tw-bg-opacity))}.bg-sky-200{--tw-bg-opacity:1;background-color:rgb(186 230 253/var(--tw-bg-opacity))}.bg-sky-50{--tw-bg-opacity:1;background-color:rgb(240 249 255/var(--tw-bg-opacity))}.bg-sky-800{--tw-bg-opacity:1;background-color:rgb(7 89 133/var(--tw-bg-opacity))}.bg-sky-900{--tw-bg-opacity:1;background-color:rgb(12 74 110/var(--tw-bg-opacity))}.bg-white{--tw-bg-opacity:1;background-color:rgb(255 255 255/var(--tw-bg-opacity))}.bg-yellow-200{--tw-bg-opacity:1;background-color:rgb(254 240 138/var(--tw-bg-opacity))}.bg-yellow-600{--tw-bg-opacity:1;background-color:rgb(202 138 4/var(--tw-bg-opacity))}.object-contain{-o-object-fit:contain;object-fit:contain}.object-cover{-o-object-fit:cover;object-fit:cover}.p-2{padding:.5rem}.p-3{padding:.75rem}.p-5{padding:1.25rem}.p-6{padding:1.5rem}.px-2{padding-left:.5rem;padding-right:.5rem}.px-4{padding-left:1rem;padding-right:1rem}.px-5{padding-left:1.25rem;padding-right:1.25rem}.py-1{padding-bottom:.25rem;padding-top:.25rem}.py-2{padding-bottom:.5rem;padding-top:.5rem}.py-3{padding-bottom:.75rem;padding-top:.75rem}.py-4{padding-bottom:1rem;padding-top:1rem}.py-5{padding-bottom:1.25rem;padding-top:1.25rem}.text-left{text-align:left}.text-center{text-align:center}.text-right{text-align:right}.font-sans{font-family:ui-sans-serif,system-ui,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji}.text-2xl{font-size:1.5rem;line-height:2rem}.text-3xl{font-size:1.875rem;line-height:2.25rem}.text-lg{font-size:1.125rem;line-height:1.75rem}.text-sm{font-size:.875rem;line-height:1.25rem}.text-xl{font-size:1.25rem;line-height:1.75rem}.font-bold{font-weight:700}.font-extrabold{font-weight:800}.font-medium{font-weight:500}.font-normal{font-weight:400}.font-semibold{font-weight:600}.uppercase{text-transform:uppercase}.leading-normal{line-height:1.5}.text-gray-50{--tw-text-opacity:1;color:rgb(249 250 251/var(--tw-text-opacity))}.text-gray-800{--tw-text-opacity:1;color:rgb(31 41 55/var(--tw-text-opacity))}.text-gray-900{--tw-text-opacity:1;color:rgb(17 24 39/var(--tw-text-opacity))}.text-red-500{--tw-text-opacity:1;color:rgb(239 68 68/var(--tw-text-opacity))}.text-red-600{--tw-text-opacity:1;color:rgb(220 38 38/var(--tw-text-opacity))}.text-sky-50{--tw-text-opacity:1;color:rgb(240 249 255/var(--tw-text-opacity))}.text-sky-900{--tw-text-opacity:1;color:rgb(12 74 110/var(--tw-text-opacity))}.text-white{--tw-text-opacity:1;color:rgb(255 255 255/var(--tw-text-opacity))}.opacity-50{opacity:.5}.shadow-lg{--tw-shadow:0 10px 15px -3px rgba(0,0,0,.1),0 4px 6px -4px rgba(0,0,0,.1);--tw-shadow-colored:0 10px 15px -3px var(--tw-shadow-color),0 4px 6px -4px var(--tw-shadow-color)}.shadow-lg,.shadow-md{box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.shadow-md{--tw-shadow:0 4px 6px -1px rgba(0,0,0,.1),0 2px 4px -2px rgba(0,0,0,.1);--tw-shadow-colored:0 4px 6px -1px var(--tw-shadow-color),0 2px 4px -2px var(--tw-shadow-color)}.transition{transition-duration:.15s;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,-webkit-backdrop-filter;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter,-webkit-backdrop-filter;transition-timing-function:cubic-bezier(.4,0,.2,1)}.display-htmx-indicator{display:none}.htmx-request .display-htmx-indicator,.htmx-request.display-htmx-indicator{display:inline}.hover\:cursor-pointer:hover{cursor:pointer}.hover\:bg-gray-600:hover{--tw-bg-opacity:1;background-color:rgb(75 85 99/var(--tw-bg-opacity))}.hover\:bg-red-400:hover{--tw-bg-opacity:1;background-color:rgb(248 113 113/var(--tw-bg-opacity))}.hover\:bg-sky-100:hover{--tw-bg-opacity:1;background-color:rgb(224 242 254/var(--tw-bg-opacity))}.hover\:bg-sky-200:hover{--tw-bg-opacity:1;background-color:rgb(186 230 253/var(--tw-bg-opacity))}.hover\:bg-sky-700:hover{--tw-bg-opacity:1;background-color:rgb(3 105 161/var(--tw-bg-opacity))}.hover\:bg-sky-800:hover{--tw-bg-opacity:1;background-color:rgb(7 89 133/var(--tw-bg-opacity))}.hover\:bg-white:hover{--tw-bg-opacity:1;background-color:rgb(255 255 255/var(--tw-bg-opacity))}.group:hover .group-hover\:border-blue-500{--tw-border-opacity:1;border-color:rgb(59 130 246/var(--tw-border-opacity))}.group:hover .group-hover\:text-blue-500{--tw-text-opacity:1;color:rgb(59 130 246/var(--tw-text-opacity))}@media (min-width:768px){.md\:grid{display:grid}.md\:auto-rows-auto{grid-auto-rows:auto}.md\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.md\:justify-between{justify-content:space-between}.md\:justify-self-end{justify-self:end}.md\:text-lg{font-size:1.125rem;line-height:1.75rem}.md\:text-xl{font-size:1.25rem;line-height:1.75rem}}@media (min-width:1024px){.lg\:size-20{height:5rem;width:5rem}.lg\:size-5{height:1.25rem;width:1.25rem}.lg\:size-6{height:1.5rem;width:1.5rem}.lg\:w-1\/2{width:50%}.lg\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.lg\:flex-row{flex-direction:row}}@media (min-width:1280px){.xl\:text-lg{font-size:1.125rem;line-height:1.75rem}}@media (prefers-color-scheme:dark){.dark\:border-sky-700{--tw-border-opacity:1;border-color:rgb(3 105 161/var(--tw-border-opacity))}.dark\:bg-sky-600{--tw-bg-opacity:1;background-color:rgb(2 132 199/var(--tw-bg-opacity))}.dark\:bg-sky-700{--tw-bg-opacity:1;background-color:rgb(3 105 161/var(--tw-bg-opacity))}.dark\:bg-sky-800{--tw-bg-opacity:1;background-color:rgb(7 89 133/var(--tw-bg-opacity))}.dark\:bg-sky-900{--tw-bg-opacity:1;background-color:rgb(12 74 110/var(--tw-bg-opacity))}.dark\:bg-sky-950{--tw-bg-opacity:1;background-color:rgb(8 47 73/var(--tw-bg-opacity))}.dark\:text-gray-50{--tw-text-opacity:1;color:rgb(249 250 251/var(--tw-text-opacity))}.dark\:text-sky-50{--tw-text-opacity:1;color:rgb(240 249 255/var(--tw-text-opacity))}.dark\:shadow-none{--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.dark\:hover\:bg-sky-700:hover{--tw-bg-opacity:1;background-color:rgb(3 105 161/var(--tw-bg-opacity))}.dark\:hover\:bg-sky-800:hover{--tw-bg-opacity:1;background-color:rgb(7 89 133/var(--tw-bg-opacity))}} \ No newline at end of file diff --git a/test/service/training_task_service_test.go b/test/service/training_task_service_test.go index 7bbd690..f2361e3 100644 --- a/test/service/training_task_service_test.go +++ b/test/service/training_task_service_test.go @@ -195,6 +195,7 @@ func TestTrainingTaskService_GetByID_Training(t *testing.T) { tdId := uint(1) ttId := uint(1) tt := models.TrainingTask{ + Model: gorm.Model{ID: ttId}, Name: "task2", UserId: userId, Status: models.Training, @@ -202,8 +203,8 @@ func TestTrainingTaskService_GetByID_Training(t *testing.T) { Configuration: "", } ut.TTRepo.On("GetByID", ttId).Return(&tt, nil) - ut.TTRepo.On("GetByType", ttId, models.Onnx).Return([]models.TrainingTaskResult{}, nil) - ut.TTRepo.On("GetByType", ttId, models.Image).Return([]models.TrainingTaskResult{}, nil) + ut.TTRRepo.On("GetByType", ttId, models.Onnx).Return([]models.TrainingTaskResult{}, nil) + ut.TTRRepo.On("GetByType", ttId, models.Image).Return([]models.TrainingTaskResult{}, nil) // Act ttWithRes, err := ttService.GetByID(ttId) @@ -212,10 +213,10 @@ func TestTrainingTaskService_GetByID_Training(t *testing.T) { assert.NoError(t, err) ut.TTRepo.AssertCalled(t, "GetByID", ttId) ut.TTRRepo.AssertNotCalled(t, "GetByType", ttId, models.Onnx) - ut.TTRRepo.AssertNotCalled(t, "GetByType", ttId, models.Image) + ut.TTRRepo.AssertCalled(t, "GetByType", ttId, models.Image) assert.Equal(t, tt.Status, ttWithRes.TrainingTask.Status) assert.Equal(t, []models.TrainingTaskResult(nil), ttWithRes.OnnxFiles) - assert.Equal(t, []models.TrainingTaskResult(nil), ttWithRes.ImageFiles) + assert.Equal(t, []models.TrainingTaskResult{}, ttWithRes.ImageFiles) } func TestTrainingTaskService_GetByID_Benchmarking(t *testing.T) { @@ -248,10 +249,10 @@ func TestTrainingTaskService_GetByID_Benchmarking(t *testing.T) { assert.NoError(t, err) ut.TTRepo.AssertCalled(t, "GetByID", ttId) ut.TTRRepo.AssertCalled(t, "GetByType", ttId, models.Onnx) - ut.TTRRepo.AssertNotCalled(t, "GetByType", ttId, models.Image) + ut.TTRRepo.AssertCalled(t, "GetByType", ttId, models.Image) assert.Equal(t, tt.Status, ttWithRes.TrainingTask.Status) assert.True(t, reflect.DeepEqual(onnxFiles, ttWithRes.OnnxFiles)) - assert.Equal(t, []models.TrainingTaskResult(nil), ttWithRes.ImageFiles) + assert.Equal(t, []models.TrainingTaskResult{}, ttWithRes.ImageFiles) } func TestTrainingTaskService_GetByID_Completed(t *testing.T) { diff --git a/web/nn_architectures/proposed.json b/web/nn_architectures/proposed.json index 1e325b6..265e8e2 100644 --- a/web/nn_architectures/proposed.json +++ b/web/nn_architectures/proposed.json @@ -10,6 +10,12 @@ } }, "field_configs": { + "undersample": { + "full_name": "Undersample Training Dataset", + "type": "bool", + "default_value": false, + "description": "Undersample training dataset, in result count of tracks of every missing detectors combination would be equal." + }, "bs": { "full_name": "Batch Size", "type": "uint", diff --git a/web/templates/training-tasks/new.html b/web/templates/training-tasks/new.html index 26b3f0b..ef5103b 100644 --- a/web/templates/training-tasks/new.html +++ b/web/templates/training-tasks/new.html @@ -47,7 +47,7 @@