feat: add 10 new puzzles with automated image processing pipeline
- Added process_puzzles.sh script for end-to-end puzzle image management: - Renames prep/ files to lowercase with underscores - Moves validated images to puzzles/ directory - Generates standardized thumbnails (576×324) using ImageMagick - Syncs puzzles.json and thumbnails.json manifests - Added 10 new puzzle images (and corresponding thumbnails): cownappers, forest_conjurer, germanic_castle, hong_kong_phonecall, lonely_robot_2, mushroom_world, octomech_2, old_polish_town, red_eyes, the_mall_interior - Updated asset manifests with new puzzle entries and thumbnails
|
|
@ -0,0 +1,167 @@
|
||||||
|
#!/bin/bash
|
||||||
|
#
|
||||||
|
# Process new puzzle images end-to-end:
|
||||||
|
# 1. Rename files in prep/ to lowercase with underscores
|
||||||
|
# 2. Move them to puzzles/
|
||||||
|
# 3. Generate thumbnails for any images missing one
|
||||||
|
# 4. Sync puzzles.json and thumbnails.json
|
||||||
|
#
|
||||||
|
# Run from: assets/images/
|
||||||
|
# Requires: ImageMagick (convert command)
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
cd "$(dirname "$0")"
|
||||||
|
|
||||||
|
PREP_DIR="prep"
|
||||||
|
PUZZLE_DIR="puzzles"
|
||||||
|
REPO_ROOT=$(git rev-parse --show-toplevel)
|
||||||
|
PUZZLES_JSON="$REPO_ROOT/assets/puzzles.json"
|
||||||
|
THUMBS_JSON="$REPO_ROOT/assets/thumbnails.json"
|
||||||
|
THUMB_WIDTH=576
|
||||||
|
THUMB_HEIGHT=324
|
||||||
|
|
||||||
|
# ─── 1. Rename files in prep/ ──────────────────────────────────────────
|
||||||
|
|
||||||
|
echo "=== Step 1: Renaming files in $PREP_DIR/ ==="
|
||||||
|
renamed=0
|
||||||
|
for f in "$PREP_DIR"/*.png "$PREP_DIR"/*.jpg "$PREP_DIR"/*.jpeg; do
|
||||||
|
[ -f "$f" ] || continue
|
||||||
|
dir=$(dirname "$f")
|
||||||
|
base=$(basename "$f")
|
||||||
|
newname=$(echo "$base" | tr '[:upper:]' '[:lower:]' | tr ' ' '_')
|
||||||
|
if [ "$base" != "$newname" ]; then
|
||||||
|
mv "$f" "$dir/$newname"
|
||||||
|
echo " Renamed: $base -> $newname"
|
||||||
|
renamed=$((renamed + 1))
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
echo " Renamed $renamed file(s)"
|
||||||
|
|
||||||
|
# ─── 2. Move files from prep/ to puzzles/ ──────────────────────────────
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "=== Step 2: Moving images from $PREP_DIR/ to $PUZZLE_DIR/ ==="
|
||||||
|
moved=0
|
||||||
|
for f in "$PREP_DIR"/*.png "$PREP_DIR"/*.jpg "$PREP_DIR"/*.jpeg; do
|
||||||
|
[ -f "$f" ] || continue
|
||||||
|
base=$(basename "$f")
|
||||||
|
# Skip shell scripts
|
||||||
|
case "$base" in *.sh) continue ;; esac
|
||||||
|
if [ -f "$PUZZLE_DIR/$base" ]; then
|
||||||
|
echo " SKIP $base (already exists in $PUZZLE_DIR/)"
|
||||||
|
else
|
||||||
|
mv "$f" "$PUZZLE_DIR/$base"
|
||||||
|
echo " Moved: $base"
|
||||||
|
moved=$((moved + 1))
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
echo " Moved $moved file(s)"
|
||||||
|
|
||||||
|
# ─── 3. Generate thumbnails ────────────────────────────────────────────
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "=== Step 3: Generating thumbnails ==="
|
||||||
|
|
||||||
|
if ! command -v convert &> /dev/null; then
|
||||||
|
echo "Error: ImageMagick is not installed."
|
||||||
|
echo " Ubuntu/Debian: sudo apt install imagemagick"
|
||||||
|
echo " macOS: brew install imagemagick"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
created=0
|
||||||
|
skipped=0
|
||||||
|
for file in "$PUZZLE_DIR"/*; do
|
||||||
|
[ -f "$file" ] || continue
|
||||||
|
base=$(basename "$file")
|
||||||
|
# Skip thumbnails, scripts
|
||||||
|
case "$base" in
|
||||||
|
thumb_*|*.sh) continue ;;
|
||||||
|
esac
|
||||||
|
# Check it's actually an image
|
||||||
|
mime=$(file --mime-type -b "$file")
|
||||||
|
case "$mime" in
|
||||||
|
image/*) ;;
|
||||||
|
*) continue ;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
thumb="$PUZZLE_DIR/thumb_${base}"
|
||||||
|
if [ -f "$thumb" ]; then
|
||||||
|
skipped=$((skipped + 1))
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
|
||||||
|
convert "$file" -resize "${THUMB_WIDTH}x${THUMB_HEIGHT}!" -strip "$thumb"
|
||||||
|
echo " Created: thumb_${base}"
|
||||||
|
created=$((created + 1))
|
||||||
|
done
|
||||||
|
echo " Created $created thumbnail(s), skipped $skipped existing"
|
||||||
|
|
||||||
|
# ─── 4. Sync JSON manifests ────────────────────────────────────────────
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "=== Step 4: Syncing JSON manifests ==="
|
||||||
|
|
||||||
|
puzzles="["
|
||||||
|
thumbs="["
|
||||||
|
first=true
|
||||||
|
|
||||||
|
for img in "$PUZZLE_DIR"/*.png "$PUZZLE_DIR"/*.jpg "$PUZZLE_DIR"/*.jpeg; do
|
||||||
|
[ -f "$img" ] || continue
|
||||||
|
base=$(basename "$img")
|
||||||
|
ext="${base##*.}"
|
||||||
|
name="${base%.*}"
|
||||||
|
|
||||||
|
# Skip thumbnails
|
||||||
|
[[ "$name" == thumb_* ]] && continue
|
||||||
|
|
||||||
|
# Derive keys (replace hyphens with underscores)
|
||||||
|
safe="${name//-/_}"
|
||||||
|
puzzle_key="puzzle_${safe}"
|
||||||
|
thumb_key="thumb_${safe}"
|
||||||
|
thumb_file="$PUZZLE_DIR/thumb_${name}.${ext}"
|
||||||
|
|
||||||
|
# Skip if no matching thumbnail
|
||||||
|
if [ ! -f "$thumb_file" ]; then
|
||||||
|
echo " WARNING: No thumbnail for $name — skipping"
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Build label: replace underscores/hyphens with spaces, then title-case
|
||||||
|
label=$(echo "$name" | sed 's/[_-]/ /g' | sed 's/\b\(.\)/\u\1/g')
|
||||||
|
|
||||||
|
# Paths relative to repo root
|
||||||
|
rel_img="assets/images/puzzles/${base}"
|
||||||
|
rel_thumb="assets/images/puzzles/thumb_${name}.${ext}"
|
||||||
|
|
||||||
|
sep=""
|
||||||
|
$first || sep=","
|
||||||
|
first=false
|
||||||
|
|
||||||
|
puzzles+="${sep}
|
||||||
|
{
|
||||||
|
\"key\": \"${puzzle_key}\",
|
||||||
|
\"path\": \"${rel_img}\",
|
||||||
|
\"label\": \"${label}\"
|
||||||
|
}"
|
||||||
|
|
||||||
|
thumbs+="${sep}
|
||||||
|
{
|
||||||
|
\"key\": \"${thumb_key}\",
|
||||||
|
\"path\": \"${rel_thumb}\",
|
||||||
|
\"puzzleKey\": \"${puzzle_key}\"
|
||||||
|
}"
|
||||||
|
done
|
||||||
|
|
||||||
|
puzzles+="
|
||||||
|
]"
|
||||||
|
thumbs+="
|
||||||
|
]"
|
||||||
|
|
||||||
|
echo "$puzzles" > "$PUZZLES_JSON"
|
||||||
|
echo "$thumbs" > "$THUMBS_JSON"
|
||||||
|
|
||||||
|
echo " Updated puzzles.json ($(grep -c '"key"' "$PUZZLES_JSON") entries)"
|
||||||
|
echo " Updated thumbnails.json ($(grep -c '"key"' "$THUMBS_JSON") entries)"
|
||||||
|
echo ""
|
||||||
|
echo "=== Done! ==="
|
||||||
|
After Width: | Height: | Size: 2.7 MiB |
|
After Width: | Height: | Size: 3.7 MiB |
|
After Width: | Height: | Size: 3.4 MiB |
|
After Width: | Height: | Size: 3.6 MiB |
|
After Width: | Height: | Size: 4.0 MiB |
|
After Width: | Height: | Size: 3.4 MiB |
|
After Width: | Height: | Size: 4.0 MiB |
|
After Width: | Height: | Size: 4.3 MiB |
|
After Width: | Height: | Size: 3.1 MiB |
|
After Width: | Height: | Size: 4.2 MiB |
|
After Width: | Height: | Size: 307 KiB |
|
After Width: | Height: | Size: 349 KiB |
|
After Width: | Height: | Size: 261 KiB |
|
After Width: | Height: | Size: 319 KiB |
|
After Width: | Height: | Size: 362 KiB |
|
After Width: | Height: | Size: 336 KiB |
|
After Width: | Height: | Size: 325 KiB |
|
After Width: | Height: | Size: 363 KiB |
|
After Width: | Height: | Size: 295 KiB |
|
After Width: | Height: | Size: 323 KiB |
|
|
@ -44,6 +44,11 @@
|
||||||
"path": "assets/images/puzzles/cottages_on_the_street.png",
|
"path": "assets/images/puzzles/cottages_on_the_street.png",
|
||||||
"label": "Cottages On The Street"
|
"label": "Cottages On The Street"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"key": "puzzle_cownappers",
|
||||||
|
"path": "assets/images/puzzles/cownappers.png",
|
||||||
|
"label": "Cownappers"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"key": "puzzle_dwarven_blacksmith",
|
"key": "puzzle_dwarven_blacksmith",
|
||||||
"path": "assets/images/puzzles/dwarven_blacksmith.png",
|
"path": "assets/images/puzzles/dwarven_blacksmith.png",
|
||||||
|
|
@ -69,6 +74,11 @@
|
||||||
"path": "assets/images/puzzles/floating_wizards_village.png",
|
"path": "assets/images/puzzles/floating_wizards_village.png",
|
||||||
"label": "Floating Wizards Village"
|
"label": "Floating Wizards Village"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"key": "puzzle_forest_conjurer",
|
||||||
|
"path": "assets/images/puzzles/forest_conjurer.png",
|
||||||
|
"label": "Forest Conjurer"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"key": "puzzle_four_seasons_2",
|
"key": "puzzle_four_seasons_2",
|
||||||
"path": "assets/images/puzzles/four_seasons_2.png",
|
"path": "assets/images/puzzles/four_seasons_2.png",
|
||||||
|
|
@ -84,6 +94,11 @@
|
||||||
"path": "assets/images/puzzles/fuzzy_halloween.png",
|
"path": "assets/images/puzzles/fuzzy_halloween.png",
|
||||||
"label": "Fuzzy Halloween"
|
"label": "Fuzzy Halloween"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"key": "puzzle_germanic_castle",
|
||||||
|
"path": "assets/images/puzzles/germanic_castle.png",
|
||||||
|
"label": "Germanic Castle"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"key": "puzzle_golden_in_the_mountains",
|
"key": "puzzle_golden_in_the_mountains",
|
||||||
"path": "assets/images/puzzles/golden_in_the_mountains.png",
|
"path": "assets/images/puzzles/golden_in_the_mountains.png",
|
||||||
|
|
@ -114,6 +129,11 @@
|
||||||
"path": "assets/images/puzzles/home_sweet_home.png",
|
"path": "assets/images/puzzles/home_sweet_home.png",
|
||||||
"label": "Home Sweet Home"
|
"label": "Home Sweet Home"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"key": "puzzle_hong_kong_phonecall",
|
||||||
|
"path": "assets/images/puzzles/hong_kong_phonecall.png",
|
||||||
|
"label": "Hong Kong Phonecall"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"key": "puzzle_jeweled_frogs",
|
"key": "puzzle_jeweled_frogs",
|
||||||
"path": "assets/images/puzzles/jeweled_frogs.png",
|
"path": "assets/images/puzzles/jeweled_frogs.png",
|
||||||
|
|
@ -129,6 +149,11 @@
|
||||||
"path": "assets/images/puzzles/lake_treehouse.png",
|
"path": "assets/images/puzzles/lake_treehouse.png",
|
||||||
"label": "Lake Treehouse"
|
"label": "Lake Treehouse"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"key": "puzzle_lonely_robot_2",
|
||||||
|
"path": "assets/images/puzzles/lonely_robot_2.png",
|
||||||
|
"label": "Lonely Robot 2"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"key": "puzzle_lone_ship_in_the_seas",
|
"key": "puzzle_lone_ship_in_the_seas",
|
||||||
"path": "assets/images/puzzles/lone_ship_in_the_seas.png",
|
"path": "assets/images/puzzles/lone_ship_in_the_seas.png",
|
||||||
|
|
@ -159,6 +184,21 @@
|
||||||
"path": "assets/images/puzzles/mountain_blanket.png",
|
"path": "assets/images/puzzles/mountain_blanket.png",
|
||||||
"label": "Mountain Blanket"
|
"label": "Mountain Blanket"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"key": "puzzle_mushroom_world",
|
||||||
|
"path": "assets/images/puzzles/mushroom_world.png",
|
||||||
|
"label": "Mushroom World"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "puzzle_octomech_2",
|
||||||
|
"path": "assets/images/puzzles/octomech_2.png",
|
||||||
|
"label": "Octomech 2"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "puzzle_old_polish_town",
|
||||||
|
"path": "assets/images/puzzles/old_polish_town.png",
|
||||||
|
"label": "Old Polish Town"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"key": "puzzle_opulant_flowers",
|
"key": "puzzle_opulant_flowers",
|
||||||
"path": "assets/images/puzzles/opulant_flowers.png",
|
"path": "assets/images/puzzles/opulant_flowers.png",
|
||||||
|
|
@ -169,6 +209,11 @@
|
||||||
"path": "assets/images/puzzles/orc_and_the_undead.png",
|
"path": "assets/images/puzzles/orc_and_the_undead.png",
|
||||||
"label": "Orc And The Undead"
|
"label": "Orc And The Undead"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"key": "puzzle_red_eyes",
|
||||||
|
"path": "assets/images/puzzles/red_eyes.png",
|
||||||
|
"label": "Red Eyes"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"key": "puzzle_red_panda_in_the_bamboo_forest",
|
"key": "puzzle_red_panda_in_the_bamboo_forest",
|
||||||
"path": "assets/images/puzzles/red_panda_in_the_bamboo_forest.png",
|
"path": "assets/images/puzzles/red_panda_in_the_bamboo_forest.png",
|
||||||
|
|
@ -204,6 +249,11 @@
|
||||||
"path": "assets/images/puzzles/the_disassembled_android.png",
|
"path": "assets/images/puzzles/the_disassembled_android.png",
|
||||||
"label": "The Disassembled Android"
|
"label": "The Disassembled Android"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"key": "puzzle_the_mall_interior",
|
||||||
|
"path": "assets/images/puzzles/the_mall_interior.png",
|
||||||
|
"label": "The Mall Interior"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"key": "puzzle_the_old_w0rm",
|
"key": "puzzle_the_old_w0rm",
|
||||||
"path": "assets/images/puzzles/the_old_w0rm.png",
|
"path": "assets/images/puzzles/the_old_w0rm.png",
|
||||||
|
|
|
||||||
|
|
@ -44,6 +44,11 @@
|
||||||
"path": "assets/images/puzzles/thumb_cottages_on_the_street.png",
|
"path": "assets/images/puzzles/thumb_cottages_on_the_street.png",
|
||||||
"puzzleKey": "puzzle_cottages_on_the_street"
|
"puzzleKey": "puzzle_cottages_on_the_street"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"key": "thumb_cownappers",
|
||||||
|
"path": "assets/images/puzzles/thumb_cownappers.png",
|
||||||
|
"puzzleKey": "puzzle_cownappers"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"key": "thumb_dwarven_blacksmith",
|
"key": "thumb_dwarven_blacksmith",
|
||||||
"path": "assets/images/puzzles/thumb_dwarven_blacksmith.png",
|
"path": "assets/images/puzzles/thumb_dwarven_blacksmith.png",
|
||||||
|
|
@ -69,6 +74,11 @@
|
||||||
"path": "assets/images/puzzles/thumb_floating_wizards_village.png",
|
"path": "assets/images/puzzles/thumb_floating_wizards_village.png",
|
||||||
"puzzleKey": "puzzle_floating_wizards_village"
|
"puzzleKey": "puzzle_floating_wizards_village"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"key": "thumb_forest_conjurer",
|
||||||
|
"path": "assets/images/puzzles/thumb_forest_conjurer.png",
|
||||||
|
"puzzleKey": "puzzle_forest_conjurer"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"key": "thumb_four_seasons_2",
|
"key": "thumb_four_seasons_2",
|
||||||
"path": "assets/images/puzzles/thumb_four_seasons_2.png",
|
"path": "assets/images/puzzles/thumb_four_seasons_2.png",
|
||||||
|
|
@ -84,6 +94,11 @@
|
||||||
"path": "assets/images/puzzles/thumb_fuzzy_halloween.png",
|
"path": "assets/images/puzzles/thumb_fuzzy_halloween.png",
|
||||||
"puzzleKey": "puzzle_fuzzy_halloween"
|
"puzzleKey": "puzzle_fuzzy_halloween"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"key": "thumb_germanic_castle",
|
||||||
|
"path": "assets/images/puzzles/thumb_germanic_castle.png",
|
||||||
|
"puzzleKey": "puzzle_germanic_castle"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"key": "thumb_golden_in_the_mountains",
|
"key": "thumb_golden_in_the_mountains",
|
||||||
"path": "assets/images/puzzles/thumb_golden_in_the_mountains.png",
|
"path": "assets/images/puzzles/thumb_golden_in_the_mountains.png",
|
||||||
|
|
@ -114,6 +129,11 @@
|
||||||
"path": "assets/images/puzzles/thumb_home_sweet_home.png",
|
"path": "assets/images/puzzles/thumb_home_sweet_home.png",
|
||||||
"puzzleKey": "puzzle_home_sweet_home"
|
"puzzleKey": "puzzle_home_sweet_home"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"key": "thumb_hong_kong_phonecall",
|
||||||
|
"path": "assets/images/puzzles/thumb_hong_kong_phonecall.png",
|
||||||
|
"puzzleKey": "puzzle_hong_kong_phonecall"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"key": "thumb_jeweled_frogs",
|
"key": "thumb_jeweled_frogs",
|
||||||
"path": "assets/images/puzzles/thumb_jeweled_frogs.png",
|
"path": "assets/images/puzzles/thumb_jeweled_frogs.png",
|
||||||
|
|
@ -129,6 +149,11 @@
|
||||||
"path": "assets/images/puzzles/thumb_lake_treehouse.png",
|
"path": "assets/images/puzzles/thumb_lake_treehouse.png",
|
||||||
"puzzleKey": "puzzle_lake_treehouse"
|
"puzzleKey": "puzzle_lake_treehouse"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"key": "thumb_lonely_robot_2",
|
||||||
|
"path": "assets/images/puzzles/thumb_lonely_robot_2.png",
|
||||||
|
"puzzleKey": "puzzle_lonely_robot_2"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"key": "thumb_lone_ship_in_the_seas",
|
"key": "thumb_lone_ship_in_the_seas",
|
||||||
"path": "assets/images/puzzles/thumb_lone_ship_in_the_seas.png",
|
"path": "assets/images/puzzles/thumb_lone_ship_in_the_seas.png",
|
||||||
|
|
@ -159,6 +184,21 @@
|
||||||
"path": "assets/images/puzzles/thumb_mountain_blanket.png",
|
"path": "assets/images/puzzles/thumb_mountain_blanket.png",
|
||||||
"puzzleKey": "puzzle_mountain_blanket"
|
"puzzleKey": "puzzle_mountain_blanket"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"key": "thumb_mushroom_world",
|
||||||
|
"path": "assets/images/puzzles/thumb_mushroom_world.png",
|
||||||
|
"puzzleKey": "puzzle_mushroom_world"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "thumb_octomech_2",
|
||||||
|
"path": "assets/images/puzzles/thumb_octomech_2.png",
|
||||||
|
"puzzleKey": "puzzle_octomech_2"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "thumb_old_polish_town",
|
||||||
|
"path": "assets/images/puzzles/thumb_old_polish_town.png",
|
||||||
|
"puzzleKey": "puzzle_old_polish_town"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"key": "thumb_opulant_flowers",
|
"key": "thumb_opulant_flowers",
|
||||||
"path": "assets/images/puzzles/thumb_opulant_flowers.png",
|
"path": "assets/images/puzzles/thumb_opulant_flowers.png",
|
||||||
|
|
@ -169,6 +209,11 @@
|
||||||
"path": "assets/images/puzzles/thumb_orc_and_the_undead.png",
|
"path": "assets/images/puzzles/thumb_orc_and_the_undead.png",
|
||||||
"puzzleKey": "puzzle_orc_and_the_undead"
|
"puzzleKey": "puzzle_orc_and_the_undead"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"key": "thumb_red_eyes",
|
||||||
|
"path": "assets/images/puzzles/thumb_red_eyes.png",
|
||||||
|
"puzzleKey": "puzzle_red_eyes"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"key": "thumb_red_panda_in_the_bamboo_forest",
|
"key": "thumb_red_panda_in_the_bamboo_forest",
|
||||||
"path": "assets/images/puzzles/thumb_red_panda_in_the_bamboo_forest.png",
|
"path": "assets/images/puzzles/thumb_red_panda_in_the_bamboo_forest.png",
|
||||||
|
|
@ -204,6 +249,11 @@
|
||||||
"path": "assets/images/puzzles/thumb_the_disassembled_android.png",
|
"path": "assets/images/puzzles/thumb_the_disassembled_android.png",
|
||||||
"puzzleKey": "puzzle_the_disassembled_android"
|
"puzzleKey": "puzzle_the_disassembled_android"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"key": "thumb_the_mall_interior",
|
||||||
|
"path": "assets/images/puzzles/thumb_the_mall_interior.png",
|
||||||
|
"puzzleKey": "puzzle_the_mall_interior"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"key": "thumb_the_old_w0rm",
|
"key": "thumb_the_old_w0rm",
|
||||||
"path": "assets/images/puzzles/thumb_the_old_w0rm.png",
|
"path": "assets/images/puzzles/thumb_the_old_w0rm.png",
|
||||||
|
|
|
||||||