wip + convertis images
|
|
@ -37,46 +37,46 @@
|
||||||
],
|
],
|
||||||
"require": {
|
"require": {
|
||||||
"php": ">=8.5",
|
"php": ">=8.5",
|
||||||
"azjezz/psl": "^4.2",
|
"php-standard-library/php-standard-library": "^4.3",
|
||||||
"composer/installers": "^2.3",
|
"composer/installers": "^2.3",
|
||||||
"crell/fp": "^1.0",
|
"crell/fp": "^1.0",
|
||||||
"htmlburger/carbon-fields": "^3.6",
|
"htmlburger/carbon-fields": "^3.6.9",
|
||||||
"illuminate/support": "^12.43",
|
"illuminate/support": "^12.56",
|
||||||
"laravel/helpers": "^1.7.1",
|
"laravel/helpers": "^1.8.3",
|
||||||
"log1x/wp-smtp": "^1.0.2",
|
"log1x/wp-smtp": "^1.0.2",
|
||||||
"lstrojny/functional-php": "^1.17",
|
"lstrojny/functional-php": "^1.18",
|
||||||
"mnsami/composer-custom-directory-installer": "^2.0",
|
"mnsami/composer-custom-directory-installer": "^2.0",
|
||||||
"nesbot/carbon": "^3.8.2",
|
"nesbot/carbon": "^3.11.3",
|
||||||
"oscarotero/env": "^2.1.1",
|
"oscarotero/env": "^2.1.1",
|
||||||
"roots/bedrock-autoloader": "^1.0.4",
|
"roots/bedrock-autoloader": "^1.1.0",
|
||||||
"roots/bedrock-disallow-indexing": "^2.0",
|
"roots/bedrock-disallow-indexing": "^2.1",
|
||||||
"roots/wordpress": "^6.8.1",
|
"roots/wordpress": "^6.9.4",
|
||||||
"roots/wp-config": "^1.0",
|
"roots/wp-config": "^1.0",
|
||||||
"stripe/stripe-php": "^19",
|
"stripe/stripe-php": "^19.4.1",
|
||||||
"symfony/uid": "^8",
|
"symfony/uid": "^8.0.4",
|
||||||
"timber/timber": "^2.3",
|
"timber/timber": "^2.3.3",
|
||||||
"vlucas/phpdotenv": "^5.6.1",
|
"vlucas/phpdotenv": "^5.6.3",
|
||||||
"wpackagist-plugin/falcon": "^2.8.4",
|
"wpackagist-plugin/falcon": "^2.9.3",
|
||||||
"wpackagist-plugin/force-regenerate-thumbnails": "^2.2.1",
|
"wpackagist-plugin/force-regenerate-thumbnails": "^2.3.0",
|
||||||
"wpackagist-plugin/query-monitor": "^3.17.0",
|
"wpackagist-plugin/query-monitor": "^3.20.4",
|
||||||
"wpackagist-plugin/redis-cache": "^2.5.4",
|
"wpackagist-plugin/redis-cache": "^2.7.0",
|
||||||
"wpackagist-plugin/wc-multishipping": "^3.0",
|
"wpackagist-plugin/wc-multishipping": "^3.0.2",
|
||||||
"wpackagist-plugin/woo-preview-emails": "^2.2.13",
|
"wpackagist-plugin/woo-preview-emails": "^2.2.14",
|
||||||
"wpackagist-plugin/woocommerce": "^10",
|
"wpackagist-plugin/woocommerce": "^10.6.1",
|
||||||
"wpackagist-plugin/wp-mail-logging": "^1.13.1",
|
"wpackagist-plugin/wp-mail-logging": "^1.16.0",
|
||||||
"wpackagist-plugin/wp-mail-smtp": "^4.2",
|
"wpackagist-plugin/wp-mail-smtp": "^4.7.1",
|
||||||
"wpackagist-plugin/wp-openapi": "^1.0.16",
|
"wpackagist-plugin/wp-openapi": "^1.0.27",
|
||||||
"wpackagist-theme/twentytwentyfour": "^1.3"
|
"wpackagist-theme/twentytwentyfour": "^1.4"
|
||||||
},
|
},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
"friendsofphp/php-cs-fixer": "^3.89",
|
"friendsofphp/php-cs-fixer": "^3.94.2",
|
||||||
"php-standard-library/phpstan-extension": "^2.0",
|
"php-standard-library/phpstan-extension": "^2.1",
|
||||||
"phpstan/extension-installer": "^1.4.3",
|
"phpstan/extension-installer": "^1.4.3",
|
||||||
"phpstan/phpstan": "^2.0.3",
|
"phpstan/phpstan": "^2.1.45",
|
||||||
"rector/rector": "^2.2",
|
"rector/rector": "^2.3.9",
|
||||||
"roave/security-advisories": "dev-latest",
|
"roave/security-advisories": "dev-latest",
|
||||||
"szepeviktor/phpstan-wordpress": "2.x-dev",
|
"szepeviktor/phpstan-wordpress": "2.x-dev",
|
||||||
"vincentlanglet/twig-cs-fixer": "^3.10"
|
"vincentlanglet/twig-cs-fixer": "^3.14"
|
||||||
},
|
},
|
||||||
"support": {
|
"support": {
|
||||||
"forum": "https://discourse.roots.io/category/bedrock",
|
"forum": "https://discourse.roots.io/category/bedrock",
|
||||||
|
|
|
||||||
558
composer.lock
generated
68
scripts/convertis-images.fish
Executable file
|
|
@ -0,0 +1,68 @@
|
||||||
|
#!/usr/bin/fish
|
||||||
|
|
||||||
|
for jpg in **/*.{jpg,jpeg}
|
||||||
|
echo $jpg
|
||||||
|
|
||||||
|
set -f avif (path change-extension 'avif' "$jpg")
|
||||||
|
set -f jxl (path change-extension 'jxl' "$jpg")
|
||||||
|
set -f png (path change-extension 'png' "$jpg")
|
||||||
|
|
||||||
|
set -f dimensions (magick identify -format "%w-%h" $jpg)
|
||||||
|
set -f dimensions (string split "-" $dimensions)
|
||||||
|
|
||||||
|
if test $dimensions[1] -eq 1920 || test $dimensions[2] -eq 1920
|
||||||
|
set -f a_bonnes_dimensions true
|
||||||
|
else
|
||||||
|
set -f a_bonnes_dimensions false
|
||||||
|
end
|
||||||
|
|
||||||
|
if test -e $avif && test -e $jxl
|
||||||
|
echo -e "\tAll there."
|
||||||
|
continue
|
||||||
|
end
|
||||||
|
|
||||||
|
magick "$jpg" -resize 1920x1920\> "$png" >/dev/null
|
||||||
|
|
||||||
|
if ! test -e $jxl
|
||||||
|
if test $a_bonnes_dimensions = false
|
||||||
|
cjxl \
|
||||||
|
--allow_jpeg_reconstruction=1 \
|
||||||
|
--brotli_effort=11 \
|
||||||
|
--container=1 \
|
||||||
|
--effort=9 \
|
||||||
|
--lossless_jpeg=1 \
|
||||||
|
--num_threads=-1 \
|
||||||
|
--progressive \
|
||||||
|
$png $jxl &>/dev/null
|
||||||
|
|
||||||
|
djxl \
|
||||||
|
--num_threads=-1 \
|
||||||
|
$jxl $jpg &>/dev/null
|
||||||
|
end
|
||||||
|
|
||||||
|
cjxl \
|
||||||
|
--allow_jpeg_reconstruction=0 \
|
||||||
|
--brotli_effort=11 \
|
||||||
|
--container=1 \
|
||||||
|
--effort=10 \
|
||||||
|
--quality=70 \
|
||||||
|
--lossless_jpeg=0 \
|
||||||
|
--num_threads=-1 \
|
||||||
|
--progressive \
|
||||||
|
$png $jxl &>/dev/null
|
||||||
|
echo -e "\t$jxl"
|
||||||
|
|
||||||
|
set -f avif (path change-extension 'avif' "$jpg")
|
||||||
|
if ! test -e $avif
|
||||||
|
avifenc \
|
||||||
|
-q 70 \
|
||||||
|
-s 0 \
|
||||||
|
-c aom \
|
||||||
|
-y 420 \
|
||||||
|
"$png" "$avif" &>/dev/null
|
||||||
|
echo -e "\t$avif"
|
||||||
|
end
|
||||||
|
|
||||||
|
rm $png
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
@ -0,0 +1,42 @@
|
||||||
|
import { Option, pipe } from "effect";
|
||||||
|
import { Array as EffectArray } from "effect";
|
||||||
|
import { NonEmptyReadonlyArray } from "effect/Array";
|
||||||
|
import { getOptionOrThrowWithError } from "./utils";
|
||||||
|
|
||||||
|
/** Type union des parents possibles pour un `querySelector`. */
|
||||||
|
export type ParentElement = Document | Element;
|
||||||
|
|
||||||
|
export const getFirstSelectorFromParent =
|
||||||
|
(parent: ParentElement) => <E extends Element = Element>(selector: string): Option.Option<NonNullable<E>> =>
|
||||||
|
Option.fromNullishOr(parent.querySelector<E>(selector));
|
||||||
|
|
||||||
|
export const getFirstSelectorFromDocument = <E extends Element = Element>(
|
||||||
|
selector: string,
|
||||||
|
): Option.Option<NonNullable<E>> => getFirstSelectorFromParent(document)<E>(selector);
|
||||||
|
|
||||||
|
export const getFirstSelectorFromDocumentOrThrow = <E extends Element = Element>(selector: string): NonNullable<E> =>
|
||||||
|
pipe(
|
||||||
|
getFirstSelectorFromDocument<E>(selector),
|
||||||
|
getOptionOrThrowWithError(`Il n'y a pas d'Élément dans le Document avec le sélecteur suivant : ${selector}.`),
|
||||||
|
);
|
||||||
|
|
||||||
|
export const getAllSelectorFromParent =
|
||||||
|
(parent: ParentElement) => <E extends Element = Element>(selector: string): Option.Option<NonEmptyReadonlyArray<E>> =>
|
||||||
|
pipe(
|
||||||
|
parent.querySelectorAll<E>(selector),
|
||||||
|
// Convertis NodeListOf en Array.
|
||||||
|
Array.from<E>,
|
||||||
|
(xs: Array<E>) => Option.liftPredicate(EffectArray.isReadonlyArrayNonEmpty)(xs),
|
||||||
|
);
|
||||||
|
|
||||||
|
export const getAllSelectorFromDocument = <E extends Element = Element>(
|
||||||
|
selector: string,
|
||||||
|
): Option.Option<NonEmptyReadonlyArray<E>> => getAllSelectorFromParent(document)<E>(selector);
|
||||||
|
|
||||||
|
export const getAllSelectorFromDocumentOrThrow = <E extends Element = Element>(
|
||||||
|
selector: string,
|
||||||
|
): NonEmptyReadonlyArray<E> =>
|
||||||
|
pipe(
|
||||||
|
getAllSelectorFromDocument<E>(selector),
|
||||||
|
getOptionOrThrowWithError(`Il n'y a pas d'Éléments dans le Document avec le sélecteur suivant : ${selector}.`),
|
||||||
|
);
|
||||||
|
|
@ -0,0 +1,7 @@
|
||||||
|
import { pipe, Option } from "effect";
|
||||||
|
|
||||||
|
export const getOptionOrThrowWithError = (message: string) => <T>(option: Option.Option<T>): T =>
|
||||||
|
pipe(
|
||||||
|
option,
|
||||||
|
Option.getOrThrowWith(() => new Error(message)),
|
||||||
|
);
|
||||||
|
|
@ -26,7 +26,7 @@ export const ATTRIBUT_TABINDEX = "tabindex";
|
||||||
// En-tête
|
// En-tête
|
||||||
export const DOM_BOUTON_MENU_MOBILE = "#bouton-menu-mobile";
|
export const DOM_BOUTON_MENU_MOBILE = "#bouton-menu-mobile";
|
||||||
export const DOM_BOUTON_PANIER = ".compte-panier a[rel='cart']";
|
export const DOM_BOUTON_PANIER = ".compte-panier a[rel='cart']";
|
||||||
export const DOM_ENTREE_MENU_CATEGORIES_PRODUITS = "#menu-categories-produits ul li a";
|
export const DOM_ENTREES_MENU_CATEGORIES_PRODUITS = "#menu-categories-produits ul li a";
|
||||||
export const DOM_MENU_CATEGORIES_PRODUITS = "#menu-categories-produits";
|
export const DOM_MENU_CATEGORIES_PRODUITS = "#menu-categories-produits";
|
||||||
export const DOM_MENU_MOBILE = "#menu-mobile";
|
export const DOM_MENU_MOBILE = "#menu-mobile";
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,25 +1,10 @@
|
||||||
import { pipe } from "@mobily/ts-belt";
|
|
||||||
import { EitherAsync } from "purify-ts";
|
import { EitherAsync } from "purify-ts";
|
||||||
import { match, P } from "ts-pattern";
|
import { match } from "ts-pattern";
|
||||||
import { type GenericSchema, parse } from "valibot";
|
|
||||||
|
|
||||||
import type { HttpCodeErrors, SimplifiedResponse } from "./types/reseau";
|
import type { HttpCodeErrors, SimplifiedResponse } from "./types/reseau";
|
||||||
|
|
||||||
import { ENTETE_WC_NONCE } from "../constantes/api.ts";
|
import { ENTETE_WC_NONCE } from "../constantes/api.ts";
|
||||||
import {
|
import { BadRequestError, ForbiddenError, NotFoundError, ServerError, UnauthorizedError } from "./erreurs.ts";
|
||||||
BadRequestError,
|
|
||||||
ErreurInconnue,
|
|
||||||
ForbiddenError,
|
|
||||||
leveBadRequestError,
|
|
||||||
leveErreur,
|
|
||||||
leveNotFoundError,
|
|
||||||
leveUnauthorizedError,
|
|
||||||
NotFoundError,
|
|
||||||
ServerError,
|
|
||||||
UnauthorizedError,
|
|
||||||
type UnknownError,
|
|
||||||
} from "./erreurs.ts";
|
|
||||||
import { estWCError } from "./schemas/api/erreurs.ts";
|
|
||||||
|
|
||||||
// Types
|
// Types
|
||||||
|
|
||||||
|
|
@ -149,22 +134,6 @@ export const prefilledPostBackend =
|
||||||
export const safeFetch = (f: Promise<Response>): EitherAsync<DOMException | TypeError, Response> =>
|
export const safeFetch = (f: Promise<Response>): EitherAsync<DOMException | TypeError, Response> =>
|
||||||
EitherAsync<DOMException | TypeError, Response>(async () => await f);
|
EitherAsync<DOMException | TypeError, Response>(async () => await f);
|
||||||
|
|
||||||
// TODO: Ne traite pas du tout les Erreurs
|
|
||||||
// TODO: Utiliser un Either
|
|
||||||
export const traiteReponseBackendWCSelonCodesHTTP = <R, S extends GenericSchema<R>>(
|
|
||||||
corpsReponse: unknown,
|
|
||||||
schemaReponse: S,
|
|
||||||
): R =>
|
|
||||||
match(corpsReponse)
|
|
||||||
// Réponses problématiques
|
|
||||||
.with({ body: P.select(), status: 400 }, estWCError, leveBadRequestError)
|
|
||||||
.with({ body: P.select(), status: 401 }, estWCError, leveUnauthorizedError)
|
|
||||||
.with({ body: P.select(), status: 404 }, estWCError, leveNotFoundError)
|
|
||||||
// Réponse OK (201)
|
|
||||||
.with(P._, corpsOkInconnu => parse<S>(schemaReponse, corpsOkInconnu))
|
|
||||||
// Réponses inconnues
|
|
||||||
.otherwise(e => pipe(e, ErreurInconnue, leveErreur<UnknownError>));
|
|
||||||
|
|
||||||
// Réponses Simplifiées
|
// Réponses Simplifiées
|
||||||
export const newPartialResponse = async (reponse: Response): Promise<SimplifiedResponse> => {
|
export const newPartialResponse = async (reponse: Response): Promise<SimplifiedResponse> => {
|
||||||
return {
|
return {
|
||||||
|
|
|
||||||
|
|
@ -1,35 +1,39 @@
|
||||||
/** Scripts pour le Menu des Catégories de Produits */
|
/** Scripts pour le Menu des Catégories de Produits */
|
||||||
|
|
||||||
import { A } from "@mobily/ts-belt";
|
import { Array as EffectArray, Match, Predicate } from "effect";
|
||||||
import { match } from "ts-pattern";
|
|
||||||
|
|
||||||
import { DOM_ENTREE_MENU_CATEGORIES_PRODUITS, DOM_MENU_CATEGORIES_PRODUITS } from "./constantes/dom.ts";
|
import { DOM_ENTREES_MENU_CATEGORIES_PRODUITS, DOM_MENU_CATEGORIES_PRODUITS } from "./constantes/dom.ts";
|
||||||
import { mustGetEleInDocument, mustGetElesInDocument } from "./lib/dom.ts";
|
import { getAllSelectorFromDocumentOrThrow, getFirstSelectorFromDocumentOrThrow } from "../scripts-effect/lib/dom.ts";
|
||||||
|
|
||||||
|
// Initialise les attributs HTML pour l'affichage initiale des flèches de défilement du menu de catégories de Produits.
|
||||||
document.addEventListener("DOMContentLoaded", (): void => {
|
document.addEventListener("DOMContentLoaded", (): void => {
|
||||||
const MENU_CATEGORIES_PRODUITS: HTMLElement = mustGetEleInDocument(DOM_MENU_CATEGORIES_PRODUITS);
|
const productsCategoriesMenu: HTMLElement = getFirstSelectorFromDocumentOrThrow<HTMLElement>(
|
||||||
const ENTREES_MENU_CATEGORIES_PRODUITS: Array<HTMLAnchorElement> = mustGetElesInDocument(
|
DOM_MENU_CATEGORIES_PRODUITS,
|
||||||
DOM_ENTREE_MENU_CATEGORIES_PRODUITS,
|
);
|
||||||
|
const menuEntries: ReadonlyArray<HTMLAnchorElement> = getAllSelectorFromDocumentOrThrow(
|
||||||
|
DOM_ENTREES_MENU_CATEGORIES_PRODUITS,
|
||||||
);
|
);
|
||||||
|
|
||||||
A.forEachWithIndex(
|
const firstAndLastEntries: Array<(HTMLAnchorElement | undefined)> = [menuEntries.at(0), menuEntries.at(-1)];
|
||||||
[ENTREES_MENU_CATEGORIES_PRODUITS.at(0), ENTREES_MENU_CATEGORIES_PRODUITS.at(-1)],
|
|
||||||
(index, entreeMenu): void => {
|
|
||||||
if (!entreeMenu) return;
|
|
||||||
|
|
||||||
new IntersectionObserver(
|
// Créé un nouvel Observer pour la première et dernière entrée.
|
||||||
A.forEach(entree => {
|
EffectArray.forEach(firstAndLastEntries, (menuEntry, _index) => {
|
||||||
// Ne déclenche rien si le scroll n'est pas horizontal
|
if (Predicate.isUndefined(menuEntry)) return;
|
||||||
if (entree.boundingClientRect.top <= 0) return;
|
|
||||||
match([entree.isIntersecting, index])
|
new IntersectionObserver(
|
||||||
.with([true, 0], () => MENU_CATEGORIES_PRODUITS.removeAttribute("data-entrees-presentes-debut"))
|
EffectArray.forEach(intersectionEntry => {
|
||||||
.with([true, 1], () => MENU_CATEGORIES_PRODUITS.removeAttribute("data-entrees-presentes-fin"))
|
// Ne déclenche rien si le scroll n'est pas horizontal
|
||||||
.with([false, 0], () => MENU_CATEGORIES_PRODUITS.setAttribute("data-entrees-presentes-debut", ""))
|
if (intersectionEntry.boundingClientRect.top <= 0) return;
|
||||||
.with([false, 1], () => MENU_CATEGORIES_PRODUITS.setAttribute("data-entrees-presentes-fin", ""))
|
|
||||||
.run();
|
Match.value([intersectionEntry.isIntersecting]).pipe(
|
||||||
}),
|
Match.when([true, 0], () => productsCategoriesMenu.removeAttribute("data-entrees-presentes-debut")),
|
||||||
{ root: null, threshold: 0.9 },
|
Match.when([true, 1], () => productsCategoriesMenu.removeAttribute("data-entrees-presentes-fin")),
|
||||||
).observe(entreeMenu);
|
Match.when([false, 0], () => productsCategoriesMenu.setAttribute("data-entrees-presentes-debut", "")),
|
||||||
},
|
Match.when([false, 1], () => productsCategoriesMenu.setAttribute("data-entrees-presentes-fin", "")),
|
||||||
);
|
Match.orElse(() => {}),
|
||||||
|
);
|
||||||
|
}),
|
||||||
|
{ root: null, threshold: 0.9 },
|
||||||
|
).observe(menuEntry);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
|
||||||
BIN
web/app/uploads/2024/09/DSC8400-copie-300x300.avif
Executable file → Normal file
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 8.3 KiB |
|
Before Width: | Height: | Size: 17 KiB After Width: | Height: | Size: 28 KiB |
BIN
web/app/uploads/2024/09/DSC8400-copie-300x300.jxl
Executable file → Normal file
|
Before Width: | Height: | Size: 9.8 KiB |
BIN
web/app/uploads/2024/09/DSC8400-copie.avif
Executable file → Normal file
|
Before Width: | Height: | Size: 430 KiB After Width: | Height: | Size: 422 KiB |
BIN
web/app/uploads/2024/09/DSC8400-copie.jxl
Executable file → Normal file
|
Before Width: | Height: | Size: 455 KiB |
BIN
web/app/uploads/2024/09/DSC9148-300x300.avif
Executable file → Normal file
|
Before Width: | Height: | Size: 7.3 KiB After Width: | Height: | Size: 6.1 KiB |
|
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 22 KiB |
BIN
web/app/uploads/2024/09/DSC9148-300x300.jxl
Executable file → Normal file
|
Before Width: | Height: | Size: 6.1 KiB |
BIN
web/app/uploads/2024/09/DSC9148.avif
Executable file → Normal file
|
Before Width: | Height: | Size: 152 KiB After Width: | Height: | Size: 150 KiB |
BIN
web/app/uploads/2024/09/DSC9148.jxl
Executable file → Normal file
|
Before Width: | Height: | Size: 124 KiB |
BIN
web/app/uploads/2024/09/DSC9269-300x300.avif
Executable file → Normal file
|
Before Width: | Height: | Size: 7.6 KiB After Width: | Height: | Size: 6.3 KiB |
|
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 22 KiB |
BIN
web/app/uploads/2024/09/DSC9269-300x300.jxl
Executable file → Normal file
|
Before Width: | Height: | Size: 6.7 KiB |
BIN
web/app/uploads/2024/09/DSC9269.avif
Executable file → Normal file
|
Before Width: | Height: | Size: 166 KiB After Width: | Height: | Size: 165 KiB |
BIN
web/app/uploads/2024/09/DSC9269.jxl
Executable file → Normal file
|
Before Width: | Height: | Size: 144 KiB |
BIN
web/app/uploads/2024/09/DSC9339-300x300.avif
Executable file → Normal file
|
Before Width: | Height: | Size: 8.4 KiB After Width: | Height: | Size: 6.7 KiB |
|
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 23 KiB |
BIN
web/app/uploads/2024/09/DSC9339-300x300.jxl
Executable file → Normal file
|
Before Width: | Height: | Size: 7.1 KiB |
BIN
web/app/uploads/2024/09/DSC9339.avif
Executable file → Normal file
|
Before Width: | Height: | Size: 196 KiB After Width: | Height: | Size: 195 KiB |
BIN
web/app/uploads/2024/09/DSC9339.jxl
Executable file → Normal file
|
Before Width: | Height: | Size: 162 KiB |
BIN
web/app/uploads/2024/09/DSC9760-300x300.avif
Executable file → Normal file
|
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 9.9 KiB |
|
Before Width: | Height: | Size: 18 KiB After Width: | Height: | Size: 28 KiB |
BIN
web/app/uploads/2024/09/DSC9760-300x300.jxl
Executable file → Normal file
|
Before Width: | Height: | Size: 11 KiB |
BIN
web/app/uploads/2024/09/DSC9760.avif
Executable file → Normal file
|
Before Width: | Height: | Size: 286 KiB After Width: | Height: | Size: 273 KiB |
BIN
web/app/uploads/2024/09/DSC9760.jxl
Executable file → Normal file
|
Before Width: | Height: | Size: 259 KiB |
BIN
web/app/uploads/2024/09/DSC9897-300x300.avif
Executable file → Normal file
|
Before Width: | Height: | Size: 3.4 KiB After Width: | Height: | Size: 3.4 KiB |
|
Before Width: | Height: | Size: 6.9 KiB After Width: | Height: | Size: 15 KiB |
BIN
web/app/uploads/2024/09/DSC9897-300x300.jxl
Executable file → Normal file
|
Before Width: | Height: | Size: 3.8 KiB |
BIN
web/app/uploads/2024/09/DSC9897.avif
Executable file → Normal file
|
Before Width: | Height: | Size: 307 KiB After Width: | Height: | Size: 340 KiB |
BIN
web/app/uploads/2024/09/DSC9897.jxl
Executable file → Normal file
|
Before Width: | Height: | Size: 280 KiB |
BIN
web/app/uploads/2024/09/DSC9928-300x300.avif
Executable file → Normal file
|
Before Width: | Height: | Size: 8.2 KiB After Width: | Height: | Size: 6.6 KiB |
|
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 22 KiB |
BIN
web/app/uploads/2024/09/DSC9928-300x300.jxl
Executable file → Normal file
|
Before Width: | Height: | Size: 7 KiB |
BIN
web/app/uploads/2024/09/DSC9928.avif
Executable file → Normal file
|
Before Width: | Height: | Size: 265 KiB After Width: | Height: | Size: 261 KiB |
BIN
web/app/uploads/2024/09/DSC9928.jxl
Executable file → Normal file
|
Before Width: | Height: | Size: 237 KiB |
BIN
web/app/uploads/2024/09/HADOU-B-300x300.avif
Executable file → Normal file
|
Before Width: | Height: | Size: 2.3 KiB After Width: | Height: | Size: 2 KiB |
|
Before Width: | Height: | Size: 4.4 KiB After Width: | Height: | Size: 9.8 KiB |
BIN
web/app/uploads/2024/09/HADOU-B-300x300.jxl
Executable file → Normal file
|
Before Width: | Height: | Size: 2.4 KiB |
BIN
web/app/uploads/2024/09/HADOU-B-mix-300x300.avif
Executable file → Normal file
|
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 9.4 KiB |
|
Before Width: | Height: | Size: 19 KiB After Width: | Height: | Size: 30 KiB |
BIN
web/app/uploads/2024/09/HADOU-B-mix-300x300.jxl
Executable file → Normal file
|
Before Width: | Height: | Size: 11 KiB |
BIN
web/app/uploads/2024/09/HADOU-B-mix.avif
Executable file → Normal file
|
Before Width: | Height: | Size: 253 KiB After Width: | Height: | Size: 250 KiB |
BIN
web/app/uploads/2024/09/HADOU-B-mix.jxl
Executable file → Normal file
|
Before Width: | Height: | Size: 224 KiB |
BIN
web/app/uploads/2024/09/HADOU-B.avif
Executable file → Normal file
|
Before Width: | Height: | Size: 22 KiB After Width: | Height: | Size: 18 KiB |
BIN
web/app/uploads/2024/09/HADOU-B.jxl
Executable file → Normal file
|
Before Width: | Height: | Size: 25 KiB |
BIN
web/app/uploads/2024/09/HADOU-BKIGEN-Bo-300x300.avif
Executable file → Normal file
|
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 24 KiB After Width: | Height: | Size: 37 KiB |
BIN
web/app/uploads/2024/09/HADOU-BKIGEN-Bo-300x300.jxl
Executable file → Normal file
|
Before Width: | Height: | Size: 22 KiB |
BIN
web/app/uploads/2024/09/HADOU-BKIGEN-Bo.avif
Executable file → Normal file
|
Before Width: | Height: | Size: 423 KiB After Width: | Height: | Size: 352 KiB |
BIN
web/app/uploads/2024/09/HADOU-BKIGEN-Bo.jxl
Executable file → Normal file
|
Before Width: | Height: | Size: 422 KiB |
|
Before Width: | Height: | Size: 12 KiB |
|
Before Width: | Height: | Size: 9.9 KiB |
|
Before Width: | Height: | Size: 466 KiB |
|
Before Width: | Height: | Size: 496 KiB |
|
Before Width: | Height: | Size: 10 KiB |
|
Before Width: | Height: | Size: 9.4 KiB |
|
Before Width: | Height: | Size: 467 KiB |
|
Before Width: | Height: | Size: 528 KiB |
|
Before Width: | Height: | Size: 2 KiB |
|
Before Width: | Height: | Size: 2 KiB |
|
Before Width: | Height: | Size: 18 KiB |
|
Before Width: | Height: | Size: 23 KiB |
BIN
web/app/uploads/2024/09/IKKAN-B-arg-300x300.avif
Executable file → Normal file
|
Before Width: | Height: | Size: 3.9 KiB After Width: | Height: | Size: 3.3 KiB |
|
Before Width: | Height: | Size: 7.6 KiB After Width: | Height: | Size: 15 KiB |