random generator

Flag: πŸ“ Modified: February 14, 2026 7:58 PM Created: January 21, 2026 10:32 AM Master Type: Notes Hide: No Starred: No Status: Unassigned


import random

vibe = ["Kawaii", "Retro futuristic", "Vintage", "Minimalist", "Kidcore", "Tropical", "Glam"]
aesthetic = ["midcentury modern", "vaporwave", "soft pastel", "brutalism", "steampunk", "modern", "art deco", "art nouveau"]

random_theme = random.choice(vibe) + " " + random.choice(aesthetic)

print(f"Pick a mood, any mood. Like, say... {random_theme}.")

title = ["The Apple", "story of a girl", "Une petite"]
date = 1918, 1431, 2004
artist = ["Mme. Girard", "Antony Bergario", "Stuld"]
provenance = ["Gift of the artist.", "Bequest of Mr. Sydney Harris.", "Purchased with funding provided by The Art Council."]
object = "2013.17.1", "1969.2.04", "1998.66.7"
materials = "Oil on wood", "Watercolor on paper", "Rubber with beaded detail"

random_title = random.choice(title)
random_date = random.choice(date)
random_artist = random.choice(artist)
random_provenance = random.choice(provenance)
random_object = random.choice(object)
random_materials = random.choice(materials)

print(f"\"{random_title}\" ({random_date})")
print(f"by {random_artist}")
print(f"{random_materials}")
print(f"{random_object}")
print(f"{random_provenance}")
#!/bin/bash
# ImageTool.command β€” Simple batch image utility with folder drag-drop

shopt -s nullglob

SUPPORTED_EXT="psd PSD tif TIF tiff TIFF png PNG jpg JPG jpeg JPEG gif GIF bmp BMP"

##############################################
# FOLDER SELECTION (drag-and-drop aware)
##############################################

if [ -n "$1" ]; then
    WORKDIR="$1"
else
    WORKDIR=$(osascript <<EOF
set f to choose folder with prompt "Select a folder of images:"
POSIX path of f
EOF
)
fi

[ -d "$WORKDIR" ] || { echo "Folder not found."; exit 1; }

##############################################
# FILE SCAN
##############################################

