release: v2.5.0 - UI enhancements, pagination, and security
|
|
@ -7,6 +7,10 @@ const inter = Inter({ subsets: ["latin"] });
|
||||||
export const metadata: Metadata = {
|
export const metadata: Metadata = {
|
||||||
title: "kv-pix | AI Image Generator",
|
title: "kv-pix | AI Image Generator",
|
||||||
description: "Generate images with Google ImageFX (Whisk)",
|
description: "Generate images with Google ImageFX (Whisk)",
|
||||||
|
robots: {
|
||||||
|
index: false,
|
||||||
|
follow: false,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export default function RootLayout({
|
export default function RootLayout({
|
||||||
|
|
|
||||||
|
|
@ -164,8 +164,24 @@ export function PromptLibrary({ onSelect }: { onSelect?: (prompt: string) => voi
|
||||||
return filteredPrompts;
|
return filteredPrompts;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Pagination State
|
||||||
|
const [currentPage, setCurrentPage] = useState(1);
|
||||||
|
const [itemsPerPage, setItemsPerPage] = useState(24);
|
||||||
|
|
||||||
|
// Reset pagination when filters change
|
||||||
|
useEffect(() => {
|
||||||
|
setCurrentPage(1);
|
||||||
|
}, [searchTerm, selectedCategory, selectedSource, sortMode]);
|
||||||
|
|
||||||
const finalPrompts = displayPrompts();
|
const finalPrompts = displayPrompts();
|
||||||
|
|
||||||
|
// Pagination Logic
|
||||||
|
const totalPages = Math.ceil(finalPrompts.length / itemsPerPage);
|
||||||
|
const paginatedPrompts = finalPrompts.slice(
|
||||||
|
(currentPage - 1) * itemsPerPage,
|
||||||
|
currentPage * itemsPerPage
|
||||||
|
);
|
||||||
|
|
||||||
const uniqueCategories = ['All', ...Array.from(new Set(prompts.map(p => p.category)))].filter(Boolean);
|
const uniqueCategories = ['All', ...Array.from(new Set(prompts.map(p => p.category)))].filter(Boolean);
|
||||||
const uniqueSources = ['All', ...Array.from(new Set(prompts.map(p => p.source)))].filter(Boolean);
|
const uniqueSources = ['All', ...Array.from(new Set(prompts.map(p => p.source)))].filter(Boolean);
|
||||||
|
|
||||||
|
|
@ -237,23 +253,42 @@ export function PromptLibrary({ onSelect }: { onSelect?: (prompt: string) => voi
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Sub-Categories (only show if NOT history/foryou to keep clean? Or keep it?) */}
|
{/* Sub-Categories */}
|
||||||
{sortMode === 'all' && (
|
{sortMode === 'all' && (
|
||||||
<div className="flex flex-wrap gap-2">
|
<div className="flex flex-wrap gap-2 py-4 overflow-x-auto scrollbar-hide">
|
||||||
{uniqueCategories.map(cat => (
|
{(() => {
|
||||||
|
const priority = ['NAM', 'NỮ', 'SINH NHẬT', 'HALLOWEEN', 'NOEL', 'NEW YEAR', 'TRẺ EM', 'COUPLE', 'CHA - MẸ', 'MẸ BẦU', 'ĐẶC BIỆT'];
|
||||||
|
|
||||||
|
// Sort uniqueCategories (which only contains categories that exist in data)
|
||||||
|
const sortedCategories = uniqueCategories.sort((a, b) => {
|
||||||
|
if (a === 'All') return -1;
|
||||||
|
if (b === 'All') return 1;
|
||||||
|
|
||||||
|
const idxA = priority.indexOf(a);
|
||||||
|
const idxB = priority.indexOf(b);
|
||||||
|
|
||||||
|
if (idxA !== -1 && idxB !== -1) return idxA - idxB;
|
||||||
|
if (idxA !== -1) return -1;
|
||||||
|
if (idxB !== -1) return 1;
|
||||||
|
|
||||||
|
return a.localeCompare(b);
|
||||||
|
});
|
||||||
|
|
||||||
|
return sortedCategories.map(cat => (
|
||||||
<button
|
<button
|
||||||
key={cat}
|
key={cat}
|
||||||
onClick={() => setSelectedCategory(cat)}
|
onClick={() => setSelectedCategory(cat)}
|
||||||
className={cn(
|
className={cn(
|
||||||
"px-4 py-2 rounded-full text-sm font-medium transition-colors",
|
"px-4 py-2 text-sm font-bold uppercase tracking-wider transition-all duration-200 rounded-md whitespace-nowrap",
|
||||||
selectedCategory === cat
|
selectedCategory === cat
|
||||||
? "bg-primary text-primary-foreground"
|
? "bg-[#8B1E1E] text-white border border-white/80 shadow-[0_0_12px_rgba(139,30,30,0.6)]" // Active: Deep Red + Glow
|
||||||
: "bg-card hover:bg-secondary text-muted-foreground"
|
: "text-gray-400 hover:text-yellow-400 border border-transparent hover:bg-white/5" // Inactive: Yellow Hover
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
{cat}
|
{cat}
|
||||||
</button>
|
</button>
|
||||||
))}
|
));
|
||||||
|
})()}
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
|
@ -276,14 +311,38 @@ export function PromptLibrary({ onSelect }: { onSelect?: (prompt: string) => voi
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{/* Top Pagination Controls */}
|
||||||
|
{!loading && totalPages > 1 && (
|
||||||
|
<div className="flex items-center justify-end gap-2 py-2">
|
||||||
|
<span className="text-sm font-medium text-muted-foreground mr-2">
|
||||||
|
Page {currentPage} of {totalPages}
|
||||||
|
</span>
|
||||||
|
<button
|
||||||
|
onClick={() => setCurrentPage(p => Math.max(1, p - 1))}
|
||||||
|
disabled={currentPage === 1}
|
||||||
|
className="px-3 py-1 rounded-lg bg-secondary text-sm font-medium disabled:opacity-50 hover:bg-secondary/80 transition-colors"
|
||||||
|
>
|
||||||
|
Prev
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
onClick={() => setCurrentPage(p => Math.min(totalPages, p + 1))}
|
||||||
|
disabled={currentPage === totalPages}
|
||||||
|
className="px-3 py-1 rounded-lg bg-secondary text-sm font-medium disabled:opacity-50 hover:bg-secondary/80 transition-colors"
|
||||||
|
>
|
||||||
|
Next
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
{loading && !prompts.length ? (
|
{loading && !prompts.length ? (
|
||||||
<div className="flex justify-center py-20">
|
<div className="flex justify-center py-20">
|
||||||
<Loader2 className="h-8 w-8 animate-spin text-primary" />
|
<Loader2 className="h-8 w-8 animate-spin text-primary" />
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
|
<>
|
||||||
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
|
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
|
||||||
<AnimatePresence mode="popLayout">
|
<AnimatePresence mode="popLayout">
|
||||||
{finalPrompts.map((p) => (
|
{paginatedPrompts.map((p) => (
|
||||||
<motion.div
|
<motion.div
|
||||||
key={p.id}
|
key={p.id}
|
||||||
layout
|
layout
|
||||||
|
|
@ -339,6 +398,50 @@ export function PromptLibrary({ onSelect }: { onSelect?: (prompt: string) => voi
|
||||||
))}
|
))}
|
||||||
</AnimatePresence>
|
</AnimatePresence>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{/* Pagination Controls */}
|
||||||
|
{totalPages > 1 && (
|
||||||
|
<div className="flex flex-col sm:flex-row items-center justify-between gap-4 py-8 border-t mt-8">
|
||||||
|
<div className="flex items-center gap-2">
|
||||||
|
<span className="text-sm text-muted-foreground">Show:</span>
|
||||||
|
{[24, 48, 96].map(size => (
|
||||||
|
<button
|
||||||
|
key={size}
|
||||||
|
onClick={() => { setItemsPerPage(size); setCurrentPage(1); }}
|
||||||
|
className={cn(
|
||||||
|
"px-2 py-1 rounded text-xs font-medium transition-colors",
|
||||||
|
itemsPerPage === size
|
||||||
|
? "bg-primary text-primary-foreground"
|
||||||
|
: "bg-secondary text-muted-foreground hover:bg-secondary/80"
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
{size}
|
||||||
|
</button>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="flex items-center gap-2">
|
||||||
|
<button
|
||||||
|
onClick={() => setCurrentPage(p => Math.max(1, p - 1))}
|
||||||
|
disabled={currentPage === 1}
|
||||||
|
className="px-4 py-2 rounded-lg bg-secondary text-sm font-medium disabled:opacity-50 hover:bg-secondary/80 transition-colors"
|
||||||
|
>
|
||||||
|
Previous
|
||||||
|
</button>
|
||||||
|
<span className="text-sm font-medium text-muted-foreground">
|
||||||
|
Page {currentPage} of {totalPages}
|
||||||
|
</span>
|
||||||
|
<button
|
||||||
|
onClick={() => setCurrentPage(p => Math.min(totalPages, p + 1))}
|
||||||
|
disabled={currentPage === totalPages}
|
||||||
|
className="px-4 py-2 rounded-lg bg-secondary text-sm font-medium disabled:opacity-50 hover:bg-secondary/80 transition-colors"
|
||||||
|
>
|
||||||
|
Next
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{!loading && finalPrompts.length === 0 && (
|
{!loading && finalPrompts.length === 0 && (
|
||||||
|
|
|
||||||
18002
data/habu_prompts.json
Normal file
33908
data/prompts.json
|
|
@ -1,4 +1,36 @@
|
||||||
import { Prompt } from '@/lib/types';
|
import { Prompt } from '@/lib/types';
|
||||||
|
import fs from 'fs/promises';
|
||||||
|
import path from 'path';
|
||||||
|
|
||||||
|
export class HabuCrawler {
|
||||||
|
async crawl(): Promise<Prompt[]> {
|
||||||
|
console.log("[HabuCrawler] Reading from local data...");
|
||||||
|
const filePath = path.join(process.cwd(), 'data', 'habu_prompts.json');
|
||||||
|
try {
|
||||||
|
const data = await fs.readFile(filePath, 'utf-8');
|
||||||
|
const habuPrompts = JSON.parse(data);
|
||||||
|
|
||||||
|
return habuPrompts.map((p: any) => ({
|
||||||
|
id: 0, // Will be overwritten by sync service
|
||||||
|
title: p.name || 'Untitled Habu Prompt',
|
||||||
|
prompt: p.prompt,
|
||||||
|
category: 'Habu', // Default category since mapping is unknown
|
||||||
|
category_type: 'style',
|
||||||
|
description: p.prompt ? (p.prompt.substring(0, 150) + (p.prompt.length > 150 ? '...' : '')) : '',
|
||||||
|
images: p.imageUrl ? [p.imageUrl] : [],
|
||||||
|
author: 'Habu',
|
||||||
|
source: 'habu',
|
||||||
|
source_url: `https://taoanhez.com/#/prompt-library/${p.id}`,
|
||||||
|
createdAt: p.createdAt ? new Date(p.createdAt).getTime() : Date.now(),
|
||||||
|
useCount: 0
|
||||||
|
}));
|
||||||
|
} catch (e) {
|
||||||
|
console.error("[HabuCrawler] Error reading habu data", e);
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
export class JimmyLvCrawler {
|
export class JimmyLvCrawler {
|
||||||
async crawl(): Promise<Prompt[]> {
|
async crawl(): Promise<Prompt[]> {
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
import fs from 'fs/promises';
|
import fs from 'fs/promises';
|
||||||
import path from 'path';
|
import path from 'path';
|
||||||
import { Prompt, PromptCache } from '@/lib/types';
|
import { Prompt, PromptCache } from '@/lib/types';
|
||||||
import { JimmyLvCrawler, YouMindCrawler, ZeroLuCrawler } from '@/lib/crawler';
|
import { JimmyLvCrawler, YouMindCrawler, ZeroLuCrawler, HabuCrawler } from '@/lib/crawler';
|
||||||
|
|
||||||
const DATA_FILE = path.join(process.cwd(), 'data', 'prompts.json');
|
const DATA_FILE = path.join(process.cwd(), 'data', 'prompts.json');
|
||||||
|
|
||||||
|
|
@ -21,15 +21,17 @@ export async function syncPromptsService(): Promise<{ success: boolean, count: n
|
||||||
const jimmyCrawler = new JimmyLvCrawler();
|
const jimmyCrawler = new JimmyLvCrawler();
|
||||||
const youMindCrawler = new YouMindCrawler();
|
const youMindCrawler = new YouMindCrawler();
|
||||||
const zeroLuCrawler = new ZeroLuCrawler();
|
const zeroLuCrawler = new ZeroLuCrawler();
|
||||||
|
const habuCrawler = new HabuCrawler();
|
||||||
|
|
||||||
const [jimmyPrompts, youMindPrompts, zeroLuPrompts] = await Promise.all([
|
const [jimmyPrompts, youMindPrompts, zeroLuPrompts, habuPrompts] = await Promise.all([
|
||||||
jimmyCrawler.crawl(),
|
jimmyCrawler.crawl(),
|
||||||
youMindCrawler.crawl(),
|
youMindCrawler.crawl(),
|
||||||
zeroLuCrawler.crawl()
|
zeroLuCrawler.crawl(),
|
||||||
|
habuCrawler.crawl()
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const crawledPrompts = [...jimmyPrompts, ...youMindPrompts, ...zeroLuPrompts];
|
const crawledPrompts = [...jimmyPrompts, ...youMindPrompts, ...zeroLuPrompts, ...habuPrompts];
|
||||||
console.log(`[SyncService] Total crawled ${crawledPrompts.length} prompts (Jimmy: ${jimmyPrompts.length}, YouMind: ${youMindPrompts.length}, ZeroLu: ${zeroLuPrompts.length}).`);
|
console.log(`[SyncService] Total crawled ${crawledPrompts.length} prompts (Jimmy: ${jimmyPrompts.length}, YouMind: ${youMindPrompts.length}, ZeroLu: ${zeroLuPrompts.length}, Habu: ${habuPrompts.length}).`);
|
||||||
|
|
||||||
// 2. Read existing
|
// 2. Read existing
|
||||||
const cache = await getPrompts();
|
const cache = await getPrompts();
|
||||||
|
|
|
||||||
10
package-lock.json
generated
|
|
@ -1947,6 +1947,7 @@
|
||||||
"integrity": "sha512-N2clP5pJhB2YnZJ3PIHFk5RkygRX5WO/5f0WC08tp0wd+sv0rsJk3MqWn3CbNmT2J505a5336jaQj4ph1AdMug==",
|
"integrity": "sha512-N2clP5pJhB2YnZJ3PIHFk5RkygRX5WO/5f0WC08tp0wd+sv0rsJk3MqWn3CbNmT2J505a5336jaQj4ph1AdMug==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"undici-types": "~6.21.0"
|
"undici-types": "~6.21.0"
|
||||||
}
|
}
|
||||||
|
|
@ -1964,6 +1965,7 @@
|
||||||
"integrity": "sha512-cisd7gxkzjBKU2GgdYrTdtQx1SORymWyaAFhaxQPK9bYO9ot3Y5OikQRvY0VYQtvwjeQnizCINJAenh/V7MK2w==",
|
"integrity": "sha512-cisd7gxkzjBKU2GgdYrTdtQx1SORymWyaAFhaxQPK9bYO9ot3Y5OikQRvY0VYQtvwjeQnizCINJAenh/V7MK2w==",
|
||||||
"devOptional": true,
|
"devOptional": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@types/prop-types": "*",
|
"@types/prop-types": "*",
|
||||||
"csstype": "^3.2.2"
|
"csstype": "^3.2.2"
|
||||||
|
|
@ -2030,6 +2032,7 @@
|
||||||
"integrity": "sha512-3xP4XzzDNQOIqBMWogftkwxhg5oMKApqY0BAflmLZiFYHqyhSOxv/cd/zPQLTcCXr4AkaKb25joocY0BD1WC6A==",
|
"integrity": "sha512-3xP4XzzDNQOIqBMWogftkwxhg5oMKApqY0BAflmLZiFYHqyhSOxv/cd/zPQLTcCXr4AkaKb25joocY0BD1WC6A==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@typescript-eslint/scope-manager": "8.51.0",
|
"@typescript-eslint/scope-manager": "8.51.0",
|
||||||
"@typescript-eslint/types": "8.51.0",
|
"@typescript-eslint/types": "8.51.0",
|
||||||
|
|
@ -2619,6 +2622,7 @@
|
||||||
"integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==",
|
"integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
"bin": {
|
"bin": {
|
||||||
"acorn": "bin/acorn"
|
"acorn": "bin/acorn"
|
||||||
},
|
},
|
||||||
|
|
@ -3644,6 +3648,7 @@
|
||||||
"integrity": "sha512-LEyamqS7W5HB3ujJyvi0HQK/dtVINZvd5mAAp9eT5S/ujByGjiZLCzPcHVzuXbpJDJF/cxwHlfceVUDZ2lnSTw==",
|
"integrity": "sha512-LEyamqS7W5HB3ujJyvi0HQK/dtVINZvd5mAAp9eT5S/ujByGjiZLCzPcHVzuXbpJDJF/cxwHlfceVUDZ2lnSTw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@eslint-community/eslint-utils": "^4.8.0",
|
"@eslint-community/eslint-utils": "^4.8.0",
|
||||||
"@eslint-community/regexpp": "^4.12.1",
|
"@eslint-community/regexpp": "^4.12.1",
|
||||||
|
|
@ -3817,6 +3822,7 @@
|
||||||
"integrity": "sha512-whOE1HFo/qJDyX4SnXzP4N6zOWn79WhnCUY/iDR0mPfQZO8wcYE4JClzI2oZrhBnnMUCBCHZhO6VQyoBU95mZA==",
|
"integrity": "sha512-whOE1HFo/qJDyX4SnXzP4N6zOWn79WhnCUY/iDR0mPfQZO8wcYE4JClzI2oZrhBnnMUCBCHZhO6VQyoBU95mZA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@rtsao/scc": "^1.1.0",
|
"@rtsao/scc": "^1.1.0",
|
||||||
"array-includes": "^3.1.9",
|
"array-includes": "^3.1.9",
|
||||||
|
|
@ -6268,6 +6274,7 @@
|
||||||
"resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz",
|
"resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz",
|
||||||
"integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==",
|
"integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"loose-envify": "^1.1.0"
|
"loose-envify": "^1.1.0"
|
||||||
},
|
},
|
||||||
|
|
@ -6280,6 +6287,7 @@
|
||||||
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz",
|
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz",
|
||||||
"integrity": "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==",
|
"integrity": "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"loose-envify": "^1.1.0",
|
"loose-envify": "^1.1.0",
|
||||||
"scheduler": "^0.23.2"
|
"scheduler": "^0.23.2"
|
||||||
|
|
@ -7101,6 +7109,7 @@
|
||||||
"integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==",
|
"integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=12"
|
"node": ">=12"
|
||||||
},
|
},
|
||||||
|
|
@ -7280,6 +7289,7 @@
|
||||||
"integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==",
|
"integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
|
"peer": true,
|
||||||
"bin": {
|
"bin": {
|
||||||
"tsc": "bin/tsc",
|
"tsc": "bin/tsc",
|
||||||
"tsserver": "bin/tsserver"
|
"tsserver": "bin/tsserver"
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "v2_temp",
|
"name": "v2_temp",
|
||||||
"version": "0.1.0",
|
"version": "2.5.0",
|
||||||
"private": true,
|
"private": true,
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "next dev",
|
"dev": "next dev",
|
||||||
|
|
|
||||||
BIN
public/images/prompts/1.png
Normal file
|
After Width: | Height: | Size: 340 KiB |
BIN
public/images/prompts/10.png
Normal file
|
After Width: | Height: | Size: 381 KiB |
BIN
public/images/prompts/100.png
Normal file
|
After Width: | Height: | Size: 287 KiB |
BIN
public/images/prompts/1000.png
Normal file
|
After Width: | Height: | Size: 349 KiB |
BIN
public/images/prompts/1001.png
Normal file
|
After Width: | Height: | Size: 386 KiB |
BIN
public/images/prompts/1002.png
Normal file
|
After Width: | Height: | Size: 298 KiB |
BIN
public/images/prompts/1003.png
Normal file
|
After Width: | Height: | Size: 454 KiB |
BIN
public/images/prompts/1004.png
Normal file
|
After Width: | Height: | Size: 405 KiB |
BIN
public/images/prompts/1005.png
Normal file
|
After Width: | Height: | Size: 432 KiB |
BIN
public/images/prompts/1006.png
Normal file
|
After Width: | Height: | Size: 323 KiB |
BIN
public/images/prompts/1007.png
Normal file
|
After Width: | Height: | Size: 341 KiB |
BIN
public/images/prompts/1008.png
Normal file
|
After Width: | Height: | Size: 413 KiB |
BIN
public/images/prompts/1009.png
Normal file
|
After Width: | Height: | Size: 504 KiB |
BIN
public/images/prompts/101.png
Normal file
|
After Width: | Height: | Size: 398 KiB |
BIN
public/images/prompts/1010.png
Normal file
|
After Width: | Height: | Size: 483 KiB |
BIN
public/images/prompts/1011.png
Normal file
|
After Width: | Height: | Size: 257 KiB |
BIN
public/images/prompts/1012.png
Normal file
|
After Width: | Height: | Size: 412 KiB |
BIN
public/images/prompts/1013.png
Normal file
|
After Width: | Height: | Size: 348 KiB |
BIN
public/images/prompts/1014.png
Normal file
|
After Width: | Height: | Size: 337 KiB |
BIN
public/images/prompts/1015.png
Normal file
|
After Width: | Height: | Size: 242 KiB |
BIN
public/images/prompts/1016.png
Normal file
|
After Width: | Height: | Size: 432 KiB |
BIN
public/images/prompts/1017.png
Normal file
|
After Width: | Height: | Size: 373 KiB |
BIN
public/images/prompts/1018.png
Normal file
|
After Width: | Height: | Size: 443 KiB |
BIN
public/images/prompts/1019.png
Normal file
|
After Width: | Height: | Size: 361 KiB |
BIN
public/images/prompts/102.png
Normal file
|
After Width: | Height: | Size: 340 KiB |
BIN
public/images/prompts/1020.png
Normal file
|
After Width: | Height: | Size: 368 KiB |
BIN
public/images/prompts/1021.png
Normal file
|
After Width: | Height: | Size: 350 KiB |
BIN
public/images/prompts/1022.png
Normal file
|
After Width: | Height: | Size: 284 KiB |
BIN
public/images/prompts/1023.png
Normal file
|
After Width: | Height: | Size: 419 KiB |
BIN
public/images/prompts/1024.png
Normal file
|
After Width: | Height: | Size: 366 KiB |
BIN
public/images/prompts/1025.png
Normal file
|
After Width: | Height: | Size: 377 KiB |
BIN
public/images/prompts/1026.png
Normal file
|
After Width: | Height: | Size: 379 KiB |
BIN
public/images/prompts/1027.jpg
Normal file
|
After Width: | Height: | Size: 186 KiB |
BIN
public/images/prompts/1028.png
Normal file
|
After Width: | Height: | Size: 452 KiB |
BIN
public/images/prompts/1029.png
Normal file
|
After Width: | Height: | Size: 369 KiB |
BIN
public/images/prompts/103.png
Normal file
|
After Width: | Height: | Size: 422 KiB |
BIN
public/images/prompts/1030.png
Normal file
|
After Width: | Height: | Size: 383 KiB |
BIN
public/images/prompts/1031.png
Normal file
|
After Width: | Height: | Size: 457 KiB |
BIN
public/images/prompts/1032.png
Normal file
|
After Width: | Height: | Size: 379 KiB |
BIN
public/images/prompts/1033.png
Normal file
|
After Width: | Height: | Size: 462 KiB |
BIN
public/images/prompts/1034.png
Normal file
|
After Width: | Height: | Size: 384 KiB |
BIN
public/images/prompts/1035.png
Normal file
|
After Width: | Height: | Size: 456 KiB |
BIN
public/images/prompts/1036.png
Normal file
|
After Width: | Height: | Size: 407 KiB |
BIN
public/images/prompts/1037.png
Normal file
|
After Width: | Height: | Size: 429 KiB |
BIN
public/images/prompts/1038.png
Normal file
|
After Width: | Height: | Size: 398 KiB |
BIN
public/images/prompts/1039.png
Normal file
|
After Width: | Height: | Size: 453 KiB |
BIN
public/images/prompts/104.png
Normal file
|
After Width: | Height: | Size: 478 KiB |
BIN
public/images/prompts/1040.png
Normal file
|
After Width: | Height: | Size: 363 KiB |
BIN
public/images/prompts/1041.png
Normal file
|
After Width: | Height: | Size: 293 KiB |
BIN
public/images/prompts/1042.png
Normal file
|
After Width: | Height: | Size: 365 KiB |
BIN
public/images/prompts/1043.jpg
Normal file
|
After Width: | Height: | Size: 213 KiB |
BIN
public/images/prompts/1044.png
Normal file
|
After Width: | Height: | Size: 450 KiB |
BIN
public/images/prompts/1045.png
Normal file
|
After Width: | Height: | Size: 408 KiB |
BIN
public/images/prompts/1046.png
Normal file
|
After Width: | Height: | Size: 330 KiB |
BIN
public/images/prompts/1047.png
Normal file
|
After Width: | Height: | Size: 398 KiB |
BIN
public/images/prompts/1048.png
Normal file
|
After Width: | Height: | Size: 403 KiB |
BIN
public/images/prompts/1049.png
Normal file
|
After Width: | Height: | Size: 361 KiB |
BIN
public/images/prompts/105.png
Normal file
|
After Width: | Height: | Size: 383 KiB |
BIN
public/images/prompts/1050.png
Normal file
|
After Width: | Height: | Size: 367 KiB |
BIN
public/images/prompts/1051.png
Normal file
|
After Width: | Height: | Size: 393 KiB |
BIN
public/images/prompts/1052.png
Normal file
|
After Width: | Height: | Size: 377 KiB |
BIN
public/images/prompts/1053.png
Normal file
|
After Width: | Height: | Size: 463 KiB |
BIN
public/images/prompts/1054.png
Normal file
|
After Width: | Height: | Size: 460 KiB |
BIN
public/images/prompts/1055.png
Normal file
|
After Width: | Height: | Size: 264 KiB |
BIN
public/images/prompts/1056.png
Normal file
|
After Width: | Height: | Size: 373 KiB |
BIN
public/images/prompts/1057.png
Normal file
|
After Width: | Height: | Size: 255 KiB |
BIN
public/images/prompts/1058.png
Normal file
|
After Width: | Height: | Size: 375 KiB |
BIN
public/images/prompts/1059.png
Normal file
|
After Width: | Height: | Size: 427 KiB |
BIN
public/images/prompts/106.png
Normal file
|
After Width: | Height: | Size: 482 KiB |
BIN
public/images/prompts/1060.png
Normal file
|
After Width: | Height: | Size: 522 KiB |
BIN
public/images/prompts/1061.png
Normal file
|
After Width: | Height: | Size: 418 KiB |
BIN
public/images/prompts/1062.png
Normal file
|
After Width: | Height: | Size: 428 KiB |
BIN
public/images/prompts/1063.jpg
Normal file
|
After Width: | Height: | Size: 172 KiB |
BIN
public/images/prompts/1064.png
Normal file
|
After Width: | Height: | Size: 377 KiB |
BIN
public/images/prompts/1065.png
Normal file
|
After Width: | Height: | Size: 374 KiB |
BIN
public/images/prompts/1066.png
Normal file
|
After Width: | Height: | Size: 450 KiB |
BIN
public/images/prompts/1067.png
Normal file
|
After Width: | Height: | Size: 349 KiB |
BIN
public/images/prompts/1068.png
Normal file
|
After Width: | Height: | Size: 404 KiB |
BIN
public/images/prompts/1069.png
Normal file
|
After Width: | Height: | Size: 438 KiB |
BIN
public/images/prompts/107.png
Normal file
|
After Width: | Height: | Size: 378 KiB |
BIN
public/images/prompts/1070.png
Normal file
|
After Width: | Height: | Size: 456 KiB |
BIN
public/images/prompts/1071.png
Normal file
|
After Width: | Height: | Size: 466 KiB |
BIN
public/images/prompts/1072.png
Normal file
|
After Width: | Height: | Size: 462 KiB |
BIN
public/images/prompts/1073.png
Normal file
|
After Width: | Height: | Size: 438 KiB |
BIN
public/images/prompts/1074.png
Normal file
|
After Width: | Height: | Size: 472 KiB |
BIN
public/images/prompts/1075.png
Normal file
|
After Width: | Height: | Size: 494 KiB |
BIN
public/images/prompts/1076.png
Normal file
|
After Width: | Height: | Size: 426 KiB |
BIN
public/images/prompts/1077.png
Normal file
|
After Width: | Height: | Size: 425 KiB |
BIN
public/images/prompts/1078.png
Normal file
|
After Width: | Height: | Size: 462 KiB |
BIN
public/images/prompts/1079.png
Normal file
|
After Width: | Height: | Size: 387 KiB |
BIN
public/images/prompts/108.png
Normal file
|
After Width: | Height: | Size: 537 KiB |
BIN
public/images/prompts/1080.png
Normal file
|
After Width: | Height: | Size: 419 KiB |