Compare commits

...

15 commits

93 changed files with 2819 additions and 3589 deletions

1
.gitignore vendored
View file

@ -4,6 +4,7 @@ venv/
scanners/ole/venv/
tmp/
temp/
node_modules
**/__pycache__
# Created by https://www.toptal.com/developers/gitignore/api/linux,go,vim,visualstudiocode,macos,windows
# Edit at https://www.toptal.com/developers/gitignore?templates=linux,go,vim,visualstudiocode,macos,windows

View file

@ -27,13 +27,14 @@ clean: ## Delete build artifacts
rm -rf storage/*
dev: ## Start templ-dev tailwind-dev and watch
make -j3 templ-dev tailwind-dev watch
make -j5 templ-dev tailwind-dev capa-dev ole-dev watch
templ-dev: ## Watch & Live rebuild of templ
templ generate --watch --proxy="http://localhost:8080" --open-browser=false
tailwind-dev: ##Live rebuild of tailwind
tailwindcss -o server/web/assets/styles.css -i input.css --watch
#tailwindcss -o server/web/assets/styles.css -i input.css --watch
npx @tailwindcss/cli -o server/web/assets/styles.css -i input.css --watch
ole-dev: ##Live rebouild of ole-scanner
. ./venv/bin/activate; \

View file

@ -12,3 +12,8 @@ these dependencies are required additionally to what is specified in go.mod and
- python3 3.13
- python3-venv
## TODO
ICAP - if someone wants to integrate (multiple) Antivirus scanners
CAPE - for dynamic sandbox analysis

View file

@ -17,4 +17,5 @@ services:
- "5001:5001"
volumes:
- "./storage/files:/mnt/storage/files"
# db:
# image: 'postgres:latest'

2
go.mod
View file

@ -4,7 +4,7 @@ go 1.24.1
require (
github.com/Oudwins/tailwind-merge-go v0.2.1
github.com/a-h/templ v0.3.865
github.com/a-h/templ v0.3.924
github.com/gabriel-vasile/mimetype v1.4.9
github.com/gorilla/securecookie v1.1.2
github.com/gorilla/sessions v1.4.0

2
go.sum
View file

@ -2,6 +2,8 @@ github.com/Oudwins/tailwind-merge-go v0.2.1 h1:jxRaEqGtwwwF48UuFIQ8g8XT7YSualNuG
github.com/Oudwins/tailwind-merge-go v0.2.1/go.mod h1:kkZodgOPvZQ8f7SIrlWkG/w1g9JTbtnptnePIh3V72U=
github.com/a-h/templ v0.3.865 h1:nYn5EWm9EiXaDgWcMQaKiKvrydqgxDUtT1+4zU2C43A=
github.com/a-h/templ v0.3.865/go.mod h1:oLBbZVQ6//Q6zpvSMPTuBK0F3qOtBdFBcGRspcT+VNQ=
github.com/a-h/templ v0.3.924 h1:t5gZqTneXqvehpNZsgtnlOscnBboNh9aASBH2MgV/0k=
github.com/a-h/templ v0.3.924/go.mod h1:FFAu4dI//ESmEN7PQkJ7E7QfnSEMdcnu7QrAY8Dn334=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=

1063
package-lock.json generated Normal file

File diff suppressed because it is too large Load diff

6
package.json Normal file
View file

@ -0,0 +1,6 @@
{
"dependencies": {
"@tailwindcss/cli": "^4.1.11",
"tailwindcss": "^4.1.11"
}
}

View file

@ -1,4 +1,5 @@
from flask import Blueprint, request, abort
from flask.json import jsonify
from werkzeug.utils import secure_filename
import capa.main
import capa.rules
@ -11,9 +12,13 @@ from pathlib import Path
import config
import json
import os
import capa.render.utils as rutils
import capa.render.result_document as rd
import collections
from capa.render.default import find_subrule_matches
capa_bp = Blueprint('capa', __name__)
# This function is essentially a hacked up version of https://github.com/mandiant/capa/blob/master/capa/render/default.py
@capa_bp.route('/analyze', methods=['GET'])
def analyze_capa():
file = secure_filename(request.args.get('file', ''))
@ -29,6 +34,82 @@ def analyze_capa():
capabilities = capa.capabilities.common.find_capabilities(rules, extractor, disable_progress=True)
meta = capa.loader.collect_metadata([], filepath, FORMAT_AUTO, OS_AUTO, [capa.main.get_default_root()/ "rules"], extractor, capabilities)
doc = rd.ResultDocument.from_capa(meta, rules, capabilities.matches)
caps = {}
tactics = {}
maec = {}
objectives = {}
subrule_matches = find_subrule_matches(doc)
for rule in rutils.capability_rules(doc):
if rule.meta.name in subrule_matches:
# rules that are also matched by other rules should not get rendered by default.
# this cuts down on the amount of output while giving approx the same detail.
# see #224
continue
count = len(rule.matches)
if count == 1:
capability = rule.meta.name
else:
capability = rule.meta.name + f" ({count} matches)"
caps[capability] = rule.meta.namespace
for attack in rule.meta.attack:
tactics[attack.tactic] = attack.technique + attack.subtechnique + attack.id.strip("[").strip("]")
maec_categories = {
"analysis_conclusion",
"analysis_conclusion_ov",
"malware_family",
"malware_category",
"malware_category_ov",
}
for rule in rutils.maec_rules(doc):
for maec_category in maec_categories:
maec_value = getattr(rule.meta.maec, maec_category, None)
if maec_value:
maec[maec_category] = maec_value
for rule in rutils.capability_rules(doc):
for mbc in rule.meta.mbc:
objectives[mbc.objective] = mbc.behavior + mbc.method + mbc.id.strip("[").strip("]")
return jsonify(capabilities=caps, tactics=tactics, maec=maec, objectives=objectives)
@capa_bp.route('/json', methods=['GET'])
def analyze_capa_json():
file = secure_filename(request.args.get('file', ''))
if file == '':
abort(400)
filepath = Path(path.join(config.Config.FILE_DIRECTORY, file))
if not os.path.exists(filepath):
print(f"Error: File not found at '{filepath}'")
abort(400)
rules = capa.rules.get_rules([Path(config.Config.RULES)])
extractor = capa.loader.get_extractor(filepath, FORMAT_AUTO, OS_AUTO, capa.main.BACKEND_VIV, [], should_save_workspace=False, disable_progress=True)
capabilities = capa.capabilities.common.find_capabilities(rules, extractor, disable_progress=True)
meta = capa.loader.collect_metadata([], filepath, FORMAT_AUTO, OS_AUTO, [capa.main.get_default_root()/ "rules"], extractor, capabilities)
return json.loads(capa.render.json.render(meta=meta, rules=rules, capabilities=capabilities.matches))
@capa_bp.route('/default', methods=['GET'])
def analyze_capa_default():
file = secure_filename(request.args.get('file', ''))
if file == '':
abort(400)
filepath = Path(path.join(config.Config.FILE_DIRECTORY, file))
if not os.path.exists(filepath):
print(f"Error: File not found at '{filepath}'")
abort(400)
rules = capa.rules.get_rules([Path(config.Config.RULES)])
extractor = capa.loader.get_extractor(filepath, FORMAT_AUTO, OS_AUTO, capa.main.BACKEND_VIV, [], should_save_workspace=False, disable_progress=True)
capabilities = capa.capabilities.common.find_capabilities(rules, extractor, disable_progress=True)
meta = capa.loader.collect_metadata([], filepath, FORMAT_AUTO, OS_AUTO, [capa.main.get_default_root()/ "rules"], extractor, capabilities)
return capa.render.default.render(meta=meta, rules=rules, capabilities=capabilities.matches)

View file

@ -36,6 +36,9 @@ func setDefaults() {
viper.SetDefault("web.key", "/etc/ssl/key/ssl-cert-snakeoil.key")
viper.SetDefault("web.loghttp", true)
viper.SetDefault("web.maxfilesizemb", 100)
viper.SetDefault("web.download.usermax", 5)
viper.SetDefault("web.download.anonmax", 1)
viper.SetDefault("web.download.disable", false)
// Database
viper.SetDefault("db.host", "localhost")
viper.SetDefault("db.port", 5432)
@ -45,6 +48,7 @@ func setDefaults() {
viper.SetDefault("db.debug", false)
// Others
viper.SetDefault("processing.oleurl", "http://localhost:5000")
viper.SetDefault("processing.capaurl", "http://localhost:5001")
viper.SetDefault("processing.maxmimesize", "100MB")
viper.SetDefault("processing.yararules", "./storage/rules")
viper.SetDefault("processing.yaracompiled", "./storage/output.yarc")
@ -53,7 +57,7 @@ func setDefaults() {
// UI Interface info
viper.SetDefault("ui.name", "Scanfile")
viper.SetDefault("ui.byurl", "https://www.jmbit.de")
viper.SetDefault("ui.byurl", "Johannes Bülow")
viper.SetDefault("ui.byname", "Johannes Bülow")
viper.SetDefault("ui.source", "https://git.jmbit.de/jmb/scanfile")
}

View file

@ -3,6 +3,7 @@ package database
import (
"context"
"encoding/hex"
"encoding/json"
"log/slog"
"git.jmbit.de/jmb/scanfile/server/internal/sqlc"
@ -77,5 +78,63 @@ func GetAllFiles() ([]sqlc.File, error) {
slog.Error("Error in GetAllProperties", "error", err)
}
return files, err
}
func InsertFileDiec(params sqlc.InsertFileDIECParams) error {
query := sqlc.New(pool)
err := query.InsertFileDIEC(context.Background(), params)
if err != nil {
slog.Error("Error from query in InsertFileDiec", "file-uuid", params.FileID.String(), "error", err)
}
return err
}
func GetFileDiec(fileID pgtype.UUID) (Diec, error){
var r Diec
var data DiecData
query := sqlc.New(pool)
rawDiec, err := query.GetFileDIEC(context.Background(), fileID)
if err != nil {
slog.Error("Error from query in GetFileDiec", "file-uuid", fileID.String(), "error", err)
return r, err
}
r.ID = rawDiec.ID
r.FileID = rawDiec.FileID
err = json.Unmarshal(rawDiec.Data, &data)
if err != nil {
slog.Error("Error in GetFileDiec", "file-uuid", fileID.String(), "error", err)
return r, err
}
r.Data = data
return r, nil
}
func InsertFileCapa(params sqlc.InsertFileCapaParams) error {
query := sqlc.New(pool)
err := query.InsertFileCapa(context.Background(), params)
if err != nil {
slog.Error("Error from Query in InsertFileCapa", "file-uuid", params.FileID.String(), "error", err)
}
return err
}
func GetFileCapa(fileID pgtype.UUID) (CapaResult, error) {
var r CapaResult
var data CapaData
query := sqlc.New(pool)
rawResult, err := query.GetFileCapa(context.Background(), fileID)
if err != nil {
slog.Error("Error from Query in GetFileCapa", "file-uuid", fileID.String(), "error", err)
}
r.ID = rawResult.ID
r.FileID = rawResult.FileID
err = json.Unmarshal(rawResult.Data, &data)
if err != nil {
slog.Error("Error in GetFileCapa", "file-uuid", fileID.String(), "error", err)
return r, err
}
return r, nil
}

View file

@ -0,0 +1,37 @@
package database
import "github.com/jackc/pgx/v5/pgtype"
type DiecData struct {
Detects []struct {
Filetype string `json:"filetype"`
Parentfilepart string `json:"parentfilepart"`
Values []struct {
Info string `json:"info"`
Name string `json:"name"`
String string `json:"string"`
Type string `json:"type"`
Version string `json:"version"`
} `json:"values"`
} `json:"detects"`
}
type Diec struct {
ID int64
FileID pgtype.UUID
Data DiecData
}
type CapaResult struct {
ID int64
FileID pgtype.UUID
Data CapaData
}
type CapaData struct {
Capabilities map[string]string `json:"capabilities"`
Maec map[string]string `json:"maec"`
Objectives map[string]string `json:"objectives"`
Tactics map[string]string `json:"tactics"`
}

View file

@ -50,6 +50,7 @@ func FailProcessingJob(jobid int64, jobErr error) error {
var params sqlc.FailProcessingJobParams
params.ID = jobid
params.Error.String = jobErr.Error()
params.Error.Valid = true
err := query.FailProcessingJob(context.Background(), params)
if err != nil {
slog.Error("Unable to mark processing job as failed", "job-id", jobid, "error", err)

View file

@ -13,3 +13,17 @@ INSERT INTO diec (
file_id, data
) VALUES ($1, $2);
-- name: GetFileDIEC :one
SELECT * FROM diec
WHERE file_id = $1;
-- name: InsertFileCapa :exec
INSERT INTO capa_results (
file_id, data
) VALUES ($1, $2);
-- name: GetFileCapa :one
SELECT * FROM capa_results
WHERE file_id = $1;

View file

@ -1,25 +1,3 @@
-- name: InsertFileMsofficeOleid :exec
INSERT INTO msoffice_oleid (
file_id, data
) VALUES ($1, $2);
-- name: InsertFileMsofficeOlevba :exec
INSERT INTO msoffice_olevba (
file_id, data
) VALUES ($1, $2);
-- name: InsertFileMsofficeMraptor :exec
INSERT INTO msoffice_mraptor (
file_id, data
) VALUES ($1, $2);
-- name: GetMSOfficeData :one
SELECT t1.file_id, t1.data AS oleid, t2.data AS olevba, t3.data AS mraptor
FROM msoffice_oleid as t1
LEFT join msoffice_olevba AS t2 ON t2.file_id = t1.file_id
LEFT JOIN msoffice_mraptor AS t3 ON t3.file_id = t1.file_id
WHERE t1.file_id = $1;
-- name: InsertMSOfficeResults :exec
INSERT INTO msoffice (
file_id, verdict, container_format, encrypted, file_format, vba_macros, xlm_macros,

View file

@ -16,10 +16,6 @@ SET completed = NOW(),
status = 'completed'
WHERE id = $1;
-- name: GetJobsForFile :many
SELECT * FROM processing_jobs
WHERE file_id = $1;
-- name: GetJob :one
SELECT * FROM processing_jobs
WHERE id = $1
@ -34,3 +30,8 @@ WHERE id = $2;
-- name: GetAllJobs :many
SELECT * FROM processing_jobs;
-- name: GetJobsForFile :many
SELECT * FROM processing_jobs
WHERE file_id = $1
ORDER BY created DESC;

View file

@ -0,0 +1,32 @@
-- CreateUser :exec
INSERT INTO users (
user_name, display_name, pw_hash, email_address
) VALUES ($1, $2, $3, $4);
-- DeleteUser :exec
DELETE FROM users
WHERE id = $1;
-- UpdateUserPW :exec
UPDATE users
SET pw_hash = $2
WHERE id = $1;
-- UpdateUserName :exec
UPDATE users
SET user_name = $2
WHERE id = $1;
-- UpdateUserDisplayName :exec
UPDATE users
SET display_name = $2
WHERE id = $1;
-- GetUser :one
SELECT * FROM users
WHERE id = $1;
-- GetUserByName :one
SELECT * FROM users
WHERE user_name = $1;

View file

@ -2,6 +2,17 @@
CREATE EXTENSION IF NOT EXISTS "pgcrypto";
-- Tables
CREATE TABLE IF NOT EXISTS users (
id BIGSERIAL PRIMARY KEY,
user_name TEXT NOT NULL UNIQUE,
display_name TEXT NOT NULL,
pw_hash BYTEA NOT NULL,
email_address TEXT NOT NULL,
enabled BOOLEAN NOT NULL DEFAULT TRUE,
created TIMESTAMP DEFAULT NOW() NOT NULL
);
CREATE TABLE IF NOT EXISTS files (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
name TEXT NOT NULL,
@ -9,6 +20,8 @@ CREATE TABLE IF NOT EXISTS files (
mimetype TEXT NOT NULL,
size BIGINT NOT NULL,
blake2 BYTEA NOT NULL UNIQUE,
score DECIMAL,
creator BIGINT REFERENCES users (id),
created TIMESTAMP DEFAULT NOW() NOT NULL,
updated TIMESTAMP DEFAULT NOW() NOT NULL
);
@ -16,7 +29,7 @@ CREATE TABLE IF NOT EXISTS files (
CREATE TABLE IF NOT EXISTS processing_jobs (
id BIGSERIAL PRIMARY KEY,
file_id UUID REFERENCES files (id) ON DELETE CASCADE,
created TIMESTAMP DEFAULT NOW(),
created TIMESTAMP DEFAULT NOW() NOT NULL,
started TIMESTAMP,
completed TIMESTAMP,
status TEXT,
@ -28,7 +41,8 @@ CREATE TABLE IF NOT EXISTS processing_jobs (
CREATE TABLE IF NOT EXISTS diec (
id BIGSERIAL PRIMARY KEY,
file_id UUID REFERENCES files (id) ON DELETE CASCADE,
data JSONB
data JSONB,
created TIMESTAMP DEFAULT NOW() NOT NULL
);
CREATE TABLE IF NOT EXISTS msoffice (
@ -46,7 +60,8 @@ CREATE TABLE IF NOT EXISTS msoffice (
nb_macros INTEGER,
nb_suspicious INTEGER,
olevba_results TEXT[][],
macros TEXT[][]
macros TEXT[][],
created TIMESTAMP DEFAULT NOW() NOT NULL
);
@ -57,23 +72,32 @@ CREATE TABLE IF NOT EXISTS file_properties (
md5 BYTEA,
libmagic_mime TEXT,
libmagic_extension TEXT,
libmagic_apple TEXT
libmagic_apple TEXT,
created TIMESTAMP DEFAULT NOW() NOT NULL
);
CREATE TABLE IF NOT EXISTS yara_results (
id BIGSERIAL PRIMARY KEY,
file_id UUID REFERENCES files (id) ON DELETE CASCADE,
matched TEXT[]
matched TEXT[],
created TIMESTAMP DEFAULT NOW() NOT NULL
);
CREATE TABLE IF NOT EXISTS capa_results (
id BIGSERIAL PRIMARY KEY,
file_id UUID REFERENCES files (id) ON DELETE CASCADE,
data JSONB,
type TEXT DEFAULT 'default' NOT NULL,
created TIMESTAMP DEFAULT NOW() NOT NULL
);
-- Indices
-- Since tables will be heavily accessed by file_id, there should be indices for them
CREATE INDEX idx_diec_file_id ON diec (file_id);
CREATE INDEX idx_processing_jobs_file_id ON processing_jobs (file_id);
CREATE INDEX idx_msoffice_oleid_file_id ON msoffice_oleid (file_id);
CREATE INDEX idx_msoffice_olevba_file_id ON msoffice_olevba (file_id);
CREATE INDEX idx_msoffice_mraptor_file_id ON msoffice_mraptor (file_id);
CREATE INDEX idx_msoffice_results_file_id ON msoffice (file_id);
CREATE INDEX idx_file_properties_file_id ON file_properties (file_id);
CREATE INDEX idx_file_id ON files (id);
CREATE INDEX idx_yara_results_file_id ON yara_results (file_id);
CREATE INDEX idx_user_name ON users (user_name);
CREATE INDEX idx_capa_results_file_id ON capa_results (file_id);

View file

@ -1,8 +1,2 @@
package database
type User struct {
Id int64
Name string `xorm:"not null unique"`
PwHash string //Password hash
Role int64 `xorm:"default 0"`
}

View file

@ -43,6 +43,23 @@ func BasicProcessing(job sqlc.ProcessingJob) error {
slog.Error("Error inserting basic file properties into database", "file-uuid", job.FileID.String(), "error", err)
return err
}
diec, err := DiecScan(job.FileID.String())
if err != nil {
database.FailProcessingJob(job.ID, err)
slog.Error("Error processing file", "file-uuid", job.FileID.String(), "error", err)
return err
}
slog.Debug("Diec result", "file-uuid", job.FileID.String(), "diec", diec)
err = database.InsertFileDiec(sqlc.InsertFileDIECParams{
FileID: job.FileID,
Data: diec,
})
if err != nil {
database.FailProcessingJob(job.ID, err)
slog.Error("Error inserting detect-it-easy results into database", "file-uuid", job.FileID.String(), "error", err)
return err
}
database.FinishProcessingJob(job.ID)
return nil
}

View file

@ -0,0 +1,63 @@
package capa
import (
"log/slog"
"net/url"
"net/http"
"fmt"
"io"
"git.jmbit.de/jmb/scanfile/server/internal/database"
"git.jmbit.de/jmb/scanfile/server/internal/sqlc"
"github.com/jackc/pgx/v5/pgtype"
"github.com/spf13/viper"
)
func CapaProcessing(job sqlc.ProcessingJob) error {
database.StartProcessingJob(job.ID)
capaBytes, err := CapaScan(job.FileID)
if err != nil {
database.FailProcessingJob(job.ID, err)
slog.Error("Error processing file", "file-uuid", job.FileID.String(), "error", err)
return err
}
var params sqlc.InsertFileCapaParams
params.FileID = job.FileID
params.Data = capaBytes
err = database.InsertFileCapa(params)
if err != nil {
database.FailProcessingJob(job.ID, err)
slog.Error("Error processing file CAPA data", "file-uuid", job.FileID.String(), "error", err)
return err
}
database.FinishProcessingJob(job.ID)
return nil
}
func CapaScan(fileID pgtype.UUID) ([]byte, error) {
var by []byte
slog.Debug("Started Capa scan", "file-uuid", fileID.String())
capaUrl, err := url.Parse(viper.GetString("processing.capaurl"))
if err != nil {
slog.Error("Error in CapaScan parsing URL for ole service", "file-uuid", fileID.String(), "error", err)
return by, err
}
capaUrl.Path = "/capa/analyze"
capaUrl.RawQuery = fmt.Sprintf("file=%s", fileID.String())
capaResp, err := http.Get(capaUrl.String())
slog.Debug("CAPA scan request", "file-uuid", fileID.String(), "url", capaUrl.String(), "status-code", capaResp.StatusCode)
if err != nil {
slog.Error("Error in CapaScan getting capa result from service", "file-uuid", fileID.String(), "error", err)
}
defer capaResp.Body.Close()
body, err := io.ReadAll(capaResp.Body)
if err != nil {
slog.Error("Error in CapaScan parsing body", "file-uuid", fileID.String(), "error", err)
}
slog.Debug("CapaScan", "file-uuid", fileID.String(), "data", body)
return body, nil
}

View file

@ -56,5 +56,6 @@ func MSOfficeProcessing(job sqlc.ProcessingJob) error {
return err
}
database.FinishProcessingJob(job.ID)
return nil
}

View file

@ -24,7 +24,6 @@ type oleidResponse struct {
}
func OleIDScan(fileID pgtype.UUID) (oleidResponse, error) {
slog.Debug("Starting OleID scan", "file-uuid", fileID.String())
oleidUrl, err := url.Parse(viper.GetString("processing.oleurl"))
if err != nil {

View file

@ -8,6 +8,7 @@ import (
"git.jmbit.de/jmb/scanfile/server/internal/database"
"git.jmbit.de/jmb/scanfile/server/internal/processing/basic"
"git.jmbit.de/jmb/scanfile/server/internal/processing/capa"
"git.jmbit.de/jmb/scanfile/server/internal/processing/msoffice"
"git.jmbit.de/jmb/scanfile/server/internal/processing/yara"
"github.com/jackc/pgx/v5/pgtype"
@ -32,12 +33,12 @@ func Submit(ctx context.Context, file pgtype.UUID) error {
go basic.BasicProcessing(job)
yaraJob, err := database.NewProcessingJob(ctx, file, TypeYARA)
if err != nil {
slog.Error("Could not submit processing job", "error", err, "file-uuid", file, "type", TypeBasic)
return err
}
go yara.YaraProcessing(yaraJob)
//yaraJob, err := database.NewProcessingJob(ctx, file, TypeYARA)
//if err != nil {
// slog.Error("Could not submit processing job", "error", err, "file-uuid", file, "type", TypeBasic)
// return err
//}
//go yara.YaraProcessing(yaraJob)
mimeType, err := database.GetFileMime(file)
if err != nil {
@ -52,6 +53,20 @@ func Submit(ctx context.Context, file pgtype.UUID) error {
return err
}
go msoffice.MSOfficeProcessing(officeJob)
case TypeELF:
capaJob, err := database.NewProcessingJob(ctx, file, TypeELF)
if err != nil {
slog.Error("Could not submit processing job", "error", err, "file-uuid", file, "type", TypeCAPA)
return err
}
go capa.CapaProcessing(capaJob)
case TypePE:
capaJob, err := database.NewProcessingJob(ctx, file, TypeELF)
if err != nil {
slog.Error("Could not submit processing job", "error", err, "file-uuid", file, "type", TypeCAPA)
return err
}
go capa.CapaProcessing(capaJob)
}
return nil
}

View file

@ -28,6 +28,9 @@ const TypeOther = "Other"
// Yara Scan (can be done for all filetypes)
const TypeYARA = "Yara"
// CAPA Scan
const TypeCAPA = "Capa"
var MSOfficeMime = []string{
"application/msword",
"application/vnd.ms-excel",

View file

@ -8,10 +8,19 @@ import (
"github.com/jackc/pgx/v5/pgtype"
)
type CapaResult struct {
ID int64
FileID pgtype.UUID
Data []byte
Type string
Created pgtype.Timestamp
}
type Diec struct {
ID int64
FileID pgtype.UUID
Data []byte
Created pgtype.Timestamp
}
type File struct {
@ -21,6 +30,8 @@ type File struct {
Mimetype string
Size int64
Blake2 []byte
Score pgtype.Numeric
Creator pgtype.Int8
Created pgtype.Timestamp
Updated pgtype.Timestamp
}
@ -33,6 +44,7 @@ type FileProperty struct {
LibmagicMime pgtype.Text
LibmagicExtension pgtype.Text
LibmagicApple pgtype.Text
Created pgtype.Timestamp
}
type Msoffice struct {
@ -51,6 +63,7 @@ type Msoffice struct {
NbSuspicious pgtype.Int4
OlevbaResults [][]string
Macros [][]string
Created pgtype.Timestamp
}
type ProcessingJob struct {
@ -65,8 +78,19 @@ type ProcessingJob struct {
Messages []string
}
type User struct {
ID int64
UserName string
DisplayName string
PwHash []byte
EmailAddress string
Enabled bool
Created pgtype.Timestamp
}
type YaraResult struct {
ID int64
FileID pgtype.UUID
Matched []string
Created pgtype.Timestamp
}

View file

@ -11,8 +11,43 @@ import (
"github.com/jackc/pgx/v5/pgtype"
)
const getFileCapa = `-- name: GetFileCapa :one
SELECT id, file_id, data, type, created FROM capa_results
WHERE file_id = $1
`
func (q *Queries) GetFileCapa(ctx context.Context, fileID pgtype.UUID) (CapaResult, error) {
row := q.db.QueryRow(ctx, getFileCapa, fileID)
var i CapaResult
err := row.Scan(
&i.ID,
&i.FileID,
&i.Data,
&i.Type,
&i.Created,
)
return i, err
}
const getFileDIEC = `-- name: GetFileDIEC :one
SELECT id, file_id, data, created FROM diec
WHERE file_id = $1
`
func (q *Queries) GetFileDIEC(ctx context.Context, fileID pgtype.UUID) (Diec, error) {
row := q.db.QueryRow(ctx, getFileDIEC, fileID)
var i Diec
err := row.Scan(
&i.ID,
&i.FileID,
&i.Data,
&i.Created,
)
return i, err
}
const getFileProperties = `-- name: GetFileProperties :one
SELECT id, file_id, sha256, md5, libmagic_mime, libmagic_extension, libmagic_apple FROM file_properties
SELECT id, file_id, sha256, md5, libmagic_mime, libmagic_extension, libmagic_apple, created FROM file_properties
WHERE file_id = $1
`
@ -27,10 +62,27 @@ func (q *Queries) GetFileProperties(ctx context.Context, fileID pgtype.UUID) (Fi
&i.LibmagicMime,
&i.LibmagicExtension,
&i.LibmagicApple,
&i.Created,
)
return i, err
}
const insertFileCapa = `-- name: InsertFileCapa :exec
INSERT INTO capa_results (
file_id, data
) VALUES ($1, $2)
`
type InsertFileCapaParams struct {
FileID pgtype.UUID
Data []byte
}
func (q *Queries) InsertFileCapa(ctx context.Context, arg InsertFileCapaParams) error {
_, err := q.db.Exec(ctx, insertFileCapa, arg.FileID, arg.Data)
return err
}
const insertFileDIEC = `-- name: InsertFileDIEC :exec
INSERT INTO diec (
file_id, data

View file

@ -18,7 +18,7 @@ INSERT INTO files (
$1,$2,$3,$4,$5
)
ON CONFLICT DO NOTHING -- Handle this in application code
RETURNING id, name, description, mimetype, size, blake2, created, updated
RETURNING id, name, description, mimetype, size, blake2, score, creator, created, updated
`
type CreateFileParams struct {
@ -45,6 +45,8 @@ func (q *Queries) CreateFile(ctx context.Context, arg CreateFileParams) (File, e
&i.Mimetype,
&i.Size,
&i.Blake2,
&i.Score,
&i.Creator,
&i.Created,
&i.Updated,
)
@ -63,7 +65,7 @@ func (q *Queries) DeleteFile(ctx context.Context, id pgtype.UUID) error {
}
const getAllFiles = `-- name: GetAllFiles :many
SELECT id, name, description, mimetype, size, blake2, created, updated FROM files
SELECT id, name, description, mimetype, size, blake2, score, creator, created, updated FROM files
ORDER BY created DESC
`
@ -83,6 +85,8 @@ func (q *Queries) GetAllFiles(ctx context.Context) ([]File, error) {
&i.Mimetype,
&i.Size,
&i.Blake2,
&i.Score,
&i.Creator,
&i.Created,
&i.Updated,
); err != nil {
@ -97,7 +101,7 @@ func (q *Queries) GetAllFiles(ctx context.Context) ([]File, error) {
}
const getFileByBlake2 = `-- name: GetFileByBlake2 :one
SELECT id, name, description, mimetype, size, blake2, created, updated
SELECT id, name, description, mimetype, size, blake2, score, creator, created, updated
FROM files
WHERE blake2 = $1
`
@ -112,6 +116,8 @@ func (q *Queries) GetFileByBlake2(ctx context.Context, blake2 []byte) (File, err
&i.Mimetype,
&i.Size,
&i.Blake2,
&i.Score,
&i.Creator,
&i.Created,
&i.Updated,
)
@ -119,7 +125,7 @@ func (q *Queries) GetFileByBlake2(ctx context.Context, blake2 []byte) (File, err
}
const getFileByUUID = `-- name: GetFileByUUID :one
SELECT id, name, description, mimetype, size, blake2, created, updated
SELECT id, name, description, mimetype, size, blake2, score, creator, created, updated
FROM files
WHERE id = $1
`
@ -134,6 +140,8 @@ func (q *Queries) GetFileByUUID(ctx context.Context, id pgtype.UUID) (File, erro
&i.Mimetype,
&i.Size,
&i.Blake2,
&i.Score,
&i.Creator,
&i.Created,
&i.Updated,
)

View file

@ -11,35 +11,8 @@ import (
"github.com/jackc/pgx/v5/pgtype"
)
const getMSOfficeData = `-- name: GetMSOfficeData :one
SELECT t1.file_id, t1.data AS oleid, t2.data AS olevba, t3.data AS mraptor
FROM msoffice_oleid as t1
LEFT join msoffice_olevba AS t2 ON t2.file_id = t1.file_id
LEFT JOIN msoffice_mraptor AS t3 ON t3.file_id = t1.file_id
WHERE t1.file_id = $1
`
type GetMSOfficeDataRow struct {
FileID pgtype.UUID
Oleid []byte
Olevba []byte
Mraptor []byte
}
func (q *Queries) GetMSOfficeData(ctx context.Context, dollar_1 pgtype.UUID) (GetMSOfficeDataRow, error) {
row := q.db.QueryRow(ctx, getMSOfficeData, dollar_1)
var i GetMSOfficeDataRow
err := row.Scan(
&i.FileID,
&i.Oleid,
&i.Olevba,
&i.Mraptor,
)
return i, err
}
const getMSOfficeResults = `-- name: GetMSOfficeResults :one
SELECT id, file_id, verdict, container_format, encrypted, file_format, vba_macros, xlm_macros, vba_stomping, nb_autoexec, nb_iocs, nb_macros, nb_suspicious, olevba_results, macros FROM msoffice
SELECT id, file_id, verdict, container_format, encrypted, file_format, vba_macros, xlm_macros, vba_stomping, nb_autoexec, nb_iocs, nb_macros, nb_suspicious, olevba_results, macros, created FROM msoffice
WHERE file_id = $1
LIMIT 1
`
@ -63,58 +36,11 @@ func (q *Queries) GetMSOfficeResults(ctx context.Context, fileID pgtype.UUID) (M
&i.NbSuspicious,
&i.OlevbaResults,
&i.Macros,
&i.Created,
)
return i, err
}
const insertFileMsofficeMraptor = `-- name: InsertFileMsofficeMraptor :exec
INSERT INTO msoffice_mraptor (
file_id, data
) VALUES ($1, $2)
`
type InsertFileMsofficeMraptorParams struct {
Column1 pgtype.UUID
Column2 []byte
}
func (q *Queries) InsertFileMsofficeMraptor(ctx context.Context, arg InsertFileMsofficeMraptorParams) error {
_, err := q.db.Exec(ctx, insertFileMsofficeMraptor, arg.Column1, arg.Column2)
return err
}
const insertFileMsofficeOleid = `-- name: InsertFileMsofficeOleid :exec
INSERT INTO msoffice_oleid (
file_id, data
) VALUES ($1, $2)
`
type InsertFileMsofficeOleidParams struct {
Column1 pgtype.UUID
Column2 []byte
}
func (q *Queries) InsertFileMsofficeOleid(ctx context.Context, arg InsertFileMsofficeOleidParams) error {
_, err := q.db.Exec(ctx, insertFileMsofficeOleid, arg.Column1, arg.Column2)
return err
}
const insertFileMsofficeOlevba = `-- name: InsertFileMsofficeOlevba :exec
INSERT INTO msoffice_olevba (
file_id, data
) VALUES ($1, $2)
`
type InsertFileMsofficeOlevbaParams struct {
Column1 pgtype.UUID
Column2 []byte
}
func (q *Queries) InsertFileMsofficeOlevba(ctx context.Context, arg InsertFileMsofficeOlevbaParams) error {
_, err := q.db.Exec(ctx, insertFileMsofficeOlevba, arg.Column1, arg.Column2)
return err
}
const insertMSOfficeResults = `-- name: InsertMSOfficeResults :exec
INSERT INTO msoffice (
file_id, verdict, container_format, encrypted, file_format, vba_macros, xlm_macros,

View file

@ -125,6 +125,7 @@ func (q *Queries) GetJob(ctx context.Context, id int64) (ProcessingJob, error) {
const getJobsForFile = `-- name: GetJobsForFile :many
SELECT id, file_id, created, started, completed, status, job_type, error, messages FROM processing_jobs
WHERE file_id = $1
ORDER BY created DESC
`
func (q *Queries) GetJobsForFile(ctx context.Context, fileID pgtype.UUID) ([]ProcessingJob, error) {

View file

@ -22,7 +22,7 @@ func (q *Queries) DeleteYaraResults(ctx context.Context, id int64) error {
}
const getYaraResults = `-- name: GetYaraResults :one
SELECT id, file_id, matched FROM yara_results
SELECT id, file_id, matched, created FROM yara_results
WHERE file_id = $1
LIMIT 1
`
@ -30,7 +30,12 @@ LIMIT 1
func (q *Queries) GetYaraResults(ctx context.Context, fileID pgtype.UUID) (YaraResult, error) {
row := q.db.QueryRow(ctx, getYaraResults, fileID)
var i YaraResult
err := row.Scan(&i.ID, &i.FileID, &i.Matched)
err := row.Scan(
&i.ID,
&i.FileID,
&i.Matched,
&i.Created,
)
return i, err
}
@ -38,7 +43,7 @@ const insertYaraResults = `-- name: InsertYaraResults :one
INSERT INTO yara_results (
file_id, matched
) VALUES ($1, $2)
RETURNING id, file_id, matched
RETURNING id, file_id, matched, created
`
type InsertYaraResultsParams struct {
@ -49,6 +54,11 @@ type InsertYaraResultsParams struct {
func (q *Queries) InsertYaraResults(ctx context.Context, arg InsertYaraResultsParams) (YaraResult, error) {
row := q.db.QueryRow(ctx, insertYaraResults, arg.FileID, arg.Matched)
var i YaraResult
err := row.Scan(&i.ID, &i.FileID, &i.Matched)
err := row.Scan(
&i.ID,
&i.FileID,
&i.Matched,
&i.Created,
)
return i, err
}

View file

@ -1,6 +1,6 @@
// Code generated by templ - DO NOT EDIT.
// templ: version: v0.3.865
// templ: version: v0.3.924
package web
//lint:file-ignore SA4006 This context is only used if a nested component is present.

View file

@ -1,6 +1,6 @@
// Code generated by templ - DO NOT EDIT.
// templ: version: v0.3.865
// templ: version: v0.3.924
package web
//lint:file-ignore SA4006 This context is only used if a nested component is present.

File diff suppressed because it is too large Load diff

View file

@ -67,7 +67,7 @@ templ NavBar(title string) {
<div class="container mx-auto flex justify-between items-center">
<!-- Logo or Brand Name -->
<a href="/" class="text-white text-lg font-bold">
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-search"><circle cx="11" cy="11" r="8"></circle><line x1="21" y1="21" x2="16.65" y2="16.65"></line></svg>
Scanfile
</a>
<!-- Navigation Links -->
<div class="flex space-x-4">

View file

@ -1,6 +1,6 @@
// Code generated by templ - DO NOT EDIT.
// templ: version: v0.3.865
// templ: version: v0.3.924
package web
//lint:file-ignore SA4006 This context is only used if a nested component is present.
@ -79,8 +79,12 @@ func Base(title string) templ.Component {
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var4 templ.SafeURL = templ.URL(viper.GetString("ui.byurl"))
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(string(templ_7745c5c3_Var4)))
var templ_7745c5c3_Var4 templ.SafeURL
templ_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinURLErrs(templ.URL(viper.GetString("ui.byurl")))
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/base.templ`, Line: 27, Col: 90}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var4))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
@ -101,8 +105,12 @@ func Base(title string) templ.Component {
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var6 templ.SafeURL = templ.URL(viper.GetString("ui.source"))
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(string(templ_7745c5c3_Var6)))
var templ_7745c5c3_Var6 templ.SafeURL
templ_7745c5c3_Var6, templ_7745c5c3_Err = templ.JoinURLErrs(templ.URL(viper.GetString("ui.source")))
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/base.templ`, Line: 28, Col: 59}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var6))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
@ -135,7 +143,7 @@ func NavBar(title string) templ.Component {
templ_7745c5c3_Var7 = templ.NopComponent
}
ctx = templ.ClearChildren(ctx)
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 9, "<nav class=\"bg-blue-600 p-4 shadow-lg\"><div class=\"container mx-auto flex justify-between items-center\"><!-- Logo or Brand Name --><a href=\"/\" class=\"text-white text-lg font-bold\"><svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" class=\"feather feather-search\"><circle cx=\"11\" cy=\"11\" r=\"8\"></circle><line x1=\"21\" y1=\"21\" x2=\"16.65\" y2=\"16.65\"></line></svg></a><!-- Navigation Links --><div class=\"flex space-x-4\"><a href=\"/\" class=\"text-white hover:bg-blue-700 px-3 py-2 rounded-md\">Home</a> <a href=\"/about\" class=\"text-white hover:bg-blue-700 px-3 py-2 rounded-md\">About</a> <a href=\"/login\" class=\"text-white hover:bg-blue-700 px-3 py-2 rounded-md\">Login</a></div></div></nav>")
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 9, "<nav class=\"bg-blue-600 p-4 shadow-lg\"><div class=\"container mx-auto flex justify-between items-center\"><!-- Logo or Brand Name --><a href=\"/\" class=\"text-white text-lg font-bold\">Scanfile</a><!-- Navigation Links --><div class=\"flex space-x-4\"><a href=\"/\" class=\"text-white hover:bg-blue-700 px-3 py-2 rounded-md\">Home</a> <a href=\"/about\" class=\"text-white hover:bg-blue-700 px-3 py-2 rounded-md\">About</a> <a href=\"/login\" class=\"text-white hover:bg-blue-700 px-3 py-2 rounded-md\">Login</a></div></div></nav>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}

View file

@ -1,6 +1,6 @@
// Code generated by templ - DO NOT EDIT.
// templ: version: v0.3.865
// templ: version: v0.3.924
package web
//lint:file-ignore SA4006 This context is only used if a nested component is present.
@ -253,8 +253,12 @@ func FileList(files []sqlc.File) templ.Component {
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var13 templ.SafeURL = templ.SafeURL(fmt.Sprintf("/files/%s", file.ID.String()))
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(string(templ_7745c5c3_Var13)))
var templ_7745c5c3_Var13 templ.SafeURL
templ_7745c5c3_Var13, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(fmt.Sprintf("/files/%s", file.ID.String())))
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/fileList.templ`, Line: 33, Col: 78}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var13))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
@ -301,8 +305,12 @@ func FileList(files []sqlc.File) templ.Component {
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var16 templ.SafeURL = templ.SafeURL(fmt.Sprintf("/files/%s", file.ID.String()))
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(string(templ_7745c5c3_Var16)))
var templ_7745c5c3_Var16 templ.SafeURL
templ_7745c5c3_Var16, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(fmt.Sprintf("/files/%s", file.ID.String())))
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/fileList.templ`, Line: 38, Col: 78}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var16))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
@ -349,8 +357,12 @@ func FileList(files []sqlc.File) templ.Component {
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var19 templ.SafeURL = templ.SafeURL(fmt.Sprintf("/files/%s", file.ID.String()))
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(string(templ_7745c5c3_Var19)))
var templ_7745c5c3_Var19 templ.SafeURL
templ_7745c5c3_Var19, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(fmt.Sprintf("/files/%s", file.ID.String())))
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/fileList.templ`, Line: 43, Col: 78}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var19))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
@ -397,8 +409,12 @@ func FileList(files []sqlc.File) templ.Component {
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var22 templ.SafeURL = templ.SafeURL(fmt.Sprintf("/files/%s", file.ID.String()))
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(string(templ_7745c5c3_Var22)))
var templ_7745c5c3_Var22 templ.SafeURL
templ_7745c5c3_Var22, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(fmt.Sprintf("/files/%s", file.ID.String())))
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/fileList.templ`, Line: 48, Col: 78}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var22))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
@ -445,8 +461,12 @@ func FileList(files []sqlc.File) templ.Component {
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var25 templ.SafeURL = templ.SafeURL(fmt.Sprintf("/files/%s", file.ID.String()))
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(string(templ_7745c5c3_Var25)))
var templ_7745c5c3_Var25 templ.SafeURL
templ_7745c5c3_Var25, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(fmt.Sprintf("/files/%s", file.ID.String())))
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/fileList.templ`, Line: 53, Col: 78}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var25))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}

View file

@ -25,7 +25,13 @@ func FileViewWebHandler(w http.ResponseWriter, r *http.Request) {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
component := FileView(file, fileProperties)
diec, err := database.GetFileDiec(file.ID)
if err != nil {
slog.Error("Error getting Detect-It-Easy in FileViewWebHandler", "error", err, "file-uuid", r.PathValue("uuid"))
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
component := FileView(file, fileProperties, diec)
err = component.Render(r.Context(), w)
if err != nil {
slog.Error("Error rendering in FileViewWebHandler", "error", err)

View file

@ -6,8 +6,9 @@ import "git.jmbit.de/jmb/scanfile/server/web/templui/components/modal"
import "git.jmbit.de/jmb/scanfile/server/internal/processing"
import "fmt"
import "git.jmbit.de/jmb/scanfile/server/web/templui/components/icon"
import "git.jmbit.de/jmb/scanfile/server/internal/database"
templ FileView(file sqlc.File, fileProperties sqlc.FileProperty) {
templ FileView(file sqlc.File, fileProperties sqlc.FileProperty, diec database.Diec) {
@Base(file.Name) {
<div class="flex space-x-4 pb-4">
<h1 class="text-4xl">{file.Name}</h1>
@ -15,12 +16,11 @@ templ FileView(file sqlc.File, fileProperties sqlc.FileProperty) {
@FileViewDownloadModal(file.ID.String())
</div>
<div class="grid grid-cols-2 gap-4">
@FileViewGenericTable(file, fileProperties)
@FileViewGenericTable(file, fileProperties, diec)
if processing.TypeFromMime(file.Mimetype) == processing.TypeMSOffice {
@FileViewMsofficeLoader(file.ID.String())
}
</div>
}
}

View file

@ -5,8 +5,9 @@ import "git.jmbit.de/jmb/scanfile/server/web/templui/components/table"
import "git.jmbit.de/jmb/scanfile/server/web/templui/components/button"
import "encoding/hex"
import "fmt"
import "git.jmbit.de/jmb/scanfile/server/internal/database"
templ FileViewGenericTable(file sqlc.File, fileProperties sqlc.FileProperty) {
templ FileViewGenericTable(file sqlc.File, fileProperties sqlc.FileProperty, diec database.Diec) {
<div class="w-full">
<h2 class="text-3xl">Generic Information</h2>
@table.Table() {
@ -71,7 +72,7 @@ templ FileViewGenericTable(file sqlc.File, fileProperties sqlc.FileProperty) {
}
}
}
if fileProperties.LibmagicApple.Valid {
if fileProperties.LibmagicApple.Valid && fileProperties.LibmagicApple.String != "UNKNUNKN" {
@table.Row() {
@table.Cell() {
Apple Filetype
@ -90,17 +91,65 @@ templ FileViewGenericTable(file sqlc.File, fileProperties sqlc.FileProperty) {
}
}
}
@DiecInfo(diec)
@OtherServices(hex.EncodeToString(fileProperties.Sha256))
</div>
}
<p class="p-1">Look for this file on other services</p>
templ DiecInfo(diec database.Diec) {
<h3 class="text-2xl">Detect-It-Easy information</h3>
@table.Table() {
@table.Header() {
@table.Head() {
Info
}
@table.Head() {
Name
}
@table.Head() {
Type
}
@table.Head() {
Details
}
@table.Head() {
Version
}
}
@table.Body() {
for _, row := range diec.Data.Detects[0].Values {
@table.Row() {
@table.Cell() {
{row.Info}
}
@table.Cell() {
{row.Name}
}
@table.Cell() {
{row.Type}
}
@table.Cell() {
{row.String}
}
@table.Cell() {
{row.Version}
}
}
}
}
}
}
templ OtherServices(sha256 string) {
<h3 class="text-2xl">Look for this file on other Services</h3>
<div class="flex space-x-4 pb-4">
@button.Button(button.Props{
Variant: button.VariantOutline,
Href: fmt.Sprintf("https://www.virustotal.com/gui/file/%s", hex.EncodeToString(fileProperties.Sha256)),
Href: fmt.Sprintf("https://www.virustotal.com/gui/file/%s", sha256),
}) {VirusTotal}
@button.Button(button.Props{
Variant: button.VariantOutline,
Href: fmt.Sprintf("https://bazaar.abuse.ch/sample/%s", hex.EncodeToString(fileProperties.Sha256)),
Href: fmt.Sprintf("https://bazaar.abuse.ch/sample/%s", sha256),
}) {Malware Bazaar}
</div>
</div>
}

View file

@ -1,6 +1,6 @@
// Code generated by templ - DO NOT EDIT.
// templ: version: v0.3.865
// templ: version: v0.3.924
package web
//lint:file-ignore SA4006 This context is only used if a nested component is present.
@ -13,8 +13,9 @@ import "git.jmbit.de/jmb/scanfile/server/web/templui/components/table"
import "git.jmbit.de/jmb/scanfile/server/web/templui/components/button"
import "encoding/hex"
import "fmt"
import "git.jmbit.de/jmb/scanfile/server/internal/database"
func FileViewGenericTable(file sqlc.File, fileProperties sqlc.FileProperty) templ.Component {
func FileViewGenericTable(file sqlc.File, fileProperties sqlc.FileProperty, diec database.Diec) templ.Component {
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
@ -104,7 +105,7 @@ func FileViewGenericTable(file sqlc.File, fileProperties sqlc.FileProperty) temp
var templ_7745c5c3_Var6 string
templ_7745c5c3_Var6, templ_7745c5c3_Err = templ.JoinStringErrs(file.Size)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/fileViewGeneric.templ`, Line: 18, Col: 22}
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/fileViewGeneric.templ`, Line: 19, Col: 22}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var6))
if templ_7745c5c3_Err != nil {
@ -183,7 +184,7 @@ func FileViewGenericTable(file sqlc.File, fileProperties sqlc.FileProperty) temp
var templ_7745c5c3_Var10 string
templ_7745c5c3_Var10, templ_7745c5c3_Err = templ.JoinStringErrs(file.Mimetype)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/fileViewGeneric.templ`, Line: 26, Col: 26}
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/fileViewGeneric.templ`, Line: 27, Col: 26}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var10))
if templ_7745c5c3_Err != nil {
@ -258,7 +259,7 @@ func FileViewGenericTable(file sqlc.File, fileProperties sqlc.FileProperty) temp
var templ_7745c5c3_Var14 string
templ_7745c5c3_Var14, templ_7745c5c3_Err = templ.JoinStringErrs(hex.EncodeToString(file.Blake2))
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/fileViewGeneric.templ`, Line: 35, Col: 44}
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/fileViewGeneric.templ`, Line: 36, Col: 44}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var14))
if templ_7745c5c3_Err != nil {
@ -333,7 +334,7 @@ func FileViewGenericTable(file sqlc.File, fileProperties sqlc.FileProperty) temp
var templ_7745c5c3_Var18 string
templ_7745c5c3_Var18, templ_7745c5c3_Err = templ.JoinStringErrs(hex.EncodeToString(fileProperties.Sha256))
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/fileViewGeneric.templ`, Line: 43, Col: 54}
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/fileViewGeneric.templ`, Line: 44, Col: 54}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var18))
if templ_7745c5c3_Err != nil {
@ -408,7 +409,7 @@ func FileViewGenericTable(file sqlc.File, fileProperties sqlc.FileProperty) temp
var templ_7745c5c3_Var22 string
templ_7745c5c3_Var22, templ_7745c5c3_Err = templ.JoinStringErrs(hex.EncodeToString(fileProperties.Md5))
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/fileViewGeneric.templ`, Line: 51, Col: 51}
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/fileViewGeneric.templ`, Line: 52, Col: 51}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var22))
if templ_7745c5c3_Err != nil {
@ -484,7 +485,7 @@ func FileViewGenericTable(file sqlc.File, fileProperties sqlc.FileProperty) temp
var templ_7745c5c3_Var26 string
templ_7745c5c3_Var26, templ_7745c5c3_Err = templ.JoinStringErrs(fileProperties.LibmagicMime.String)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/fileViewGeneric.templ`, Line: 60, Col: 49}
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/fileViewGeneric.templ`, Line: 61, Col: 49}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var26))
if templ_7745c5c3_Err != nil {
@ -561,7 +562,7 @@ func FileViewGenericTable(file sqlc.File, fileProperties sqlc.FileProperty) temp
var templ_7745c5c3_Var30 string
templ_7745c5c3_Var30, templ_7745c5c3_Err = templ.JoinStringErrs(fileProperties.LibmagicExtension.String)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/fileViewGeneric.templ`, Line: 70, Col: 54}
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/fileViewGeneric.templ`, Line: 71, Col: 54}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var30))
if templ_7745c5c3_Err != nil {
@ -584,7 +585,7 @@ func FileViewGenericTable(file sqlc.File, fileProperties sqlc.FileProperty) temp
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
if fileProperties.LibmagicApple.Valid {
if fileProperties.LibmagicApple.Valid && fileProperties.LibmagicApple.String != "UNKNUNKN" {
templ_7745c5c3_Var31 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
@ -638,7 +639,7 @@ func FileViewGenericTable(file sqlc.File, fileProperties sqlc.FileProperty) temp
var templ_7745c5c3_Var34 string
templ_7745c5c3_Var34, templ_7745c5c3_Err = templ.JoinStringErrs(fileProperties.LibmagicApple.String)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/fileViewGeneric.templ`, Line: 80, Col: 50}
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/fileViewGeneric.templ`, Line: 81, Col: 50}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var34))
if templ_7745c5c3_Err != nil {
@ -714,7 +715,7 @@ func FileViewGenericTable(file sqlc.File, fileProperties sqlc.FileProperty) temp
var templ_7745c5c3_Var38 string
templ_7745c5c3_Var38, templ_7745c5c3_Err = templ.JoinStringErrs(file.Created.Time.String())
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/fileViewGeneric.templ`, Line: 89, Col: 39}
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/fileViewGeneric.templ`, Line: 90, Col: 39}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var38))
if templ_7745c5c3_Err != nil {
@ -738,12 +739,28 @@ func FileViewGenericTable(file sqlc.File, fileProperties sqlc.FileProperty) temp
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 29, "<p class=\"p-1\">Look for this file on other services</p><div class=\"flex space-x-4 pb-4\">")
templ_7745c5c3_Err = DiecInfo(diec).Render(ctx, templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Var39 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_Err = OtherServices(hex.EncodeToString(fileProperties.Sha256)).Render(ctx, templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 29, "</div>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return nil
})
}
func DiecInfo(diec database.Diec) templ.Component {
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
return templ_7745c5c3_CtxErr
}
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
if !templ_7745c5c3_IsBuffer {
defer func() {
@ -754,16 +771,12 @@ func FileViewGenericTable(file sqlc.File, fileProperties sqlc.FileProperty) temp
}()
}
ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 30, "VirusTotal")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
templ_7745c5c3_Var39 := templ.GetChildren(ctx)
if templ_7745c5c3_Var39 == nil {
templ_7745c5c3_Var39 = templ.NopComponent
}
return nil
})
templ_7745c5c3_Err = button.Button(button.Props{
Variant: button.VariantOutline,
Href: fmt.Sprintf("https://www.virustotal.com/gui/file/%s", hex.EncodeToString(fileProperties.Sha256)),
}).Render(templ.WithChildren(ctx, templ_7745c5c3_Var39), templ_7745c5c3_Buffer)
ctx = templ.ClearChildren(ctx)
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 30, "<h3 class=\"text-2xl\">Detect-It-Easy information</h3>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
@ -779,7 +792,391 @@ func FileViewGenericTable(file sqlc.File, fileProperties sqlc.FileProperty) temp
}()
}
ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 31, "Malware Bazaar")
templ_7745c5c3_Var41 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
if !templ_7745c5c3_IsBuffer {
defer func() {
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
if templ_7745c5c3_Err == nil {
templ_7745c5c3_Err = templ_7745c5c3_BufErr
}
}()
}
ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Var42 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
if !templ_7745c5c3_IsBuffer {
defer func() {
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
if templ_7745c5c3_Err == nil {
templ_7745c5c3_Err = templ_7745c5c3_BufErr
}
}()
}
ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 31, "Info")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return nil
})
templ_7745c5c3_Err = table.Head().Render(templ.WithChildren(ctx, templ_7745c5c3_Var42), templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 32, " ")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Var43 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
if !templ_7745c5c3_IsBuffer {
defer func() {
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
if templ_7745c5c3_Err == nil {
templ_7745c5c3_Err = templ_7745c5c3_BufErr
}
}()
}
ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 33, "Name")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return nil
})
templ_7745c5c3_Err = table.Head().Render(templ.WithChildren(ctx, templ_7745c5c3_Var43), templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 34, " ")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Var44 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
if !templ_7745c5c3_IsBuffer {
defer func() {
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
if templ_7745c5c3_Err == nil {
templ_7745c5c3_Err = templ_7745c5c3_BufErr
}
}()
}
ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 35, "Type")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return nil
})
templ_7745c5c3_Err = table.Head().Render(templ.WithChildren(ctx, templ_7745c5c3_Var44), templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 36, " ")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Var45 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
if !templ_7745c5c3_IsBuffer {
defer func() {
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
if templ_7745c5c3_Err == nil {
templ_7745c5c3_Err = templ_7745c5c3_BufErr
}
}()
}
ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 37, "Details")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return nil
})
templ_7745c5c3_Err = table.Head().Render(templ.WithChildren(ctx, templ_7745c5c3_Var45), templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 38, " ")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Var46 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
if !templ_7745c5c3_IsBuffer {
defer func() {
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
if templ_7745c5c3_Err == nil {
templ_7745c5c3_Err = templ_7745c5c3_BufErr
}
}()
}
ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 39, "Version")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return nil
})
templ_7745c5c3_Err = table.Head().Render(templ.WithChildren(ctx, templ_7745c5c3_Var46), templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return nil
})
templ_7745c5c3_Err = table.Header().Render(templ.WithChildren(ctx, templ_7745c5c3_Var41), templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 40, " ")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Var47 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
if !templ_7745c5c3_IsBuffer {
defer func() {
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
if templ_7745c5c3_Err == nil {
templ_7745c5c3_Err = templ_7745c5c3_BufErr
}
}()
}
ctx = templ.InitializeContext(ctx)
for _, row := range diec.Data.Detects[0].Values {
templ_7745c5c3_Var48 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
if !templ_7745c5c3_IsBuffer {
defer func() {
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
if templ_7745c5c3_Err == nil {
templ_7745c5c3_Err = templ_7745c5c3_BufErr
}
}()
}
ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Var49 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
if !templ_7745c5c3_IsBuffer {
defer func() {
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
if templ_7745c5c3_Err == nil {
templ_7745c5c3_Err = templ_7745c5c3_BufErr
}
}()
}
ctx = templ.InitializeContext(ctx)
var templ_7745c5c3_Var50 string
templ_7745c5c3_Var50, templ_7745c5c3_Err = templ.JoinStringErrs(row.Info)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/fileViewGeneric.templ`, Line: 123, Col: 25}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var50))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return nil
})
templ_7745c5c3_Err = table.Cell().Render(templ.WithChildren(ctx, templ_7745c5c3_Var49), templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 41, " ")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Var51 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
if !templ_7745c5c3_IsBuffer {
defer func() {
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
if templ_7745c5c3_Err == nil {
templ_7745c5c3_Err = templ_7745c5c3_BufErr
}
}()
}
ctx = templ.InitializeContext(ctx)
var templ_7745c5c3_Var52 string
templ_7745c5c3_Var52, templ_7745c5c3_Err = templ.JoinStringErrs(row.Name)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/fileViewGeneric.templ`, Line: 126, Col: 25}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var52))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return nil
})
templ_7745c5c3_Err = table.Cell().Render(templ.WithChildren(ctx, templ_7745c5c3_Var51), templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 42, " ")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Var53 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
if !templ_7745c5c3_IsBuffer {
defer func() {
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
if templ_7745c5c3_Err == nil {
templ_7745c5c3_Err = templ_7745c5c3_BufErr
}
}()
}
ctx = templ.InitializeContext(ctx)
var templ_7745c5c3_Var54 string
templ_7745c5c3_Var54, templ_7745c5c3_Err = templ.JoinStringErrs(row.Type)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/fileViewGeneric.templ`, Line: 129, Col: 25}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var54))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return nil
})
templ_7745c5c3_Err = table.Cell().Render(templ.WithChildren(ctx, templ_7745c5c3_Var53), templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 43, " ")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Var55 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
if !templ_7745c5c3_IsBuffer {
defer func() {
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
if templ_7745c5c3_Err == nil {
templ_7745c5c3_Err = templ_7745c5c3_BufErr
}
}()
}
ctx = templ.InitializeContext(ctx)
var templ_7745c5c3_Var56 string
templ_7745c5c3_Var56, templ_7745c5c3_Err = templ.JoinStringErrs(row.String)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/fileViewGeneric.templ`, Line: 132, Col: 27}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var56))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return nil
})
templ_7745c5c3_Err = table.Cell().Render(templ.WithChildren(ctx, templ_7745c5c3_Var55), templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 44, " ")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Var57 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
if !templ_7745c5c3_IsBuffer {
defer func() {
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
if templ_7745c5c3_Err == nil {
templ_7745c5c3_Err = templ_7745c5c3_BufErr
}
}()
}
ctx = templ.InitializeContext(ctx)
var templ_7745c5c3_Var58 string
templ_7745c5c3_Var58, templ_7745c5c3_Err = templ.JoinStringErrs(row.Version)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/fileViewGeneric.templ`, Line: 135, Col: 28}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var58))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return nil
})
templ_7745c5c3_Err = table.Cell().Render(templ.WithChildren(ctx, templ_7745c5c3_Var57), templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return nil
})
templ_7745c5c3_Err = table.Row().Render(templ.WithChildren(ctx, templ_7745c5c3_Var48), templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
}
return nil
})
templ_7745c5c3_Err = table.Body().Render(templ.WithChildren(ctx, templ_7745c5c3_Var47), templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return nil
})
templ_7745c5c3_Err = table.Table().Render(templ.WithChildren(ctx, templ_7745c5c3_Var40), templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return nil
})
}
func OtherServices(sha256 string) templ.Component {
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
return templ_7745c5c3_CtxErr
}
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
if !templ_7745c5c3_IsBuffer {
defer func() {
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
if templ_7745c5c3_Err == nil {
templ_7745c5c3_Err = templ_7745c5c3_BufErr
}
}()
}
ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Var59 := templ.GetChildren(ctx)
if templ_7745c5c3_Var59 == nil {
templ_7745c5c3_Var59 = templ.NopComponent
}
ctx = templ.ClearChildren(ctx)
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 45, "<h3 class=\"text-2xl\">Look for this file on other Services</h3><div class=\"flex space-x-4 pb-4\">")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Var60 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
if !templ_7745c5c3_IsBuffer {
defer func() {
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
if templ_7745c5c3_Err == nil {
templ_7745c5c3_Err = templ_7745c5c3_BufErr
}
}()
}
ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 46, "VirusTotal")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
@ -787,12 +1184,37 @@ func FileViewGenericTable(file sqlc.File, fileProperties sqlc.FileProperty) temp
})
templ_7745c5c3_Err = button.Button(button.Props{
Variant: button.VariantOutline,
Href: fmt.Sprintf("https://bazaar.abuse.ch/sample/%s", hex.EncodeToString(fileProperties.Sha256)),
}).Render(templ.WithChildren(ctx, templ_7745c5c3_Var40), templ_7745c5c3_Buffer)
Href: fmt.Sprintf("https://www.virustotal.com/gui/file/%s", sha256),
}).Render(templ.WithChildren(ctx, templ_7745c5c3_Var60), templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 32, "</div></div>")
templ_7745c5c3_Var61 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
if !templ_7745c5c3_IsBuffer {
defer func() {
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
if templ_7745c5c3_Err == nil {
templ_7745c5c3_Err = templ_7745c5c3_BufErr
}
}()
}
ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 47, "Malware Bazaar")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return nil
})
templ_7745c5c3_Err = button.Button(button.Props{
Variant: button.VariantOutline,
Href: fmt.Sprintf("https://bazaar.abuse.ch/sample/%s", sha256),
}).Render(templ.WithChildren(ctx, templ_7745c5c3_Var61), templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 48, "</div>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}

View file

@ -1,6 +1,6 @@
// Code generated by templ - DO NOT EDIT.
// templ: version: v0.3.865
// templ: version: v0.3.924
package web
//lint:file-ignore SA4006 This context is only used if a nested component is present.
@ -66,8 +66,12 @@ func FileViewMsofficeLoader(fileid string) templ.Component {
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var3 templ.SafeURL = templ.URL(fmt.Sprintf("/files/%s/msoffice", fileid))
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(string(templ_7745c5c3_Var3)))
var templ_7745c5c3_Var3 templ.SafeURL
templ_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinURLErrs(templ.URL(fmt.Sprintf("/files/%s/msoffice", fileid)))
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/fileViewMsoffice.templ`, Line: 18, Col: 79}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}

View file

@ -1,6 +1,6 @@
// Code generated by templ - DO NOT EDIT.
// templ: version: v0.3.865
// templ: version: v0.3.924
package web
//lint:file-ignore SA4006 This context is only used if a nested component is present.
@ -14,8 +14,9 @@ import "git.jmbit.de/jmb/scanfile/server/web/templui/components/modal"
import "git.jmbit.de/jmb/scanfile/server/internal/processing"
import "fmt"
import "git.jmbit.de/jmb/scanfile/server/web/templui/components/icon"
import "git.jmbit.de/jmb/scanfile/server/internal/database"
func FileView(file sqlc.File, fileProperties sqlc.FileProperty) templ.Component {
func FileView(file sqlc.File, fileProperties sqlc.FileProperty, diec database.Diec) templ.Component {
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
@ -55,7 +56,7 @@ func FileView(file sqlc.File, fileProperties sqlc.FileProperty) templ.Component
var templ_7745c5c3_Var3 string
templ_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(file.Name)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/fileView.templ`, Line: 13, Col: 37}
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/fileView.templ`, Line: 14, Col: 37}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3))
if templ_7745c5c3_Err != nil {
@ -77,7 +78,7 @@ func FileView(file sqlc.File, fileProperties sqlc.FileProperty) templ.Component
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = FileViewGenericTable(file, fileProperties).Render(ctx, templ_7745c5c3_Buffer)
templ_7745c5c3_Err = FileViewGenericTable(file, fileProperties, diec).Render(ctx, templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}

View file

@ -1,6 +1,6 @@
// Code generated by templ - DO NOT EDIT.
// templ: version: v0.3.865
// templ: version: v0.3.924
package web
//lint:file-ignore SA4006 This context is only used if a nested component is present.

View file

@ -1,6 +1,6 @@
// Code generated by templ - DO NOT EDIT.
// templ: version: v0.3.865
// templ: version: v0.3.924
// templui component accordion - version: v0.84.0 installed by templui v0.84.0
package accordion
@ -64,8 +64,7 @@ func Accordion(props ...Props) templ.Component {
if len(props) > 0 {
p = props[0]
}
var templ_7745c5c3_Var2 = []any{
utils.TwMerge(
var templ_7745c5c3_Var2 = []any{utils.TwMerge(
"divide-y rounded-md divide-border border",
p.Class,
),
@ -159,8 +158,7 @@ func Item(props ...ItemProps) templ.Component {
if len(props) > 0 {
p = props[0]
}
var templ_7745c5c3_Var6 = []any{
utils.TwMerge(
var templ_7745c5c3_Var6 = []any{utils.TwMerge(
"group",
"open:[&>summary_svg]:rotate-180",
p.Class,
@ -255,8 +253,7 @@ func Trigger(props ...TriggerProps) templ.Component {
if len(props) > 0 {
p = props[0]
}
var templ_7745c5c3_Var10 = []any{
utils.TwMerge(
var templ_7745c5c3_Var10 = []any{utils.TwMerge(
"flex w-full items-center justify-between py-4 px-5",
"text-left font-medium cursor-pointer",
"transition-all hover:underline",
@ -364,8 +361,7 @@ func Content(props ...ContentProps) templ.Component {
if len(props) > 0 {
p = props[0]
}
var templ_7745c5c3_Var14 = []any{
utils.TwMerge(
var templ_7745c5c3_Var14 = []any{utils.TwMerge(
"px-5 pb-4 pt-0",
p.Class,
),

View file

@ -1,6 +1,6 @@
// Code generated by templ - DO NOT EDIT.
// templ: version: v0.3.865
// templ: version: v0.3.924
// templui component alert - version: v0.84.0 installed by templui v0.84.0
package alert
@ -63,8 +63,7 @@ func Alert(props ...Props) templ.Component {
if len(props) > 0 {
p = props[0]
}
var templ_7745c5c3_Var2 = []any{
utils.TwMerge(
var templ_7745c5c3_Var2 = []any{utils.TwMerge(
"relative w-full p-4",
"[&>svg]:absolute [&>svg]:left-4 [&>svg]:top-4",
"[&>svg+div]:translate-y-[-3px] [&:has(svg)]:pl-11",
@ -162,8 +161,7 @@ func Title(props ...TitleProps) templ.Component {
if len(props) > 0 {
p = props[0]
}
var templ_7745c5c3_Var6 = []any{
utils.TwMerge(
var templ_7745c5c3_Var6 = []any{utils.TwMerge(
"mb-1 font-medium leading-none tracking-tight",
p.Class,
),
@ -257,8 +255,7 @@ func Description(props ...DescriptionProps) templ.Component {
if len(props) > 0 {
p = props[0]
}
var templ_7745c5c3_Var10 = []any{
utils.TwMerge(
var templ_7745c5c3_Var10 = []any{utils.TwMerge(
"[&_p]:leading-relaxed text-sm",
p.Class,
),

View file

@ -1,6 +1,6 @@
// Code generated by templ - DO NOT EDIT.
// templ: version: v0.3.865
// templ: version: v0.3.924
// templui component aspectratio - version: main installed by templui v0.71.0
package aspectratio
@ -54,8 +54,7 @@ func AspectRatio(props ...Props) templ.Component {
if len(props) > 0 {
p = props[0]
}
var templ_7745c5c3_Var2 = []any{
utils.TwMerge(
var templ_7745c5c3_Var2 = []any{utils.TwMerge(
"relative w-full",
ratioClass(p.Ratio),
p.Class,

View file

@ -1,6 +1,6 @@
// Code generated by templ - DO NOT EDIT.
// templ: version: v0.3.865
// templ: version: v0.3.924
// templui component aspectratio - version: v0.84.0 installed by templui v0.84.0
package aspectratio
@ -54,8 +54,7 @@ func AspectRatio(props ...Props) templ.Component {
if len(props) > 0 {
p = props[0]
}
var templ_7745c5c3_Var2 = []any{
utils.TwMerge(
var templ_7745c5c3_Var2 = []any{utils.TwMerge(
"relative w-full",
ratioClass(p.Ratio),
p.Class,

View file

@ -1,6 +1,6 @@
// Code generated by templ - DO NOT EDIT.
// templ: version: v0.3.865
// templ: version: v0.3.924
// templui component avatar - version: v0.84.0 installed by templui v0.84.0
package avatar
@ -85,8 +85,7 @@ func Avatar(props ...Props) templ.Component {
if len(props) > 0 {
p = props[0]
}
var templ_7745c5c3_Var2 = []any{
utils.TwMerge(
var templ_7745c5c3_Var2 = []any{utils.TwMerge(
"inline-flex items-center justify-center",
SizeClasses(p.Size),
"rounded-full bg-muted",
@ -183,8 +182,7 @@ func Image(props ...ImageProps) templ.Component {
if len(props) > 0 {
p = props[0]
}
var templ_7745c5c3_Var6 = []any{
utils.TwMerge(
var templ_7745c5c3_Var6 = []any{utils.TwMerge(
"w-full h-full",
"rounded-full object-cover",
p.Class,
@ -303,8 +301,7 @@ func Fallback(props ...FallbackProps) templ.Component {
if len(props) > 0 {
p = props[0]
}
var templ_7745c5c3_Var12 = []any{
utils.TwMerge(
var templ_7745c5c3_Var12 = []any{utils.TwMerge(
"font-medium text-muted-foreground",
p.Class,
),
@ -398,8 +395,7 @@ func Group(props ...GroupProps) templ.Component {
if len(props) > 0 {
p = props[0]
}
var templ_7745c5c3_Var16 = []any{
utils.TwMerge(
var templ_7745c5c3_Var16 = []any{utils.TwMerge(
"flex items-center -space-x-3",
groupSpacingClasses(p.Spacing),
p.Class,
@ -494,8 +490,7 @@ func GroupOverflow(count int, props ...Props) templ.Component {
if len(props) > 0 {
p = props[0]
}
var templ_7745c5c3_Var20 = []any{
utils.TwMerge(
var templ_7745c5c3_Var20 = []any{utils.TwMerge(
"inline-flex items-center justify-center",
SizeClasses(p.Size),
"rounded-full bg-muted ring-2 ring-background",

View file

@ -1,6 +1,6 @@
// Code generated by templ - DO NOT EDIT.
// templ: version: v0.3.865
// templ: version: v0.3.924
// templui component badge - version: v0.84.0 installed by templui v0.84.0
package badge
@ -53,8 +53,7 @@ func Badge(props ...Props) templ.Component {
if len(props) > 0 {
p = props[0]
}
var templ_7745c5c3_Var2 = []any{
utils.TwMerge(
var templ_7745c5c3_Var2 = []any{utils.TwMerge(
"inline-flex items-center justify-center rounded-md border px-2 py-0.5 text-xs font-medium w-fit whitespace-nowrap shrink-0 [&>svg]:size-3 gap-1 [&>svg]:pointer-events-none",
"focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px]",
"aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive",

View file

@ -1,6 +1,6 @@
// Code generated by templ - DO NOT EDIT.
// templ: version: v0.3.865
// templ: version: v0.3.924
// templui component breadcrumb - version: v0.84.0 installed by templui v0.84.0
package breadcrumb
@ -73,8 +73,7 @@ func Breadcrumb(props ...Props) templ.Component {
if len(props) > 0 {
p = props[0]
}
var templ_7745c5c3_Var2 = []any{
utils.TwMerge(
var templ_7745c5c3_Var2 = []any{utils.TwMerge(
"flex",
p.Class,
),
@ -168,8 +167,7 @@ func List(props ...ListProps) templ.Component {
if len(props) > 0 {
p = props[0]
}
var templ_7745c5c3_Var6 = []any{
utils.TwMerge(
var templ_7745c5c3_Var6 = []any{utils.TwMerge(
"flex items-center flex-wrap gap-1 text-sm",
p.Class,
),
@ -263,8 +261,7 @@ func Item(props ...ItemProps) templ.Component {
if len(props) > 0 {
p = props[0]
}
var templ_7745c5c3_Var10 = []any{
utils.TwMerge(
var templ_7745c5c3_Var10 = []any{utils.TwMerge(
"flex items-center",
p.Class,
),
@ -358,8 +355,7 @@ func Link(props ...LinkProps) templ.Component {
if len(props) > 0 {
p = props[0]
}
var templ_7745c5c3_Var14 = []any{
utils.TwMerge(
var templ_7745c5c3_Var14 = []any{utils.TwMerge(
"text-muted-foreground hover:text-foreground hover:underline flex items-center gap-1.5 transition-colors",
p.Class,
),
@ -396,8 +392,12 @@ func Link(props ...LinkProps) templ.Component {
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var16 templ.SafeURL = templ.SafeURL(p.Href)
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(string(templ_7745c5c3_Var16)))
var templ_7745c5c3_Var16 templ.SafeURL
templ_7745c5c3_Var16, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(p.Href))
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/templui/components/breadcrumb/breadcrumb.templ`, Line: 116, Col: 31}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var16))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
@ -468,8 +468,7 @@ func Separator(props ...SeparatorProps) templ.Component {
if len(props) > 0 {
p = props[0]
}
var templ_7745c5c3_Var19 = []any{
utils.TwMerge(
var templ_7745c5c3_Var19 = []any{utils.TwMerge(
"mx-2 text-muted-foreground",
p.Class,
),
@ -570,8 +569,7 @@ func Page(props ...ItemProps) templ.Component {
if len(props) > 0 {
p = props[0]
}
var templ_7745c5c3_Var23 = []any{
utils.TwMerge(
var templ_7745c5c3_Var23 = []any{utils.TwMerge(
"font-medium text-foreground flex items-center gap-1.5",
p.Class,
),

View file

@ -1,4 +1,4 @@
// templui component button - version: v0.84.0 installed by templui v0.84.0
// templui component button - version: v0.85.0 installed by templui v0.85.0
package button
import (
@ -111,7 +111,7 @@ templ Button(props ...Props) {
func (b Props) variantClasses() string {
switch b.Variant {
case VariantDestructive:
return "bg-destructive text-white shadow-xs hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60"
return "bg-destructive text-destructive-foreground shadow-xs hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60"
case VariantOutline:
return "border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50"
case VariantSecondary:

View file

@ -1,7 +1,7 @@
// Code generated by templ - DO NOT EDIT.
// templ: version: v0.3.865
// templui component button - version: v0.84.0 installed by templui v0.84.0
// templ: version: v0.3.924
// templui component button - version: v0.85.0 installed by templui v0.85.0
package button
@ -83,8 +83,7 @@ func Button(props ...Props) templ.Component {
p.Type = TypeButton
}
if p.Href != "" && !p.Disabled {
var templ_7745c5c3_Var2 = []any{
utils.TwMerge(
var templ_7745c5c3_Var2 = []any{utils.TwMerge(
"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-all",
"disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0",
"outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px]",
@ -127,8 +126,12 @@ func Button(props ...Props) templ.Component {
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var4 templ.SafeURL = templ.SafeURL(p.Href)
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(string(templ_7745c5c3_Var4)))
var templ_7745c5c3_Var4 templ.SafeURL
templ_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(p.Href))
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/templui/components/button/button.templ`, Line: 61, Col: 31}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var4))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
@ -189,8 +192,7 @@ func Button(props ...Props) templ.Component {
return templ_7745c5c3_Err
}
} else {
var templ_7745c5c3_Var7 = []any{
utils.TwMerge(
var templ_7745c5c3_Var7 = []any{utils.TwMerge(
"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-all",
"disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0",
"outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px]",
@ -295,7 +297,7 @@ func Button(props ...Props) templ.Component {
func (b Props) variantClasses() string {
switch b.Variant {
case VariantDestructive:
return "bg-destructive text-white shadow-xs hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60"
return "bg-destructive text-destructive-foreground shadow-xs hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60"
case VariantOutline:
return "border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50"
case VariantSecondary:

View file

@ -1,6 +1,6 @@
// Code generated by templ - DO NOT EDIT.
// templ: version: v0.3.865
// templ: version: v0.3.924
// templui component calendar - version: v0.84.0 installed by templui v0.84.0
package calendar

View file

@ -1,6 +1,6 @@
// Code generated by templ - DO NOT EDIT.
// templ: version: v0.3.865
// templ: version: v0.3.924
// templui component card - version: v0.84.0 installed by templui v0.84.0
package card
@ -73,8 +73,7 @@ func Card(props ...Props) templ.Component {
if len(props) > 0 {
p = props[0]
}
var templ_7745c5c3_Var2 = []any{
utils.TwMerge(
var templ_7745c5c3_Var2 = []any{utils.TwMerge(
"w-full rounded-lg border bg-card text-card-foreground shadow-xs",
p.Class,
),
@ -168,8 +167,7 @@ func Header(props ...HeaderProps) templ.Component {
if len(props) > 0 {
p = props[0]
}
var templ_7745c5c3_Var6 = []any{
utils.TwMerge(
var templ_7745c5c3_Var6 = []any{utils.TwMerge(
"flex flex-col space-y-1.5 p-6 pb-0",
p.Class,
),
@ -263,8 +261,7 @@ func Title(props ...TitleProps) templ.Component {
if len(props) > 0 {
p = props[0]
}
var templ_7745c5c3_Var10 = []any{
utils.TwMerge(
var templ_7745c5c3_Var10 = []any{utils.TwMerge(
"text-lg font-semibold leading-none tracking-tight",
p.Class,
),
@ -358,8 +355,7 @@ func Description(props ...DescriptionProps) templ.Component {
if len(props) > 0 {
p = props[0]
}
var templ_7745c5c3_Var14 = []any{
utils.TwMerge(
var templ_7745c5c3_Var14 = []any{utils.TwMerge(
"text-sm text-muted-foreground",
p.Class,
),
@ -453,8 +449,7 @@ func Content(props ...ContentProps) templ.Component {
if len(props) > 0 {
p = props[0]
}
var templ_7745c5c3_Var18 = []any{
utils.TwMerge(
var templ_7745c5c3_Var18 = []any{utils.TwMerge(
"p-6",
p.Class,
),
@ -548,8 +543,7 @@ func Footer(props ...FooterProps) templ.Component {
if len(props) > 0 {
p = props[0]
}
var templ_7745c5c3_Var22 = []any{
utils.TwMerge(
var templ_7745c5c3_Var22 = []any{utils.TwMerge(
"flex items-center p-6 pt-0",
p.Class,
),

View file

@ -1,6 +1,6 @@
// Code generated by templ - DO NOT EDIT.
// templ: version: v0.3.865
// templ: version: v0.3.924
// templui component carousel - version: v0.84.0 installed by templui v0.84.0
package carousel
@ -82,8 +82,7 @@ func Carousel(props ...Props) templ.Component {
if len(props) > 0 {
p = props[0]
}
var templ_7745c5c3_Var2 = []any{
utils.TwMerge(
var templ_7745c5c3_Var2 = []any{utils.TwMerge(
"carousel-component relative overflow-hidden w-full",
p.Class,
),
@ -221,8 +220,7 @@ func Content(props ...ContentProps) templ.Component {
if len(props) > 0 {
p = props[0]
}
var templ_7745c5c3_Var9 = []any{
utils.TwMerge(
var templ_7745c5c3_Var9 = []any{utils.TwMerge(
"carousel-track flex h-full w-full transition-transform duration-500 ease-in-out",
p.Class,
),
@ -316,8 +314,7 @@ func Item(props ...ItemProps) templ.Component {
if len(props) > 0 {
p = props[0]
}
var templ_7745c5c3_Var13 = []any{
utils.TwMerge(
var templ_7745c5c3_Var13 = []any{utils.TwMerge(
"carousel-item flex-shrink-0 w-full h-full relative",
p.Class,
),
@ -411,8 +408,7 @@ func Previous(props ...PreviousProps) templ.Component {
if len(props) > 0 {
p = props[0]
}
var templ_7745c5c3_Var17 = []any{
utils.TwMerge(
var templ_7745c5c3_Var17 = []any{utils.TwMerge(
"carousel-prev absolute left-2 top-1/2 transform -translate-y-1/2 p-2 rounded-full bg-black/20 text-white hover:bg-black/40 focus:outline-none",
p.Class,
),
@ -506,8 +502,7 @@ func Next(props ...NextProps) templ.Component {
if len(props) > 0 {
p = props[0]
}
var templ_7745c5c3_Var21 = []any{
utils.TwMerge(
var templ_7745c5c3_Var21 = []any{utils.TwMerge(
"carousel-next absolute right-2 top-1/2 transform -translate-y-1/2 p-2 rounded-full bg-black/20 text-white hover:bg-black/40 focus:outline-none",
p.Class,
),
@ -601,8 +596,7 @@ func Indicators(props ...IndicatorsProps) templ.Component {
if len(props) > 0 {
p = props[0]
}
var templ_7745c5c3_Var25 = []any{
utils.TwMerge(
var templ_7745c5c3_Var25 = []any{utils.TwMerge(
"absolute bottom-4 left-1/2 transform -translate-x-1/2 flex gap-2",
p.Class,
),
@ -660,8 +654,7 @@ func Indicators(props ...IndicatorsProps) templ.Component {
return templ_7745c5c3_Err
}
for i := 0; i < p.Count; i++ {
var templ_7745c5c3_Var28 = []any{
utils.TwMerge(
var templ_7745c5c3_Var28 = []any{utils.TwMerge(
"carousel-indicator w-3 h-3 rounded-full bg-white/50 hover:bg-white/80 focus:outline-none transition-colors",
utils.If(i == 0, "bg-white"),
),

View file

@ -1,6 +1,6 @@
// Code generated by templ - DO NOT EDIT.
// templ: version: v0.3.865
// templ: version: v0.3.924
// templui component chart - version: v0.84.0 installed by templui v0.84.0
package chart
@ -106,8 +106,7 @@ func Chart(props ...Props) templ.Component {
}
canvasId := p.ID + "-canvas"
dataId := p.ID + "-data"
var templ_7745c5c3_Var2 = []any{
utils.TwMerge(
var templ_7745c5c3_Var2 = []any{utils.TwMerge(
"chart-container relative",
p.Class),
}

View file

@ -1,6 +1,6 @@
// Code generated by templ - DO NOT EDIT.
// templ: version: v0.3.865
// templ: version: v0.3.924
// templui component checkbox - version: v0.84.0 installed by templui v0.84.0
package checkbox
@ -56,8 +56,7 @@ func Checkbox(props ...Props) templ.Component {
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var2 = []any{
utils.TwMerge(
var templ_7745c5c3_Var2 = []any{utils.TwMerge(
"relative size-4 overflow-hidden peer",
"before:absolute before:inset-0 before:content['']",
"appearance-none rounded-sm border-2 border-primary bg-background",
@ -175,8 +174,7 @@ func Checkbox(props ...Props) templ.Component {
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var7 = []any{
utils.TwMerge(
var templ_7745c5c3_Var7 = []any{utils.TwMerge(
"absolute left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2",
"size-3 text-primary-foreground pointer-events-none opacity-0",
"peer-checked:opacity-100",

View file

@ -1,6 +1,6 @@
// Code generated by templ - DO NOT EDIT.
// templ: version: v0.3.865
// templ: version: v0.3.924
// templui component checkboxcard - version: main installed by templui v0.71.0
package checkboxcard
@ -70,8 +70,7 @@ func CheckboxCard(props ...Props) templ.Component {
p.ID = utils.RandomID()
}
inputId := p.ID + "-input"
var templ_7745c5c3_Var2 = []any{
utils.TwMerge(
var templ_7745c5c3_Var2 = []any{utils.TwMerge(
"relative",
utils.If(p.Disabled, "opacity-60"),
p.Class,
@ -202,8 +201,7 @@ func CheckboxCard(props ...Props) templ.Component {
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var8 = []any{
utils.TwMerge(
var templ_7745c5c3_Var8 = []any{utils.TwMerge(
"block w-full rounded-lg border overflow-hidden h-full",
"bg-card text-card-foreground p-4 flex flex-col",
"cursor-pointer",
@ -285,8 +283,7 @@ func Header(props ...HeaderProps) templ.Component {
if len(props) > 0 {
p = props[0]
}
var templ_7745c5c3_Var12 = []any{
utils.TwMerge(
var templ_7745c5c3_Var12 = []any{utils.TwMerge(
"flex items-center justify-between mb-2",
p.Class,
),
@ -380,8 +377,7 @@ func Description(props ...DescriptionProps) templ.Component {
if len(props) > 0 {
p = props[0]
}
var templ_7745c5c3_Var16 = []any{
utils.TwMerge(
var templ_7745c5c3_Var16 = []any{utils.TwMerge(
"text-sm text-muted-foreground",
p.Class,
),
@ -475,8 +471,7 @@ func Footer(props ...FooterProps) templ.Component {
if len(props) > 0 {
p = props[0]
}
var templ_7745c5c3_Var20 = []any{
utils.TwMerge(
var templ_7745c5c3_Var20 = []any{utils.TwMerge(
"mt-auto pt-4 w-full",
p.Class,
),

View file

@ -1,6 +1,6 @@
// Code generated by templ - DO NOT EDIT.
// templ: version: v0.3.865
// templ: version: v0.3.924
// templui component checkboxcard - version: v0.84.0 installed by templui v0.84.0
package checkboxcard
@ -70,8 +70,7 @@ func CheckboxCard(props ...Props) templ.Component {
p.ID = utils.RandomID()
}
inputId := p.ID + "-input"
var templ_7745c5c3_Var2 = []any{
utils.TwMerge(
var templ_7745c5c3_Var2 = []any{utils.TwMerge(
"relative",
utils.If(p.Disabled, "opacity-60"),
p.Class,
@ -202,8 +201,7 @@ func CheckboxCard(props ...Props) templ.Component {
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var8 = []any{
utils.TwMerge(
var templ_7745c5c3_Var8 = []any{utils.TwMerge(
"block w-full rounded-lg border overflow-hidden h-full",
"bg-card text-card-foreground p-4 flex flex-col",
"cursor-pointer",
@ -285,8 +283,7 @@ func Header(props ...HeaderProps) templ.Component {
if len(props) > 0 {
p = props[0]
}
var templ_7745c5c3_Var12 = []any{
utils.TwMerge(
var templ_7745c5c3_Var12 = []any{utils.TwMerge(
"flex items-center justify-between mb-2",
p.Class,
),
@ -380,8 +377,7 @@ func Description(props ...DescriptionProps) templ.Component {
if len(props) > 0 {
p = props[0]
}
var templ_7745c5c3_Var16 = []any{
utils.TwMerge(
var templ_7745c5c3_Var16 = []any{utils.TwMerge(
"text-sm text-muted-foreground",
p.Class,
),
@ -475,8 +471,7 @@ func Footer(props ...FooterProps) templ.Component {
if len(props) > 0 {
p = props[0]
}
var templ_7745c5c3_Var20 = []any{
utils.TwMerge(
var templ_7745c5c3_Var20 = []any{utils.TwMerge(
"mt-auto pt-4 w-full",
p.Class,
),

View file

@ -1,6 +1,6 @@
// Code generated by templ - DO NOT EDIT.
// templ: version: v0.3.865
// templ: version: v0.3.924
// templui component code - version: v0.84.0 installed by templui v0.84.0
package code
@ -108,8 +108,7 @@ func Code(props ...Props) templ.Component {
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var5 = []any{
utils.TwMerge(
var templ_7745c5c3_Var5 = []any{utils.TwMerge(
"language-"+p.Language,
"overflow-y-auto! rounded-md block text-sm max-h-[501px]",
utils.If(p.Size == SizeSm, "max-h-[250px]"),

View file

@ -1,6 +1,6 @@
// Code generated by templ - DO NOT EDIT.
// templ: version: v0.3.865
// templ: version: v0.3.924
// templui component datepicker - version: main installed by templui v0.71.0
package datepicker

View file

@ -1,6 +1,6 @@
// Code generated by templ - DO NOT EDIT.
// templ: version: v0.3.865
// templ: version: v0.3.924
// templui component datepicker - version: v0.84.0 installed by templui v0.84.0
package datepicker

View file

@ -1,6 +1,6 @@
// Code generated by templ - DO NOT EDIT.
// templ: version: v0.3.865
// templ: version: v0.3.924
// templui component drawer - version: v0.84.0 installed by templui v0.84.0
package drawer
@ -245,8 +245,7 @@ func Content(props ...ContentProps) templ.Component {
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var8 = []any{
utils.TwMerge(
var templ_7745c5c3_Var8 = []any{utils.TwMerge(
"fixed z-50 templui-drawer-content hidden",
p.Class,
utils.If(p.Position == PositionRight, "inset-y-0 right-0 w-3/4 md:w-1/2 lg:w-1/3"),
@ -310,8 +309,7 @@ func Content(props ...ContentProps) templ.Component {
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var12 = []any{
utils.TwMerge(
var templ_7745c5c3_Var12 = []any{utils.TwMerge(
"h-full overflow-y-auto bg-background p-6 shadow-lg",
utils.If(p.Position == PositionRight, "border-l"),
utils.If(p.Position == PositionLeft, "border-r"),
@ -737,8 +735,7 @@ func Close(props ...CloseProps) templ.Component {
if len(props) > 0 {
p = props[0]
}
var templ_7745c5c3_Var31 = []any{
utils.TwMerge(
var templ_7745c5c3_Var31 = []any{utils.TwMerge(
"inline-flex items-center justify-center rounded-md text-sm font-medium ring-offset-background",
"transition-colors focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
"disabled:pointer-events-none disabled:opacity-50 border border-input bg-background hover:bg-accent",

View file

@ -1,6 +1,6 @@
// Code generated by templ - DO NOT EDIT.
// templ: version: v0.3.865
// templ: version: v0.3.924
// templui component dropdown - version: v0.84.0 installed by templui v0.84.0
package dropdown
@ -519,8 +519,7 @@ func Item(props ...ItemProps) templ.Component {
p.ID = utils.RandomID()
}
if p.Href != "" {
var templ_7745c5c3_Var17 = []any{
utils.TwMerge(
var templ_7745c5c3_Var17 = []any{utils.TwMerge(
"flex text-left items-center px-2 py-1.5 text-sm rounded-sm",
utils.If(!p.Disabled, "focus:bg-accent focus:text-accent-foreground hover:bg-accent hover:text-accent-foreground cursor-default"),
utils.If(p.Disabled, "opacity-50 pointer-events-none"),
@ -553,8 +552,12 @@ func Item(props ...ItemProps) templ.Component {
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var19 templ.SafeURL = templ.SafeURL(p.Href)
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(string(templ_7745c5c3_Var19)))
var templ_7745c5c3_Var19 templ.SafeURL
templ_7745c5c3_Var19, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(p.Href))
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `server/web/templui/components/dropdown/dropdown.templ`, Line: 216, Col: 32}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var19))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
@ -622,8 +625,7 @@ func Item(props ...ItemProps) templ.Component {
return templ_7745c5c3_Err
}
} else {
var templ_7745c5c3_Var22 = []any{
utils.TwMerge(
var templ_7745c5c3_Var22 = []any{utils.TwMerge(
"w-full text-left flex items-center justify-between px-2 py-1.5 text-sm rounded-sm",
utils.If(!p.Disabled, "focus:bg-accent focus:text-accent-foreground hover:bg-accent hover:text-accent-foreground cursor-default"),
utils.If(p.Disabled, "opacity-50 pointer-events-none"),
@ -1007,8 +1009,7 @@ func SubTrigger(props ...SubTriggerProps) templ.Component {
}()
}
ctx = templ.InitializeContext(ctx)
var templ_7745c5c3_Var39 = []any{
utils.TwMerge(
var templ_7745c5c3_Var39 = []any{utils.TwMerge(
"w-full text-left flex items-center justify-between px-2 py-1.5 text-sm rounded-sm",
"focus:bg-accent focus:text-accent-foreground hover:bg-accent hover:text-accent-foreground cursor-default",
p.Class,

View file

@ -1,6 +1,6 @@
// Code generated by templ - DO NOT EDIT.
// templ: version: v0.3.865
// templ: version: v0.3.924
// templui component form - version: v0.84.0 installed by templui v0.84.0
package form
@ -400,8 +400,7 @@ func Message(props ...MessageProps) templ.Component {
if len(props) > 0 {
p = props[0]
}
var templ_7745c5c3_Var16 = []any{
utils.TwMerge(
var templ_7745c5c3_Var16 = []any{utils.TwMerge(
"text-[0.8rem] font-medium",
messageVariantClass(p.Variant),
p.Class,

View file

@ -1,6 +1,6 @@
// Code generated by templ - DO NOT EDIT.
// templ: version: v0.3.865
// templ: version: v0.3.924
// templui component input - version: v0.84.0 installed by templui v0.84.0
package input
@ -82,8 +82,7 @@ func Input(props ...Props) templ.Component {
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var2 = []any{
utils.TwMerge(
var templ_7745c5c3_Var2 = []any{utils.TwMerge(
// Base styles
"flex h-9 w-full min-w-0 rounded-md border border-input bg-transparent px-3 py-1 text-base shadow-xs transition-[color,box-shadow] outline-none md:text-sm",
// Dark mode background

View file

@ -1,6 +1,6 @@
// Code generated by templ - DO NOT EDIT.
// templ: version: v0.3.865
// templ: version: v0.3.924
// templui component inputotp - version: main installed by templui v0.71.0
package inputotp
@ -76,8 +76,7 @@ func InputOTP(props ...Props) templ.Component {
if len(props) > 0 {
p = props[0]
}
var templ_7745c5c3_Var2 = []any{
utils.TwMerge(
var templ_7745c5c3_Var2 = []any{utils.TwMerge(
"flex flex-row items-center gap-2 w-fit",
p.Class,
),
@ -242,8 +241,7 @@ func Group(props ...GroupProps) templ.Component {
if len(props) > 0 {
p = props[0]
}
var templ_7745c5c3_Var9 = []any{
utils.TwMerge(
var templ_7745c5c3_Var9 = []any{utils.TwMerge(
"flex gap-2",
p.Class,
),
@ -375,8 +373,7 @@ func Slot(props ...SlotProps) templ.Component {
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var14 = []any{
utils.TwMerge(
var templ_7745c5c3_Var14 = []any{utils.TwMerge(
"w-10 h-12 text-center",
"rounded-md border border-input bg-background text-sm",
"file:border-0 file:bg-transparent file:text-sm file:font-medium",
@ -503,8 +500,7 @@ func Separator(props ...SeparatorProps) templ.Component {
if len(props) > 0 {
p = props[0]
}
var templ_7745c5c3_Var20 = []any{
utils.TwMerge(
var templ_7745c5c3_Var20 = []any{utils.TwMerge(
"flex items-center text-muted-foreground text-xl",
p.Class,
),

View file

@ -1,6 +1,6 @@
// Code generated by templ - DO NOT EDIT.
// templ: version: v0.3.865
// templ: version: v0.3.924
// templui component inputotp - version: v0.84.0 installed by templui v0.84.0
package inputotp
@ -73,8 +73,7 @@ func InputOTP(props ...Props) templ.Component {
if len(props) > 0 {
p = props[0]
}
var templ_7745c5c3_Var2 = []any{
utils.TwMerge(
var templ_7745c5c3_Var2 = []any{utils.TwMerge(
"flex flex-row items-center gap-2 w-fit",
p.Class,
),
@ -245,8 +244,7 @@ func Group(props ...GroupProps) templ.Component {
if len(props) > 0 {
p = props[0]
}
var templ_7745c5c3_Var9 = []any{
utils.TwMerge(
var templ_7745c5c3_Var9 = []any{utils.TwMerge(
"flex gap-2",
p.Class,
),
@ -378,8 +376,7 @@ func Slot(props ...SlotProps) templ.Component {
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var14 = []any{
utils.TwMerge(
var templ_7745c5c3_Var14 = []any{utils.TwMerge(
// Base styles - keeping the specific OTP dimensions
"w-10 h-12 text-center rounded-md border border-input bg-transparent text-base shadow-xs transition-[color,box-shadow] outline-none md:text-sm",
// Dark mode background
@ -521,8 +518,7 @@ func Separator(props ...SeparatorProps) templ.Component {
if len(props) > 0 {
p = props[0]
}
var templ_7745c5c3_Var20 = []any{
utils.TwMerge(
var templ_7745c5c3_Var20 = []any{utils.TwMerge(
"flex items-center text-muted-foreground text-xl",
p.Class,
),

View file

@ -1,6 +1,6 @@
// Code generated by templ - DO NOT EDIT.
// templ: version: v0.3.865
// templ: version: v0.3.924
// templui component label - version: v0.84.0 installed by templui v0.84.0
package label
@ -45,8 +45,7 @@ func Label(props ...Props) templ.Component {
if len(props) > 0 {
p = props[0]
}
var templ_7745c5c3_Var2 = []any{
utils.TwMerge(
var templ_7745c5c3_Var2 = []any{utils.TwMerge(
"text-sm font-medium leading-none inline-block",
utils.If(len(p.Error) > 0, "text-destructive"),
p.Class,

View file

@ -1,6 +1,6 @@
// Code generated by templ - DO NOT EDIT.
// templ: version: v0.3.865
// templ: version: v0.3.924
// templui component modal - version: v0.84.0 installed by templui v0.84.0
package modal
@ -138,8 +138,7 @@ func Modal(props ...Props) templ.Component {
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var4 = []any{
utils.TwMerge(
var templ_7745c5c3_Var4 = []any{utils.TwMerge(
"modal-content relative bg-background rounded-lg border text-left overflow-hidden shadow-xl transform transition-all sm:my-8 w-full scale-95 opacity-0", // Base classes + transition start
"duration-300 ease-out", // Enter duration
p.Class,
@ -216,8 +215,7 @@ func Trigger(props ...TriggerProps) templ.Component {
if len(props) > 0 {
p = props[0]
}
var templ_7745c5c3_Var8 = []any{
utils.TwMerge(
var templ_7745c5c3_Var8 = []any{utils.TwMerge(
"group",
utils.IfElse(p.Disabled, "cursor-not-allowed opacity-50", "cursor-pointer"),
p.Class,

View file

@ -1,6 +1,6 @@
// Code generated by templ - DO NOT EDIT.
// templ: version: v0.3.865
// templ: version: v0.3.924
// templui component pagination - version: v0.84.0 installed by templui v0.84.0
package pagination

View file

@ -1,6 +1,6 @@
// Code generated by templ - DO NOT EDIT.
// templ: version: v0.3.865
// templ: version: v0.3.924
// templui component popover - version: main installed by templui v0.71.0
package popover

View file

@ -1,6 +1,6 @@
// Code generated by templ - DO NOT EDIT.
// templ: version: v0.3.865
// templ: version: v0.3.924
// templui component popover - version: main installed by templui v0.71.0
package popover

View file

@ -1,6 +1,6 @@
// Code generated by templ - DO NOT EDIT.
// templ: version: v0.3.865
// templ: version: v0.3.924
// templui component popover - version: v0.84.0 installed by templui v0.84.0
package popover

View file

@ -1,6 +1,6 @@
// Code generated by templ - DO NOT EDIT.
// templ: version: v0.3.865
// templ: version: v0.3.924
// templui component progress - version: v0.84.0 installed by templui v0.84.0
package progress
@ -192,8 +192,7 @@ func Progress(props ...Props) templ.Component {
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var9 = []any{
utils.TwMerge(
var templ_7745c5c3_Var9 = []any{utils.TwMerge(
"h-full rounded-full transition-all",
sizeClasses(p.Size),
variantClasses(p.Variant),

View file

@ -1,6 +1,6 @@
// Code generated by templ - DO NOT EDIT.
// templ: version: v0.3.865
// templ: version: v0.3.924
// templui component radio - version: v0.84.0 installed by templui v0.84.0
package radio
@ -48,8 +48,7 @@ func Radio(props ...Props) templ.Component {
if len(props) > 0 {
p = props[0]
}
var templ_7745c5c3_Var2 = []any{
utils.TwMerge(
var templ_7745c5c3_Var2 = []any{utils.TwMerge(
"relative h-4 w-4",
"before:absolute before:left-1/2 before:top-1/2",
"before:h-1.5 before:w-1.5 before:-translate-x-1/2 before:-translate-y-1/2",

View file

@ -1,6 +1,6 @@
// Code generated by templ - DO NOT EDIT.
// templ: version: v0.3.865
// templ: version: v0.3.924
// templui component radiocard - version: main installed by templui v0.71.0
package radiocard
@ -69,8 +69,7 @@ func RadioCard(props ...Props) templ.Component {
if p.ID == "" {
p.ID = utils.RandomID()
}
var templ_7745c5c3_Var2 = []any{
utils.TwMerge(
var templ_7745c5c3_Var2 = []any{utils.TwMerge(
"relative",
utils.If(p.Disabled, "opacity-60"),
p.Class,
@ -191,8 +190,7 @@ func RadioCard(props ...Props) templ.Component {
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var8 = []any{
utils.TwMerge(
var templ_7745c5c3_Var8 = []any{utils.TwMerge(
"block w-full rounded-lg border overflow-hidden h-full",
"bg-card text-card-foreground p-4 flex flex-col",
"cursor-pointer",

View file

@ -1,6 +1,6 @@
// Code generated by templ - DO NOT EDIT.
// templ: version: v0.3.865
// templ: version: v0.3.924
// templui component radiocard - version: v0.84.0 installed by templui v0.84.0
package radiocard
@ -69,8 +69,7 @@ func RadioCard(props ...Props) templ.Component {
if p.ID == "" {
p.ID = utils.RandomID()
}
var templ_7745c5c3_Var2 = []any{
utils.TwMerge(
var templ_7745c5c3_Var2 = []any{utils.TwMerge(
"relative",
utils.If(p.Disabled, "opacity-60"),
p.Class,
@ -191,8 +190,7 @@ func RadioCard(props ...Props) templ.Component {
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var8 = []any{
utils.TwMerge(
var templ_7745c5c3_Var8 = []any{utils.TwMerge(
"block w-full rounded-lg border overflow-hidden h-full",
"bg-card text-card-foreground p-4 flex flex-col",
"cursor-pointer",

View file

@ -1,6 +1,6 @@
// Code generated by templ - DO NOT EDIT.
// templ: version: v0.3.865
// templ: version: v0.3.924
// templui component rating - version: v0.84.0 installed by templui v0.84.0
package rating
@ -76,8 +76,7 @@ func Rating(props ...Props) templ.Component {
p = props[0]
}
p.setDefaults()
var templ_7745c5c3_Var2 = []any{
utils.TwMerge(
var templ_7745c5c3_Var2 = []any{utils.TwMerge(
"flex flex-col items-start gap-1",
p.Class,
),
@ -369,8 +368,7 @@ func Item(props ...ItemProps) templ.Component {
p = props[0]
}
p.setDefaults()
var templ_7745c5c3_Var17 = []any{
utils.TwMerge(
var templ_7745c5c3_Var17 = []any{utils.TwMerge(
"relative",
colorClass(p.Style),
"transition-opacity",

View file

@ -1,6 +1,6 @@
// Code generated by templ - DO NOT EDIT.
// templ: version: v0.3.865
// templ: version: v0.3.924
// templui component selectbox - version: main installed by templui v0.71.0
package selectbox
@ -705,8 +705,7 @@ func Item(props ...ItemProps) templ.Component {
if len(props) > 0 {
p = props[0]
}
var templ_7745c5c3_Var26 = []any{
utils.TwMerge(
var templ_7745c5c3_Var26 = []any{utils.TwMerge(
"select-item relative flex w-full cursor-default select-none items-center rounded-sm py-1.5 px-2 text-sm font-light outline-none",
"hover:bg-accent hover:text-accent-foreground",
"focus:bg-accent focus:text-accent-foreground",
@ -814,8 +813,7 @@ func Item(props ...ItemProps) templ.Component {
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var32 = []any{
utils.TwMerge(
var templ_7745c5c3_Var32 = []any{utils.TwMerge(
"select-check absolute right-2 flex h-3.5 w-3.5 items-center justify-center",
utils.IfElse(p.Selected, "opacity-100", "opacity-0"),
),

View file

@ -1,6 +1,6 @@
// Code generated by templ - DO NOT EDIT.
// templ: version: v0.3.865
// templ: version: v0.3.924
// templui component selectbox - version: v0.84.0 installed by templui v0.84.0
package selectbox
@ -752,8 +752,7 @@ func Item(props ...ItemProps) templ.Component {
if len(props) > 0 {
p = props[0]
}
var templ_7745c5c3_Var25 = []any{
utils.TwMerge(
var templ_7745c5c3_Var25 = []any{utils.TwMerge(
"select-item relative flex w-full cursor-default select-none items-center rounded-sm py-1.5 px-2 text-sm font-light outline-none",
"hover:bg-accent hover:text-accent-foreground",
"focus:bg-accent focus:text-accent-foreground",
@ -861,8 +860,7 @@ func Item(props ...ItemProps) templ.Component {
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var31 = []any{
utils.TwMerge(
var templ_7745c5c3_Var31 = []any{utils.TwMerge(
"select-check absolute right-2 flex h-3.5 w-3.5 items-center justify-center",
utils.IfElse(p.Selected, "opacity-100", "opacity-0"),
),

View file

@ -1,6 +1,6 @@
// Code generated by templ - DO NOT EDIT.
// templ: version: v0.3.865
// templ: version: v0.3.924
// templui component separator - version: v0.84.0 installed by templui v0.84.0
package separator
@ -115,8 +115,7 @@ func Separator(props ...Props) templ.Component {
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var5 = []any{
utils.TwMerge(
var templ_7745c5c3_Var5 = []any{utils.TwMerge(
"absolute w-full border-t h-[1px]",
decorationClasses(p.Decoration),
),
@ -204,8 +203,7 @@ func Separator(props ...Props) templ.Component {
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var10 = []any{
utils.TwMerge(
var templ_7745c5c3_Var10 = []any{utils.TwMerge(
"absolute h-full border-l w-[1px]",
decorationClasses(p.Decoration),
),

View file

@ -1,6 +1,6 @@
// Code generated by templ - DO NOT EDIT.
// templ: version: v0.3.865
// templ: version: v0.3.924
// templui component skeleton - version: v0.84.0 installed by templui v0.84.0
package skeleton
@ -43,8 +43,7 @@ func Skeleton(props ...Props) templ.Component {
if len(props) > 0 {
p = props[0]
}
var templ_7745c5c3_Var2 = []any{
utils.TwMerge(
var templ_7745c5c3_Var2 = []any{utils.TwMerge(
"animate-pulse rounded bg-muted",
p.Class,
),

View file

@ -1,6 +1,6 @@
// Code generated by templ - DO NOT EDIT.
// templ: version: v0.3.865
// templ: version: v0.3.924
// templui component slider - version: v0.84.0 installed by templui v0.84.0
package slider
@ -158,8 +158,7 @@ func Input(props ...InputProps) templ.Component {
if p.ID == "" {
p.ID = utils.RandomID()
}
var templ_7745c5c3_Var6 = []any{
utils.TwMerge(
var templ_7745c5c3_Var6 = []any{utils.TwMerge(
"w-full h-2 rounded-full bg-secondary appearance-none cursor-pointer",
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
"[&::-webkit-slider-thumb]:appearance-none [&::-webkit-slider-thumb]:w-4 [&::-webkit-slider-thumb]:h-4",

View file

@ -1,6 +1,6 @@
// Code generated by templ - DO NOT EDIT.
// templ: version: v0.3.865
// templ: version: v0.3.924
// templui component spinner - version: main installed by templui v0.71.0
package spinner
@ -53,8 +53,7 @@ func Spinner(props ...Props) templ.Component {
if len(props) > 0 {
p = props[0]
}
var templ_7745c5c3_Var2 = []any{
utils.TwMerge(
var templ_7745c5c3_Var2 = []any{utils.TwMerge(
"inline-flex flex-col items-center justify-center",
p.Class,
),
@ -111,8 +110,7 @@ func Spinner(props ...Props) templ.Component {
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var5 = []any{
utils.TwMerge(
var templ_7745c5c3_Var5 = []any{utils.TwMerge(
"animate-spin rounded-full",
sizeClass(p.Size),
borderSizeClass(p.Size),

View file

@ -1,6 +1,6 @@
// Code generated by templ - DO NOT EDIT.
// templ: version: v0.3.865
// templ: version: v0.3.924
// templui component table - version: v0.84.0 installed by templui v0.84.0
package table
@ -450,8 +450,7 @@ func Row(props ...RowProps) templ.Component {
if len(props) > 0 {
p = props[0]
}
var templ_7745c5c3_Var18 = []any{
utils.TwMerge(
var templ_7745c5c3_Var18 = []any{utils.TwMerge(
"border-b transition-colors hover:bg-muted/50",
utils.If(p.Selected, "data-[state=selected]:bg-muted"),
p.Class,
@ -546,8 +545,7 @@ func Head(props ...HeadProps) templ.Component {
if len(props) > 0 {
p = props[0]
}
var templ_7745c5c3_Var22 = []any{
utils.TwMerge(
var templ_7745c5c3_Var22 = []any{utils.TwMerge(
"h-10 px-2 text-left align-middle font-medium text-muted-foreground",
"[&:has([role=checkbox])]:pr-0 [&>[role=checkbox]]:translate-y-[2px]",
p.Class,
@ -642,8 +640,7 @@ func Cell(props ...CellProps) templ.Component {
if len(props) > 0 {
p = props[0]
}
var templ_7745c5c3_Var26 = []any{
utils.TwMerge(
var templ_7745c5c3_Var26 = []any{utils.TwMerge(
"p-2 align-middle",
"[&:has([role=checkbox])]:pr-0 [&>[role=checkbox]]:translate-y-[2px]",
p.Class,

View file

@ -1,6 +1,6 @@
// Code generated by templ - DO NOT EDIT.
// templ: version: v0.3.865
// templ: version: v0.3.924
// templui component tabs - version: v0.84.0 installed by templui v0.84.0
package tabs
@ -179,8 +179,7 @@ func List(props ...ListProps) templ.Component {
p = props[0]
}
tabsID := IDFromContext(ctx)
var templ_7745c5c3_Var7 = []any{
utils.TwMerge(
var templ_7745c5c3_Var7 = []any{utils.TwMerge(
"relative flex items-center justify-center h-10 p-1 rounded-lg select-none bg-muted text-muted-foreground",
p.Class,
),
@ -297,8 +296,7 @@ func Trigger(props ...TriggerProps) templ.Component {
return templ_7745c5c3_Err
}
}
var templ_7745c5c3_Var12 = []any{
utils.TwMerge(
var templ_7745c5c3_Var12 = []any{utils.TwMerge(
"relative z-20 flex-1 inline-flex items-center justify-center h-8 px-3 text-sm font-medium transition-all rounded-md cursor-pointer whitespace-nowrap hover:text-foreground",
p.Class,
),
@ -441,8 +439,7 @@ func Content(props ...ContentProps) templ.Component {
return templ_7745c5c3_Err
}
}
var templ_7745c5c3_Var19 = []any{
utils.TwMerge(
var templ_7745c5c3_Var19 = []any{utils.TwMerge(
"relative",
utils.If(!p.IsActive, "hidden"),
p.Class,

View file

@ -1,6 +1,6 @@
// Code generated by templ - DO NOT EDIT.
// templ: version: v0.3.865
// templ: version: v0.3.924
// templui component tagsinput - version: v0.84.0 installed by templui v0.84.0
package tagsinput
@ -49,8 +49,7 @@ func TagsInput(p Props) templ.Component {
templ_7745c5c3_Var1 = templ.NopComponent
}
ctx = templ.ClearChildren(ctx)
var templ_7745c5c3_Var2 = []any{
utils.TwMerge(
var templ_7745c5c3_Var2 = []any{utils.TwMerge(
// Base styles
"flex items-center flex-wrap gap-2 p-2 rounded-md border border-input bg-transparent shadow-xs transition-[color,box-shadow] outline-none",
// Dark mode background

View file

@ -1,6 +1,6 @@
// Code generated by templ - DO NOT EDIT.
// templ: version: v0.3.865
// templ: version: v0.3.924
// templui component textarea - version: v0.84.0 installed by templui v0.84.0
package textarea
@ -58,8 +58,7 @@ func Textarea(props ...Props) templ.Component {
if p.ID == "" {
p.ID = utils.RandomID()
}
var templ_7745c5c3_Var2 = []any{
utils.TwMerge(
var templ_7745c5c3_Var2 = []any{utils.TwMerge(
// Base styles
"flex w-full min-w-0 rounded-md border border-input bg-transparent px-3 py-1 text-base shadow-xs transition-[color,box-shadow] outline-none md:text-sm",
"min-h-[80px]", // Default min-height

View file

@ -1,6 +1,6 @@
// Code generated by templ - DO NOT EDIT.
// templ: version: v0.3.865
// templ: version: v0.3.924
// templui component toast - version: v0.84.0 installed by templui v0.84.0
package toast

View file

@ -1,6 +1,6 @@
// Code generated by templ - DO NOT EDIT.
// templ: version: v0.3.865
// templ: version: v0.3.924
// templui component toggle - version: v0.84.0 installed by templui v0.84.0
package toggle
@ -183,8 +183,7 @@ func Toggle(props ...Props) templ.Component {
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var9 = []any{
utils.TwMerge(
var templ_7745c5c3_Var9 = []any{utils.TwMerge(
"relative h-6 w-10",
"after:absolute after:left-0.5 after:top-0.5",
"after:h-5 after:w-5",

View file

@ -1,6 +1,6 @@
// Code generated by templ - DO NOT EDIT.
// templ: version: v0.3.865
// templ: version: v0.3.924
// templui component tooltip - version: v0.84.0 installed by templui v0.84.0
package tooltip