scan_files() {
    FILES=()
    for ext in $SUPPORTED_EXT; do
        for f in "$WORKDIR"/*.$ext; do FILES+=("$f"); done
    done
}

scan_files
[ ${#FILES[@]} -gt 0 ] || { echo "No supported images found."; exit 1; }

##############################################
# MENU
##############################################

menu() {
    clear
    echo "==========================================="
    echo "                IMAGE TOOL"
    echo "Folder: $WORKDIR"
    echo "Files: ${#FILES[@]}"
    echo "==========================================="
    echo "1. Convert"
    echo "2. Resize"
    echo "3. Rotate"
    echo "4. Compress"
    echo "5. Zip"
    echo "6. Thumbnails"
    echo "7. Batch Rename"
    echo "8. Copy"
    echo "9. Quit"
    echo "-------------------------------------------"
    printf "Choose option: "
}

##############################################
# UTILITIES
##############################################

parse_size() {
    local s="$1"
    case "$s" in
        *m|*M) echo $(( ${s%?} * 1024 * 1024 ));;
        *k|*K) echo $(( ${s%?} * 1024 ));;
        *) echo "$s";;
    esac
}

png_lossy() {
    local f="$1"
    local out="$2"
    local q="$3"
    local colors=$(( 256 - (q * 2) ))
    [ $colors -lt 16 ] && colors=16
    magick "$f" -colors "$colors" -define png:compression-level=9 "$out"
}

##############################################
# COPY (standalone)
##############################################

copy_files() {
    printf "Destination folder: "
    read -r DEST
    mkdir -p "$DEST"
    for f in "${FILES[@]}"; do
        cp "$f" "$DEST/"
    done
    echo "Copied ${#FILES[@]} files to $DEST"
}

##############################################
# COPY β†’ CONVERT β†’ MOVE (auto subfolder)
##############################################

copy_convert_move() {
    printf "Convert to format (psd/tif/png/jpg/gif): "
    read -r OUTEXT

    SUBFOLDER="${OUTEXT^^}"          # uppercase folder name
    DEST="$WORKDIR/$SUBFOLDER"
    mkdir -p "$DEST"

    for f in "${FILES[@]}"; do
        filename=$(basename "$f")

        # copy original
        cp "$f" "$DEST/$filename"

        # convert inside destination
        src_copy="$DEST/$filename"
        base="${src_copy%.*}"

        magick "$src_copy" "$base.$OUTEXT"
    done

    echo "Copied + converted β†’ $OUTEXT inside $DEST"
}

##############################################
# CONVERT MENU
##############################################

convert_menu() {
    echo "Convert Mode:"
    echo "1 = Convert (normal)"
    echo "2 = Copy β†’ Convert β†’ Move (auto subfolder)"
    read -r opt

    case "$opt" in
        1)
            printf "Convert to format (psd/tif/png/jpg/gif): "
            read -r OUTEXT
            for f in "${FILES[@]}"; do
                base="${f%.*}"
                magick "$f" "$base.$OUTEXT"
            done
            scan_files
            ;;
        2)
            copy_convert_move
            ;;
        *)
            echo "Invalid."
            ;;
    esac
}

##############################################
# RESIZE
##############################################

resize_menu() {
    echo "1 = by width"
    echo "2 = by height"
    read -r mode

    if [ "$mode" = "1" ]; then
        printf "Width px: "
        read -r W
        geom="${W}x"
    else
        printf "Height px: "
        read -r H
        geom="x$H"
    fi

    for f in "${FILES[@]}"; do
        base="${f%.*}"
        magick "$f" -resize "$geom" "$base"_resized."${f##*.}"
    done
}

##############################################
# ROTATE
##############################################

rotate_menu() {
    echo "1 = Landscape"
    echo "2 = Portrait"
    echo "3 = 90Β° CW"
    echo "4 = 90Β° CCW"
    echo "5 = 180Β°"
    read -r opt

    for f in "${FILES[@]}"; do
        out="${f%.*}_rot.${f##*.}"
        case "$opt" in
            1)
                w=$(magick identify -format "%w" "$f")
                h=$(magick identify -format "%h" "$f")
                if [ $h -gt $w ]; then magick "$f" -rotate 90 "$out"; else cp "$f" "$out"; fi
                ;;
            2)
                w=$(magick identify -format "%w" "$f")
                h=$(magick identify -format "%h" "$f")
                if [ $w -gt $h ]; then magick "$f" -rotate 90 "$out"; else cp "$f" "$out"; fi
                ;;
            3) magick "$f" -rotate 90 "$out" ;;
            4) magick "$f" -rotate -90 "$out" ;;
            5) magick "$f" -rotate 180 "$out" ;;
        esac
    done
}

##############################################
# COMPRESS (QUALITY AND TARGET-SIZE)
##############################################

compress_percent() {
    local Q="$1"
    for f in "${FILES[@]}"; do
        base="${f%.*}"
        out="$base"_compressed."${f##*.}"
        case "${f##*.}" in
            png|PNG) png_lossy "$f" "$out" "$Q" ;;
            *) magick "$f" -quality "$Q" "$out" ;;
        esac
    done
}

compress_target() {
    printf "Target size (e.g. 1m, 900k, 1500k): "
    read -r TARGET_RAW
    TARGET=$(parse_size "$TARGET_RAW")
    TOL_PCT=5

    for f in "${FILES[@]}"; do
        ext="${f##*.}"
        base="${f%.*}"
        out="$base"_target."$ext"

        low_q=5
        high_q=95
        best_q=$high_q

        while [ $low_q -le $high_q ]; do
            mid_q=$(( (low_q + high_q) / 2 ))
            tmp="$base"_tmp."$ext"

            if [[ "$ext" == "png" || "$ext" == "PNG" ]]; then
                png_lossy "$f" "$tmp" "$mid_q"
            else
                magick "$f" -quality "$mid_q" "$tmp"
            fi

            size=$(stat -f%z "$tmp")
            low_limit=$(( TARGET - (TARGET * TOL_PCT / 100) ))
            high_limit=$(( TARGET + (TARGET * TOL_PCT / 100) ))

            if [[ $size -ge $low_limit && $size -le $high_limit ]]; then
                mv "$tmp" "$out"
                break
            fi

            if [ $size -gt $TARGET ]; then
                low_q=$(( mid_q + 1 ))
            else
                best_q=$mid_q
                high_q=$(( mid_q - 1 ))
            fi

            rm -f "$tmp"
        done

        if [ ! -f "$out" ]; then
            if [[ "$ext" == "png" || "$ext" == "PNG" ]]; then
                png_lossy "$f" "$out" "$best_q"
            else
                magick "$f" -quality "$best_q" "$out"
            fi
        fi
    done
}

compress_menu() {
    echo "1 = Quality %"
    echo "2 = Target File Size"
    read -r mode

    if [ "$mode" = "1" ]; then
        printf "Quality %: "
        read -r Q
        compress_percent "$Q"
    else
        compress_target
    fi
}

##############################################
# ZIP (STANDARD / TARGET / SPLIT)
##############################################

zip_standard() {
    printf "Zip filename: "
    read -r ZNAME
    zip -9 -r "$ZNAME.zip" "$WORKDIR"
}

zip_split() {
    printf "Zip filename: "
    read -r ZNAME
    printf "Split size (e.g. 200m): "
    read -r SIZE
    zip -9 -r "$ZNAME.zip" "$WORKDIR"
    split -b "$SIZE" "$ZNAME.zip" "$ZNAME.zip.part_"
}

zip_target() {
    printf "Target zip size (e.g. 50m, 200m): "
    read -r TARGET_RAW
    TARGET=$(parse_size "$TARGET_RAW")

    tmpdir=$(mktemp -d)
    basezip="$tmpdir/base.zip"

    zip -9 -r "$basezip" "$WORKDIR" >/dev/null
    original=$(stat -f%z "$basezip")

    BEST_ZIP="./zip_target.zip"
    BEST_DIFF=$(( original - TARGET ))
    cp "$basezip" "$BEST_ZIP"

    methods=("deflate" "bzip2" "lzma")

    for m in "${methods[@]}"; do
        tmp="$tmpdir/m_$m.zip"
        zip -Z "$m" -9 -r "$tmp" "$WORKDIR" 2>/dev/null || continue

        zsize=$(stat -f%z "$tmp")
        diff=$(( zsize > TARGET ? zsize - TARGET : TARGET - zsize ))

        if [ $diff -lt $BEST_DIFF ]; then
            BEST_DIFF=$diff
            cp "$tmp" "$BEST_ZIP"
        fi
    done

    rm -rf "$tmpdir"
}

zip_menu() {
    echo "1 = Standard zip"
    echo "2 = Zip to target size"
    echo "3 = Zip + Split"
    read -r mode

    case "$mode" in
        1) zip_standard ;;
        2) zip_target ;;
        3) zip_split ;;
    esac
}

##############################################
# THUMBNAILS
##############################################

thumb_menu() {
    printf "Thumbnail size px: "
    read -r T
    printf "Thumbnail quality: "
    read -r Q

    mkdir -p "$WORKDIR/thumbnails"

    for f in "${FILES[@]}"; do
        base=$(basename "$f")
        magick "$f" -resize "${T}x${T}" -quality "$Q" \
            "$WORKDIR/thumbnails/${base%.*}_thumb.jpg"
    done
}

##############################################
# BATCH RENAME
##############################################

batch_rename() {
    printf "Base name prefix: "
    read -r BASE
    printf "Start number: "
    read -r START

    num=$START
    for f in "${FILES[@]}"; do
        ext="${f##*.}"
        mv "$f" "$WORKDIR/${BASE}${num}.$ext"
        num=$(( num + 1 ))
    done
    scan_files
}

##############################################
# MAIN LOOP
##############################################

while true; do
    menu
    read -r choice

    case "$choice" in
        1) convert_menu ;;
        2) resize_menu ;;
        3) rotate_menu ;;
        4) compress_menu ;;
        5) zip_menu ;;
        6) thumb_menu ;;
        7) batch_rename ;;
        8) copy_files ;;
        9) exit 0 ;;
        *) echo "Invalid." ;;
    esac

    printf "\nPress Enter to continue..."
    read -r _
done
shut up -> 
die -> dance 
go to hell -> go to the moon
shit themselves -> forgive themselves 
kill themselves -> praise themselves 
get murdered -> get the giggles 
shut the fuck up -> 
get everything they deserve
stop talking -> start smiling 
stop existing -> start singing 
go far far the fuck away -> come much much closer 
literally die -> literally dance 
die painfully -> dance happily 
die slow -> dance slow
eat shit -> eat cake 
eat shit and die -> eat cake and dance 
get fucked -> get hugged
rope themselves -> love themselves 
chop off a transfag’s dick today!

import random

# ---------------------------------------------------------
# Phrase banks (grammar-safe, no caps)
# ---------------------------------------------------------

starts = [
    "I want", "I need", "I wish", "I hope", "I dream",
    "it would be great if", "it would be fantastic if",
    "man I wish", "man I hope", "wouldn’t it be nice if",
    "it would be soooo good if", "it would be soooo great if",
    "I can’t wait for", "I can’t wait until",
    "I truly want", "I really need", "I honestly wish",
    "I sincerely hope", "I quietly dream that", "I loudly dream that",
    "I’d be thrilled if", "I’d be delighted if", "I could really use it if",
    "I yearn for", "I desire that", "I’m manifesting that"
]

subjects = [
    "people", "some people", "all the people", "all the people and then some",
    "everybody", "everyone", "all these people and also those guys",
    "everyone and their cousin", "everyone but especially them",
    "the whole crowd", "the entire room", "every single one of them",
    "literally everyone", "all the folks", "the masses", "the collective",
    "everyone out there", "the whole universe of people"
]

optionals = [
    "", "would", "could", "should",
    "really should", "really could", "definitely would",
    "might", "might just", "absolutely could"
]

actions = [
    "dance", "go to the moon", "forgive themselves", "praise themselves",
    "get the giggles", "get everything they deserve", "start smiling",
    "start singing", "come much closer", "literally dance", "dance happily",
    "dance slow", "eat cake", "eat cake and smile", "get hugged",
    "love themselves",
    "glow a little", "bloom a little", "laugh again", "soften",
    "rest deeply", "say yes", "say yes again", "take a breath",
    "feel brighter", "feel lighter", "celebrate something tiny",
    "finally believe in themselves", "step forward gently"
]

endings = [
    "that would be wonderful", "thank you", "thanks for listening",
    "yes that too", "more of that", "please please please",
    "I’m waiting and hoping", "hopin and waitin", "oh if only",
    "if only if only",
    "that would be magic", "I’d love that so much", "that would heal something",
    "yes please", "more of that energy", "that would fix everything",
    "that would be everything", "okay but seriously yes"
]

emojis = ["πŸŽ€", "✨", "πŸ’«", "πŸ’•", "🌼", "🌸", "⭐️", "πŸŒ™", "πŸ’–", "🩷", "🌟"]

# ---------------------------------------------------------
# Helpers
# ---------------------------------------------------------

def maybe_caps(text):
    # 25% chance to all-caps the phrase
    return text.upper() if random.random() < 0.25 else text

def pepper_words_with_emojis(text):
    # Insert emojis between individual words (heavy density)
    words = text.split()
    out = []
    for i, w in enumerate(words):
        out.append(w)
        if i < len(words) - 1 and random.random() < 0.7:
            out.append(random.choice(emojis))
    return " ".join(out)

def generate_affirmation():
    s = maybe_caps(random.choice(starts))
    subj = maybe_caps(random.choice(subjects))
    opt = maybe_caps(random.choice(optionals))
    act = maybe_caps(random.choice(actions))
    end = maybe_caps(random.choice(endings))
    combined = f"{s} {subj} {opt} {act}, {end}"
    return pepper_words_with_emojis(combined)

# ---------------------------------------------------------
# MAGIC-WORD PROTECTION
# ---------------------------------------------------------

if __name__ == "__main__":
    print("Type the magic word to receive an affirmation:")
    code = input("> ").strip()

    if code == "123456":
        print(generate_affirmation())
    else:
        print("Incorrect magic word. Nothing appears.")
#!/bin/bash

export LC_NUMERIC=C
: "${MAGICK_OCL_DEVICE_DISABLE:=1}"
export MAGICK_THREAD_LIMIT=4

###############################################
# PRINT / NEG thresholds (normalized 0–1 scale)
###############################################
PRINT_SD_MIN=0.16
PRINT_SD_MAX=0.33

PRINT_GE_MIN=0.30
PRINT_GE_MAX=0.60

PRINT_GM_MIN=0.30
PRINT_GM_MAX=0.65

NEG_COLOR_RG_DELTA=0.06
NEG_COLOR_GB_DELTA=0.04

VAR_PRINT_MAX_RATIO=1.20
VAR_NEG_MIN_RATIO=1.50
VAR_NEG_SD_MAX=0.10

###############################################
# Normalization helpers (Fix #1 + Fix #2)
###############################################
normalize_scalar() {
    local raw="$1"

    raw="$(printf "%s" "$raw" | tr -cd '0-9.eE+-')"
    [ -z "$raw" ] && { echo 0; return; }

    # fixed order: 0–1 first, then 100, then 255, then 65535
    if (( $(echo "$raw <= 1" | bc -l) )); then
        echo "$raw"
        return
    fi
    if (( $(echo "$raw <= 100" | bc -l) )); then
        echo "$(echo "$raw/100" | bc -l)"
        return
    fi
    if (( $(echo "$raw <= 255" | bc -l) )); then
        echo "$(echo "$raw/255" | bc -l)"
        return
    fi
    if (( $(echo "$raw <= 65535" | bc -l) )); then
        echo "$(echo "$raw/65535" | bc -l)"
        return
    fi

    echo "1"
}

normalize_pair() {
    local a=$(normalize_scalar "$1")
    local b=$(normalize_scalar "$2")
    echo "$a $b"
}

safe_absdiff() {
    local x=$(normalize_scalar "${1:-0}")
    local y=$(normalize_scalar "${2:-0}")
    local d=$(echo "$x-$y" | bc -l)
    echo "${d#-}"
}

###############################################
# Main classifier
###############################################
classify_file() {
    local file="$1"

    case "$file" in */._*) echo "NEGATIVE"; return ;; esac

    ###############################################
    # RGB mean + SD
    ###############################################
    local Rm Gm Bm Rs Gs Bs
    read Rm Gm Bm Rs Gs Bs <<< "$(
        magick -quiet -- "$file[0]" \
            -alpha off -flatten -colorspace RGB \
            -format "%[fx:mean.r*255] %[fx:mean.g*255] %[fx:mean.b*255] %[fx:standard_deviation.r*255] %[fx:standard_deviation.g*255] %[fx:standard_deviation.b*255]" info:
    )"

    Rm=$(normalize_scalar "$Rm")
    Gm=$(normalize_scalar "$Gm")
    Bm=$(normalize_scalar "$Bm")
    Rs=$(normalize_scalar "$Rs")
    Gs=$(normalize_scalar "$Gs")
    Bs=$(normalize_scalar "$Bs")

    ###############################################
    # Gray stats + entropy
    ###############################################
    local gm_raw sd_raw ent_raw
    read gm_raw sd_raw ent_raw <<< "$(
        magick -quiet -- "$file[0]" \
            -alpha off -flatten -colorspace Gray \
            -format "%[fx:mean] %[fx:standard_deviation] %[entropy]" info:
    )"

    gm_raw=$(normalize_scalar "$gm_raw")
    sd_raw=$(normalize_scalar "$sd_raw")
    ent_raw=$(normalize_scalar "$ent_raw")

    local gm sd ent
    read gm sd <<< "$(normalize_pair "$gm_raw" "$sd_raw")"
    ent=$(normalize_scalar "$ent_raw")

    gm="${gm:-0}"
    sd="${sd:-0}"
    ent="${ent:-0}"

    ###############################################
    # Warm mask (color negative)
    ###############################################
    local warm
    warm=$(echo "($Rm >= $Gm + $NEG_COLOR_RG_DELTA) && ($Gm >= $Bm + $NEG_COLOR_GB_DELTA)" | bc -l)
    [ "${warm:-0}" -eq 1 ] && { echo "NEG_COLOR"; return; }

    ###############################################
    # Variance uniformity (Fix #5)
    ###############################################
    local maxSD="$Rs"
    (( $(echo "$Gs > $maxSD" | bc -l) )) && maxSD="$Gs"
    (( $(echo "$Bs > $maxSD" | bc -l) )) && maxSD="$Bs"

    local minSD="$Rs"
    (( $(echo "$Gs < $minSD" | bc -l) )) && minSD="$Gs"
    (( $(echo "$Bs < $minSD" | bc -l) )) && minSD="$Bs"

    minSD=$(echo "$minSD+0.000001" | bc -l)
    local var_ratio=$(echo "$maxSD/$minSD" | bc -l)

    ###############################################
    # Neutrality check (Fix #6)
    ###############################################
    local absRG=$(safe_absdiff "$Rm" "$Gm")
    local absGB=$(safe_absdiff "$Gm" "$Bm")
    local absRB=$(safe_absdiff "$Rm" "$Bm")

    local neutrality_sum=0
    (( $(echo "$absRG < 0.08" | bc -l) )) && neutrality_sum=$((neutrality_sum+1))
    (( $(echo "$absGB < 0.08" | bc -l) )) && neutrality_sum=$((neutrality_sum+1))
    (( $(echo "$absRB < 0.08" | bc -l) )) && neutrality_sum=$((neutrality_sum+1))

    ###############################################
    # 3-of-5 majority system (your requirement)
    ###############################################
    local score=0

    (( $(echo "$sd >= $PRINT_SD_MIN && $sd <= $PRINT_SD_MAX" | bc -l) )) && score=$((score+1))
    (( $(echo "$ent >= $PRINT_GE_MIN && $ent <= $PRINT_GE_MAX" | bc -l) )) && score=$((score+1))
    (( $(echo "$var_ratio <= $VAR_PRINT_MAX_RATIO" | bc -l) )) && score=$((score+1))
    (( $(echo "$gm >= $PRINT_GM_MIN && $gm <= $PRINT_GM_MAX" | bc -l) )) && score=$((score+1))
    (( neutrality_sum >= 2 )) && score=$((score+1))

    if [ "$score" -ge 3 ]; then
        echo "PRINT"
        return
    fi

    ###############################################
    # NEGATIVE fallback
    ###############################################
    (( $(echo "$sd <= $VAR_NEG_SD_MAX" | bc -l) )) && { echo "NEGATIVE"; return; }
    (( $(echo "$var_ratio >= $VAR_NEG_MIN_RATIO" | bc -l) )) && { echo "NEGATIVE"; return; }

    echo "NEGATIVE"
}
#!/bin/bash
set -euo pipefail

