Spaces:
Running
Running
Upload folder using huggingface_hub
Browse files- index.html +224 -234
index.html
CHANGED
|
@@ -4,10 +4,10 @@
|
|
| 4 |
<head>
|
| 5 |
<meta charset="UTF-8">
|
| 6 |
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
| 7 |
-
<title>AI Prompt
|
| 8 |
<link rel="preconnect" href="https://fonts.googleapis.com">
|
| 9 |
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
| 10 |
-
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap" rel="stylesheet">
|
| 11 |
<style>
|
| 12 |
:root {
|
| 13 |
--bg-body: #0f172a;
|
|
@@ -18,6 +18,7 @@
|
|
| 18 |
--primary: #3b82f6;
|
| 19 |
--primary-hover: #2563eb;
|
| 20 |
--accent: #10b981;
|
|
|
|
| 21 |
--border: #334155;
|
| 22 |
--shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);
|
| 23 |
--radius: 12px;
|
|
@@ -59,6 +60,9 @@
|
|
| 59 |
-webkit-background-clip: text;
|
| 60 |
-webkit-text-fill-color: transparent;
|
| 61 |
letter-spacing: -0.025em;
|
|
|
|
|
|
|
|
|
|
| 62 |
}
|
| 63 |
|
| 64 |
.anycoder-link {
|
|
@@ -79,12 +83,12 @@
|
|
| 79 |
/* Main Layout */
|
| 80 |
main {
|
| 81 |
flex: 1;
|
| 82 |
-
max-width:
|
| 83 |
margin: 0 auto;
|
| 84 |
width: 100%;
|
| 85 |
padding: 2rem;
|
| 86 |
display: grid;
|
| 87 |
-
grid-template-columns:
|
| 88 |
gap: 2rem;
|
| 89 |
}
|
| 90 |
|
|
@@ -137,7 +141,7 @@
|
|
| 137 |
|
| 138 |
textarea {
|
| 139 |
resize: vertical;
|
| 140 |
-
min-height:
|
| 141 |
}
|
| 142 |
|
| 143 |
input:focus,
|
|
@@ -186,6 +190,9 @@
|
|
| 186 |
display: flex;
|
| 187 |
justify-content: space-between;
|
| 188 |
align-items: center;
|
|
|
|
|
|
|
|
|
|
| 189 |
}
|
| 190 |
|
| 191 |
.status-badge {
|
|
@@ -198,7 +205,7 @@
|
|
| 198 |
|
| 199 |
.grid {
|
| 200 |
display: grid;
|
| 201 |
-
grid-template-columns: repeat(auto-fill, minmax(
|
| 202 |
gap: 1.5rem;
|
| 203 |
}
|
| 204 |
|
|
@@ -206,7 +213,7 @@
|
|
| 206 |
background-color: var(--bg-card);
|
| 207 |
border: 1px solid var(--border);
|
| 208 |
border-radius: var(--radius);
|
| 209 |
-
padding:
|
| 210 |
display: flex;
|
| 211 |
flex-direction: column;
|
| 212 |
transition: transform 0.2s, box-shadow 0.2s;
|
|
@@ -223,36 +230,51 @@
|
|
| 223 |
.card-header {
|
| 224 |
display: flex;
|
| 225 |
justify-content: space-between;
|
| 226 |
-
align-items:
|
| 227 |
-
|
|
|
|
|
|
|
| 228 |
}
|
| 229 |
|
| 230 |
.card-title {
|
| 231 |
-
font-size: 0.
|
| 232 |
font-weight: 700;
|
| 233 |
color: var(--primary);
|
| 234 |
text-transform: uppercase;
|
| 235 |
letter-spacing: 0.05em;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 236 |
}
|
| 237 |
|
| 238 |
.card-content {
|
| 239 |
-
|
| 240 |
-
|
| 241 |
-
border-radius: 8px;
|
| 242 |
-
font-family: 'Courier New', Courier, monospace;
|
| 243 |
font-size: 0.85rem;
|
| 244 |
color: #e2e8f0;
|
| 245 |
white-space: pre-wrap;
|
| 246 |
word-break: break-word;
|
| 247 |
-
max-height:
|
| 248 |
overflow-y: auto;
|
| 249 |
-
|
|
|
|
| 250 |
}
|
| 251 |
|
| 252 |
.card-actions {
|
| 253 |
-
|
|
|
|
| 254 |
display: flex;
|
| 255 |
justify-content: flex-end;
|
|
|
|
| 256 |
}
|
| 257 |
|
| 258 |
.btn-copy {
|
|
@@ -278,7 +300,7 @@
|
|
| 278 |
/* Empty State */
|
| 279 |
.empty-state {
|
| 280 |
text-align: center;
|
| 281 |
-
padding:
|
| 282 |
color: var(--text-muted);
|
| 283 |
border: 2px dashed var(--border);
|
| 284 |
border-radius: var(--radius);
|
|
@@ -316,6 +338,7 @@
|
|
| 316 |
opacity: 0;
|
| 317 |
transform: translateY(10px);
|
| 318 |
}
|
|
|
|
| 319 |
to {
|
| 320 |
opacity: 1;
|
| 321 |
transform: translateY(0);
|
|
@@ -347,13 +370,31 @@
|
|
| 347 |
padding: 1rem;
|
| 348 |
}
|
| 349 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 350 |
</style>
|
| 351 |
</head>
|
| 352 |
|
| 353 |
<body>
|
| 354 |
|
| 355 |
<header>
|
| 356 |
-
<div class="brand">
|
|
|
|
|
|
|
|
|
|
| 357 |
<a href="https://huggingface.co/spaces/akhaliq/anycoder" target="_blank" class="anycoder-link">Built with
|
| 358 |
anycoder</a>
|
| 359 |
</header>
|
|
@@ -371,15 +412,15 @@
|
|
| 371 |
</h2>
|
| 372 |
|
| 373 |
<div class="form-group">
|
| 374 |
-
<label for="productName">Nome do Produto</label>
|
| 375 |
-
<textarea id="productName" placeholder="e.g. Bermuda Viena Feminina em Algodão
|
| 376 |
-
<p class="helper-text">Inclua material, gênero e
|
| 377 |
</div>
|
| 378 |
|
| 379 |
<div class="form-group">
|
| 380 |
-
<label for="colorList">Lista de Cores</label>
|
| 381 |
-
<input type="text" id="colorList" placeholder="e.g. Green
|
| 382 |
-
<p class="helper-text">
|
| 383 |
</div>
|
| 384 |
|
| 385 |
<button class="btn-primary" id="generateBtn">Gerar Prompts</button>
|
|
@@ -388,7 +429,7 @@
|
|
| 388 |
<!-- Output Section -->
|
| 389 |
<section class="output-container">
|
| 390 |
<div class="results-header">
|
| 391 |
-
<h2>
|
| 392 |
<span class="status-badge" id="statusBadge">Aguardando entrada...</span>
|
| 393 |
</div>
|
| 394 |
|
|
@@ -406,41 +447,60 @@
|
|
| 406 |
|
| 407 |
<script>
|
| 408 |
// --- Constants & Templates ---
|
|
|
|
| 409 |
const TEMPLATES = [
|
| 410 |
{
|
|
|
|
| 411 |
title: "DETALHE DO PRODUTO",
|
|
|
|
| 412 |
content: `STRICT VISUAL MATCH TAKEN WITH IPHONE. 1:1 Square format. The subject is the EXACT "Bermuda Viena Feminina" in Linen and Cotton. The design must be IDENTICAL to the reference: high-waisted structure with precise vertical front seams (nervuras). A feminine hand is gently pinching the fabric on the front seam to display the exact ribbing detail and texture. Extreme close-up focus on the material weave and seam construction. Natural sunlight, casual Brazilian atmosphere, amateur raw photo style, beige color. DO NOT ALTER THE SILHOUETTE OR DETAILS. --ar 1:1 --style raw --v 6.0`
|
| 413 |
},
|
| 414 |
{
|
|
|
|
| 415 |
title: "DETALHE DO PRODUTO 2",
|
|
|
|
| 416 |
content: `Commercial macro photography, extreme close-up focus on fabric texture, women's high-waisted bermuda shorts made of premium linen and cotton blend, detailed visible front ribs/nervuras, natural beige color, soft diffused studio lighting to enhance fabric grain, tactile surface quality, shallow depth of field with bokeh neutral background, ultra-realistic, 8k resolution, shot on Sony A7R IV, 100mm macro lens, cinematic style, luxury e-commerce aesthetic, visible fiber details, no text, no watermark. --ar 4:5 --style raw --v 6.0`
|
| 417 |
},
|
| 418 |
{
|
|
|
|
| 419 |
title: "PESSOA USANDO",
|
|
|
|
| 420 |
content: `Square 1:1 photo taken on an iPhone, candid street photography style. A female model stands on a bright Brazilian street, neck down, wearing shorts that are an exact visual match to the reference image: High-waisted 'Bermuda Viena' made of Linen and Cotton. Key details: Prominent vertical front seams/ribs (nervuras frontais), structured high waist, and a textured natural fabric weave that looks like linen. The shorts fit is relaxed but tailored. The color is natural beige. The lighting is harsh natural sunlight typical of Brazil, emphasizing the fabric texture. Background is a blurred concrete wall or sidewalk. The shot is raw and unposed, focused on capturing the precise cut and design of the product.`
|
| 421 |
},
|
| 422 |
{
|
|
|
|
| 423 |
title: "PESSOA USANDO 2",
|
|
|
|
| 424 |
content: `A raw, candid square photo taken on an iPhone 15 Pro Max. STRICT VISUAL REPLICATION REQUIRED. The subject is wearing the EXACT 'Bermuda Viena Feminina' shorts. MUST FEATURE: High-waisted cut, distinctive vertical front ribs/nervuras seams running down the front, straight leg silhouette made of premium linen and cotton blend. The fabric texture is clearly visible, highlighting the natural earthy beige color and coarse weave. DO NOT ALTER THE DESIGN OR SILHOUETTE. Setting: Vibrant Brazilian urban street, textured white concrete wall, Portuguese stone sidewalk, intense midday sun casting sharp natural shadows. The vibe is effortless, tropical, and relaxed 'bem básico' style. High definition, authentic iPhone camera aesthetic, unposed, street photography style. --ar 1:1 --style raw --v 6.0`
|
| 425 |
},
|
| 426 |
{
|
|
|
|
| 427 |
title: "AVALIAÇÃO ESPELHO",
|
|
|
|
| 428 |
content: `Authentic Shopee-style customer review photo, raw vertical mirror selfie, 9:18 aspect ratio. A female model is standing in front of a bathroom mirror, framed from the neck up (no face visible, hiding face). She is wearing the EXACT "Bermuda Viena" high-waisted shorts. STRICT VISUAL FIDELITY: The shorts must feature the specific vertical front ribs/nervuras seams, linen and cotton fabric texture, beige color. The setting is a typical Brazilian home bathroom with natural ambient light. The image must look like a real amateur photo taken by a customer, realistic phone camera grain, showing the fit of the high waist and the straight leg cut. Candid, unposed, honest product demonstration. --ar 9:16 --style raw --v 6.0`
|
| 429 |
},
|
| 430 |
{
|
|
|
|
| 431 |
title: "AVALIAÇÃO CAMA",
|
|
|
|
| 432 |
content: `Authentic Brazilian Shopee customer review photo, raw vertical mobile shot, 9:16 aspect ratio. THE SCENE: A messy, unorganized pile of exactly 5 pairs of 'Bermuda Viena' shorts thrown casually across a bedroom bed. The shorts are fully unfolded and lying in a heap. COLOR CRITICAL: The pile must display the specific 5 colors from the product listing: Green, Khaki, White, Black, and Bege. STICT FIDELITY: Exact 'Bermuda Viena' model, high-waisted, vertical front ribs/nervuras, linen texture. LOGO: Brand tag visible. VIBE: Honest amateur photo, natural daylight, typical home setting, showing the variety of the purchase. --ar 9:16 --style raw --v 6.0`
|
| 433 |
},
|
| 434 |
{
|
|
|
|
| 435 |
title: "FOTO PRINCIPAL",
|
|
|
|
| 436 |
content: `Professional 1:1 square e-commerce product photograph featuring a charismatic, confident Brazilian woman standing behind a horizontal clothing rail. She has a warm, sun-kissed Brazilian complexion, natural hair texture, and distinctively Brazilian facial features. Her expression is authentic, engaging, and confident, with realistic human skin texture to avoid an artificial look. The rail displays exactly 5 identical pairs of "Bermuda Viena Feminina" shorts hanging perfectly flat, straight side-by-side, and FULLY UNCROPPED. STRICT DESIGN SPECIFICATIONS: The shorts must be exact replicas: high-waisted structure, distinctive vertical front ribs/nervuras seams, premium linen and cotton blend texture, straight leg cut. LOGO: A visible brand logo is present on the waistband or label of the shorts. COLOR PALETTE: Verde (Green), Cáqui (Khaki), Branco (White), Preto (Black), Beige. COMPOSITION: Hands gripping the rail, clear full view of all 5 shorts in the foreground without obstruction. BACKGROUND: Minimalist white studio backdrop, soft uniform lighting. Hyper-realistic texture focus, commercial catalog quality. --ar 1:1 --v 6.0 --style raw`
|
| 437 |
},
|
| 438 |
{
|
|
|
|
| 439 |
title: "TEXTO FOTO PRINCIPAL",
|
|
|
|
| 440 |
content: `Ensure the promotional text "Pague 3, Leve 5". Preserve exact original image position. Maintain flat lighting, no visible JPEG artifacts, Ultra-realistic, 8k resolution, photographic clarity, sharp focus, high fidelity textures, crisp details. Simple composition, use of symmetry, shallow depth of field, background blurred, leading lines created by clothes rack, no other objects, minimalist style. Add bold, sharp graphic text overlays seamlessly integrated without altering the photography subject.`
|
| 441 |
},
|
| 442 |
{
|
|
|
|
| 443 |
title: "SOMENTE O PRODUTO (PNG)",
|
|
|
|
| 444 |
content: `Professional product photography of exactly 5 identical copies of the source image product arranged in a tight horizontal row. COLOR PALETTE EXACT: The five shorts must display the following distinct colors: Green (Verde), Khaki (Cáki), White (Branco), Black (Preto), and Beige. The shorts are suspended in mid-air as if on invisible hangers, maintaining a stiff, perfectly straight structured shape. The legs are pressing tightly against each other with zero space or gaps between the items. NO HARDWARE: Absolutely no visible hangers, hooks, or strings, only the shorts floating. CRITICAL: The texture, fabric, stitching nervuras, and logo must be an exact duplication of the reference image provided. Product photography, pure white background, studio light. --ar 5:1 --style raw --iw 3`
|
| 445 |
}
|
| 446 |
];
|
|
@@ -448,24 +508,52 @@
|
|
| 448 |
// --- Logic Functions ---
|
| 449 |
|
| 450 |
/**
|
| 451 |
-
* Step 1:
|
| 452 |
*/
|
| 453 |
-
function
|
| 454 |
// 1. PRODUCT_NAME: Clean input
|
| 455 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 456 |
|
| 457 |
-
// 2. MATERIAL: Identify
|
| 458 |
const materialMap = {
|
| 459 |
'algodão': 'Cotton',
|
|
|
|
| 460 |
'linho': 'Linen',
|
| 461 |
'poliéster': 'Polyester',
|
|
|
|
| 462 |
'seda': 'Silk',
|
| 463 |
'jeans': 'Denim',
|
| 464 |
-
'denim': 'Denim'
|
|
|
|
| 465 |
};
|
| 466 |
|
| 467 |
-
let material = 'Cotton'; // Default
|
| 468 |
-
const lowerInput =
|
| 469 |
|
| 470 |
for (const [key, value] of Object.entries(materialMap)) {
|
| 471 |
if (lowerInput.includes(key)) {
|
|
@@ -476,232 +564,134 @@
|
|
| 476 |
|
| 477 |
// 3. TARGET_AUDIENCE
|
| 478 |
let gender = 'Female'; // Default
|
| 479 |
-
if (/masculina|masculino|homem|menino/i.test(
|
| 480 |
gender = 'Male';
|
| 481 |
}
|
| 482 |
|
| 483 |
-
// 4.
|
| 484 |
-
const
|
| 485 |
|
| 486 |
-
// 5. TOTAL_QUANTITY
|
| 487 |
-
|
| 488 |
-
|
| 489 |
-
|
| 490 |
-
if (explicitNumberMatch) {
|
| 491 |
-
quantity = parseInt(explicitNumberMatch[1], 10);
|
| 492 |
}
|
| 493 |
|
| 494 |
-
//
|
| 495 |
-
const
|
| 496 |
-
const
|
| 497 |
-
|
| 498 |
-
|
| 499 |
-
|
| 500 |
-
|
| 501 |
-
|
| 502 |
-
|
| 503 |
-
|
| 504 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 505 |
};
|
| 506 |
-
}
|
| 507 |
|
| 508 |
-
|
| 509 |
-
|
| 510 |
-
|
| 511 |
-
|
| 512 |
-
|
| 513 |
|
| 514 |
-
|
|
|
|
|
|
|
|
|
|
| 515 |
|
| 516 |
-
// Format
|
| 517 |
-
let
|
| 518 |
-
if (
|
| 519 |
-
|
| 520 |
-
} else if (
|
| 521 |
-
|
|
|
|
|
|
|
| 522 |
} else {
|
| 523 |
-
const last =
|
| 524 |
-
const rest =
|
| 525 |
-
|
| 526 |
}
|
| 527 |
|
| 528 |
return {
|
| 529 |
-
|
| 530 |
-
|
| 531 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 532 |
};
|
| 533 |
}
|
| 534 |
|
| 535 |
/**
|
| 536 |
-
* Step 3: Substitution
|
| 537 |
*/
|
| 538 |
-
function
|
| 539 |
-
|
| 540 |
-
let totalQuantity = productData.quantity;
|
| 541 |
-
if (totalQuantity === 0) {
|
| 542 |
-
totalQuantity = colorData.list.length > 0 ? colorData.list.length : 1;
|
| 543 |
-
}
|
| 544 |
|
| 545 |
-
|
| 546 |
-
const quantityString = totalQuantity.toString();
|
| 547 |
-
const pluralPairs = `${totalQuantity} pairs`;
|
| 548 |
-
const pluralCopies = `${totalQuantity} identical copies`;
|
| 549 |
-
|
| 550 |
-
const results = TEMPLATES.map(template => {
|
| 551 |
let text = template.content;
|
| 552 |
|
| 553 |
-
//
|
| 554 |
-
|
| 555 |
-
|
| 556 |
-
|
| 557 |
-
|
| 558 |
-
// 2. Replace Material
|
| 559 |
-
const matRegex = /linen and cotton/gi;
|
| 560 |
-
text = text.replace(matRegex, productData.material);
|
| 561 |
-
|
| 562 |
-
const blendRegex = /linen and cotton blend/gi;
|
| 563 |
-
text = text.replace(blendRegex, `${productData.material} blend`);
|
| 564 |
-
|
| 565 |
-
// 3. Replace Color List
|
| 566 |
-
text = text.replace(/Green, Khaki, White, Black, and Bege/g, colorData.formattedList);
|
| 567 |
-
|
| 568 |
-
// 4. Replace Singular Color
|
| 569 |
-
text = text.replace(/\bbeige\b/g, colorData.first);
|
| 570 |
-
|
| 571 |
-
// 5. Replace Quantity References
|
| 572 |
-
text = text.replace(/5 pairs/g, pluralPairs);
|
| 573 |
-
text = text.replace(/5 identical copies/g, pluralCopies);
|
| 574 |
-
|
| 575 |
-
if (template.title === "TEXTO FOTO PRINCIPAL") {
|
| 576 |
-
if (productData.promoText) {
|
| 577 |
-
text = text.replace(/"Pague 3, Leve 5"/g, `"${productData.promoText}"`);
|
| 578 |
-
text = text.replace(/Pague 3, Leve 5/g, productData.promoText);
|
| 579 |
-
} else {
|
| 580 |
-
text = text.replace(/Leve 5/g, `Leve ${quantityString}`);
|
| 581 |
-
}
|
| 582 |
} else {
|
| 583 |
-
|
| 584 |
-
|
| 585 |
-
|
| 586 |
-
text = text.replace(/exactly 5 pairs/g, `exactly ${pluralPairs}`);
|
| 587 |
-
text = text.replace(/exactly 5 identical/g, `exactly ${totalQuantity} identical`);
|
| 588 |
-
|
| 589 |
-
// 6. Gender Adaptation
|
| 590 |
-
if (productData.gender === 'Male') {
|
| 591 |
-
text = text.replace(/female model/g, 'male model');
|
| 592 |
-
text = text.replace(/women's/g, "men's");
|
| 593 |
-
text = text.replace(/\bwomen\b/g, 'men');
|
| 594 |
-
text = text.replace(/\bwoman\b/g, 'man');
|
| 595 |
-
text = text.replace(/feminine hand/g, 'masculine hand');
|
| 596 |
-
text = text.replace(/Brazilian woman/g, 'Brazilian man');
|
| 597 |
-
text = text.replace(/A female model/g, 'A male model');
|
| 598 |
}
|
| 599 |
|
| 600 |
-
|
| 601 |
-
title: template.title,
|
| 602 |
-
content: text
|
| 603 |
-
};
|
| 604 |
-
});
|
| 605 |
-
|
| 606 |
-
return results;
|
| 607 |
-
}
|
| 608 |
-
|
| 609 |
-
// --- UI Interactions ---
|
| 610 |
-
|
| 611 |
-
const generateBtn = document.getElementById('generateBtn');
|
| 612 |
-
const productNameInput = document.getElementById('productName');
|
| 613 |
-
const colorListInput = document.getElementById('colorList');
|
| 614 |
-
const resultsGrid = document.getElementById('resultsGrid');
|
| 615 |
-
const statusBadge = document.getElementById('statusBadge');
|
| 616 |
-
const toast = document.getElementById('toast');
|
| 617 |
-
|
| 618 |
-
function showToast(message) {
|
| 619 |
-
toast.textContent = message;
|
| 620 |
-
toast.classList.add('show');
|
| 621 |
-
setTimeout(() => {
|
| 622 |
-
toast.classList.remove('show');
|
| 623 |
-
}, 3000);
|
| 624 |
-
}
|
| 625 |
|
| 626 |
-
|
| 627 |
-
|
| 628 |
-
|
| 629 |
-
|
| 630 |
-
|
| 631 |
-
|
| 632 |
-
|
| 633 |
-
|
| 634 |
-
|
| 635 |
-
|
| 636 |
-
|
| 637 |
-
if (results.length === 0) {
|
| 638 |
-
resultsGrid.innerHTML = `<div class="empty-state" style="grid-column: 1 / -1;"><p>Nenhum resultado gerado.</p></div>`;
|
| 639 |
-
return;
|
| 640 |
-
}
|
| 641 |
-
|
| 642 |
-
results.forEach((item, index) => {
|
| 643 |
-
const card = document.createElement('div');
|
| 644 |
-
card.className = 'card';
|
| 645 |
-
card.style.animation = `fadeIn 0.5s ease forwards ${index * 0.1}s`;
|
| 646 |
-
card.style.opacity = '0'; // For animation
|
| 647 |
-
|
| 648 |
-
const header = document.createElement('div');
|
| 649 |
-
header.className = 'card-header';
|
| 650 |
-
|
| 651 |
-
const title = document.createElement('div');
|
| 652 |
-
title.className = 'card-title';
|
| 653 |
-
title.textContent = item.title;
|
| 654 |
-
|
| 655 |
-
header.appendChild(title);
|
| 656 |
-
|
| 657 |
-
const content = document.createElement('div');
|
| 658 |
-
content.className = 'card-content';
|
| 659 |
-
content.textContent = item.content;
|
| 660 |
-
|
| 661 |
-
const actions = document.createElement('div');
|
| 662 |
-
actions.className = 'card-actions';
|
| 663 |
-
|
| 664 |
-
const copyBtn = document.createElement('button');
|
| 665 |
-
copyBtn.className = 'btn-copy';
|
| 666 |
-
copyBtn.innerHTML = `
|
| 667 |
-
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="9" y="9" width="13" height="13" rx="2" ry="2"></rect><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"></path></svg>
|
| 668 |
-
Copiar
|
| 669 |
-
`;
|
| 670 |
-
copyBtn.onclick = () => copyToClipboard(item.content);
|
| 671 |
-
|
| 672 |
-
actions.appendChild(copyBtn);
|
| 673 |
-
card.appendChild(header);
|
| 674 |
-
card.appendChild(content);
|
| 675 |
-
card.appendChild(actions);
|
| 676 |
-
|
| 677 |
-
resultsGrid.appendChild(card);
|
| 678 |
-
});
|
| 679 |
-
}
|
| 680 |
-
|
| 681 |
-
generateBtn.addEventListener('click', () => {
|
| 682 |
-
const pName = productNameInput.value;
|
| 683 |
-
const cList = colorListInput.value;
|
| 684 |
-
|
| 685 |
-
if (!pName || !cList) {
|
| 686 |
-
showToast('Por favor, preencha ambos os campos.');
|
| 687 |
-
return;
|
| 688 |
-
}
|
| 689 |
-
|
| 690 |
-
// 1. Analyze Data
|
| 691 |
-
const pData = analyzeProductName(pName);
|
| 692 |
-
const cData = analyzeColors(cList);
|
| 693 |
-
|
| 694 |
-
// 2. Generate Prompts
|
| 695 |
-
const results = generatePrompts(pData, cData);
|
| 696 |
|
| 697 |
-
|
| 698 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 699 |
|
| 700 |
-
|
| 701 |
-
|
| 702 |
-
|
| 703 |
-
|
| 704 |
-
});
|
| 705 |
-
</script>
|
| 706 |
-
</body>
|
| 707 |
-
</html>
|
|
|
|
| 4 |
<head>
|
| 5 |
<meta charset="UTF-8">
|
| 6 |
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
| 7 |
+
<title>AI Prompt Gen | E-Commerce Specialist</title>
|
| 8 |
<link rel="preconnect" href="https://fonts.googleapis.com">
|
| 9 |
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
| 10 |
+
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&family=JetBrains+Mono:wght@400;500&display=swap" rel="stylesheet">
|
| 11 |
<style>
|
| 12 |
:root {
|
| 13 |
--bg-body: #0f172a;
|
|
|
|
| 18 |
--primary: #3b82f6;
|
| 19 |
--primary-hover: #2563eb;
|
| 20 |
--accent: #10b981;
|
| 21 |
+
--danger: #ef4444;
|
| 22 |
--border: #334155;
|
| 23 |
--shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);
|
| 24 |
--radius: 12px;
|
|
|
|
| 60 |
-webkit-background-clip: text;
|
| 61 |
-webkit-text-fill-color: transparent;
|
| 62 |
letter-spacing: -0.025em;
|
| 63 |
+
display: flex;
|
| 64 |
+
align-items: center;
|
| 65 |
+
gap: 0.5rem;
|
| 66 |
}
|
| 67 |
|
| 68 |
.anycoder-link {
|
|
|
|
| 83 |
/* Main Layout */
|
| 84 |
main {
|
| 85 |
flex: 1;
|
| 86 |
+
max-width: 1600px;
|
| 87 |
margin: 0 auto;
|
| 88 |
width: 100%;
|
| 89 |
padding: 2rem;
|
| 90 |
display: grid;
|
| 91 |
+
grid-template-columns: 400px 1fr;
|
| 92 |
gap: 2rem;
|
| 93 |
}
|
| 94 |
|
|
|
|
| 141 |
|
| 142 |
textarea {
|
| 143 |
resize: vertical;
|
| 144 |
+
min-height: 120px;
|
| 145 |
}
|
| 146 |
|
| 147 |
input:focus,
|
|
|
|
| 190 |
display: flex;
|
| 191 |
justify-content: space-between;
|
| 192 |
align-items: center;
|
| 193 |
+
border-bottom: 1px solid var(--border);
|
| 194 |
+
padding-bottom: 1rem;
|
| 195 |
+
margin-bottom: 1rem;
|
| 196 |
}
|
| 197 |
|
| 198 |
.status-badge {
|
|
|
|
| 205 |
|
| 206 |
.grid {
|
| 207 |
display: grid;
|
| 208 |
+
grid-template-columns: repeat(auto-fill, minmax(450px, 1fr));
|
| 209 |
gap: 1.5rem;
|
| 210 |
}
|
| 211 |
|
|
|
|
| 213 |
background-color: var(--bg-card);
|
| 214 |
border: 1px solid var(--border);
|
| 215 |
border-radius: var(--radius);
|
| 216 |
+
padding: 0;
|
| 217 |
display: flex;
|
| 218 |
flex-direction: column;
|
| 219 |
transition: transform 0.2s, box-shadow 0.2s;
|
|
|
|
| 230 |
.card-header {
|
| 231 |
display: flex;
|
| 232 |
justify-content: space-between;
|
| 233 |
+
align-items: center;
|
| 234 |
+
padding: 1rem 1.5rem;
|
| 235 |
+
border-bottom: 1px solid var(--border);
|
| 236 |
+
background-color: rgba(255, 255, 255, 0.02);
|
| 237 |
}
|
| 238 |
|
| 239 |
.card-title {
|
| 240 |
+
font-size: 0.85rem;
|
| 241 |
font-weight: 700;
|
| 242 |
color: var(--primary);
|
| 243 |
text-transform: uppercase;
|
| 244 |
letter-spacing: 0.05em;
|
| 245 |
+
display: flex;
|
| 246 |
+
align-items: center;
|
| 247 |
+
gap: 0.5rem;
|
| 248 |
+
}
|
| 249 |
+
|
| 250 |
+
.card-type {
|
| 251 |
+
font-size: 0.7rem;
|
| 252 |
+
padding: 2px 6px;
|
| 253 |
+
border-radius: 4px;
|
| 254 |
+
background: var(--bg-input);
|
| 255 |
+
color: var(--text-muted);
|
| 256 |
+
text-transform: uppercase;
|
| 257 |
}
|
| 258 |
|
| 259 |
.card-content {
|
| 260 |
+
padding: 1.5rem;
|
| 261 |
+
font-family: 'JetBrains Mono', monospace;
|
|
|
|
|
|
|
| 262 |
font-size: 0.85rem;
|
| 263 |
color: #e2e8f0;
|
| 264 |
white-space: pre-wrap;
|
| 265 |
word-break: break-word;
|
| 266 |
+
max-height: 400px;
|
| 267 |
overflow-y: auto;
|
| 268 |
+
background-color: rgba(0, 0, 0, 0.2);
|
| 269 |
+
flex: 1;
|
| 270 |
}
|
| 271 |
|
| 272 |
.card-actions {
|
| 273 |
+
padding: 0.75rem 1.5rem;
|
| 274 |
+
border-top: 1px solid var(--border);
|
| 275 |
display: flex;
|
| 276 |
justify-content: flex-end;
|
| 277 |
+
background-color: rgba(255, 255, 255, 0.02);
|
| 278 |
}
|
| 279 |
|
| 280 |
.btn-copy {
|
|
|
|
| 300 |
/* Empty State */
|
| 301 |
.empty-state {
|
| 302 |
text-align: center;
|
| 303 |
+
padding: 5rem 2rem;
|
| 304 |
color: var(--text-muted);
|
| 305 |
border: 2px dashed var(--border);
|
| 306 |
border-radius: var(--radius);
|
|
|
|
| 338 |
opacity: 0;
|
| 339 |
transform: translateY(10px);
|
| 340 |
}
|
| 341 |
+
|
| 342 |
to {
|
| 343 |
opacity: 1;
|
| 344 |
transform: translateY(0);
|
|
|
|
| 370 |
padding: 1rem;
|
| 371 |
}
|
| 372 |
}
|
| 373 |
+
|
| 374 |
+
/* Scrollbar styling */
|
| 375 |
+
::-webkit-scrollbar {
|
| 376 |
+
width: 8px;
|
| 377 |
+
}
|
| 378 |
+
::-webkit-scrollbar-track {
|
| 379 |
+
background: transparent;
|
| 380 |
+
}
|
| 381 |
+
::-webkit-scrollbar-thumb {
|
| 382 |
+
background: var(--border);
|
| 383 |
+
border-radius: 4px;
|
| 384 |
+
}
|
| 385 |
+
::-webkit-scrollbar-thumb:hover {
|
| 386 |
+
background: var(--text-muted);
|
| 387 |
+
}
|
| 388 |
</style>
|
| 389 |
</head>
|
| 390 |
|
| 391 |
<body>
|
| 392 |
|
| 393 |
<header>
|
| 394 |
+
<div class="brand">
|
| 395 |
+
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 2a10 10 0 1 0 10 10 4 4 0 0 1-5-5 4 4 0 0 1-5-5"></path><path d="M8.5 8.5v.01"></path><path d="M16 12l-2-2"></path><path d="M16 16l-2-2"></path><path d="M12 12l-2-2"></path><path d="M12 16l-2-2"></path></svg>
|
| 396 |
+
PromptGen AI
|
| 397 |
+
</div>
|
| 398 |
<a href="https://huggingface.co/spaces/akhaliq/anycoder" target="_blank" class="anycoder-link">Built with
|
| 399 |
anycoder</a>
|
| 400 |
</header>
|
|
|
|
| 412 |
</h2>
|
| 413 |
|
| 414 |
<div class="form-group">
|
| 415 |
+
<label for="productName">Nome do Produto (INPUT_PRODUCT_NAME)</label>
|
| 416 |
+
<textarea id="productName" placeholder="e.g. Bermuda Viena Feminina em Algodão High-Waisted Pague 3 Leve 5"></textarea>
|
| 417 |
+
<p class="helper-text">Inclua material, gênero, recursos estruturais e oferta promocional.</p>
|
| 418 |
</div>
|
| 419 |
|
| 420 |
<div class="form-group">
|
| 421 |
+
<label for="colorList">Lista de Cores (INPUT_COLORS)</label>
|
| 422 |
+
<input type="text" id="colorList" placeholder="e.g. Black/Grey/Blue/Green">
|
| 423 |
+
<p class="helper-text">Use vírgulas, barras ou + para separar (ex: Green, Khaki, White).</p>
|
| 424 |
</div>
|
| 425 |
|
| 426 |
<button class="btn-primary" id="generateBtn">Gerar Prompts</button>
|
|
|
|
| 429 |
<!-- Output Section -->
|
| 430 |
<section class="output-container">
|
| 431 |
<div class="results-header">
|
| 432 |
+
<h2>Resultados Gerados</h2>
|
| 433 |
<span class="status-badge" id="statusBadge">Aguardando entrada...</span>
|
| 434 |
</div>
|
| 435 |
|
|
|
|
| 447 |
|
| 448 |
<script>
|
| 449 |
// --- Constants & Templates ---
|
| 450 |
+
|
| 451 |
const TEMPLATES = [
|
| 452 |
{
|
| 453 |
+
id: "detail_1",
|
| 454 |
title: "DETALHE DO PRODUTO",
|
| 455 |
+
type: "SINGLE",
|
| 456 |
content: `STRICT VISUAL MATCH TAKEN WITH IPHONE. 1:1 Square format. The subject is the EXACT "Bermuda Viena Feminina" in Linen and Cotton. The design must be IDENTICAL to the reference: high-waisted structure with precise vertical front seams (nervuras). A feminine hand is gently pinching the fabric on the front seam to display the exact ribbing detail and texture. Extreme close-up focus on the material weave and seam construction. Natural sunlight, casual Brazilian atmosphere, amateur raw photo style, beige color. DO NOT ALTER THE SILHOUETTE OR DETAILS. --ar 1:1 --style raw --v 6.0`
|
| 457 |
},
|
| 458 |
{
|
| 459 |
+
id: "detail_2",
|
| 460 |
title: "DETALHE DO PRODUTO 2",
|
| 461 |
+
type: "SINGLE",
|
| 462 |
content: `Commercial macro photography, extreme close-up focus on fabric texture, women's high-waisted bermuda shorts made of premium linen and cotton blend, detailed visible front ribs/nervuras, natural beige color, soft diffused studio lighting to enhance fabric grain, tactile surface quality, shallow depth of field with bokeh neutral background, ultra-realistic, 8k resolution, shot on Sony A7R IV, 100mm macro lens, cinematic style, luxury e-commerce aesthetic, visible fiber details, no text, no watermark. --ar 4:5 --style raw --v 6.0`
|
| 463 |
},
|
| 464 |
{
|
| 465 |
+
id: "person_1",
|
| 466 |
title: "PESSOA USANDO",
|
| 467 |
+
type: "SINGLE",
|
| 468 |
content: `Square 1:1 photo taken on an iPhone, candid street photography style. A female model stands on a bright Brazilian street, neck down, wearing shorts that are an exact visual match to the reference image: High-waisted 'Bermuda Viena' made of Linen and Cotton. Key details: Prominent vertical front seams/ribs (nervuras frontais), structured high waist, and a textured natural fabric weave that looks like linen. The shorts fit is relaxed but tailored. The color is natural beige. The lighting is harsh natural sunlight typical of Brazil, emphasizing the fabric texture. Background is a blurred concrete wall or sidewalk. The shot is raw and unposed, focused on capturing the precise cut and design of the product.`
|
| 469 |
},
|
| 470 |
{
|
| 471 |
+
id: "person_2",
|
| 472 |
title: "PESSOA USANDO 2",
|
| 473 |
+
type: "SINGLE",
|
| 474 |
content: `A raw, candid square photo taken on an iPhone 15 Pro Max. STRICT VISUAL REPLICATION REQUIRED. The subject is wearing the EXACT 'Bermuda Viena Feminina' shorts. MUST FEATURE: High-waisted cut, distinctive vertical front ribs/nervuras seams running down the front, straight leg silhouette made of premium linen and cotton blend. The fabric texture is clearly visible, highlighting the natural earthy beige color and coarse weave. DO NOT ALTER THE DESIGN OR SILHOUETTE. Setting: Vibrant Brazilian urban street, textured white concrete wall, Portuguese stone sidewalk, intense midday sun casting sharp natural shadows. The vibe is effortless, tropical, and relaxed 'bem básico' style. High definition, authentic iPhone camera aesthetic, unposed, street photography style. --ar 1:1 --style raw --v 6.0`
|
| 475 |
},
|
| 476 |
{
|
| 477 |
+
id: "mirror",
|
| 478 |
title: "AVALIAÇÃO ESPELHO",
|
| 479 |
+
type: "SINGLE",
|
| 480 |
content: `Authentic Shopee-style customer review photo, raw vertical mirror selfie, 9:18 aspect ratio. A female model is standing in front of a bathroom mirror, framed from the neck up (no face visible, hiding face). She is wearing the EXACT "Bermuda Viena" high-waisted shorts. STRICT VISUAL FIDELITY: The shorts must feature the specific vertical front ribs/nervuras seams, linen and cotton fabric texture, beige color. The setting is a typical Brazilian home bathroom with natural ambient light. The image must look like a real amateur photo taken by a customer, realistic phone camera grain, showing the fit of the high waist and the straight leg cut. Candid, unposed, honest product demonstration. --ar 9:16 --style raw --v 6.0`
|
| 481 |
},
|
| 482 |
{
|
| 483 |
+
id: "bed",
|
| 484 |
title: "AVALIAÇÃO CAMA",
|
| 485 |
+
type: "GLOBAL",
|
| 486 |
content: `Authentic Brazilian Shopee customer review photo, raw vertical mobile shot, 9:16 aspect ratio. THE SCENE: A messy, unorganized pile of exactly 5 pairs of 'Bermuda Viena' shorts thrown casually across a bedroom bed. The shorts are fully unfolded and lying in a heap. COLOR CRITICAL: The pile must display the specific 5 colors from the product listing: Green, Khaki, White, Black, and Bege. STICT FIDELITY: Exact 'Bermuda Viena' model, high-waisted, vertical front ribs/nervuras, linen texture. LOGO: Brand tag visible. VIBE: Honest amateur photo, natural daylight, typical home setting, showing the variety of the purchase. --ar 9:16 --style raw --v 6.0`
|
| 487 |
},
|
| 488 |
{
|
| 489 |
+
id: "main",
|
| 490 |
title: "FOTO PRINCIPAL",
|
| 491 |
+
type: "GLOBAL",
|
| 492 |
content: `Professional 1:1 square e-commerce product photograph featuring a charismatic, confident Brazilian woman standing behind a horizontal clothing rail. She has a warm, sun-kissed Brazilian complexion, natural hair texture, and distinctively Brazilian facial features. Her expression is authentic, engaging, and confident, with realistic human skin texture to avoid an artificial look. The rail displays exactly 5 identical pairs of "Bermuda Viena Feminina" shorts hanging perfectly flat, straight side-by-side, and FULLY UNCROPPED. STRICT DESIGN SPECIFICATIONS: The shorts must be exact replicas: high-waisted structure, distinctive vertical front ribs/nervuras seams, premium linen and cotton blend texture, straight leg cut. LOGO: A visible brand logo is present on the waistband or label of the shorts. COLOR PALETTE: Verde (Green), Cáqui (Khaki), Branco (White), Preto (Black), Beige. COMPOSITION: Hands gripping the rail, clear full view of all 5 shorts in the foreground without obstruction. BACKGROUND: Minimalist white studio backdrop, soft uniform lighting. Hyper-realistic texture focus, commercial catalog quality. --ar 1:1 --v 6.0 --style raw`
|
| 493 |
},
|
| 494 |
{
|
| 495 |
+
id: "text_overlay",
|
| 496 |
title: "TEXTO FOTO PRINCIPAL",
|
| 497 |
+
type: "GLOBAL",
|
| 498 |
content: `Ensure the promotional text "Pague 3, Leve 5". Preserve exact original image position. Maintain flat lighting, no visible JPEG artifacts, Ultra-realistic, 8k resolution, photographic clarity, sharp focus, high fidelity textures, crisp details. Simple composition, use of symmetry, shallow depth of field, background blurred, leading lines created by clothes rack, no other objects, minimalist style. Add bold, sharp graphic text overlays seamlessly integrated without altering the photography subject.`
|
| 499 |
},
|
| 500 |
{
|
| 501 |
+
id: "png",
|
| 502 |
title: "SOMENTE O PRODUTO (PNG)",
|
| 503 |
+
type: "GLOBAL",
|
| 504 |
content: `Professional product photography of exactly 5 identical copies of the source image product arranged in a tight horizontal row. COLOR PALETTE EXACT: The five shorts must display the following distinct colors: Green (Verde), Khaki (Cáki), White (Branco), Black (Preto), and Beige. The shorts are suspended in mid-air as if on invisible hangers, maintaining a stiff, perfectly straight structured shape. The legs are pressing tightly against each other with zero space or gaps between the items. NO HARDWARE: Absolutely no visible hangers, hooks, or strings, only the shorts floating. CRITICAL: The texture, fabric, stitching nervuras, and logo must be an exact duplication of the reference image provided. Product photography, pure white background, studio light. --ar 5:1 --style raw --iw 3`
|
| 505 |
}
|
| 506 |
];
|
|
|
|
| 508 |
// --- Logic Functions ---
|
| 509 |
|
| 510 |
/**
|
| 511 |
+
* Step 1: Advanced Variable Extraction
|
| 512 |
*/
|
| 513 |
+
function extractData(productNameInput, colorsInput) {
|
| 514 |
// 1. PRODUCT_NAME: Clean input
|
| 515 |
+
// Remove promotional text for the core name, but keep it for PROMOTIONAL_OFFER extraction
|
| 516 |
+
// However, the prompt says "PRODUCT_NAME: The core product name (cleaned of promotional text)."
|
| 517 |
+
// We need to extract promo text first, then remove it.
|
| 518 |
+
|
| 519 |
+
let rawName = productNameInput.trim();
|
| 520 |
+
let promoOffer = null;
|
| 521 |
+
let totalQuantity = 0;
|
| 522 |
+
|
| 523 |
+
// Extract Promotional Offer (e.g., "Pague 3, Leve 5")
|
| 524 |
+
// Regex looks for "Pague X, Leve Y" variations
|
| 525 |
+
const promoRegex = /pague\s*\d+\s*(?:,|e)?\s*leve\s*\d+/i;
|
| 526 |
+
const promoMatch = rawName.match(promoRegex);
|
| 527 |
+
|
| 528 |
+
if (promoMatch) {
|
| 529 |
+
promoOffer = promoMatch[0];
|
| 530 |
+
// Extract Quantity from offer
|
| 531 |
+
const qtyMatch = promoOffer.match(/leve\s*(\d+)/i);
|
| 532 |
+
if (qtyMatch) {
|
| 533 |
+
totalQuantity = parseInt(qtyMatch[1], 10);
|
| 534 |
+
}
|
| 535 |
+
}
|
| 536 |
+
|
| 537 |
+
// Clean Product Name (Remove promo text)
|
| 538 |
+
let productName = rawName.replace(promoRegex, '').trim();
|
| 539 |
+
// Remove trailing commas or artifacts
|
| 540 |
+
productName = productName.replace(/,\s*$/, '').trim();
|
| 541 |
|
| 542 |
+
// 2. MATERIAL: Identify and translate
|
| 543 |
const materialMap = {
|
| 544 |
'algodão': 'Cotton',
|
| 545 |
+
'algodon': 'Cotton',
|
| 546 |
'linho': 'Linen',
|
| 547 |
'poliéster': 'Polyester',
|
| 548 |
+
'poliester': 'Polyester',
|
| 549 |
'seda': 'Silk',
|
| 550 |
'jeans': 'Denim',
|
| 551 |
+
'denim': 'Denim',
|
| 552 |
+
'couro': 'Leather'
|
| 553 |
};
|
| 554 |
|
| 555 |
+
let material = 'Cotton'; // Default
|
| 556 |
+
const lowerInput = rawName.toLowerCase(); // Check raw input for material keywords
|
| 557 |
|
| 558 |
for (const [key, value] of Object.entries(materialMap)) {
|
| 559 |
if (lowerInput.includes(key)) {
|
|
|
|
| 564 |
|
| 565 |
// 3. TARGET_AUDIENCE
|
| 566 |
let gender = 'Female'; // Default
|
| 567 |
+
if (/masculina|masculino|homem|menino|male/i.test(rawName)) {
|
| 568 |
gender = 'Male';
|
| 569 |
}
|
| 570 |
|
| 571 |
+
// 4. HAS_GIFTS
|
| 572 |
+
const hasGifts = /brinde|bônus|presente|bonus/i.test(rawName);
|
| 573 |
|
| 574 |
+
// 5. TOTAL_QUANTITY (Fallback if no promo offer)
|
| 575 |
+
if (totalQuantity === 0) {
|
| 576 |
+
// Will be calculated from color array later if 0
|
|
|
|
|
|
|
|
|
|
| 577 |
}
|
| 578 |
|
| 579 |
+
// 6. STRUCTURAL_FEATURES
|
| 580 |
+
const hasHighWaisted = /(?:high-waisted|alta cintura|cintura alta)/i.test(rawName);
|
| 581 |
+
const hasRibs = /(?:nervuras|ribs|costuras)/i.test(rawName);
|
| 582 |
+
|
| 583 |
+
// 7. COLORS
|
| 584 |
+
// Split delimiters (/, ,, or +)
|
| 585 |
+
const rawColors = colorsInput.split(/[\/,+]/).map(c => c.trim()).filter(c => c.length > 0);
|
| 586 |
+
|
| 587 |
+
// Color Translation Map
|
| 588 |
+
const colorMap = {
|
| 589 |
+
'verde': 'Green',
|
| 590 |
+
'vermelho': 'Red',
|
| 591 |
+
'azul': 'Blue',
|
| 592 |
+
'amarelo': 'Yellow',
|
| 593 |
+
'laranja': 'Orange',
|
| 594 |
+
'roxo': 'Purple',
|
| 595 |
+
'rosa': 'Pink',
|
| 596 |
+
'marrom': 'Brown',
|
| 597 |
+
'preto': 'Black',
|
| 598 |
+
'branco': 'White',
|
| 599 |
+
'cinza': 'Grey',
|
| 600 |
+
'grey': 'Grey',
|
| 601 |
+
'bege': 'Beige',
|
| 602 |
+
'khaki': 'Khaki',
|
| 603 |
+
'cáqui': 'Khaki',
|
| 604 |
+
'dourado': 'Gold',
|
| 605 |
+
'prata': 'Silver'
|
| 606 |
};
|
|
|
|
| 607 |
|
| 608 |
+
const colorArray = rawColors.map(c => {
|
| 609 |
+
const lowerC = c.toLowerCase();
|
| 610 |
+
// If it's already in the map, translate. Otherwise keep as is (assuming English or proper noun).
|
| 611 |
+
return colorMap[lowerC] || c;
|
| 612 |
+
});
|
| 613 |
|
| 614 |
+
// Calculate Total Quantity from colors if not set by promo
|
| 615 |
+
if (totalQuantity === 0) {
|
| 616 |
+
totalQuantity = colorArray.length > 0 ? colorArray.length : 1;
|
| 617 |
+
}
|
| 618 |
|
| 619 |
+
// Format List String (e.g., "Green, Khaki, White, Black, and Beige")
|
| 620 |
+
let colorListString = '';
|
| 621 |
+
if (colorArray.length === 0) {
|
| 622 |
+
colorListString = 'Assorted Colors';
|
| 623 |
+
} else if (colorArray.length === 1) {
|
| 624 |
+
colorListString = colorArray[0];
|
| 625 |
+
} else if (colorArray.length === 2) {
|
| 626 |
+
colorListString = `${colorArray[0]} and ${colorArray[1]}`;
|
| 627 |
} else {
|
| 628 |
+
const last = colorArray[colorArray.length - 1];
|
| 629 |
+
const rest = colorArray.slice(0, -1).join(', ');
|
| 630 |
+
colorListString = `${rest}, and ${last}`;
|
| 631 |
}
|
| 632 |
|
| 633 |
return {
|
| 634 |
+
productName,
|
| 635 |
+
material,
|
| 636 |
+
gender,
|
| 637 |
+
promoOffer,
|
| 638 |
+
totalQuantity,
|
| 639 |
+
hasGifts,
|
| 640 |
+
hasHighWaisted,
|
| 641 |
+
hasRibs,
|
| 642 |
+
colorArray,
|
| 643 |
+
colorListString
|
| 644 |
};
|
| 645 |
}
|
| 646 |
|
| 647 |
/**
|
| 648 |
+
* Step 2, 3, & 4: Logic, Substitution & Output Generation
|
| 649 |
*/
|
| 650 |
+
function generateFinalPrompts(data) {
|
| 651 |
+
let singleColorIndex = 0;
|
|
|
|
|
|
|
|
|
|
|
|
|
| 652 |
|
| 653 |
+
return TEMPLATES.map(template => {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 654 |
let text = template.content;
|
| 655 |
|
| 656 |
+
// --- Step 3: Color Distribution Logic ---
|
| 657 |
+
let assignedColor = '';
|
| 658 |
+
if (template.type === "GLOBAL") {
|
| 659 |
+
// Use Color List String
|
| 660 |
+
assignedColor = data.colorListString;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 661 |
} else {
|
| 662 |
+
// Use Unique Color Rotation
|
| 663 |
+
assignedColor = data.colorArray[singleColorIndex % data.colorArray.length] || 'Assorted';
|
| 664 |
+
singleColorIndex++;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 665 |
}
|
| 666 |
|
| 667 |
+
// --- Step 3: Template Substitution (Global Replacements) ---
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 668 |
|
| 669 |
+
// 1. Replace Product Name
|
| 670 |
+
// Replace "Bermuda Viena Feminina", "'Bermuda Viena'", "Bermuda Viena"
|
| 671 |
+
const nameVariations = [
|
| 672 |
+
/Bermuda Viena Feminina/g,
|
| 673 |
+
/'Bermuda Viena'/g,
|
| 674 |
+
/Bermuda Viena/g
|
| 675 |
+
];
|
| 676 |
+
nameVariations.forEach(regex => {
|
| 677 |
+
text = text.replace(regex, data.productName);
|
| 678 |
+
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 679 |
|
| 680 |
+
// 2. Replace Material
|
| 681 |
+
// "Linen and Cotton", "linen and cotton", "Linen", "Cotton"
|
| 682 |
+
// We replace the specific blend mention first, then individual if needed,
|
| 683 |
+
// but usually, we map the input material to the blend.
|
| 684 |
+
const matRegex = /linen and cotton/gi;
|
| 685 |
+
text = text.replace(matRegex, data.material);
|
| 686 |
+
|
| 687 |
+
// Also catch standalone "linen" or "cotton" if the input is just one
|
| 688 |
+
if (data.material === 'Linen') {
|
| 689 |
+
text = text.replace(/\bcotton\b/gi, 'Linen');
|
| 690 |
+
} else if (data.material === 'Cotton') {
|
| 691 |
+
text = text.replace(/\blinen\b/gi, 'Cotton');
|
| 692 |
+
}
|
| 693 |
|
| 694 |
+
// 3. Replace Quantity
|
| 695 |
+
// "5 pairs", "5 identical copies", "exactly 5 pairs"
|
| 696 |
+
const qStr = data.totalQuantity.toString();
|
| 697 |
+
text = text.replace(/5 pairs/g,
|
|
|
|
|
|
|
|
|
|
|
|