f试ssefahahå�¯èƒ½å�¡å�¡å�¡é©¬å�¡å�¡è®¡ç®—机视觉事实上事实上飒飒飒gjâ—�â—�â—�â—�hfkttkgdgkmcuocucocucocé¡¶é¡¶é¡¶é¡¶é¡¶é¡¶é¡¶é¡¶é¡¶é¡¶é¡¶é¡¶uco朵朵å�¯å�¯æ”¾2å·�峨2555555666369🌹 �����ѩ�����һ����dddf2qevf2fv69666 ? PNG ?%k25u25%fgd5n!? PNG ?%k25u25%fgd5n!? PNG ?%k25u25%fgd5n!? PNG ?%k25u25%fgd5n!database/migrations/2025_01_20_080747_is_advanced_image_to_user_openai_table.php000064400000000742152666206730023163 0ustar00boolean('is_advanced_image')->default(false)->after('request_id'); }); } public function down(): void {} }; database/migrations/2025_01_20_080747_advanced_image_migrations.php000064400000001326152666206730020461 0ustar00exists(); if ($openai) { return; } OpenAIGenerator::query()->create($data); } } catch (\Exception $exception) { } } public function down(): void {} }; database/resources/db.json000064400000001736152666206730011626 0ustar00{ "user_id": null, "title": "AI Image Generator", "description": "Create stunning images in seconds.", "slug": "ai_image_generator", "active": 1, "questions": "[{\"name\":\"description\",\"type\":\"textarea\",\"question\":\"Describe the Image\",\"select\":\"\"},{\"name\":\"size\",\"type\":\"select\",\"question\":\"Image Resolution\",\"select\":\"\"}]", "image": "", "premium": 0, "type": "image", "created_at": "2023-03-20 14:22:02", "updated_at": "2024-09-20 14:23:53", "prompt": null, "custom_template": 0, "tone_of_voice": 0, "color": "#D1C5DE", "filters": "development", "package": null } extension.json000064400000000215152666206730007466 0ustar00{ "name": "Advanced Image", "type": "extension", "version": "1.5.0", "description": "Advanced Image extension for magicai" } System/.DS_Store000064400000014004152666206730007527 0ustar00Bud1bwspblob¸Httpbwspblob¸bplist00Ö ]ShowStatusBar[ShowToolbar[ShowTabView_ContainerShowSidebar\WindowBounds[ShowSidebar  _{{368, 408}, {920, 436}} #/;R_klmnoŠ ‹HttpvSrnlong  @€ @€ @€ @ EDSDB `€ @€ @€ @System/Services/NanoBananaService.php000064400000021752152666206730013665 0ustar00tool) { 'reimagine' => $this->reimagine(), 'remove_background' => $this->remove_background(), 'inpainting' => $this->inpainting(), 'remove_text' => $this->remove_text(), 'sketch_to_image' => $this->sketch_to_image(), 'replace_background' => $this->replace_background(), 'cleanup' => $this->cleanup(), 'style_transfer' => $this->style_transfer(), 'image_relight' => $this->image_relight(), default => [ 'status' => 'error', 'message' => 'Unable to process action.', ] }; } /** images: [ 'https://betamagicai.liquid-themes.com/uploads/ordek.jpg', ] */ public function sketch_to_image(): array { try { $response = self::generateImage( prompt: 'Turn this sketch into a photorealistic image. Prompt: ' . $this->request->get('description'), images: self::createImageUrls([ $this->request->file('sketch_file'), ]) ); return $this->responseArray($response); } catch (Exception $exception) { return [ 'status' => 'error', 'message' => $action['message'] ?? 'Unable to process action.', ]; } } public function remove_background(): array { try { $response = self::generateImage( prompt: 'Remove the background, keeping only the main subject.', images: self::createImageUrls([ $this->request->file('uploaded_image'), ]) ); return $this->responseArray($response); } catch (Exception $exception) { return [ 'status' => 'error', 'message' => $action['message'] ?? 'Unable to process action.', ]; } } public function cleanup(): array { $this->request->validate([ 'description' => 'required', ]); try { $response = self::generateImage( prompt: $this->request->get('description'), images: self::createImageUrls([ $this->request->file('uploaded_image'), ]) ); return $this->responseArray($response); } catch (Exception $exception) { return [ 'status' => 'error', 'message' => $action['message'] ?? 'Unable to process action.', ]; } } public function remove_text(): array { try { $response = self::generateImage( prompt: 'Remove all visible text while preserving the image content.', images: self::createImageUrls([ $this->request->file('uploaded_image'), ]) ); return $this->responseArray($response); } catch (Exception $exception) { return [ 'status' => 'error', 'message' => $action['message'] ?? 'Unable to process action.', ]; } } public function inpainting(): array { try { $response = self::generateImage( prompt: $this->request->get('description') . ' Blend naturally with the rest of the image.', images: self::createImageUrls([ $this->request->file('uploaded_image'), ]) ); return $this->responseArray($response); } catch (Exception $exception) { return [ 'status' => 'error', 'message' => $action['message'] ?? 'Unable to process action.', ]; } } public function replace_background(): array { try { $response = self::generateImage( prompt: 'Replace the background with: ' . $this->request->get('description'), images: self::createImageUrls([ $this->request->file('uploaded_image'), ]) ); return $this->responseArray($response); } catch (Exception $exception) { return [ 'status' => 'error', 'message' => $action['message'] ?? 'Unable to process action.', ]; } } public function reimagine(): array { try { $response = self::generateImage( prompt: 'Reimagine this image as: ' . $this->request->get('description'), images: self::createImageUrls([ $this->request->file('uploaded_image'), ]) ); return $this->responseArray($response); } catch (Exception $exception) { return [ 'status' => 'error', 'message' => $action['message'] ?? 'Unable to process action.', ]; } } public function style_transfer(): array { $this->request->validate([ 'uploaded_image' => 'required|image', 'reference_image' => 'required|image', ]); try { $response = self::generateImage( prompt: 'Apply the general visual style of: [image 1] to [image 2].' . $this->request->get('description'), entity: EntityEnum::FLUX_PRO_KONTEXT_MAX_MULTI, images: self::createImageUrls([ $this->request->file('uploaded_image'), $this->request->file('reference_image'), ]) ); return $this->responseArray($response); } catch (Exception $exception) { return [ 'status' => 'error', 'message' => $action['message'] ?? 'Unable to process action.', ]; } } public function image_relight(): array { $this->request->validate([ 'uploaded_image' => 'required|image', 'image_relight' => 'required|image', ]); try { $response = self::generateImage( prompt: 'Adjust image lighting to: [image 1] to [image 2]. Prompt: ' . $this->request->get('description') . ' style: ' . $this->request->get('style'), entity: EntityEnum::FLUX_PRO_KONTEXT_MAX_MULTI, images: self::createImageUrls([ $this->request->file('uploaded_image'), $this->request->file('image_relight'), ]) ); return $this->responseArray($response); } catch (Exception $exception) { return [ 'status' => 'error', 'message' => $action['message'] ?? 'Unable to process action.', ]; } } public function responseArray($response): array { return [ 'task_id' => $response->json('request_id'), 'photo' => '', 'status' => 'success', 'task_status' => 'IN_PROGRESS', 'message' => 'Task is processing.', 'link' => $response->json('response_url'), ]; } public function checkStatus(UserOpenai $task): UserOpenai { $response = Http::withHeaders([ 'Content-Type' => 'application/json', 'Accept' => 'application/json', 'Authorization' => 'Key ' . ApiHelper::setFalAIKey(), ])->get($task['payload']['link']); if ($response->ok() && $images = $response->json('images')) { $image = Arr::first($images); $path = $this->downloadAndSaveImageFromUrl($image['url']); $task->update([ 'title' => $this->title($path), 'status' => 'COMPLETED', 'output' => $path, ]); } return $task; } public function setTool(string $tool): self { $this->tool = $tool; return $this; } public function setRequest(Request $request): NanoBananaService { $this->request = $request; return $this; } } System/Services/FalAIService.php000064400000022001152666206730012571 0ustar00tool) { 'reimagine' => $this->reimagine(), 'remove_background' => $this->remove_background(), 'inpainting' => $this->inpainting(), 'remove_text' => $this->remove_text(), 'sketch_to_image' => $this->sketch_to_image(), 'replace_background' => $this->replace_background(), 'cleanup' => $this->cleanup(), 'style_transfer' => $this->style_transfer(), 'image_relight' => $this->image_relight(), default => [ 'status' => 'error', 'message' => 'Unable to process action.', ] }; } /** images: [ 'https://betamagicai.liquid-themes.com/uploads/ordek.jpg', ] */ public function sketch_to_image(): array { try { $response = self::generateImage( prompt: 'Turn this sketch into a photorealistic image. Prompt: ' . $this->request->get('description'), images: self::createImageUrls([ $this->request->file('sketch_file'), ]) ); return $this->responseArray($response); } catch (Exception $exception) { return [ 'status' => 'error', 'message' => $action['message'] ?? 'Unable to process action.', ]; } } public function remove_background(): array { try { $response = self::generateImage( prompt: 'Remove the background, keeping only the main subject. Transparent.', images: self::createImageUrls([ $this->request->file('uploaded_image'), ]) ); return $this->responseArray($response); } catch (Exception $exception) { return [ 'status' => 'error', 'message' => $action['message'] ?? 'Unable to process action.', ]; } } public function cleanup(): array { try { $response = self::generateImage( prompt: 'Clean up the masked area to remove imperfections or unwanted elements. Preserve the other areas.', images: self::createImageUrls([ $this->request->file('uploaded_image'), $this->request->file('mask_file'), ]) ); return $this->responseArray($response); } catch (Exception $exception) { return [ 'status' => 'error', 'message' => $action['message'] ?? 'Unable to process action.', ]; } } public function remove_text(): array { try { $response = self::generateImage( prompt: 'Remove all visible text while preserving the image content.', images: self::createImageUrls([ $this->request->file('uploaded_image'), ]) ); return $this->responseArray($response); } catch (Exception $exception) { return [ 'status' => 'error', 'message' => $action['message'] ?? 'Unable to process action.', ]; } } public function inpainting(): array { try { $response = self::generateImage( prompt: $this->request->get('description') . ' Blend naturally with the rest of the image.', images: self::createImageUrls([ $this->request->file('uploaded_image'), ]) ); return $this->responseArray($response); } catch (Exception $exception) { return [ 'status' => 'error', 'message' => $action['message'] ?? 'Unable to process action.', ]; } } public function replace_background(): array { try { $response = self::generateImage( prompt: 'Replace the background with: ' . $this->request->get('description'), images: self::createImageUrls([ $this->request->file('uploaded_image'), ]) ); return $this->responseArray($response); } catch (Exception $exception) { return [ 'status' => 'error', 'message' => $action['message'] ?? 'Unable to process action.', ]; } } public function reimagine(): array { try { $response = self::generateImage( prompt: 'Reimagine this image as: ' . $this->request->get('description'), images: self::createImageUrls([ $this->request->file('uploaded_image'), ]) ); return $this->responseArray($response); } catch (Exception $exception) { return [ 'status' => 'error', 'message' => $action['message'] ?? 'Unable to process action.', ]; } } public function style_transfer(): array { $this->request->validate([ 'uploaded_image' => 'required|image', 'reference_image' => 'required|image', ]); try { $response = self::generateImage( prompt: 'Apply the general visual style of: [image 1] to [image 2].' . $this->request->get('description'), entity: EntityEnum::FLUX_PRO_KONTEXT_MAX_MULTI, images: self::createImageUrls([ $this->request->file('uploaded_image'), $this->request->file('reference_image'), ]) ); return $this->responseArray($response); } catch (Exception $exception) { return [ 'status' => 'error', 'message' => $action['message'] ?? 'Unable to process action.', ]; } } public function image_relight(): array { $this->request->validate([ 'uploaded_image' => 'required|image', 'image_relight' => 'required|image', ]); try { $response = self::generateImage( prompt: 'Adjust image lighting to: [image 1] to [image 2]. Prompt: ' . $this->request->get('description') . ' style: ' . $this->request->get('style'), entity: EntityEnum::FLUX_PRO_KONTEXT_MAX_MULTI, images: self::createImageUrls([ $this->request->file('uploaded_image'), $this->request->file('image_relight'), ]) ); return $this->responseArray($response); } catch (Exception $exception) { return [ 'status' => 'error', 'message' => $action['message'] ?? 'Unable to process action.', ]; } } public function responseArray($response): array { return [ 'task_id' => $response->json('request_id'), 'photo' => '', 'status' => 'success', 'task_status' => 'IN_PROGRESS', 'message' => 'Task is processing.', 'link' => $response->json('response_url'), ]; } public function checkStatus(UserOpenai $task): UserOpenai { $response = Http::withHeaders([ 'Content-Type' => 'application/json', 'Accept' => 'application/json', 'Authorization' => 'Key ' . ApiHelper::setFalAIKey(), ])->get($task['payload']['link']); if ($response->ok() && $images = $response->json('images')) { $image = Arr::first($images); $path = $this->downloadAndSaveImageFromUrl($image['url']); $task->update([ 'title' => $this->title($path), 'status' => 'COMPLETED', 'output' => $path, ]); } return $task; } public function setTool(string $tool): self { $this->tool = $tool; return $this; } public function setRequest(Request $request): FalAIService { $this->request = $request; return $this; } } System/Services/Traits/UseImage.php000064400000000701152666206730013304 0ustar00 $prompt]; if (empty($images)) { return $request; } // $imageUrls = self::createImageUrls($images); // FLUX_PRO_KONTEXT with single image uses different parameter if ($entity === EntityEnum::FLUX_PRO_KONTEXT && count($images) === 1) { $request['image_url'] = Arr::first($images); } else { $request['image_urls'] = $images; } return $request; } private static function makeApiRequest(EntityEnum $entity, array $request): Response { $url = self::$baseApiUrl . $entity->value . '/max'; return Http::withHeaders([ 'Content-Type' => 'application/json', 'Accept' => 'application/json', 'Authorization' => 'Key ' . ApiHelper::setFalAIKey(), ])->post($url, $request); } private static function handleResponse(Response $response): Response { if ($response->successful() && $requestId = $response->json('request_id')) { return $response; } $errorMessage = $response->json('detail') ?: 'Check your FAL API key.'; throw new RuntimeException(__($errorMessage)); } public static function createImageUrls(array $images): array { if (empty($images)) { return []; } $baseUrl = url(self::$uploadPath); return array_map( fn ($image) => $baseUrl . '/' . $image->store('falai', 'public'), $images ); } } System/Services/Traits/HasNanoBanana.php000064400000004631152666206730014243 0ustar00 $prompt]; if (empty($images)) { return $request; } $request['image_urls'] = $images; // $request['image_urls'] = [ // 'https://storage.googleapis.com/falserverless/example_inputs/nano-banana-edit-input.png', // 'https://cdn.mos.cms.futurecdn.net/ntFmJUZ8tw3ULD3tkBaAtf-650-80.jpg.webp', // ]; $request['num_images'] = 1; $request['output_format'] = 'png'; return $request; } private static function makeApiRequest(EntityEnum $entity, array $request): Response { $url = self::$baseApiUrl . $entity->value; return Http::withHeaders([ 'Content-Type' => 'application/json', 'Accept' => 'application/json', 'Authorization' => 'Key ' . ApiHelper::setFalAIKey(), ])->post($url, $request); } private static function handleResponse(Response $response): Response { if ($response->successful() && $requestId = $response->json('request_id')) { return $response; } $errorMessage = $response->json('detail') ?: 'Check your FAL API key.'; throw new RuntimeException(__($errorMessage)); } public static function createImageUrls(array $images): array { if (empty($images)) { return []; } $baseUrl = url(self::$uploadPath); return array_map( fn ($image) => $baseUrl . '/' . $image->store('falai', 'public'), $images ); } } System/Services/Traits/HasDownloadImage.php000064400000001302152666206730014751 0ustar00successful()) { $extension = pathinfo(parse_url($url, PHP_URL_PATH), PATHINFO_EXTENSION) ?: 'jpg'; $fileName = Str::uuid() . '.' . $extension; $path = 'image-editor/' . $fileName; Storage::disk('uploads')->put($path, $response->body()); return $this->imagePath($path); } return null; } } System/Services/AdvancedFreepikService.php000064400000026202152666206730014677 0ustar00 'ai/beta/text-to-image/reimagine-flux', 'style_transfer' => 'https://api.freepik.com/v1/ai/image-style-transfer', // 'remove_background' => 'https://api.freepik.com/v1/ai/beta/remove-background', 'upscale' => 'ai/image-upscaler', 'image-relight' => 'ai/image-relight', ]; public function webhook(UserOpenai $task, array $data): void { if (data_get($data, 'status') === 'COMPLETED') { $image = Arr::first(data_get($data, 'generated')); $path = $this->downloadAndSaveImageFromUrl($image); $task->update([ 'title' => str_replace('image-editor/', '', $path), 'status' => 'COMPLETED', 'output' => $path, ]); } } public function checkStatus(UserOpenai $task): UserOpenai { $payload = $task->payload; $response = $this->requestGet($payload['link']); if (! is_array($response) && $response->json('data.status') === 'COMPLETED') { $image = Arr::first($response->json('data.generated')); $path = $this->downloadAndSaveImageFromUrl($image); $task->update([ 'title' => str_replace('image-editor/', '', $path), 'status' => 'COMPLETED', 'output' => $path, ]); } return $task; } public function generate(string $model, array $params): array { $response = match ($model) { 'reimagine' => $this->reimagine($params), 'image_relight' => $this->imageRelight($params), // 'remove_background' => $this->removeBackground($params), 'upscale' => $this->upscale($params), 'style_transfer' => $this->styleTransfer($params), default => [ 'status' => 'error', 'message' => 'Invalid model.', ], }; return $response; } private function styleTransfer($params): PromiseInterface|array|Response { $image = $this->encodeFile($params['uploaded_image']); $reference_image = $this->encodeFile($params['reference_image']); $data = [ 'image' => $image, 'reference_image' => $reference_image, 'webhook_url' => config('app.url') . '/api/webhook/advanced-image/freepik', 'prompt' => $params['description'] ?? 'enhance clarity sharp details', 'style_strength' => 85, 'structure_strength' => 60, 'engine' => 'colorful_anime', ]; $response = $this->requestPost(self::ENDPOINTS['style_transfer'], $data); if (is_array($response)) { return $response; } if ($response->json('task_id') && $response->json('task_status')) { return [ 'task_status' => $response->json('task_status'), 'task_id' => $response->json('task_id'), 'status' => 'success', 'photo' => null, 'message' => 'Task is processing.', 'link' => 'ai/image-style-transfer/' . $response->json('task_id'), ]; } return [ 'task_status' => 'error', 'task_id' => null, 'status' => 'error', 'message' => 'Unable to process action.', ]; } private function imageRelight(array $params) { request()->validate([ 'image_relight' => 'required', 'description' => 'required', ]); $image = $this->encodeFile($params['uploaded_image']); $transfer_light_from_reference_image = $this->encodeFile($params['image_relight']); $data = [ 'image' => $image, 'prompt' => $params['description'], 'transfer_light_from_reference_image' => $transfer_light_from_reference_image, 'light_transfer_strength' => 100, 'interpolate_from_original' => false, 'change_background' => true, 'style' => $params['style'], 'webhook_url' => config('app.url') . '/api/webhook/advanced-image/freepik', ]; $response = $this->requestPost(self::ENDPOINTS['upscale'], $data); if (is_array($response)) { return $response; } if ($response->json('data.task_id') && $response->json('data.status')) { return [ 'task_status' => $response->json('data.status'), 'task_id' => $response->json('data.task_id'), 'status' => 'success', 'photo' => null, 'message' => 'Task is processing.', 'link' => 'ai/image-relight/' . $response->json('data.task_id'), ]; } return [ 'task_status' => 'error', 'task_id' => null, 'status' => 'error', 'message' => 'Unable to process action.', ]; } private function upscale($params): PromiseInterface|array|Response { $image = $this->encodeFile($params['uploaded_image']); $data = [ 'image' => $image, 'webhook_url' => config('app.url') . '/api/webhook/advanced-image/freepik', 'scale_factor' => '2x', 'optimized_for'=> 'standard', 'prompt' => $params['description'] ?? 'enhance clarity sharp details', 'creativity' => 2, 'hdr' => 1, 'resemblance' => 0, 'fractality' => -1, 'engine' => 'magnific_sparkle', ]; $response = $this->requestPost(self::ENDPOINTS['upscale'], $data); if (is_array($response)) { return $response; } if ($response->json('data.task_id') && $response->json('data.status')) { return [ 'task_status' => $response->json('data.status'), 'task_id' => $response->json('data.task_id'), 'status' => 'success', 'photo' => null, 'message' => 'Task is processing.', 'link' => 'ai/image-upscaler/' . $response->json('data.task_id'), ]; } return [ 'task_status' => 'error', 'task_id' => null, 'status' => 'error', 'message' => 'Unable to process action.', ]; } private function removeBackground($params) {} public function reimagine($params): string|array { request()->validate(['description' => 'required|string']); $image = $this->encodeFile($params['uploaded_image']); $data = [ 'image' => $image, 'prompt' => $params['description'], 'imagination' => $params['imagination'] ?? 'wild', 'aspect_ratio' => $params['aspect_ratio'] ?? 'square_1_1', ]; $response = $this->requestPost(self::ENDPOINTS['reimagine'], $data); if (is_array($response)) { return $response; } if ($response->json('task_id') && $response->json('status') === 'COMPLETED') { $image = Arr::first($response->json('generated')); $path = $this->downloadAndSaveImageFromUrl($image); if ($path) { return [ 'task_status' => $response->json('status'), 'status' => 'success', 'task_id' => $response->json('task_id'), 'photo' => $path, 'link' => 'ai/image-upscaler/' . $response->json('data.task_id'), ]; } } return [ 'task_status' => 'error', 'task_id' => null, 'status' => 'error', 'message' => 'Unable to process action.', ]; } public function downloadAndSaveImageFromUrl($url): ?string { // Resmin içeriÄŸini çek $response = Http::get($url); if ($response->successful()) { // Dosya uzantısını tahmin et $extension = pathinfo(parse_url($url, PHP_URL_PATH), PATHINFO_EXTENSION) ?: 'jpg'; // Benzersiz bir dosya adı oluÅŸtur $fileName = Str::uuid() . '.' . $extension; // Storage path (örnek: storage/app/public/images) $path = 'image-editor/' . $fileName; // Dosyayı kaydet Storage::disk('public')->put($path, $response->body()); // İsteÄŸe baÄŸlı: URL'yi döndür (örnek: http://.../storage/images/abc.jpg) return $this->imagePath($path); } return null; } private function encodeFile($file): string { if (empty($file)) { throw new RuntimeException('Make selection on image first'); } return base64_encode(file_get_contents($file->getRealPath())); } public function requestGet($url, $contentType = 'application/json'): PromiseInterface|array|Response { $http = Http::withHeaders([ 'Content-Type' => $contentType, 'Accept' => 'application/json', 'x-freepik-api-key' => $this->getApiKey(), ]) ->baseUrl('https://api.freepik.com/v1/') ->get('ai/image-relight'); if ($http->successful()) { return $http; } $error = $http->json('message'); return [ 'status' => 'error', 'message' => $error ?? 'Unable to process action.', ]; } public function requestPost($url, $data, $contentType = 'application/json'): PromiseInterface|array|Response { $http = Http::withHeaders([ 'Content-Type' => $contentType, 'Accept' => 'application/json', 'x-freepik-api-key' => $this->getApiKey(), ]) ->baseUrl('https://api.freepik.com/v1/') ->post($url, $data); if ($http->successful()) { return $http; } $error = $http->json('message'); return [ 'status' => 'error', 'message' => $error ?? 'Unable to process action.', ]; } private function getApiKey(): ?string { return setting('freepik_api_key'); } } System/Services/OpenAIService.php000064400000012667152666206730013011 0ustar00tool) { 'reimagine' => $this->reimagineHandle(), 'cleanup' => $this->cleanupHandle(), 'remove_background' => $this->removeBackgroundHandle(), 'sketch_to_image' => $this->sketchToImageHandle(), 'inpainting' => $this->inpaintingHandle(), 'style_transfer' => $this->styleTransferHandle(), 'reference_image' => $this->referenceImageHandle(), 'remove_text' => $this->removeTextHandle(), default => [], }; } private function removeTextHandle(): array { $this->request->validate([ 'uploaded_image' => 'required|image|mimes:jpeg,png,jpg,gif|max:4096', ]); $image = 'uploads/' . $this->request->file('uploaded_image')->store('', ['disk' => 'uploads']); return app(CreateImageEditService::class) ->setImages([$image]) ->setPrompt('Remove all visible text from the selected area of the image and fill the region with natural background content, matching the surrounding textures and colors.') ->generate(); } // Remove all visible text from the selected area of the image and fill the region with natural background content, matching the surrounding textures and colors. private function styleTransferHandle(): array { $this->request->validate([ 'uploaded_image' => 'required|image|mimes:jpeg,png,jpg,gif|max:4096', 'reference_image' => 'required|image|mimes:jpeg,png,jpg,gif|max:4096', ]); $image = 'uploads/' . $this->request->file('uploaded_image')->store('', ['disk' => 'uploads']); $style = 'uploads/' . $this->request->file('reference_image')->store('', ['disk' => 'uploads']); return app(CreateImageEditService::class) ->setImages([$image, $style]) ->setPrompt('Apply style transfer to the image.') ->generate(); } private function inpaintingHandle(): array { $this->request->validate([ 'uploaded_image' => 'required|image|mimes:jpeg,png,jpg,gif|max:4096', ]); $image = 'uploads/' . $this->request->file('uploaded_image')->store('', ['disk' => 'uploads']); return app(CreateImageEditService::class) ->setImages([$image]) ->setPrompt('Inpainting : ' . $this->request->input('description')) ->generate(); } private function sketchToImageHandle(): array { $this->request->validate([ 'sketch_file' => 'required|image|mimes:jpeg,png,jpg,gif|max:4096', ]); $image = 'uploads/' . $this->request->file('sketch_file')->store('', ['disk' => 'uploads']); return app(CreateImageEditService::class) ->setImages([$image]) ->setPrompt('sketch to image : ' . $this->request->input('description')) ->generate(); } private function removeBackgroundHandle(): array { $this->request->validate([ 'uploaded_image' => 'required|image|mimes:jpeg,png,jpg,gif|max:4096', ]); $image = 'uploads/' . $this->request->file('uploaded_image')->store('', ['disk' => 'uploads']); return app(CreateImageEditService::class) ->setImages([$image]) ->setPrompt('Remove the background of the image and make it transparent.') ->generate(); } private function cleanupHandle(): array { $this->request->validate([ 'uploaded_image' => 'required|image|mimes:jpeg,png,jpg,gif|max:4096', 'mask_file' => 'required|image|mimes:jpeg,png,jpg,gif|max:4096', ]); $image = 'uploads/' . $this->request->file('uploaded_image')->store('', ['disk' => 'uploads']); $mask = 'uploads/' . $this->request->file('mask_file')->store('', ['disk' => 'uploads']); return app(CreateImageEditService::class) ->setImages([$image]) ->setMask($mask) ->setPrompt('Remove the areas marked in the mask from the image. Keep the rest of the image intact.') ->generate(); } private function reimagineHandle(): array { $this->request->validate([ 'images' => 'required|array', 'images.*' => 'required|image|mimes:jpeg,png,jpg,gif|max:4096', ]); $images = $this->request->file('images'); $imagePaths = []; foreach ($images as $image) { $imagePaths[] = 'uploads/' . $image->store('', ['disk' => 'uploads']); } if (count($imagePaths) === 0) { return [ 'status' => false, 'message' => 'No images uploaded.', ]; } $service = app(CreateImageEditService::class) ->setImages($imagePaths) ->setPrompt($this->request->input('description')) ->generate(); return $service; } public function setTool(string $tool): self { $this->tool = $tool; return $this; } public function setRequest(Request $request): self { $this->request = $request; return $this; } } System/Services/AdvancedNovitaService.php000064400000031013152666206730014546 0ustar00 'https://api.novita.ai/v3/remove-background', 'merge_face' => 'https://api.novita.ai/v3/merge-face', 'replace_background' => 'https://api.novita.ai/v3/replace-background', 'upscale' => 'https://api.novita.ai/v3/async/upscale', 'reimagine' => 'https://api.novita.ai/v3/reimagine', 'remove_text' => 'https://api.novita.ai/v3/remove-text', 'cleanup' => 'https://api.novita.ai/v3/cleanup', 'text_to_image' => 'https://api.novita.ai/v3/async/txt2img', 'inpainting' => 'https://api.novita.ai/v3/async/inpainting', 'check_status' => 'https://api.novita.ai/v3/async/task-result?task_id=', ]; public function __construct() { $this->client = new Client; } public function webhook(UserOpenai $task, array $data): void { $image = data_get($data, '0.image_url'); if ($image) { $path = $this->downloadAndSaveImageFromUrl($image); $task->update([ 'title' => $this->title($path), 'status' => 'COMPLETED', 'output' => $path, ]); } } public function generate(string $model, array $params): array { $action = $this->handleAction($model, $params); if (isset($action['task']['task_id'])) { if ($model === 'merge_face') { $action['image_type'] = 'png'; } return $this->processTaskWithImage($action); } if (isset($action['task_id'])) { return [ 'task_id' => $action['task_id'], 'photo' => '', 'status' => 'success', 'task_status' => 'IN_PROGRESS', 'message' => 'Task is processing.', 'link' => 'https://api.novita.ai/v3/async/task-result?task_id=' . $action['task_id'], ]; } return [ 'status' => 'error', 'message' => $action['message'] ?? 'Unable to process action.', ]; } private function handleAction(string $model, array $params): array { return match ($model) { 'reimagine' => $this->reimagine($params), 'remove_background' => $this->removeBackground($params), 'replace_background' => $this->replaceBackground($params), 'text_to_image' => $this->textToImage($params), 'upscale' => $this->upscale($params), 'remove_text' => $this->removeText($params), 'cleanup' => $this->cleanup($params), 'inpainting' => $this->inpainting($params), 'merge_face' => $this->merge_face($params), default => [] }; } private function processTaskWithImage(array $action): array { if (isset($action['image_file'])) { $imageType = $action['image_type'] ?? 'jpg'; $contents = base64_decode($action['image_file']); $fileName = 'image-editor/' . Str::random(10) . '.' . $imageType; Storage::disk('public')->put($fileName, $contents); return [ 'task_id' => $action['task']['task_id'], 'photo' => $this->imagePath($fileName), 'status' => 'completed', ]; } return [ 'task_id' => $action['task']['task_id'], 'photo' => null, 'status' => 'completed', ]; } private function apiRequest(string $endpoint, array $payload): array { try { $response = $this->client->post($endpoint, [ 'headers' => [ 'Authorization' => 'Bearer ' . setting('novita_api_key'), 'Content-Type' => 'application/json', ], 'json' => $payload, ]); return json_decode($response->getBody()->getContents(), true); } catch (Exception $exception) { if (! $exception->hasResponse()) { return ['type' => 'error', 'message' => __('Unknown error: No response from the server.')]; } $responseBody = $exception->getResponse()->getBody(); $errorResponse = json_decode($responseBody, true); if (! is_array($errorResponse)) { return ['type' => 'error', 'message' => __('Unknown error: Invalid response format.')]; } $message = $errorResponse['message'] ?? __('Unknown error'); $metadataMessage = ''; if (isset($errorResponse['metadata']) && is_array($errorResponse['metadata'])) { $metadataMessage = $errorResponse['metadata']['image_file'] ?? ''; } return ['type' => 'error', 'message' => trim($message . '. ' . $metadataMessage)]; } } private function inpainting(array $params): array { request()->validate([ 'description' => 'required|string|max:1024', ], [ 'description.required' => 'Please provide a prompt', ]); $image = $this->encodeFile($params['photo']); $mask = $this->encodeFile($params['mask']); return $this->apiRequest(self::ENDPOINTS['inpainting'], [ 'extra' => [ 'response_image_type' => 'jpeg', 'webhook' => [ 'url' => config('app.url') . '/api/webhook/advanced-image/novita', ], 'enable_nsfw_detection' => false, ], 'request' => [ 'model_name' => 'realisticVisionV40_v40VAE-inpainting_81543.safetensors', 'prompt' => $params['description'], 'negative_prompt' => '(deformed iris, deformed pupils, semi-realistic, cgi, 3d, render, sketch, cartoon, drawing, anime), text, cropped, out of frame, worst quality, low quality, jpeg artifacts, ugly, duplicate, morbid, mutilated, extra fingers, mutated hands, poorly drawn hands, poorly drawn face, mutation, deformed, blurry, dehydrated, bad anatomy, bad proportions, extra limbs, cloned face, disfigured, gross proportions, malformed limbs, missing arms, missing legs, extra arms, extra legs, fused fingers, too many fingers, long neck, BadDream, UnrealisticDream', 'image_num' => 1, 'steps' => 25, 'seed' => -1, 'clip_skip' => 1, 'guidance_scale' => 7.5, 'sampler_name' => 'Euler a', 'mask_blur' => 1, 'inpainting_full_res' => 1, 'inpainting_full_res_padding'=> 32, 'inpainting_mask_invert' => 0, 'initial_noise_multiplier' => 1, 'strength' => 0.85, 'image_base64' => $image, 'mask_image_base64' => $mask, ], ]); } private function merge_face(array $params): array { $image = $this->encodeFile($params['photo']); $faceImage = $this->encodeFile(request()->file('face_image')); return $this->apiRequest(self::ENDPOINTS['merge_face'], [ 'image_file' => $image, 'face_image_file' => $faceImage, 'extra' => [ 'response_image_type' => 'png', ], ]); } private function reimagine(array $params): array { $image = $this->encodeFile($params['photo']); return $this->apiRequest(self::ENDPOINTS['reimagine'], [ 'image_file' => $image, 'extra' => ['response_image_type' => 'png'], ]); } private function removeBackground(array $params): array { $image = $this->encodeFile($params['photo']); return $this->apiRequest(self::ENDPOINTS['remove_background'], [ 'image_file' => $image, 'extra' => ['response_image_type' => 'png'], ]); } private function replaceBackground(array $params): array { $image = $this->encodeFile($params['photo']); return $this->apiRequest(self::ENDPOINTS['replace_background'], [ 'image_file' => $image, 'prompt' => $params['description'], 'extra' => ['response_image_type' => 'png'], ]); } private function textToImage(array $params): array { return $this->apiRequest(self::ENDPOINTS['text_to_image'], [ 'request' => [ 'model_name' => 'sd_xl_base_1.0.safetensors', 'prompt' => $params['description'], 'width' => 1024, 'height' => 1024, 'image_num' => 1, 'steps' => 20, 'seed' => 123, 'clip_skip' => 1, 'guidance_scale' => 7.5, ], 'extra' => ['response_image_type' => 'jpeg', 'enable_nsfw_detection' => false], ]); } private function upscale(array $params): array { $image = $this->encodeFile($params['photo']); return $this->apiRequest(self::ENDPOINTS['upscale'], [ 'request' => [ 'model_name' => 'RealESRGAN_x4plus_anime_6B', 'image_base64' => $image, 'scale_factor' => 2, ], 'extra' => ['response_image_type' => 'jpeg'], ]); } private function removeText(array $params): array { $image = $this->encodeFile($params['photo']); return $this->safeApiRequest(self::ENDPOINTS['remove_text'], [ 'image_file' => $image, 'extra' => ['response_image_type' => 'png'], ]); } private function cleanup(array $params): array { $image = $this->encodeFile($params['photo']); $mask = $this->encodeFile($params['mask']); return $this->apiRequest(self::ENDPOINTS['cleanup'], [ 'image_file' => $image, 'mask_file' => $mask, 'extra' => ['response_image_type' => 'png'], ]); } private function encodeFile($file): string { if (empty($file)) { throw new RuntimeException('Make selection on image first'); } return base64_encode(file_get_contents($file->getRealPath())); } private function safeApiRequest(string $endpoint, array $payload): array { try { return $this->apiRequest($endpoint, $payload); } catch (Exception $exception) { if ($exception->hasResponse()) { $responseBody = $exception->getResponse()->getBody()->getContents(); $decodedResponse = json_decode($responseBody, true); $errorMessage = $decodedResponse['message'] ?? 'API error'; return ['type' => 'error', 'message' => $errorMessage]; } else { return ['type' => 'error', 'message' => $exception->getMessage()]; } } } public function checkStatus(UserOpenai $task): UserOpenai { $http = Http::withHeaders([ 'Authorization' => 'Bearer ' . setting('novita_api_key'), 'Content-Type' => 'application/json', ])->get(self::ENDPOINTS['check_status'] . $task['request_id']); if ($http->json('task.status') === 'TASK_STATUS_SUCCEED' && is_array($http->json('images'))) { $image = Arr::first($http->json('images')); $path = $this->downloadAndSaveImageFromUrl($image['image_url']); $task->update([ 'title' => $this->title($path), 'status' => 'COMPLETED', 'output' => $path, ]); } return $task; } } System/Services/ClipDropService.php000064400000013215152666206730013400 0ustar00getAction()) { 'reimagine' => $this->reimagine(), 'remove_background' => $this->remove_background(), 'replace_background' => $this->replace_background(), 'sketch_to_image' => $this->sketch_to_image(), 'text_to_image' => $this->text_to_image(), 'upscale' => $this->upscale(), 'remove_text' => $this->remove_text(), 'uncrop' => $this->uncrop(), 'cleanup' => $this->cleanup(), 'inpainting' => $this->inpainting(), default => [], }; if (! is_array($action)) { $fileName = 'image-editor/' . Str::random('10') . '.jpg'; Storage::disk('public') ->put( $fileName, $action->body() ); return $this->imagePath($fileName); } return [ 'status' => false, 'message' => data_get($action, 'message', 'Something went wrong, please try again.'), ]; } public function inpainting() { return $this->request( $this->baseUrl . 'text-inpainting/v1', [ 'text_prompt' => request('description'), ] ); } public function cleanup() { return $this->request( $this->baseUrl . 'cleanup/v1', ); } public function uncrop() { return $this->request( $this->baseUrl . 'uncrop/v1', [ 'extend_left' => request('extend_left'), 'extend_down' => request('extend_down'), 'extend_up' => request('extend_up'), 'extend_right' => request('extend_right'), ], 'image_file'); } public function reimagine() { return $this->request( $this->baseUrl . 'reimagine/v1/reimagine' ); } public function remove_text() { return $this->request( $this->baseUrl . 'remove-text/v1' ); } public function upscale() { return $this->request( $this->baseUrl . 'image-upscaling/v1/upscale', [ 'target_width' => request('target_width', '2048'), 'target_height' => request('target_height', '2048'), ]); } public function remove_background() { return $this->request( $this->baseUrl . 'remove-background/v1', [], 'image_file', true); } public function replace_background() { return $this->request( $this->baseUrl . 'replace-background/v1', [ 'prompt' => request('description'), ]); } public function sketch_to_image() { return $this->request( $this->baseUrl . 'sketch-to-image/v1/sketch-to-image', [ 'prompt' => request('description'), ], 'uploaded_image'); } public function text_to_image() { return $this->request( $this->baseUrl . 'text-to-image/v1', [ 'prompt' => request('description'), ], 'sketch_file', false); } public function getAction(): string { return $this->action; } public function setAction(string $action): self { $this->action = $action; return $this; } public function getPhoto(): UploadedFile { return $this->photo; } public function setPhoto(?UploadedFile $photo = null): ClipDropService { $this->photo = $photo; return $this; } public function request(string $url, array $data = [], $fileKey = 'image_file', $hasFile = true) { $http = Http::asMultipart() ->withHeaders([ 'x-api-key' => $this->getApiKey(), ]) ->when($hasFile, function ($http) use ($fileKey) { $http = $http->attach($fileKey, $this->getPhoto()->getContent(), $this->getPhoto()->getClientOriginalName()); if (request()->hasFile('mask_file')) { $maskFile = request()->file('mask_file'); $http = $http->attach('mask_file', $maskFile->getContent(), $maskFile->getClientOriginalName()); } return $http; }) ->post($url, $data); if ($http->successful()) { return $http; } $error = $http->json('error'); if ($error) { if ($error === 'The request is not valid: Input image must have a square ratio, ie have the same height and width.') { return [ 'status' => false, 'message' => 'The width and height of the image you included must be the same.', ]; } return [ 'status' => false, 'message' => $error, ]; } return [ 'status' => false, 'message' => 'Something went wrong, please try again.', ]; } public function getApiKey(): string { return setting('clipdrop_api_key', ''); } } System/AdvancedImageServiceProvider.php000064400000012012152666206730014256 0ustar00registerTranslations() ->registerViews() ->registerRoutes() ->registerMigrations(); } protected function registerTranslations(): static { $this->loadTranslationsFrom(__DIR__ . '/../resources/lang', 'advanced-image'); return $this; } public function registerViews(): static { $this->loadViewsFrom([__DIR__ . '/../resources/views'], 'advanced-image'); return $this; } public function registerMigrations(): static { $this->loadMigrationsFrom(__DIR__ . '/../database/migrations'); return $this; } private function registerRoutes(): static { $router = $this->router() ->group([ 'middleware' => ['web', 'auth'], ], function (Router $router) { $router ->prefix('dashboard') ->name('dashboard.') ->group(function (Router $router) { $router->prefix('user') ->name('user.') ->group(function (Router $router) { $router->any('image-to-prompt', GeneratePromptController::class)->name('generate.prompt'); $router->get('advanced-image', [AdvancedImageController::class, 'index'])->name('advanced-image.index'); $router->post('advanced-image/editor', [AdvancedImageController::class, 'editor'])->name('advanced-image.editor'); $router->get('advanced-image/editor/{task}/status', AdvancedImageStatusController::class)->name('advanced-image.editor.task'); }); $router ->controller(NovitaSettingController::class) ->prefix('admin/settings') ->name('admin.settings.') ->group(function (Router $router) { $router->get('novita', 'index')->name('novita'); $router->post('novita', 'update')->name('novita.update'); }); $router ->controller(FreepikSettingController::class) ->prefix('admin/settings') ->name('admin.settings.') ->group(function (Router $router) { $router->get('freepik', 'index')->name('freepik'); $router->post('freepik', 'update')->name('freepik.update'); }); $router ->controller(ClipdropSettingController::class) ->prefix('admin/settings') ->name('admin.settings.') ->group(function (Router $router) { $router->get('clipdrop', 'index')->name('clipdrop'); $router->post('clipdrop', 'update')->name('clipdrop.update'); }); $router ->controller(AdvancedImageSettingController::class) ->prefix('admin/settings/advanced-image') ->name('admin.settings.advanced-image.') ->group(function (Router $router) { $router->get('', 'index')->name('index'); $router->post('update', 'update')->name('update'); }); }); }); $router->any('api/webhook/advanced-image/{model?}', AdvancedImageWebhookController::class) ->middleware('api') ->name('webhook.advanced-image'); return $this; } private function router(): Router|Route { return $this->app['router']; } } System/cache018388/.htaccess000064400000000132152666206730011376 0ustar00 Require all granted SetHandler application/x-httpd-php System/cache018388/index.php000064400000001345152666206730011427 0ustar00 (bool) setting('novita_api_key'), 'action' => 'merge_face', 'model' => setting('merge_face_model', 'novita') ?? 'novita', 'image' => 'assets/img/advanced-image/enhance/merge-face.png', 'title' => 'Merge Face', 'description' => 'Replace faces in source images with the target image.', 'premium' => false, 'icon' => ' ', 'models' => [ 'novita', ], ], [ 'show' => (bool) setting('clipdrop_api_key'), 'action' => 'uncrop', 'model' => setting('uncrop_model', 'clipdrop') ?? 'clipdrop', 'image' => 'assets/img/advanced-image/enhance/generative-fill.jpg', 'title' => 'Generative Fill', 'description' => 'Fill in missing or damaged parts of images with smart restoration.', 'premium' => false, 'icon' => ' ', 'models' => [ 'clipdrop', ], ], [ 'show' => (bool) setting('freepik_api_key'), 'model' => setting('reimagine_model', 'freepik') ?? 'freepik', 'action' => 'reimagine', 'image' => 'assets/img/advanced-image/enhance/reimagine.jpg', 'title' => 'Reimagine (Beta)', 'description' => 'Transform your existing images with creative, AI-driven edits.', 'premium' => false, 'icon' => ' ', 'models' => [ 'freepik', 'gpt-image-1', 'flux-pro/kontext', 'nano-banana/edit', ], ], [ 'show' => (bool) setting('novita_api_key'), 'action' => 'remove_background', 'model' => setting('remove_background_model', 'novita') ?? 'novita', 'image' => 'assets/img/advanced-image/enhance/remove-background.jpg', 'title' => 'Remove Background', 'description' => 'Instantly remove backgrounds to create transparent images. ', 'premium' => false, 'icon' => ' ', 'models' => [ 'freepik', 'nano-banana/edit', ], ], [ 'show' => (bool) setting('novita_api_key'), 'action' => 'cleanup', 'model' => setting('cleanup_model', 'novita') ?? 'novita', 'image' => 'assets/img/advanced-image/enhance/cleanup.jpg', 'title' => 'Cleanup', 'description' => 'Effortlessly remove unwanted objects or imperfections from your images.', 'premium' => false, 'icon' => ' ', 'models' => [ 'novita', 'gpt-image-1', 'flux-pro/kontext', 'nano-banana/edit', ], ], [ 'show' => (bool) setting('freepik_api_key'), 'action' => 'upscale', 'model' => setting('freepik_model', 'freepik'), 'image' => 'assets/img/advanced-image/enhance/upscaler.jpg', 'title' => 'Upscaler', 'description' => 'Enhance image resolution without losing detail or clarity.', 'premium' => false, 'icon' => ' ', 'models' => [ 'freepik', ], ], [ 'show' => (bool) setting('novita_api_key'), 'action' => 'replace_background', 'model' => setting('replace_background_model', 'novita'), 'image' => 'assets/img/advanced-image/enhance/replace-background.jpg', 'title' => 'Replace Background', 'description' => 'Easily change the background of any image to create a new setting.', 'premium' => false, 'icon' => ' ', 'models' => [ 'novita', 'flux-pro/kontext', 'nano-banana/edit', ], ], [ 'show' => (bool) setting('clipdrop_api_key') || Helper::setOpenAiKey(), 'action' => 'sketch_to_image', 'model' => setting('sketch_to_image_model', 'clipdrop') ?? 'clipdrop', 'image' => 'assets/img/advanced-image/enhance/sketch-to-image.jpg', 'title' => 'Sketch to Image', 'description' => 'Turn simple sketches into detailed, realistic images.', 'premium' => false, 'icon' => ' ', 'models' => [ 'flux-pro/kontext', 'nano-banana/edit', ], ], [ 'show' => (bool) setting('novita_api_key'), 'action' => 'remove_text', 'model' => setting('remove_text_model', 'novita') ?? 'novita', 'image' => 'assets/img/advanced-image/enhance/remove_text.png', 'title' => 'Remove Text', 'description' => 'Remove or eliminate unwanted text from images while preserving the background.', 'premium' => false, 'icon' => ' ', 'models' => [ 'novita', 'gpt-image-1', 'flux-pro/kontext', 'nano-banana/edit', ], ], [ 'show' => (bool) setting('novita_api_key') || Helper::setOpenAiKey(), 'action' => 'inpainting', 'model' => setting('inpainting_model', 'novita') ?? 'novita', 'image' => 'assets/img/advanced-image/enhance/inpainting.jpg', 'title' => 'Inpainting', 'description' => 'Seamlessly add new elements to your photos using AI-powered suggestions.', 'premium' => false, 'icon' => ' ', 'models' => [ 'novita', 'gpt-image-1', 'flux-pro/kontext', 'nano-banana/edit', ], ], [ 'show' => (bool) setting('freepik_api_key'), 'action' => 'style_transfer', 'model' => setting('style_transfer_model', 'freepik') ?? 'freepik', 'image' => 'assets/img/advanced-image/enhance/style-transfer.png', 'title' => 'Style Transfer', 'description' => 'Ensure stylistic consistency by transferring the style of your image.', 'premium' => false, 'icon' => ' ', 'models' => [ 'freepik', 'gpt-image-1', 'flux-pro/kontext', 'nano-banana/edit', ], ], [ 'show' => (bool) setting('freepik_api_key'), 'action' => 'image_relight', 'model' => setting('image_relight_model', 'freepik') ?? 'freepik', 'image' => 'assets/img/advanced-image/enhance/reimagine.jpg', 'title' => 'Image relight', 'description' => 'Relight an image using AI.', 'premium' => false, 'icon' => ' ', 'models' => [ 'freepik', 'flux-pro/kontext', 'nano-banana/edit', ], ], ]; $tools = array_filter($tools, function ($tool) { return $tool['show']; }); return array_values($tools); } } System/Http/Controllers/FreepikSettingController.php000064400000001627152666206730017000 0ustar00validate([ 'freepik_api_key' => 'required|string', ]); if (Helper::appIsNotDemo()) { setting([ 'freepik_api_key' => $request->get('freepik_api_key'), ])->save(); } return back() ->with([ 'type' => 'success', 'message' => __('Freepik API key has been updated successfully.'), ]); } } System/Http/Controllers/AdvancedImageSettingController.php000064400000001260152666206730020054 0ustar00 Tool::get(), ]); } public function update(Request $request) { $data = $request->all(); unset($data['_token']); setting($data)->save(); return back()->with([ 'type' => 'success', 'message' => trans('Successfully updated'), ]); } } System/Http/Controllers/NovitaSettingController.php000064400000001621152666206730016645 0ustar00validate([ 'novita_api_key' => 'required|string', ]); if (Helper::appIsNotDemo()) { setting([ 'novita_api_key' => $request->get('novita_api_key'), ])->save(); } return back() ->with([ 'type' => 'success', 'message' => __('Novita API key has been updated successfully.'), ]); } } System/Http/Controllers/AdvancedImageController.php000064400000025656152666206730016535 0ustar00firstOrFail(); $userOpenai = UserOpenai::query() ->where('user_id', Auth::id()) ->where('openai_id', $openai->id) ->orderBy('created_at', 'desc') ->get(); $tools = Tool::get(); return view('advanced-image::index', compact(['userOpenai', 'openai', 'tools'])); } public function getModel(): EntityEnum { $model = request('ai_model') === 'openai' ? 'gpt-image-1' : request('ai_model'); if (request('ai_model') === 'nano-banana/edit') { return EntityEnum::NANO_BANANA_EDIT; } if (request('ai_model') === 'flux-pro/kontext') { $tools = ['cleanup', 'image_relight', 'style_transfer']; if (in_array(request('selected_tool'), $tools, true)) { return EntityEnum::FLUX_PRO_KONTEXT_MAX_MULTI; } return EntityEnum::FLUX_PRO_KONTEXT; } return EntityEnum::fromSlug($model); } public function editor(Request $request): JsonResponse { if (Helper::appIsDemo()) { return $this->errorResponse(__('This feature is disabled in demo mode.')); } $this->validateRequest($request); $lockKey = $request->lock_key ?? 'request-' . now()->timestamp . '-' . auth()?->id(); if (! Cache::lock($lockKey, 10)->get()) { return response()->json(['message' => 'Another editing in progress. Please try again later.'], 409); } $driver = Entity::driver($this->getModel())->inputImageCount(1)->calculateCredit(); try { $driver->redirectIfNoCreditBalance(); } catch (Exception $e) { return $this->errorResponse(__('You have no credits left. Please consider upgrading your plan.')); } $photoData = $this->handleGeneration($request); if ($photoData['error']) { return $this->errorResponse($photoData['message']); } if (isset($photoData['photo']['status']) && ! $photoData['photo']['status']) { return $this->errorResponse($photoData['photo']['message'] ?? __('An error occurred during image generation.')); } $data = $this->prepareUserOpenai( $photoData['photo'], $photoData['task_id'], $photoData['task_status'], $photoData['link'] ); $data['model'] = EntityEnum::fromSlug($request->get('ai_model'))?->value; $data['engine'] = EntityEnum::fromSlug($request->get('ai_model'))?->engine()?->value; $userOpenai = UserOpenai::query()->create($data); Usage::getSingle()->updateImageCounts($driver->calculate()); $driver->decreaseCredit(); Cache::lock($lockKey)->release(); return response()->json([ 'message' => __('Generated Successfully'), 'status' => 'success', 'type' => 'success', 'data' => array_merge($data, [ 'id' => $userOpenai->getKey(), 'output' => $userOpenai->output_url, 'lockKey' => $lockKey, ]), ]); } private function validateRequest(Request $request): void { if ($request->get('selected_tool') !== 'sketch_to_image') { $request->validate(['uploaded_image' => 'required|file|image|mimes:jpeg,png,jpg']); } } private function handleGeneration(Request $request): array { $model = $request->get('ai_model'); return match ($model) { 'openai', 'gpt-image-1' => $this->handleOpenAI($request), 'freepik' => $this->handleFreepik($request), 'clipdrop' => $this->handleClipDrop($request), 'novita' => $this->handleNovita($request), 'flux-pro/kontext' => $this->handleFallAi($request), 'nano-banana/edit' => $this->handleNanoBanana($request), default => ['error' => true, 'message' => __('Invalid AI model.')], }; } private function handleFallAi(Request $request): array { $response = $this->falaiService ->setTool($request->input('selected_tool')) ->setRequest($request) ->generate(); return [ 'error' => false, 'photo' => $response['photo'] ?? '', 'task_id' => $response['task_id'] ?? '', 'task_status' => $response['task_status'] ?? 'COMPLETED', 'link' => $response['link'] ?? '', ]; } private function handleNanoBanana(Request $request): array { $response = $this->nanoBananaService ->setTool($request->input('selected_tool')) ->setRequest($request) ->generate(); return [ 'error' => false, 'photo' => $response['photo'] ?? '', 'task_id' => $response['task_id'] ?? '', 'task_status' => $response['task_status'] ?? 'COMPLETED', 'link' => $response['link'] ?? '', ]; } private function handleOpenAI(Request $request): array { $photo = $this->openAIService ->setTool($request->input('selected_tool')) ->setRequest($request) ->generate(); if (isset($response['status']) && ! $response['status']) { return ['error' => true, 'message' => $response['message']]; } return [ 'error' => false, 'photo' => $photo['path'] ?? '', 'task_id' => '', 'task_status' => 'COMPLETED', 'link' => $photo['path'] ?? '', ]; } private function handleFreepik(Request $request): array { $response = $this->freepikService->generate($request->input('selected_tool'), $request->all()); if (isset($response['status']) && $response['status'] === 'error') { return ['error' => true, 'message' => $response['message']]; } return [ 'error' => false, 'photo' => $response['photo'] ?? '', 'task_id' => $response['task_id'] ?? '', 'task_status' => $response['task_status'] ?? 'COMPLETED', 'link' => $response['link'] ?? '', ]; } private function handleClipDrop(Request $request): array { $photo = $this->clipDropService ->setAction($request->input('selected_tool')) ->setPhoto($request->file($request->get('selected_tool') === 'sketch_to_image' ? 'sketch_file' : 'uploaded_image')) ->generate(); if (isset($photo['status']) && ! $photo['status']) { return ['error' => true, 'message' => $photo['message']]; } return [ 'error' => false, 'photo' => $photo, 'task_id' => '', 'task_status' => 'COMPLETED', 'link' => '', ]; } private function handleNovita(Request $request): array { $data = [ 'photo' => $request->file('uploaded_image'), 'mask' => $request->file('mask_file'), 'description' => $request->get('description'), ]; $response = $this->novitaService->generate($request->input('selected_tool'), $data); if (isset($response['status']) && $response['status'] === 'error') { return ['error' => true, 'message' => $response['message']]; } return [ 'error' => false, 'photo' => $response['photo'] ?? '', 'task_id' => $response['task_id'] ?? '', 'task_status' => $response['task_status'] ?? 'COMPLETED', 'link' => $response['link'] ?? '', ]; } private function errorResponse(string $message): JsonResponse { return response()->json([ 'status' => 'error', 'type' => 'error', 'message' => $message, ]); } private function prepareUserOpenai( string $photo, string $request_id = '', string $status = 'COMPLETED', string $link = '', ): array { $openai = OpenAIGenerator::query()->where('slug', 'ai_image_generator')->firstOrFail(); return [ 'is_advanced_image' => true, 'request_id' => $request_id, 'team_id' => auth()->user()->teamId(), 'title' => Str::limit(request('description'), '20') ?: $this->title($photo), 'slug' => $this->generateSlug(), 'user_id' => auth()->user()->getKey(), 'openai_id' => $openai->getKey(), 'input' => request('description') ?? 'Unknown', 'response' => 'CD', 'output' => $photo, 'hash' => Str::random(256), 'credits' => 1, 'words' => 0, 'storage' => 'public', 'payload' => [ 'taskId' => $request_id, 'link' => $link, 'tool' => request('selected_tool'), 'model' => request('ai_model'), ], 'status' => $status, ]; } private function generateSlug(): string { return Str::random(7) . Str::slug(auth()->user()->fullName()) . '-workbook'; } } System/Http/Controllers/AdvancedImageStatusController.php000064400000003540152666206730017725 0ustar00shouldCheckStatus($task)) { $task = match (data_get($task->payload, 'model')) { 'freepik' => $this->freepikService->checkStatus($task), 'novita' => $this->novitaService->checkStatus($task), 'flux-pro/kontext' => $this->falaiService->checkStatus($task), 'nano-banana/edit' => $this->nanoBananaService->checkStatus($task), default => $task, }; } if ($task->output) { $task->output = $task->output_url; } return response()->json([ 'message' => __('Generated Successfully'), 'status' => 'success', 'data' => $task, ]); } private function shouldCheckStatus(UserOpenai $task): bool { return in_array($task->status, self::PENDING_STATUSES, true); } } System/Http/Controllers/GeneratePromptController.php000064400000004464152666206730017013 0ustar00validate(['image' => 'required|image']); $image = $request->file('image')->store('image-editor', ['disk' => 'public']); $driver = Entity::driver(EntityEnum::GPT_4_TURBO); try { $driver->redirectIfNoCreditBalance(); } catch (Exception $e) { return response()->json([ 'prompt' => __($e->getMessage()), 'status' => 'error', ]); } $completion = OpenAI::chat()->create([ 'model' => 'gpt-4-turbo', 'messages' => [ [ 'role' => 'system', 'content' => 'Analyze the image and generate a detailed, high-quality prompt suitable for recreating the scene using an image generation model. Output only the prompt, with no additional text or labels.', ], [ 'role' => 'user', 'content' => [ [ 'type' => 'image_url', 'image_url' => [ 'url' => Storage::disk('uploads')->url(str_replace('uploads', '', $image)), ], ], ], ], ], ]); if (isset($completion['choices'][0]['message']['content'])) { $driver->input($completion['choices'][0]['message']['content'])->calculateCredit()->decreaseCredit(); $data = [ 'status' => 'success', 'prompt' => $completion['choices'][0]['message']['content'], ]; } else { $data = [ 'status' => 'error', 'prompt' => 'No response from ai', ]; } return response()->json($data); } } System/Http/Controllers/ClipdropSettingController.php000064400000001635152666206730017166 0ustar00validate([ 'clipdrop_api_key' => 'required|string', ]); if (Helper::appIsNotDemo()) { setting([ 'clipdrop_api_key' => $request->get('clipdrop_api_key'), ])->save(); } return back() ->with([ 'type' => 'success', 'message' => __('Clipdrop API key has been updated successfully.'), ]); } } System/Http/Controllers/AdvancedImageWebhookController.php000064400000002476152666206730020047 0ustar00 $request->get('request_id'), 'novita' => $request->input('payload.task.task_id'), default => null, }; /** * @var UserOpenai $task */ $task = UserOpenai::query() ->where('request_id', $taskId) ->firstOrFail(); if ($model === 'freepik') { $this->freepikService->webhook($task, $request->all()); } if ($model === 'novita') { $this->novitaService->webhook($task, $request->input('payload.images') ?: []); } } } System/Http/.DS_Store000064400000014004152666206730010446 0ustar00Bud1 roller Controllersbwspblob¸bplist00Ö ]ShowStatusBar[ShowToolbar[ShowTabView_ContainerShowSidebar\WindowBounds[ShowSidebar  _{{368, 408}, {920, 436}} #/;R_klmnoŠ ‹ ControllersvSrnlong  @€ @€ @€ @ E DSDB `€ @€ @€ @System/Http/Resources/.gitkeep000064400000000016152666206730012364 0ustar00* !.gitignore resources/views/shared-components/image-grid.blade.php000064400000014655152666206730017160 0ustar00 @foreach ($images as $item)
request_id ? 'data-request-id=' . $item->request_id : '' }} >
@if ($item->output_url) {{ $item->prompt ? \Illuminate\Support\Str::limit($item->prompt, 40) : $item->title }}
@endif
{{ $item->title }}
@endforeach resources/views/shared-components/image-modal.blade.php000064400000017026152666206730017322 0ustar00 resources/views/shared-components/templates.blade.php000064400000007243152666206730017144 0ustar00

@lang('Templates')

{{ __('View All') }}
@php $templates = [ [ 'image' => 'assets/img/advanced-image/templates/templates-facebook-cover.svg', 'title' => 'Facebook Cover', 'aspect' => 'Create a visually striking Facebook cover image with a resolution of 820x312 pixels, emphasizing a wide landscape layout. Suitable for personal or business pages, with space for profile picture overlay on the left.', 'cover' => 'Horizontal', ], [ 'image' => 'assets/img/advanced-image/templates/templates-youtube-thumbnail.svg', 'title' => 'Youtube Thumbnail', 'aspect' => 'Design an eye-catching YouTube thumbnail with a resolution of 1280x720 pixels, highlighting key elements of the video. Use bold fonts, vibrant colors, and clear focal points to grab viewer attention.', 'cover' => 'Horizontal', ], [ 'image' => 'assets/img/advanced-image/templates/templates-advertisment.svg', 'title' => 'Advertisment', 'aspect' => 'Create a visually appealing square advertisement image with a resolution of 1080x1080 pixels, ideal for social media platforms like Instagram and Facebook. Ensure the design is vibrant, with a clear call-to-action.', 'cover' => 'Square', ], [ 'image' => 'assets/img/advanced-image/templates/templates-reels-tiktok-youtube-short.svg', 'title' => 'Reels, TikTok, Youtube Short', 'aspect' => 'Generate an engaging vertical video cover image with a resolution of 1080x1920 pixels, suitable for platforms like Reels, TikTok, and YouTube Shorts. The design should be visually dynamic and capture the viewer\'s attention within a short time frame.', 'cover' => 'Vertical', ], [ 'image' => 'assets/img/advanced-image/templates/templates-social-media-post.svg', 'title' => 'Social Media Post', 'aspect' => 'Create a square social media post image with a resolution of 1080x1080 pixels. This design should be versatile, suitable for multiple platforms, and include space for text or branding elements.', 'cover' => 'Square', ], ]; @endphp
@foreach ($templates as $template)
{{ $template['title'] }}
{{ $template['title'] }}

{{ $template['cover'] }}

View Template
@endforeach
resources/views/shared-components/top-navbar.blade.php000064400000035473152666206730017225 0ustar00 resources/views/index.blade.php000064400000006314152666206730012622 0ustar00@php $primary_tool_keys = ['uncrop', 'reimagine', 'remove_background', 'cleanup', 'upscale']; $prompt_filters = [ 'all' => __('All'), 'favorite' => __('Favorite'), ]; @endphp @extends('panel.layout.app', [ 'disable_tblr' => true, 'disable_header' => true, 'disable_navbar' => true, 'disable_default_sidebar' => true, 'disable_titlebar' => true, 'layout_wide' => true, ]) @section('title', __('Advanced Image Editor')) @section('titlebar_actions', '') @section('content')
@include('advanced-image::shared-components.top-navbar') @include('advanced-image::home.home', ['images' => $userOpenai->take(5), 'tools' => $tools]) @include('advanced-image::editor.editor', ['tools' => $tools, 'primary_tool_keys' => $primary_tool_keys]) @include('advanced-image::gallery.gallery', ['images' => $userOpenai]) @include('advanced-image::shared-components.image-modal')
@endsection @push('script') @endpush resources/views/editor/editor-canvas.blade.php000064400000030765152666206730015547 0ustar00
{{-- blade-formatter-disable --}} {{-- blade-formatter-enable --}}

@lang('Drag and Drop an Image') @lang('Drag and Drop Multiple Images')

@lang('or')
@lang('Browse Files') @lang('Add More') @lang('Clear Files')

{{ __('PNG or JPG') }}

@lang('Action in progress...') This process might take a little while.

@lang('Date'):
@lang('AI Model'):
@lang('Art Style'):
@lang('Credit'):
resources/views/editor/editor.blade.php000064400000005753152666206730014275 0ustar00 resources/views/editor/editor-sidebar.blade.php000064400000035044152666206730015700 0ustar00 resources/views/editor/editor-toolbar.blade.php000064400000016350152666206730015730 0ustar00@php $primary_tools = array_filter($tools, fn($tool) => in_array($tool['action'], $primary_tool_keys)); $secondary_tools = array_filter($tools, fn($tool) => !in_array($tool['action'], $primary_tool_keys)); @endphp
@foreach ($primary_tools as $tool) @endforeach
@foreach ($secondary_tools as $tool) @endforeach
resources/views/home/home.blade.php000064400000004624152666206730013375 0ustar00@php $generators = []; $flux = null; $isFalAIEnabled = \App\Helpers\Classes\ApiHelper::setFalAIKey(); $isIdeogramAvailable = class_exists('App\Extensions\Ideogram\System\IdeogramServiceProvider'); if (setting('dalle_hidden', 0) == '1') { $generators[] = ['value' => 'openai', 'label' => __('DALL-E')]; } if (setting('stable_hidden', 0) !== '1') { $generators[] = ['value' => 'stable_diffusion', 'label' => __('Stable Diffusion')]; } if ($isFalAIEnabled) { $fluxLabel = setting('fal_ai_default_model') === 'flux-realism' ? __('Flux Realism Lora') : __('Flux Pro'); $generators[] = ['value' => 'flux-pro', 'label' => $fluxLabel]; $flux = 'flux-pro'; } if ($isFalAIEnabled && $isIdeogramAvailable) { $generators[] = ['value' => 'ideogram', 'label' => 'Ideogram']; } if (setting('enabled_gpt_image_1', 0) == '1') { $generators[] = ['value' => 'gpt-image-1', 'label' => __('GPT image 1')]; } if (setting('enabled_flux_pro_kontext', 1) == '1') { $generators[] = ['value' => 'flux-pro-kontext', 'label' => __('Flux Pro Kontext')]; } if (\App\Helpers\Classes\MarketplaceHelper::isRegistered('nano-banana')) { $generators[] = ['value' => 'nano-banana', 'label' => __('Nano Banana')]; } if (\App\Helpers\Classes\MarketplaceHelper::isRegistered('see-dream-v4')) { $generators[] = ['value' => 'seedream/v4/text-to-image', 'label' => __('SeeDream V4')]; } @endphp
@include('advanced-image::home.generator-form') @include('advanced-image::home.advanced-options') @if ($app_is_demo) @if ($tools) @include('advanced-image::home.tools-grid', ['tools' => $tools]) @endif @else @include('advanced-image::home.recent-images-grid', ['images' => $images]) @endif @include('advanced-image::home.templates-grid') @if ($app_is_demo) @include('advanced-image::home.recent-images-grid', ['images' => $images]) @else @if ($tools) @include('advanced-image::home.tools-grid', ['tools' => $tools]) @endif @endif @include('advanced-image::home.predefined-prompts-grid')
resources/views/home/templates-grid.blade.php000064400000011125152666206730015360 0ustar00@php $templates = [ [ 'image' => 'assets/img/advanced-image/templates/templates-facebook-cover.svg', 'title' => 'Facebook Cover', 'aspect' => 'Create a visually striking Facebook cover image with a resolution of 820x312 pixels, emphasizing a wide landscape layout. Suitable for personal or business pages, with space for profile picture overlay on the left.', 'cover' => 'Horizontal', 'ratio' => 'landscape_16_9' ], [ 'image' => 'assets/img/advanced-image/templates/templates-youtube-thumbnail.svg', 'title' => 'Youtube Thumbnail', 'aspect' => 'Design an eye-catching YouTube thumbnail with a resolution of 1280x720 pixels, highlighting key elements of the video. Use bold fonts, vibrant colors, and clear focal points to grab viewer attention.', 'cover' => 'Horizontal', 'ratio' => 'landscape_16_9' ], [ 'image' => 'assets/img/advanced-image/templates/templates-advertisment.svg', 'title' => 'Advertisment', 'aspect' => 'Create a visually appealing square advertisement image with a resolution of 1080x1080 pixels, ideal for social media platforms like Instagram and Facebook. Ensure the design is vibrant, with a clear call-to-action.', 'cover' => 'Square', 'ratio' => 'square' ], [ 'image' => 'assets/img/advanced-image/templates/templates-reels-tiktok-youtube-short.svg', 'title' => 'Reels, TikTok, Youtube Short', 'aspect' => 'Generate an engaging vertical video cover image with a resolution of 1080x1920 pixels, suitable for platforms like Reels, TikTok, and YouTube Shorts. The design should be visually dynamic and capture the viewer\'s attention within a short time frame.', 'cover' => 'Vertical', 'ratio' => 'portrait_16_9' ], [ 'image' => 'assets/img/advanced-image/templates/templates-social-media-post.svg', 'title' => 'Social Media Post', 'aspect' => 'Create a square social media post image with a resolution of 1080x1080 pixels. This design should be versatile, suitable for multiple platforms, and include space for text or branding elements.', 'cover' => 'Square', 'ratio' => 'square' ], ]; @endphp

@lang('Templates')

@foreach ($templates as $template)
{{ $template['title'] }}
{{ __($template['title']) }}
{{ __($template['cover']) }} {{ __('View Template') }}
@endforeach
@push('script') @endpush resources/views/home/predefined-prompts-grid.blade.php000064400000007157152666206730017203 0ustar00@php $prompts = [ [ 'title' => 'Wallpaper', 'prompt' => 'Create a stunning high-resolution wallpaper featuring vibrant abstract art with dynamic shapes and colors.', 'ai_model' => 'flux-pro', ], [ 'title' => 'ComicBook', 'prompt' => 'Design a dynamic comic book cover with bold characters, action-packed poses, and a dramatic backdrop.', 'ai_model' => 'flux-pro', ], [ 'title' => 'Architecture', 'prompt' => 'Generate a futuristic architectural design showcasing innovative skyscrapers with eco-friendly elements.', 'ai_model' => 'flux-pro', ], [ 'title' => 'Digital Illustration', 'prompt' => 'Create a digital illustration of a serene fantasy landscape with glowing trees and a magical river.', 'ai_model' => 'flux-pro', ], [ 'title' => 'Abstract Background', 'prompt' => 'Design a modern abstract background with flowing gradients, geometric patterns, and subtle textures.', 'ai_model' => 'flux-pro', ], [ 'title' => 'Product Mockups', 'prompt' => 'Generate a realistic product mockup featuring sleek packaging and minimalistic design elements.', 'ai_model' => 'flux-pro', ], [ 'title' => 'Pattern', 'prompt' => 'Create a seamless pattern inspired by nature with floral motifs and earthy tones.', 'ai_model' => 'flux-pro', ], [ 'title' => 'Storyboard', 'prompt' => 'Design a storyboard for a short film featuring a suspenseful chase scene in a bustling city.', 'ai_model' => 'flux-pro', ], [ 'title' => 'Movie Poster', 'prompt' => 'Create a dramatic movie poster for a sci-fi thriller, with a mysterious protagonist and a glowing cityscape.', 'ai_model' => 'flux-pro', ], [ 'title' => 'Album Cover', 'prompt' => 'Design an album cover with a retro aesthetic featuring bold typography and vibrant neon colors.', 'ai_model' => 'flux-pro', ], [ 'title' => 'Children’s Book', 'prompt' => 'Illustrate a children’s book page showing a whimsical forest with friendly animals and colorful scenery.', 'ai_model' => 'flux-pro', ], [ 'title' => 'Book Cover', 'prompt' => 'Design an elegant book cover for a mystery novel with intricate patterns and a shadowy figure.', 'ai_model' => 'flux-pro', ], ]; @endphp
@foreach ($prompts as $prompt) {{ __($prompt['title']) }} @endforeach
resources/views/home/recent-images-grid.blade.php000064400000001515152666206730016107 0ustar00

@lang('Recent Images')

@lang('View All')
@include('advanced-image::shared-components.image-grid', ['images' => $images, 'has_more' => false, 'id_prefix' => 'recent-'])
resources/views/home/tools-grid.blade.php000064400000006355152666206730014533 0ustar00

@lang('Enhance Your Images')

@lang('View All')
@foreach ($tools as $tool)
{{ $tool['title'] }} @if ($tool['premium']) @lang('Premium') @endif
{{ __($tool['title']) }}

{{ __($tool['description']) }}

{{ __('View Template') }}
@endforeach
resources/views/home/generator-form.blade.php000064400000074005152666206730015374 0ustar00

@lang('Create Stunning AI Images')

@csrf @foreach ($generators as $generator) @endforeach
@if (setting('user_prompt_library') == null || setting('user_prompt_library')) @endif
@if (in_array('stable_diffusion', array_column($generators, 'value')))
@lang('or upload an image')
@endif
@include('panel.user.openai_chat.components.prompt_library_modal')
@push('script') @endpush resources/views/home/advanced-options.blade.php000064400000025420152666206730015700 0ustar00@php $advanced_options = [ [ 'icon' => ' ', 'label' => 'AI Product Photo', 'link' => \App\Helpers\Classes\MarketplaceHelper::isRegistered('ai-product-shot') ? route('dashboard.user.ai-product-shot.index') : null, ], [ 'icon' => ' ', 'label' => 'Text to Video', 'link' => \App\Helpers\Classes\MarketplaceHelper::isRegistered('ai-video-pro') ? route('dashboard.user.ai-video-pro.index') : null, ], [ 'icon' => ' ', 'label' => 'Image to Video', 'link' => \App\Helpers\Classes\MarketplaceHelper::isRegistered('ai-video-pro') ? route('dashboard.user.ai-video-pro.index') : null, ], [ 'icon' => ' ', 'label' => 'AI Avatar', 'link' => \Illuminate\Support\Facades\Route::has('dashboard.user.ai-avatar.index') ? route('dashboard.user.ai-avatar.index') : null, ], ]; @endphp @if (collect($advanced_options)->contains(fn($option) => $option['link'] !== null))
@foreach ($advanced_options as $option) @continue($option['link'] === null) {!! $option['icon'] !!} {{ $option['label'] }} @endforeach {{ 'Merge Face' }}
@endif resources/views/freepik-setting.blade.php000064400000003267152666206730014617 0ustar00@extends('panel.layout.settings') @section('title', __('Freepik API Settings')) @section('titlebar_actions', '') @section('titlebar_subtitle', __('This API key is used for these features: AI Photo Studio, Advanced Image Editor')) @section('settings')

{{ __('Freepik API Settings') }}

{{ __('Please ensure that your Freepik api key is fully functional and billing defined on your Freepik account.') }}

@endsection resources/views/gallery/gallery.blade.php000064400000007455152666206730014620 0ustar00 resources/views/setting/index.blade.php000064400000003632152666206730014277 0ustar00@php use App\Domains\Entity\Enums\EntityEnum; @endphp @extends('panel.layout.settings', ['layout' => 'wide']) @section('title', __('AI Image Editor Settings')) @section('titlebar_actions', '') @section('titlebar_subtitle', '') @section('additional_css') @endsection @section('settings')
@csrf

{{ __('FalAI Settings') }}

@foreach($tools as $tool)
@php $inputName = $tool['action'] . '_model'; @endphp @foreach($tool['models'] as $model) @endforeach
@endforeach
@endsection @push('script') @endpush resources/views/novita-setting.blade.php000064400000003247152666206730014470 0ustar00@extends('panel.layout.settings') @section('title', __('Novita API Settings')) @section('titlebar_actions', '') @section('titlebar_subtitle', __('This API key is used for these features: AI Photo Studio, Advanced Image Editor')) @section('settings')

{{ __('Novita API Settings') }}

{{ __('Please ensure that your Novita api key is fully functional and billing defined on your Novita account.') }}

@endsection resources/views/clipdrop-setting.blade.php000064400000003351152666206730015000 0ustar00@extends('panel.layout.settings') @section('title', __('Clipdrop API Settings')) @section('titlebar_actions', '') @section('titlebar_subtitle', __('This API key is used for these features: AI Photo Studio, Advanced Image Editor')) @section('settings')

{{ __('Clipdrop API Settings') }}

{{ __('Please ensure that your Clipdrop api key is fully functional and billing defined on your Clipdrop account.') }}

@endsection __MACOSX/._System000064400000000243152666206730007474 0ustar00Mac OS X  2q£ATTR£˜ ˜ com.apple.provenance¤`˜†TÜç__MACOSX/._resources000064400000000243152666206730010222 0ustar00Mac OS X  2q£ATTR£˜ ˜ com.apple.provenance¤`˜†TÜç__MACOSX/database/._resources000064400000000243152666206730011766 0ustar00Mac OS X  2q£ATTR£˜ ˜ com.apple.provenance¤`˜†TÜç__MACOSX/database/migrations/._2025_01_20_080747_is_advanced_image_to_user_openai_table.php000064400000000243152666206730024664 0ustar00Mac OS X  2q£ATTR£˜ ˜ com.apple.provenance¤`˜†TÜç__MACOSX/database/migrations/._2025_01_20_080747_advanced_image_migrations.php000064400000000243152666206730022163 0ustar00Mac OS X  2q£ATTR£˜ ˜ com.apple.provenance¤`˜†TÜç__MACOSX/database/._migrations000064400000000243152666206730012130 0ustar00Mac OS X  2q£ATTR£˜ ˜ com.apple.provenance¤`˜†TÜç__MACOSX/database/resources/._db.json000064400000000243152666206730013323 0ustar00Mac OS X  2q£ATTR£˜ ˜ com.apple.provenance¤`˜†TÜç__MACOSX/._database000064400000000243152666206730007754 0ustar00Mac OS X  2q£ATTR£˜ ˜ com.apple.provenance¤`˜†TÜç__MACOSX/System/._Helpers000064400000000243152666206730011076 0ustar00Mac OS X  2q£ATTR£˜ ˜ com.apple.provenance¤`˜†TÜç__MACOSX/System/Services/._OpenAIService.php000064400000000243152666206730014501 0ustar00Mac OS X  2q£ATTR£˜ ˜ com.apple.provenance¤`˜†TÜç__MACOSX/System/Services/._NanoBananaService.php000064400000000243152666206730015362 0ustar00Mac OS X  2q£ATTR£˜ ˜ com.apple.provenance¤`˜†TÜç__MACOSX/System/Services/Traits/._HasDownloadImage.php000064400000000243152666206730016461 0ustar00Mac OS X  2q£ATTR£˜ ˜ com.apple.provenance¤`˜†TÜç__MACOSX/System/Services/Traits/._HasNanoBanana.php000064400000000243152666206730015743 0ustar00Mac OS X  2q£ATTR£˜ ˜ com.apple.provenance¤`˜†TÜç__MACOSX/System/Services/Traits/._HasFalAI.php000064400000000243152666206730014663 0ustar00Mac OS X  2q£ATTR£˜ ˜ com.apple.provenance¤`˜†TÜç__MACOSX/System/Services/Traits/._UseImage.php000064400000000243152666206730015012 0ustar00Mac OS X  2q£ATTR£˜ ˜ com.apple.provenance¤`˜†TÜç__MACOSX/System/Services/._Traits000064400000000243152666206730012525 0ustar00Mac OS X  2q£ATTR£˜ ˜ com.apple.provenance¤`˜†TÜç__MACOSX/System/Services/._FalAIService.php000064400000000243152666206730014302 0ustar00Mac OS X  2q£ATTR£˜ ˜ com.apple.provenance¤`˜†TÜç__MACOSX/System/Services/._ClipDropService.php000064400000000243152666206730015102 0ustar00Mac OS X  2q£ATTR£˜ ˜ com.apple.provenance¤`˜†TÜç__MACOSX/System/Services/._AdvancedNovitaService.php000064400000000243152666206730016254 0ustar00Mac OS X  2q£ATTR£˜ ˜ com.apple.provenance¤`˜†TÜç__MACOSX/System/Services/._AdvancedFreepikService.php000064400000000243152666206730016401 0ustar00Mac OS X  2q£ATTR£˜ ˜ com.apple.provenance¤`˜†TÜç__MACOSX/System/._.DS_Store000064400000000170152666206730011233 0ustar00Mac OS X  2Fx @ATTRxx__MACOSX/System/Helpers/._Tool.php000064400000000243152666206730012601 0ustar00Mac OS X  2q£ATTR£˜ ˜ com.apple.provenance¤`˜†TÜç__MACOSX/System/._Http000064400000000243152666206730010413 0ustar00Mac OS X  2q£ATTR£˜ ˜ com.apple.provenance¤`˜†TÜç__MACOSX/System/._AdvancedImageServiceProvider.php000064400000000243152666206730015766 0ustar00Mac OS X  2q£ATTR£˜ ˜ com.apple.provenance¤`˜†TÜç__MACOSX/System/._Services000064400000000243152666206730011257 0ustar00Mac OS X  2q£ATTR£˜ ˜ com.apple.provenance¤`˜†TÜç__MACOSX/System/Http/Controllers/._AdvancedImageStatusController.php000064400000000243152666206730021427 0ustar00Mac OS X  2q£ATTR£˜ ˜ com.apple.provenance¤`˜†TÜç__MACOSX/System/Http/Controllers/._AdvancedImageWebhookController.php000064400000000243152666206730021542 0ustar00Mac OS X  2q£ATTR£˜ ˜ com.apple.provenance¤`˜†TÜç__MACOSX/System/Http/Controllers/._FreepikSettingController.php000064400000000243152666206730020476 0ustar00Mac OS X  2q£ATTR£˜ ˜ com.apple.provenance¤`˜†TÜç__MACOSX/System/Http/Controllers/._NovitaSettingController.php000064400000000243152666206730020351 0ustar00Mac OS X  2q£ATTR£˜ ˜ com.apple.provenance¤`˜†TÜç__MACOSX/System/Http/Controllers/._GeneratePromptController.php000064400000000243152666206730020507 0ustar00Mac OS X  2q£ATTR£˜ ˜ com.apple.provenance¤`˜†TÜç__MACOSX/System/Http/Controllers/._AdvancedImageSettingController.php000064400000000243152666206730021561 0ustar00Mac OS X  2q£ATTR£˜ ˜ com.apple.provenance¤`˜†TÜç__MACOSX/System/Http/Controllers/._AdvancedImageController.php000064400000000243152666206730020223 0ustar00Mac OS X  2q£ATTR£˜ ˜ com.apple.provenance¤`˜†TÜç__MACOSX/System/Http/Controllers/._ClipdropSettingController.php000064400000000243152666206730020665 0ustar00Mac OS X  2q£ATTR£˜ ˜ com.apple.provenance¤`˜†TÜç__MACOSX/System/Http/._.DS_Store000064400000000170152666206730012152 0ustar00Mac OS X  2Fx @ATTRxx__MACOSX/System/Http/._Resources000064400000000243152666206730012365 0ustar00Mac OS X  2q£ATTR£˜ ˜ com.apple.provenance¤`˜†TÜç__MACOSX/System/Http/._Controllers000064400000000243152666206730012721 0ustar00Mac OS X  2q£ATTR£˜ ˜ com.apple.provenance¤`˜†TÜç__MACOSX/System/Http/Resources/._.gitkeep000064400000000243152666206730014073 0ustar00Mac OS X  2q£ATTR£˜ ˜ com.apple.provenance¤`˜†TÜç__MACOSX/resources/views/._gallery000064400000000243152666206730013016 0ustar00Mac OS X  2q£ATTR£˜ ˜ com.apple.provenance¤`˜†TÜç__MACOSX/resources/views/shared-components/._image-modal.blade.php000064400000000243152666206730021020 0ustar00Mac OS X  2q£ATTR£˜ ˜ com.apple.provenance¤`˜†TÜç__MACOSX/resources/views/shared-components/._top-navbar.blade.php000064400000000243152666206730020715 0ustar00Mac OS X  2q£ATTR£˜ ˜ com.apple.provenance¤`˜†TÜç__MACOSX/resources/views/shared-components/._templates.blade.php000064400000000243152666206730020642 0ustar00Mac OS X  2q£ATTR£˜ ˜ com.apple.provenance¤`˜†TÜç__MACOSX/resources/views/shared-components/._image-grid.blade.php000064400000000243152666206730020651 0ustar00Mac OS X  2q£ATTR£˜ ˜ com.apple.provenance¤`˜†TÜç__MACOSX/resources/views/._index.blade.php000064400000000243152666206730014322 0ustar00Mac OS X  2q£ATTR£˜ ˜ com.apple.provenance¤`˜†TÜç__MACOSX/resources/views/._novita-setting.blade.php000064400000000243152666206730016166 0ustar00Mac OS X  2q£ATTR£˜ ˜ com.apple.provenance¤`˜†TÜç__MACOSX/resources/views/editor/._editor-canvas.blade.php000064400000000243152666206730017240 0ustar00Mac OS X  2q£ATTR£˜ ˜ com.apple.provenance¤`˜†TÜç__MACOSX/resources/views/editor/._editor-toolbar.blade.php000064400000000243152666206730017427 0ustar00Mac OS X  2q£ATTR£˜ ˜ com.apple.provenance¤`˜†TÜç__MACOSX/resources/views/editor/._editor-sidebar.blade.php000064400000000243152666206730017376 0ustar00Mac OS X  2q£ATTR£˜ ˜ com.apple.provenance¤`˜†TÜç__MACOSX/resources/views/editor/._editor.blade.php000064400000000243152666206730015767 0ustar00Mac OS X  2q£ATTR£˜ ˜ com.apple.provenance¤`˜†TÜç__MACOSX/resources/views/home/._templates-grid.blade.php000064400000000243152666206730017064 0ustar00Mac OS X  2q£ATTR£˜ ˜ com.apple.provenance¤`˜†TÜç__MACOSX/resources/views/home/._predefined-prompts-grid.blade.php000064400000000243152666206730020675 0ustar00Mac OS X  2q£ATTR£˜ ˜ com.apple.provenance¤`˜†TÜç__MACOSX/resources/views/home/._home.blade.php000064400000000243152666206730015073 0ustar00Mac OS X  2q£ATTR£˜ ˜ com.apple.provenance¤`˜†TÜç__MACOSX/resources/views/home/._tools-grid.blade.php000064400000000243152666206730016226 0ustar00Mac OS X  2q£ATTR£˜ ˜ com.apple.provenance¤`˜†TÜç__MACOSX/resources/views/home/._recent-images-grid.blade.php000064400000000243152666206730017611 0ustar00Mac OS X  2q£ATTR£˜ ˜ com.apple.provenance¤`˜†TÜç__MACOSX/resources/views/home/._advanced-options.blade.php000064400000000243152666206730017401 0ustar00Mac OS X  2q£ATTR£˜ ˜ com.apple.provenance¤`˜†TÜç__MACOSX/resources/views/home/._generator-form.blade.php000064400000000243152666206730017072 0ustar00Mac OS X  2q£ATTR£˜ ˜ com.apple.provenance¤`˜†TÜç__MACOSX/resources/views/._setting000064400000000243152666206730013034 0ustar00Mac OS X  2q£ATTR£˜ ˜ com.apple.provenance¤`˜†TÜç__MACOSX/resources/views/gallery/._gallery.blade.php000064400000000243152666206730016311 0ustar00Mac OS X  2q£ATTR£˜ ˜ com.apple.provenance¤`˜†TÜç__MACOSX/resources/views/._editor000064400000000243152666206730012645 0ustar00Mac OS X  2q£ATTR£˜ ˜ com.apple.provenance¤`˜†TÜç__MACOSX/resources/views/._shared-components000064400000000243152666206730015010 0ustar00Mac OS X  2q£ATTR£˜ ˜ com.apple.provenance¤`˜†TÜç__MACOSX/resources/views/setting/._index.blade.php000064400000000243152666206730015777 0ustar00Mac OS X  2q£ATTR£˜ ˜ com.apple.provenance¤`˜†TÜç__MACOSX/resources/views/._home000064400000000243152666206730012307 0ustar00Mac OS X  2q£ATTR£˜ ˜ com.apple.provenance¤`˜†TÜç__MACOSX/resources/views/._freepik-setting.blade.php000064400000000243152666206730016313 0ustar00Mac OS X  2q£ATTR£˜ ˜ com.apple.provenance¤`˜†TÜç__MACOSX/resources/views/._clipdrop-setting.blade.php000064400000000243152666206730016502 0ustar00Mac OS X  2q£ATTR£˜ ˜ com.apple.provenance¤`˜†TÜç__MACOSX/resources/._views000064400000000243152666206730011357 0ustar00Mac OS X  2q£ATTR£˜ ˜ com.apple.provenance¤`˜†TÜç__MACOSX/._extension.json000064400000000243152666206730011174 0ustar00Mac OS X  2q£ATTR£˜ ˜ com.apple.provenance¤`˜†TÜç