Compare commits

...

31 Commits

Author SHA1 Message Date
b486c4f3fe cleanup
Some checks failed
Build and Deploy / build-and-deploy (push) Failing after 18s
2026-04-03 16:10:25 -04:00
mbcube
bc02da9d48 Update Navigation “main” 2026-04-03 16:06:41 -04:00
7e474a85a2 add gh auth config for decap 2026-04-03 15:49:23 -04:00
8f8fcb83c9 update decap 2026-04-03 15:20:39 -04:00
936000b32a add gh app 2026-04-03 15:17:00 -04:00
5315f1b188 fix decap config 2026-04-03 14:53:55 -04:00
d6d54df384 reset 2026-04-03 14:29:01 -04:00
f1c880690f top level env var 2026-04-03 14:26:58 -04:00
9fee97dea6 update cf content branch 2026-04-03 14:16:56 -04:00
789dc380c1 add log 2026-04-03 14:14:40 -04:00
fe94d4c543 fix apis 2026-04-03 14:09:06 -04:00
f8f59a5134 reomve wrangler 2026-04-03 13:55:17 -04:00
3d1336c3b2 fix some bugs 2026-04-03 13:52:13 -04:00
05eb117e4b audit 2026-04-03 13:30:12 -04:00
84728c9532 cloudflare deployment 2026-04-03 11:19:29 -04:00
5dc33897ce fix stroke
All checks were successful
Build and Deploy / build-and-deploy (push) Successful in 46s
2026-03-30 14:09:37 -04:00
067a151be1 1.01 audrey's edits
All checks were successful
Build and Deploy / build-and-deploy (push) Successful in 46s
2026-03-28 15:37:45 -04:00
539e537572 v-1.001
All checks were successful
Build and Deploy / build-and-deploy (push) Successful in 59s
2026-03-27 12:56:15 -04:00
60c295d731 fix stupid animation
All checks were successful
Build and Deploy / build-and-deploy (push) Successful in 47s
2026-03-26 23:43:47 -04:00
0e99cb4cd7 fix env keys
All checks were successful
Build and Deploy / build-and-deploy (push) Successful in 47s
2026-03-26 18:53:19 -04:00
212baf8efc add env
All checks were successful
Build and Deploy / build-and-deploy (push) Successful in 45s
2026-03-26 18:45:47 -04:00
148d664b44 fix logo for metatags
All checks were successful
Build and Deploy / build-and-deploy (push) Successful in 45s
2026-03-26 18:41:12 -04:00
d1ad6e0f09 fix build
All checks were successful
Build and Deploy / build-and-deploy (push) Successful in 50s
2026-03-26 18:20:25 -04:00
72f652eabe fix pipeline
All checks were successful
Build and Deploy / build-and-deploy (push) Successful in 33s
2026-03-26 18:01:12 -04:00
b23809eb47 fix build
All checks were successful
Build and Deploy / build-and-deploy (push) Successful in 45s
2026-03-26 17:58:04 -04:00
cd3cb704be switch up animation
All checks were successful
Build and Deploy / build-and-deploy (push) Successful in 27s
2026-03-26 16:43:22 -04:00
b0f2bf142b faster hero 2026-03-26 16:27:05 -04:00
d9dbb43926 fix footer casing
All checks were successful
Build and Deploy / build-and-deploy (push) Successful in 2m32s
2026-03-26 13:09:35 -04:00
50ad21bb42 fix pipeline
Some checks failed
Build and Deploy / build-and-deploy (push) Failing after 15s
2026-03-26 13:07:26 -04:00
4a64e90a47 1.0
Some checks failed
Build and Deploy / build-and-deploy (push) Failing after 11s
2026-03-26 13:04:18 -04:00
70d8d83691 0.95
Some checks failed
Build and Deploy / build-and-deploy (push) Failing after 2m56s
2026-03-25 16:25:19 -04:00
173 changed files with 3406 additions and 6330 deletions

View File

@@ -12,7 +12,7 @@ jobs:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '20'
node-version: '24'
cache: 'npm'
- run: npm ci && npm run build
@@ -21,4 +21,6 @@ jobs:
docker build -t cachetdeco:latest .
docker stop cachetdeco 2>/dev/null || true
docker rm cachetdeco 2>/dev/null || true
docker run -d --name cachetdeco -p 30001:80 --restart unless-stopped cachetdeco:latest
docker run -d --name cachetdeco -p 30001:4321 --restart unless-stopped \
-e RESEND_API_KEY=${{ secrets.RESEND_API_KEY }} \
cachetdeco:latest