export LC_NUMERIC=C
export MAGICK_OCL_DEVICE_DISABLE=1
export MAGICK_THREAD_LIMIT=1

###############################################
# Load Config
###############################################
TOP_ARG="${1:-}"

if [ -n "$TOP_ARG" ]; then
    if [[ "$TOP_ARG" == /Volumes/HBC*/* ]]; then
        ROOT_VOLUME="/Volumes/$(basename "$(dirname "$TOP_ARG")")"
    else
        ROOT_VOLUME="$TOP_ARG"
    fi
else
    ROOT_VOLUME=$(ls /Volumes | grep -E '^HBC[0-9]{3,4}$' | head -n1)
    [ -n "$ROOT_VOLUME" ] || { echo "❌ No HBC### volume mounted"; exit 1; }
    ROOT_VOLUME="/Volumes/$ROOT_VOLUME"
fi

CONFIG_FILE="$ROOT_VOLUME/config.sh"
[ -f "$CONFIG_FILE" ] || { echo "❌ Config not found at $CONFIG_FILE"; exit 1; }
. "$CONFIG_FILE"

###############################################
# Guard Photoshop variables  (Fix #1)
###############################################
[ -n "${PHOTOSHOP_APP:-}" ]     || { echo "Missing PHOTOSHOP_APP"; exit 1; }
[ -n "${ACTION_SET:-}" ]        || { echo "Missing ACTION_SET"; exit 1; }
[ -n "${ACTION_NEGATIVE:-}" ]   || { echo "Missing ACTION_NEGATIVE"; exit 1; }
[ -n "${ACTION_PRINTFIX:-}" ]   || { echo "Missing ACTION_PRINTFIX"; exit 1; }
[ -n "${ACTION_COLORFIX:-}" ]   || { echo "Missing ACTION_COLORFIX"; exit 1; }

###############################################
# Load classifier (Fix #7)
###############################################
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
. "$SCRIPT_DIR/classifier.sh" || { echo "❌ Failed loading classifier"; exit 1; }
type classify_file >/dev/null 2>&1 || { echo "❌ classify_file missing"; exit 1; }

###############################################
# Determine folder
###############################################
FOLDER="$EXPORTS_DIR"
if [ -n "$TOP_ARG" ] && [ -d "$TOP_ARG" ] && [ "$TOP_ARG" != "$ROOT_VOLUME" ]; then
    FOLDER="$TOP_ARG"
fi
[ -d "$FOLDER" ] || { echo "❌ Folder does not exist: $FOLDER"; exit 1; }

echo "πŸ”Ž Classifying and adjusting PSDs in: $FOLDER"

###############################################
# Toggles
###############################################
PRINT_ON=1
NEG_ON=1
COLORMASK_ON=1

###############################################
# Retry (Spotlight) β€” Fix #3
###############################################
retry_im_read() {
    local f="$1"
    local attempts=0
    while [ $attempts -lt 10 ]; do
        if magick identify -- "${f}[0]" >/dev/null 2>&1; then
            return 0
        fi
        attempts=$((attempts+1))
        sleep 0.03
    done
    return 1
}

###############################################
# HFS path conversion β€” Fix #4
###############################################
make_hfs_path() {
    local p="${1#/}"
    p="${p//%/%%}"
    p="${p//:/\\:}"
    echo "${p//\//:}"
}

###############################################
# Prevent double suffixing
###############################################
has_suffix() {
    case "$1" in *_P.psd|*_C.psd) return 0 ;; esac
    return 1
}

###############################################
# Main loop
###############################################
for file in "$FOLDER"/*.psd; do
    [ -f "$file" ] || continue
    base=${file##*/}

    case "$base" in ._*) continue ;; esac

    # classification
    if ! retry_im_read "$file"; then
        echo " ⚠️  Could not read (Spotlight): $base β†’ forcing NEGATIVE"
        class="NEGATIVE"
    else
        class=$(classify_file "$file")
    fi

    echo " β†’ $base classified as: $class"

    ACTION_TO_USE=""
    SUFFIX=""
    RUN_ACTION=0

    case "$class" in
        PRINT)
            if [ $PRINT_ON -eq 1 ]; then
                ACTION_TO_USE="$ACTION_PRINTFIX"
                SUFFIX="_P"
                RUN_ACTION=1
            fi
        ;;
        NEG_COLOR)
            if [ $COLORMASK_ON -eq 1 ]; then
                ACTION_TO_USE="$ACTION_COLORFIX"
                SUFFIX="_C"
                RUN_ACTION=1
            elif [ $NEG_ON -eq 1 ]; then
                ACTION_TO_USE="$ACTION_NEGATIVE"
                RUN_ACTION=1
            fi
        ;;
        NEGATIVE)
            if [ $NEG_ON -eq 1 ]; then
                ACTION_TO_USE="$ACTION_NEGATIVE"
                RUN_ACTION=1
            fi
        ;;
    esac

    # Photoshop
    if [ $RUN_ACTION -eq 1 ] && [ -n "$ACTION_TO_USE" ]; then
        hfs_path=$(make_hfs_path "$file")

/usr/bin/osascript <<EOF
tell application "$PHOTOSHOP_APP"
    activate
    try
        open alias "$hfs_path"
        delay 0.4
        do action "$ACTION_TO_USE" from "$ACTION_SET"
        close current document saving yes
    end try
end tell
EOF
    fi

    # rename
    if [ -n "$SUFFIX" ] && ! has_suffix "$base"; then
        new="${file%.psd}${SUFFIX}.psd"
        mv "$file" "$new"
        echo "   β†’ renamed to: ${new##*/}"
    fi

done

echo "βœ… Classification + adjustment complete."