1
.gitignore vendored
View File

@@ -1,6 +1,7 @@
# Build output
dist/
.astro/
.wrangler/
# Dependencies
node_modules/

View File

@@ -1,3 +1,13 @@
FROM nginx:alpine
COPY dist/ /usr/share/nginx/html/
EXPOSE 80
FROM node:24-alpine AS runtime
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
ENV NODE_ENV=production
ENV HOST=0.0.0.0
ENV PORT=4321
EXPOSE 4321
CMD ["node", "./dist/server/entry.mjs"]

View File

@@ -1,6 +1,6 @@
# Cachet Peintres Décorateurs — Site Web
Site vitrine statique pour **Cachet Peintres Décorateurs** (9500-5609 Québec Inc).
Site vitrine statique pour **Cachet Peintres Décorateurs** (CACHETDECO).
Construit avec **Astro v5 + Tailwind v4 + Decap CMS**, déployé sur **Cloudflare Pages**.
## Stack
@@ -180,7 +180,6 @@ Aucune refactorisation structurelle n'est nécessaire — l'infrastructure est d
Conformément aux exigences légales québécoises, les informations suivantes doivent apparaître visiblement sur le site :
- **Raison sociale :** 9500-5609 Québec Inc
- **Numéro RBQ :** 5839 8736 01 (obligatoire pour tout service nécessitant une modification d'un bâtiment)
Ces informations sont affichées dans le footer de chaque page.

View File

@@ -2,9 +2,11 @@ import { defineConfig } from 'astro/config';
import tailwindcss from '@tailwindcss/vite';
import sitemap from '@astrojs/sitemap';
import react from '@astrojs/react';
import cloudflare from '@astrojs/cloudflare';
export default defineConfig({
output: 'static',
output: 'server',
adapter: cloudflare(),
site: 'https://cachetdeco.com',
i18n: {
defaultLocale: 'fr',
@@ -24,5 +26,8 @@ export default defineConfig({
],
vite: {
plugins: [tailwindcss()],
ssr: {
noExternal: ['motion', 'motion/react'],
},
},
});

View File

@@ -0,0 +1,76 @@
# Cloudflare Workers + Astro v6 Deployment Notes
## Stack
- Astro v6 + `@astrojs/cloudflare` adapter (v13+)
- Deployed as **Cloudflare Worker** (not Pages)
- Build: `npm run build` → Deploy: `npx wrangler deploy`
---
## Issue 1 — `wrangler.json` with `pages_build_output_dir` breaks deploy
**Error:**
```
The name 'ASSETS' is reserved in Pages projects. Please use a different name for your Assets binding.
```
**Cause:** Having `pages_build_output_dir` in `wrangler.json` makes Wrangler treat the project as a Pages project. The adapter generates `dist/server/wrangler.json` with an `ASSETS` binding for static assets, which is reserved in Pages context.
**Fix:** Remove `pages_build_output_dir` from `wrangler.json`, or delete the file entirely. The adapter generates a complete `dist/server/wrangler.json` — Wrangler picks it up automatically via config redirect.
---
## Issue 2 — `locals.runtime.env` removed in Astro v6
**Error:**
```
Astro.locals.runtime.env has been removed in Astro v6.
Use 'import { env } from "cloudflare:workers"' instead.
```
**Cause:** Astro v6 dropped the `locals.runtime.env` pattern for accessing Cloudflare env vars/bindings.
**Fix:**
```ts
// ❌ Astro v5 (broken in v6)
const runtime = (locals as any).runtime;
const apiKey = runtime?.env?.RESEND_API_KEY;
// ✅ Astro v6
import { env } from 'cloudflare:workers';
const apiKey = (env as unknown as Record<string, string>).RESEND_API_KEY;
```
Install types and add to `tsconfig.json`:
```bash
npm install --save-dev @cloudflare/workers-types
```
```json
// tsconfig.json
{
"compilerOptions": {
"types": ["@cloudflare/workers-types"]
}
}
```
---
## Env vars in Cloudflare Workers dashboard
- Set vars under **Worker → Settings → Variables and Secrets**
- They are accessible via `env` from `cloudflare:workers` at runtime
- Do **not** rely on `process.env` or `import.meta.env` for server-side secrets in Workers
---
## Wrangler config redirect (how it works)
When `astro build` runs, `@astrojs/cloudflare` generates `dist/server/wrangler.json`. Wrangler detects this and logs:
```
Using redirected Wrangler configuration.
- Configuration being used: "dist/server/wrangler.json"
- Original user's configuration: "wrangler.json"
```
The generated config includes the worker `main` entry, `assets` binding, `compatibility_date`, and any adapter-detected bindings (e.g. `IMAGES`, `SESSION`).

View File

@@ -1,175 +0,0 @@
interface SoumissionBody {
nom: string;
courriel: string;
telephone: string;
type_service: string;
adresse?: string;
message: string;
}
interface Env {
RESEND_API_KEY: string;
CONTACT_EMAIL: string;
}
const serviceLabels: Record<string, string> = {
interieur: 'Peinture intérieure',
exterieur: 'Peinture extérieure',
commercial: 'Peinture commerciale',
decoration: 'Décoration intérieure',
autre: 'Autre',
};
function buildEmailHtml(data: SoumissionBody): string {
const serviceLabel = serviceLabels[data.type_service] ?? data.type_service;
const adresseLine = data.adresse
? `<tr><td style="padding:8px 12px;color:#666;font-size:14px;border-bottom:1px solid #eee">Adresse des travaux</td><td style="padding:8px 12px;font-size:14px;border-bottom:1px solid #eee">${data.adresse}</td></tr>`
: '';
return `<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body style="margin:0;padding:0;background:#f5f5f5;font-family:system-ui,sans-serif">
<div style="max-width:600px;margin:0 auto;padding:40px 20px">
<div style="background:#314732;padding:32px;border-radius:8px 8px 0 0;text-align:center">
<h1 style="margin:0;color:#ffffff;font-size:22px;font-weight:600">Nouvelle demande de soumission</h1>
<p style="margin:8px 0 0;color:rgba(255,255,255,0.7);font-size:14px">Cachet Peintres Décorateurs</p>
</div>
<div style="background:#ffffff;border-radius:0 0 8px 8px;overflow:hidden">
<div style="padding:24px;background:#f0f4ef;border-bottom:2px solid #d6e2d4">
<p style="margin:0;font-size:15px;color:#314732;font-weight:600">
Vous avez reçu une nouvelle demande de soumission de la part de <strong>${data.nom}</strong>.
</p>
</div>
<table style="width:100%;border-collapse:collapse">
<tbody>
<tr>
<td style="padding:8px 12px;color:#666;font-size:14px;border-bottom:1px solid #eee;width:40%">Nom</td>
<td style="padding:8px 12px;font-size:14px;border-bottom:1px solid #eee;font-weight:600">${data.nom}</td>
</tr>
<tr>
<td style="padding:8px 12px;color:#666;font-size:14px;border-bottom:1px solid #eee">Courriel</td>
<td style="padding:8px 12px;font-size:14px;border-bottom:1px solid #eee"><a href="mailto:${data.courriel}" style="color:#314732;font-weight:600">${data.courriel}</a></td>
</tr>
<tr>
<td style="padding:8px 12px;color:#666;font-size:14px;border-bottom:1px solid #eee">Téléphone</td>
<td style="padding:8px 12px;font-size:14px;border-bottom:1px solid #eee"><a href="tel:${data.telephone.replace(/\D/g, '')}" style="color:#314732;font-weight:600">${data.telephone}</a></td>
</tr>
<tr>
<td style="padding:8px 12px;color:#666;font-size:14px;border-bottom:1px solid #eee">Type de service</td>
<td style="padding:8px 12px;font-size:14px;border-bottom:1px solid #eee">${serviceLabel}</td>
</tr>
${adresseLine}
</tbody>
</table>
<div style="padding:20px">
<p style="margin:0 0 8px;font-size:13px;font-weight:700;color:#666;text-transform:uppercase;letter-spacing:0.05em">Message</p>
<div style="background:#f9fafb;border:1px solid #e5e7eb;border-radius:6px;padding:16px;font-size:14px;color:#374151;line-height:1.6;white-space:pre-wrap">${data.message}</div>
</div>
<div style="padding:16px 20px 24px">
<a href="mailto:${data.courriel}?subject=Re: Soumission — Cachet Peintres Décorateurs" style="display:inline-block;padding:10px 24px;background:#314732;color:#fff;text-decoration:none;border-radius:4px;font-size:14px;font-weight:700">Répondre à ${data.nom}</a>
</div>
</div>
<p style="margin:24px 0 0;text-align:center;font-size:11px;color:#999">
Cachet Peintres Décorateurs · 9500-5609 Québec Inc · RBQ 5839 8736 01
</p>
</div>
</body>
</html>`;
}
function validateBody(body: unknown): body is SoumissionBody {
if (typeof body !== 'object' || body === null) return false;
const b = body as Record<string, unknown>;
return (
typeof b.nom === 'string' && b.nom.trim().length > 0 &&
typeof b.courriel === 'string' && /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(b.courriel) &&
typeof b.telephone === 'string' && b.telephone.trim().length > 0 &&
typeof b.type_service === 'string' && b.type_service.length > 0 &&
typeof b.message === 'string' && b.message.trim().length > 0
);
}
export const onRequestPost: PagesFunction<Env> = async (context) => {
const corsHeaders = {
'Access-Control-Allow-Origin': 'https://cachetdeco.com',
'Content-Type': 'application/json',
};
// Rate limiting via CF headers (basic check)
const ip = context.request.headers.get('CF-Connecting-IP') ?? 'unknown';
let body: unknown;
try {
body = await context.request.json();
} catch {
return new Response(
JSON.stringify({ success: false, error: 'Corps de requête invalide.' }),
{ status: 400, headers: corsHeaders }
);
}
if (!validateBody(body)) {
return new Response(
JSON.stringify({ success: false, error: 'Données manquantes ou invalides.' }),
{ status: 422, headers: corsHeaders }
);
}
const apiKey = context.env.RESEND_API_KEY;
const contactEmail = context.env.CONTACT_EMAIL;
if (!apiKey || !contactEmail) {
console.error('Missing env vars: RESEND_API_KEY or CONTACT_EMAIL');
return new Response(
JSON.stringify({ success: false, error: 'Configuration serveur manquante.' }),
{ status: 500, headers: corsHeaders }
);
}
const emailPayload = {
from: 'Cachet Peintres Décorateurs <soumission@cachetdeco.com>',
to: [contactEmail],
reply_to: body.courriel,
subject: `Soumission — ${serviceLabels[body.type_service] ?? body.type_service}${body.nom}`,
html: buildEmailHtml(body),
};
const resendRes = await fetch('https://api.resend.com/emails', {
method: 'POST',
headers: {
'Authorization': `Bearer ${apiKey}`,
'Content-Type': 'application/json',
},
body: JSON.stringify(emailPayload),
});
if (!resendRes.ok) {
const resendError = await resendRes.text().catch(() => 'Unknown error');
console.error('Resend error:', resendError, 'IP:', ip);
return new Response(
JSON.stringify({ success: false, error: 'Erreur lors de l\'envoi du courriel.' }),
{ status: 502, headers: corsHeaders }
);
}
return new Response(
JSON.stringify({ success: true }),
{ status: 200, headers: corsHeaders }
);
};
// Handle preflight OPTIONS
export const onRequestOptions: PagesFunction = async () => {
return new Response(null, {
status: 204,
headers: {
'Access-Control-Allow-Origin': 'https://cachetdeco.com',
'Access-Control-Allow-Methods': 'POST, OPTIONS',
'Access-Control-Allow-Headers': 'Content-Type',
},
});
};

0
guidline Normal file
View File

2311
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -9,29 +9,33 @@
"astro": "astro"
},
"dependencies": {
"@astrojs/react": "^5.0.0",
"@astrojs/sitemap": "^3.2.1",
"@astrojs/cloudflare": "^13.1.7",
"@astrojs/react": "^5.0.2",
"@astrojs/sitemap": "^3.7.2",
"@fontsource-variable/geist": "^5.2.8",
"@headlessui/react": "^2.2.9",
"@heroicons/react": "^2.2.0",
"@tailwindcss/vite": "^4.0.0",
"@types/react-dom": "^19.2.3",
"astro": "^5.4.0",
"astro": "^6.1.0",
"class-variance-authority": "^0.7.1",
"clsx": "^2.1.1",
"embla-carousel-autoplay": "^8.6.0",
"embla-carousel-react": "^8.6.0",
"lucide-react": "^0.577.0",
"motion": "^12.38.0",
"radix-ui": "^1.4.3",
"react": "^19.2.4",
"react-dom": "^19.2.4",
"react-hook-form": "^7.72.0",
"react-social-media-embed": "^2.5.18",
"shadcn": "^4.0.5",
"tailwind-merge": "^3.5.0",
"tailwindcss": "^4.2.1",
"tw-animate-css": "^1.4.0"
},
"devDependencies": {
"@cloudflare/workers-types": "^4.20260403.1",
"@types/react": "^19.2.14"
}
}

View File

@@ -1,10 +1,9 @@
backend:
name: github
repo: mbcube/cachetdeco # REPLACE with your GitHub org/repo
branch: main
# For Cloudflare Pages (no Netlify Identity), use PKCE flow:
auth_type: pkce
app_id: YOUR_GITHUB_OAUTH_APP_CLIENT_ID # REPLACE with your GitHub OAuth App client ID
repo: mbcube/cachetdeco
branch: cloudflare
base_url: https://cachetdeco.br-mouad.workers.dev
auth_endpoint: /api/auth
locale: fr
media_folder: "public/images"
@@ -78,7 +77,7 @@ collections:
i18n: true
fields:
- { name: "services", label: "Page Services", widget: "string" }
- { name: "soumission", label: "Page Soumission", widget: "string" }
- { name: "submission", label: "Page Soumission", widget: "string" }
- name: "hero"
label: "Hero (accueil)"
@@ -172,10 +171,10 @@ collections:
- { name: "button", label: "Bouton", widget: "string" }
- { name: "breadcrumbHome", label: "Fil d'Ariane — Accueil", widget: "string", i18n: true }
- name: "soumission"
- name: "submission"
label: "Page Soumission & formulaire"
label_singular: "Soumission"
folder: "src/content/soumission"
folder: "src/content/submission"
format: json
create: false
delete: false
@@ -191,29 +190,33 @@ collections:
i18n: true
fields:
- { name: "ariaLabel", label: "Aria-label formulaire", widget: "string" }
- { name: "nom", label: "Libellé nom", widget: "string" }
- { name: "nomPlaceholder", label: "Placeholder nom", widget: "string" }
- { name: "courriel", label: "Libellé courriel", widget: "string" }
- { name: "courrielPlaceholder", label: "Placeholder courriel", widget: "string" }
- { name: "telephone", label: "Libellé téléphone", widget: "string" }
- { name: "telephonePlaceholder", label: "Placeholder téléphone", widget: "string" }
- { name: "adresse", label: "Libellé adresse travaux", widget: "string" }
- { name: "adressePlaceholder", label: "Placeholder adresse", widget: "string" }
- { name: "typeService", label: "Libellé type de service", widget: "string" }
- { name: "typeServicePlaceholder", label: "Placeholder sélection", widget: "string" }
- name: "typeServiceOptions"
- { name: "fullNameLabel", label: "Libellé nom complet", widget: "string" }
- { name: "fullNamePlaceholder", label: "Placeholder nom", widget: "string" }
- { name: "emailLabel", label: "Libellé courriel", widget: "string" }
- { name: "emailPlaceholder", label: "Placeholder courriel", widget: "string" }
- { name: "phoneLabel", label: "Libellé téléphone", widget: "string" }
- { name: "phonePlaceholder", label: "Placeholder téléphone", widget: "string" }
- { name: "workAddressLabel", label: "Libellé adresse travaux", widget: "string" }
- { name: "workAddressPlaceholder", label: "Placeholder adresse", widget: "string" }
- { name: "serviceTypeLabel", label: "Libellé type de service", widget: "string" }
- { name: "serviceTypePlaceholder", label: "Placeholder sélection", widget: "string" }
- name: "serviceTypeOptions"
label: "Options type de service"
widget: "object"
fields:
- { name: "interieur", label: "Intérieur", widget: "string" }
- { name: "exterieur", label: "Extérieur", widget: "string" }
- { name: "interior", label: "Intérieur", widget: "string" }
- { name: "exterior", label: "Extérieur", widget: "string" }
- { name: "commercial", label: "Commercial", widget: "string" }
- { name: "decoration", label: "Décoration", widget: "string" }
- { name: "autre", label: "Autre", widget: "string" }
- { name: "message", label: "Libellé message", widget: "string" }
- { name: "other", label: "Autre", widget: "string" }
- { name: "messageLabel", label: "Libellé message", widget: "string" }
- { name: "messagePlaceholder", label: "Placeholder message", widget: "text" }
- { name: "envoyer", label: "Bouton envoyer", widget: "string" }
- { name: "sending", label: "État envoi", widget: "string" }
- { name: "attachmentsLabel", label: "Libellé pièces jointes", widget: "string" }
- { name: "attachmentsHint", label: "Aide zone dépôt", widget: "string" }
- { name: "attachmentsAccepted", label: "Formats acceptés", widget: "string" }
- { name: "attachmentsRemove", label: "Retirer fichier (aria)", widget: "string" }
- { name: "submitLabel", label: "Bouton envoyer", widget: "string" }
- { name: "submittingLabel", label: "État envoi", widget: "string" }
- { name: "successTitle", label: "Succès — titre", widget: "string" }
- { name: "successMessage", label: "Succès — message", widget: "text" }
- { name: "errorTitle", label: "Erreur — titre", widget: "string" }
@@ -222,11 +225,13 @@ collections:
label: "Messages validation"
widget: "object"
fields:
- { name: "nom", label: "Nom", widget: "string" }
- { name: "courriel", label: "Courriel", widget: "string" }
- { name: "telephone", label: "Téléphone", widget: "string" }
- { name: "typeService", label: "Type service", widget: "string" }
- { name: "fullName", label: "Nom", widget: "string" }
- { name: "email", label: "Courriel", widget: "string" }
- { name: "phone", label: "Téléphone", widget: "string" }
- { name: "serviceType", label: "Type service", widget: "string" }
- { name: "message", label: "Message", widget: "string" }
- { name: "attachmentsType", label: "Type fichier", widget: "string" }
- { name: "attachmentsSize", label: "Taille fichiers", widget: "string" }
- name: "sidebar"
label: "Barre latérale"
widget: "object"
@@ -341,7 +346,6 @@ collections:
fields:
- { name: "key", label: "Identifiant unique", widget: "string" }
- { name: "src", label: "URL du post Facebook (embed)", widget: "string" }
- { name: "height", label: "Hauteur de l'iframe (px)", widget: "number" }
- name: "settings"
label: "Paramètres du site"
@@ -356,6 +360,10 @@ collections:
- { name: "taglineHero", label: "Slogan hero", widget: "string" }
- { name: "phone", label: "Téléphone", widget: "string" }
- { name: "email", label: "Courriel", widget: "string" }
- { name: "emailFromContact", label: "Expéditeur courriel (formulaire contact, ex. Nom <adresse@domaine>)", widget: "string" }
- { name: "emailToContact", label: "Destinataire courriel (formulaire contact)", widget: "string" }
- { name: "fromAddressSubmission", label: "Expéditeur courriel (formulaire soumission, ex. Nom <adresse@domaine>)", widget: "string" }
- { name: "toAddressSubmission", label: "Destinataire courriel (formulaire soumission)", widget: "string" }
- { name: "address", label: "Adresse", widget: "string" }
- { name: "serviceArea", label: "Zone de service", widget: "string" }
- { name: "facebook", label: "Lien Facebook", widget: "string" }

Binary file not shown.

Before

Width:  |  Height:  |  Size: 152 KiB

After

Width:  |  Height:  |  Size: 525 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 202 KiB

After

Width:  |  Height:  |  Size: 287 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

View File

Before

Width:  |  Height:  |  Size: 127 KiB

After

Width:  |  Height:  |  Size: 127 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 127 KiB

After

Width:  |  Height:  |  Size: 633 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 219 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 126 KiB

After

Width:  |  Height:  |  Size: 198 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 164 KiB

After

Width:  |  Height:  |  Size: 227 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 65 KiB

After

Width:  |  Height:  |  Size: 223 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 152 KiB

After

Width:  |  Height:  |  Size: 138 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 202 KiB

After

Width:  |  Height:  |  Size: 134 KiB

View File

Before

Width:  |  Height:  |  Size: 65 KiB

After

Width:  |  Height:  |  Size: 65 KiB

View File

Before

Width:  |  Height:  |  Size: 83 KiB

After

Width:  |  Height:  |  Size: 83 KiB

View File

Before

Width:  |  Height:  |  Size: 74 KiB

After

Width:  |  Height:  |  Size: 74 KiB

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

Binary file not shown.

Before

Width:  |  Height:  |  Size: 149 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 459 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 47 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 339 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.0 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.3 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.4 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 427 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 131 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 204 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 202 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 82 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 282 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 410 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 223 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 298 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 226 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 227 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 173 KiB

Some files were not shown because too many files have changed in this diff Show More