ivanoctaviogaitansantos commited on
Commit
3743153
·
verified ·
1 Parent(s): 430b280

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +196 -212
app.py CHANGED
@@ -1,219 +1,203 @@
1
  import os
2
  import random
3
  import json
4
- from smolagents import CodeAgent, InferenceClientModel, tool
5
- import gradio as gr
6
-
7
- # Token Hugging Face, asegúrate de configurarlo en las variables de entorno
8
- # Es altamente recomendable usar 'secrets' o variables de entorno en lugar de HF_TOKEN
9
- HF_TOKEN = os.getenv("HF_TOKEN")
10
-
11
- # Modelo para LLM
12
- model = InferenceClientModel(
13
- model_id="mistralai/Mistral-7B-Instruct-v0.1",
14
- token=HF_TOKEN,
15
- )
16
-
17
- # Herramienta personalizada para analizar y corregir código Python
18
- @tool
19
- def analyze_python_code(code: str) -> str:
20
- """
21
- Corrige, completa y explica el código Python provisto.
22
-
23
- Args:
24
- code: El código Python a analizar.
25
- """
26
- prompt = f"Corrige, completa y explica el siguiente código Python claramente:\n\n{code}"
27
- response = model(prompt)
28
- return response.strip()
29
-
30
- # Lista de herramientas para el agente
31
- tools = [analyze_python_code]
32
-
33
- # Inicializa el agente con herramientas y modelo
34
- agent = CodeAgent(
35
- tools=tools,
36
- model=model,
37
- add_base_tools=False
38
- )
39
-
40
- # DATOS PARA GENERACIÓN DE PERSONAJES INVENTADOS (TEMAS DE ROL ESPECÍFICOS)
41
- FICTIONAL_ROLES = [
42
- "Secretary", "Nurse", "Schoolgirl", "Maid", "Flight Attendant", "Nun"
43
- ]
44
- HAIR_STYLES = [
45
- "long wavy auburn hair", "short, tight black bun", "blonde pigtails",
46
- "long cascading brunette hair", "high, professional chignon", "simple black veil over long hair"
47
- ]
48
- # OUTFITS REVISADOS para ser ajustados/sugerentes y acordes al rol
49
- OUTFIT_THEMES = [
50
- "a tight pencil skirt and partially unbuttoned blouse",
51
- "a fitted, short-hemline nurse's uniform dress",
52
- "a classic plaid schoolgirl uniform with a short pleated skirt",
53
- "a short black maid uniform with a tight corset and white lace apron",
54
- "a fitted aeromoza jacket and pencil skirt",
55
- "a severe black habit with exposed décolletage"
56
- ]
57
- EYE_COLORS = ["gold", "iridescent blue", "vibrant purple", "deep emerald green", "flaming orange", "silver"]
58
-
59
- # SETTINGS REVISADOS: Ambientes cotidianos, no Sci-Fi/Neon
60
- SETTINGS = [
61
- "vintage wood-paneled private office with an antique desk",
62
- "hospital examining room during a quiet moment",
63
- "empty classroom after hours, moonlight streaming through the window",
64
- "opulent vintage hotel suite with plush velvet furniture",
65
- "first-class airplane cabin during a long haul flight",
66
- "silent, dimly lit stone chapel corridor"
67
- ]
68
-
69
- # ACTIVITIES REVISADAS: Poses que revelan la ropa interior desde ángulos bajos
70
- ACTIVITIES = [
71
- "bending over a desk to pick up a dropped pen",
72
- "climbing a short set of stairs, lifting the hemline slightly",
73
- "adjusting a stocking while sitting casually on a chair",
74
- "leaning over a counter to wipe a surface with a playful smirk",
75
- "reaching for a top-shelf luggage compartment",
76
- "kneeling to pray on a marble floor"
77
- ]
78
-
79
- LINGERIE_COLORS = ["black", "red", "white", "navy blue", "deep burgundy"]
80
- STOCKING_DETAILS = ["a delicate back seam", "intricate lace pattern", "classic fishnet design", "smooth satin finish", "subtle floral embroidery"]
81
- HEEL_DETAILS = ["sharp stiletto heels", "elegant kitten heels", "strappy high heels", "sleek patent leather pumps", "classic pointed toe heels"]
82
- POSES = ["confident stance, one hand on hip", "sitting casually on a desk", "leaning slightly forward", "standing with arms crossed", "walking with a playful smile"]
83
- # EXPRESSIONS REVISADAS: Enfocadas en el deseo y contacto visual
84
- EXPRESSIONS = [
85
- "a knowing, seductive smile directed at the viewer",
86
- "an intense, lustful gaze locking with the camera",
87
- "a confident, alluring smirk and eye contact",
88
- "a playful wink and inviting stare",
89
- "a soft, inviting smile with direct eye contact"
90
- ]
91
-
92
- def generate_prompt(role, hair_style, outfit_theme, eye_color, setting, activity, lingerie_color, stocking_detail, heel_detail, pose, expression, prompt_num):
93
- """
94
- Genera un prompt en texto plano, humanizado y optimizado en inglés.
95
- """
96
-
97
- # 1. Main prompt (Humanized and integrated)
98
- main_prompt = (
99
- f"A beautiful perfect cosplay of a {role} (Invented Character). Full body shot, Low-Angle (Worm's Eye View). The character is captured while {activity} in a {setting}. "
100
- f"The shot is taken from a very low position looking upward, creating strong visual lines toward the underwear area. "
101
- f"She has {hair_style} and {eye_color} eyes, with a perfect athlete body proportion. "
102
- f"Her suggestive attire is {outfit_theme}. Underneath, she wears a transparent {lingerie_color} lace thong and matching lace bra, "
103
- f"accentuated by thigh-high stockings with {stocking_detail} and {heel_detail}. "
104
- f"The character is posed in a {pose} and maintains {expression}, always looking at the viewer with desire. "
105
- )
106
-
107
- # 2. Technical and Style Modifiers (Optimized for flow)
108
- technical_and_style = (
109
- f"Technical Details: Aspect Ratio: 9:16. Shot Type: Full-Body Shot (Plano entero). Camera: Hasselblad H6D-400c with 80mm f/2.8 lens. "
110
- f"Lighting: Rembrandt lighting, ARRI SkyPanel S360-C illumination. Aperture: f/4 (Reduced Depth of Field). "
111
- f"Focus: Selective depth of field focusing on the area of interest. "
112
- f"Style: High-fashion editorial photography, Hiper-realistic CGI by Blizzard Entertainment, Fotografía de Alexander Nanitchkov, Escaneado 3D de personaje AAA, Unreal Engine 5 Ray Tracing, Detalles epidérmicos con Mapas 8K. "
113
- f"Physics: Enhanced Human Proportions, Realistic skin imperfections (pores, scars, blemishes), Sub-surface scattering reflections on skin, Realistic fabric sheen. "
114
- )
115
-
116
- # 3. Negative prompt (Clean list)
117
- negative_prompt_keywords = [
118
- "cartoon", "blurry", "pixelated", "low-resolution", "watermark", "noise", "overexposed", "underexposed",
119
- "unnatural shadows", "color banding", "oversaturation", "artificial textures", "disallowed artifacts"
120
- ]
121
-
122
- final_text = (
123
- f"{main_prompt} "
124
- f"{technical_and_style} "
125
- f"Negative Prompt: {', '.join(negative_prompt_keywords)}"
126
- )
127
-
128
- return final_text
129
-
130
- # Nueva función para generar los prompts sin entrada de usuario "Ok"
131
- def generate_five_prompts(history):
132
- prompts = []
133
- num_prompts = 5
134
-
135
- # Selección única de componentes para asegurar 5 PROMPTS NO REPETIDOS
136
- try:
137
- # Componentes del personaje
138
- unique_roles = random.sample(FICTIONAL_ROLES, min(num_prompts, len(FICTIONAL_ROLES)))
139
- unique_hair_styles = random.sample(HAIR_STYLES, min(num_prompts, len(HAIR_STYLES)))
140
- unique_outfit_themes = random.sample(OUTFIT_THEMES, min(num_prompts, len(OUTFIT_THEMES)))
141
- unique_eye_colors = random.sample(EYE_COLORS, min(num_prompts, len(EYE_COLORS)))
142
-
143
- # Componentes de la escena
144
- unique_settings = random.sample(SETTINGS, min(num_prompts, len(SETTINGS)))
145
- unique_activities = random.sample(ACTIVITIES, min(num_prompts, len(ACTIVITIES)))
146
- unique_lingerie_colors = random.sample(LINGERIE_COLORS, min(num_prompts, len(LINGERIE_COLORS)))
147
- unique_stocking_details = random.sample(STOCKING_DETAILS, min(num_prompts, len(STOCKING_DETAILS)))
148
- unique_heel_details = random.sample(HEEL_DETAILS, min(num_prompts, len(HEEL_DETAILS)))
149
- unique_poses = random.sample(POSES, min(num_prompts, len(POSES)))
150
- unique_expressions = random.sample(EXPRESSIONS, min(num_prompts, len(EXPRESSIONS)))
151
-
152
- except ValueError as e:
153
- return history + [["", f"Error de generación: Una de las listas de componentes es demasiado corta. Error: {e}"]]
154
-
155
-
156
- output_blocks = []
157
- for i in range(num_prompts):
158
- # Genera el prompt humanizado en texto plano
159
- prompt_text = generate_prompt(
160
- unique_roles[i],
161
- unique_hair_styles[i],
162
- unique_outfit_themes[i],
163
- unique_eye_colors[i],
164
- unique_settings[i],
165
- unique_activities[i],
166
- unique_lingerie_colors[i % len(LINGERIE_COLORS)],
167
- unique_stocking_details[i % len(STOCKING_DETAILS)],
168
- unique_heel_details[i % len(HEEL_DETAILS)],
169
- unique_poses[i % len(POSES)],
170
- unique_expressions[i % len(EXPRESSIONS)],
171
- i + 1
172
  )
173
-
174
- # Envuelve el título y el prompt en bloques Markdown separados y fáciles de copiar
175
- block = (
176
- f"### PROMPT {i + 1}: {unique_roles[i].upper()}\n"
177
- f"```\n{prompt_text}\n```"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
178
  )
179
- output_blocks.append(block)
180
-
181
- # Se une la lista de bloques de Markdown en un solo mensaje
182
- return history + [["Generación Automática Solicitada", "\n\n".join(output_blocks)]]
183
-
184
-
185
- def chat_with_agent(user_message, history):
186
- user_message_clean = user_message.strip().lower()
187
-
188
- if user_message_clean.startswith("codigo:") or user_message_clean.startswith("code:"):
189
- code_to_analyze = user_message.split(":", 1)[1].strip()
190
- analysis_result = analyze_python_code(code_to_analyze)
191
- return history + [[user_message, analysis_result]]
192
-
193
- else:
194
- return history + [[user_message, "Por favor, escribe 'codigo:' seguido del código Python para analizarlo y corregirlo, o haz clic en **'Generar Prompts'**."]]
195
-
196
- with gr.Blocks() as demo:
197
- gr.Markdown("## Generador de Prompts Hiperrealistas y Análisis de Código Python")
198
- chatbot = gr.Chatbot(label="Historial de Conversación", height=400)
199
-
200
- # Contenedor para el botón y la caja de texto
201
- with gr.Row():
202
- msg = gr.Textbox(label="Escribe 'codigo:' seguido del código Python para análisis", scale=4)
203
- generate_btn = gr.Button("Generar Prompts", scale=1)
204
- clear_btn = gr.Button("Limpiar", scale=1)
205
-
206
- # Lógica de envío de la caja de texto (solo para código)
207
- msg.submit(chat_with_agent, [msg, chatbot], chatbot, queue=False).then(
208
- lambda: gr.update(value="", interactive=True), None, msg, queue=False
209
- )
210
-
211
- # Lógica del nuevo botón (para generación automática)
212
- generate_btn.click(generate_five_prompts, [chatbot], chatbot, queue=False)
213
-
214
- # Lógica del botón de limpiar
215
- clear_btn.click(lambda: None, None, chatbot, queue=False)
216
 
217
  if __name__ == "__main__":
218
- demo.launch(share=False)
219
-
 
 
 
 
 
1
  import os
2
  import random
3
  import json
4
+ from typing import Dict, Any, Optional
5
+
6
+ class SimpleJSONCache:
7
+ def __init__(self, filepath: str):
8
+ self.filepath = filepath
9
+ self._cache = self._load()
10
+
11
+ def _load(self):
12
+ if os.path.exists(self.filepath):
13
+ try:
14
+ with open(self.filepath, 'r', encoding='utf-8') as f:
15
+ return json.load(f)
16
+ except Exception:
17
+ return {}
18
+ else:
19
+ return {}
20
+
21
+ def get(self, key, default=None):
22
+ return self._cache.get(key, default)
23
+
24
+ def set(self, key, value):
25
+ self._cache[key] = value
26
+ try:
27
+ with open(self.filepath, 'w', encoding='utf-8') as f:
28
+ json.dump(self._cache, f, indent=2)
29
+ except Exception as e:
30
+ print(f"Error saving cache: {e}")
31
+
32
+ class PromptGenerator:
33
+ CACHE_KEY = "generated_prompts"
34
+
35
+ def __init__(self, cache_path: str = "prompt_cache.json") -> None:
36
+ self.cache = SimpleJSONCache(cache_path)
37
+ self._load_defaults()
38
+
39
+ def _load_defaults(self) -> None:
40
+ self.ROLES = [
41
+ "nurse", "nun", "doctor", "secretary", "teacher", "schoolgirl", "lawyer",
42
+ "yoga instructor", "policewoman", "female military officer in gala uniform",
43
+ "WWII-era secretary", "1960s flight attendant", "boudoir model",
44
+ "elegant judge", "seductive librarian", "sensual model", "alluring secretary",
45
+ "elegant flight attendant", "seductive maid", "mysterious nurse",
46
+ "captivating schoolgirl", "business executive", "fitness model"
47
+ ]
48
+
49
+ self.HAIR_COLORS = [
50
+ "deep sapphire blue", "silver platinum", "vibrant ruby red", "glossy jet black",
51
+ "luxurious chestnut brown", "emerald green", "vivid amethyst purple",
52
+ "chocolate brown", "honey blonde", "burgundy red"
53
+ ]
54
+
55
+ self.EYE_COLORS = [
56
+ "intense brown", "bright sapphire blue", "emerald green", "golden amber",
57
+ "fascinating hazel", "deep violet", "piercing emerald", "deep sapphire",
58
+ "intense amber", "hypnotic hazel", "vibrant violet", "mysterious gray"
59
+ ]
60
+
61
+ self.HAIR_STYLES = [
62
+ "long flowing chestnut hair styled in soft waves", "sleek straight long black hair",
63
+ "luxurious long blonde curls", "elegant updo with loose cascading strands",
64
+ "glossy long brunette hair parted in the middle", "long flowing waves",
65
+ "luxurious straight hair", "voluminous curls", "elegant updo with cascading strands",
66
+ "thick braid over the shoulder", "loose and silky layers", "messy chic bun"
67
+ ]
68
+
69
+ self.OUTFIT_TEMPLATES = {
70
+ "nurse": "a classic short nurse dress, thigh-high stockings, semi-transparent lace panties subtly slipping down as if accidentally revealed beneath a skirt, no bra, elegant high heels",
71
+ "nun": "a sensual interpretation of a nun's habit with a revealing long robe and thigh-high stockings, semi-transparent lace panties suggesting a playful accidental reveal, no bra, black stiletto heels",
72
+ "doctor": "a daring white lab coat minidress left slightly open, thigh-high stockings, semi-transparent lace panties exposed subtly as if by chance, no bra, high heels",
73
+ "secretary": "a provocative office pencil skirt and sheer blouse, thigh-high stockings, semi-transparent lace panties hinted at from a natural skirt shift, no bra, red high heels",
74
+ "teacher": "a fitted blazer over a silk blouse and short skirt, thigh-high stockings, delicate lace panties subtly visible during natural movement, no bra, classic pumps",
75
+ "schoolgirl": "a short pleated skirt and white blouse, thigh-high stockings, classic black lace panties slipping into view during casual poses, no bra, black loafers",
76
+ "lawyer": "a tailored suit with skirt cut above knees, silk blouse unbuttoned slightly, thigh-high stockings, lace panties revealed subtly when seated, no bra, leather pumps",
77
+ "yoga instructor": "form-fitting athletic wear that hugs curves, moisture-wicking fabric, lace panty lines subtly visible through tight clothing, sports bra barely containing",
78
+ "policewoman": "a fitted police uniform with short skirt, thigh-high stockings, lace panties subtly showing during action poses, no bra, polished combat boots",
79
+ "female military officer in gala uniform": "a ceremonial uniform with decorative elements, thigh-high stockings, lace panties hinted beneath tailored skirt, no bra, dress shoes",
80
+ "WWII-era secretary": "vintage styled dress with seamed stockings, lace panties from era subtly revealed when bending, no bra, period-appropriate heels",
81
+ "1960s flight attendant": "retro uniform with pillbox hat, thigh-high stockings, vintage lace panties subtly visible during graceful movements, no bra, classic heels",
82
+ "boudoir model": "silk robe falling open, thigh-high stockings, intricate lace panties prominently displayed, no bra, feathered mules",
83
+ "elegant judge": "judicial robes over a sophisticated dress, thigh-high stockings, luxury lace panties subtly revealed when robes part, no bra, court heels",
84
+ "seductive librarian": "tight sweater and pencil skirt, thigh-high stockings, lace panties subtly visible when reaching for books, no bra, reading glasses",
85
+ "sensual model": "designer evening gown with thigh slit, thigh-high stockings, luxury lace panties showcased during photo shoot poses, no bra, runway heels",
86
+ "alluring secretary": "bodycon dress and blazer, thigh-high stockings, lace panties clearly outlined beneath fabric, no bra, stiletto pumps",
87
+ "elegant flight attendant": "modern uniform with scarf, thigh-high stockings, lace panties subtly visible during boarding gestures, no bra, airline heels",
88
+ "seductive maid": "traditional french maid costume shortened, thigh-high stockings, lace panties prominently displayed during cleaning poses, no bra,mary janes",
89
+ "mysterious nurse": "night shift uniform with cape, thigh-high stockings, lace panties revealed during urgent movements, no bra, silent shoes",
90
+ "captivating schoolgirl": "a short skirt and blouse with thigh-high stockings, classic black lace panties slipping into view, no bra, black patent heels",
91
+ "business executive": "power suit with mini skirt, thigh-high stockings, luxury lace panties visible during confident walking, no bra, executive heels",
92
+ "fitness model": "performance activewear, thigh-high athletic socks, sporty lace panties outlined during exercise poses, no bra, training shoes"
93
+ }
94
+
95
+ self.POSES = [
96
+ "standing gracefully with one leg slightly forward, skirt adjusting as if caught in motion revealing lace panties",
97
+ "seated on the edge, legs crossed, skirt shifting and lace panties subtly visible",
98
+ "bending forward slightly as if picking something up, skirt rising to show lace panties",
99
+ "leaning against a wall, one hip cocked, skirt riding up to reveal lace panties",
100
+ "walking with a natural sway, skirt moving with motion to show glimpses of lace panties",
101
+ "reaching upwards for an object, skirt lifting to display lace panties",
102
+ "sitting on stairs, legs slightly apart, skirt providing a view of lace panties",
103
+ "lying on a sofa, dress falling open to reveal lace panties naturally",
104
+ "dancing gently, skirt flowing to show lace panties during spins",
105
+ "adjusting stockings, skirt lifted to expose lace panties momentarily"
106
+ ]
107
+
108
+ self.SETTINGS = [
109
+ "a modern professional office with golden sunset light and sophisticated decor",
110
+ "a stylish hospital room with clean bright tones and realistic medical equipment",
111
+ "a luxurious bedroom with silk sheets and soft lighting",
112
+ "an elegant living room with vintage furniture and warm ambiance",
113
+ "a photography studio with professional lighting and minimalist backdrop",
114
+ "a high-end hotel suite with city views and contemporary design",
115
+ "a classic library with wooden shelves and warm reading lights",
116
+ "a rooftop terrace with urban landscape and twilight sky",
117
+ "a dressing room with large mirrors and velvet furnishings",
118
+ "a boutique hotel lobby with art deco elements and soft lighting"
119
+ ]
120
+
121
+ self.ATMOSPHERES = [
122
+ "soft professional lighting with perfect color, crisp highlights and smooth skin shadows",
123
+ "warm ambient sunlight, rich gold reflections and depth",
124
+ "moody cinematic lighting with dramatic shadows and highlights",
125
+ "romantic candlelight with soft glows and intimate shadows",
126
+ "studio flash lighting with clean, sharp details and minimal shadows",
127
+ "golden hour natural light with warm, flattering tones",
128
+ "moonlit ambiance with cool tones and mysterious atmosphere",
129
+ "neon accent lighting with vibrant colors and urban vibe"
130
+ ]
131
+
132
+ self.TECHNICAL_DETAILS = (
133
+ "shot in full vertical 9:16 aspect ratio capturing the entire figure with natural human proportions and anatomical precision, "
134
+ "featuring hyperrealistic skin texture with subtle imperfections, perfect makeup, and real fabric and hair strand details. "
135
+ "Captured with professional camera gear (Canon R5, 85mm lens, f/1.2) emphasizing soft, natural lighting and highlights for humanized photorealism. "
136
+ "Exclude any cartoon, 2D, painting, stylized, CGI, illustration, low resolution, or watermark artifacts."
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
137
  )
138
+
139
+ def _random_choice(self, collection: list) -> str:
140
+ return random.choice(collection)
141
+
142
+ def generate_prompt(
143
+ self,
144
+ seed_config: Optional[Dict[str, Any]] = None,
145
+ context: Optional[Dict[str, Any]] = None
146
+ ) -> str:
147
+ seed = seed_config or {}
148
+
149
+ role = seed.get("role", self._random_choice(self.ROLES))
150
+ hair_color = seed.get("hair_color", self._random_choice(self.HAIR_COLORS))
151
+ eye_color = seed.get("eye_color", self._random_choice(self.EYE_COLORS))
152
+ hair_style = seed.get("hair_style", self._random_choice(self.HAIR_STYLES))
153
+ outfit = self.OUTFIT_TEMPLATES.get(role, self.OUTFIT_TEMPLATES["secretary"])
154
+ pose = seed.get("pose", self._random_choice(self.POSES))
155
+ setting = seed.get("setting", self._random_choice(self.SETTINGS))
156
+ atmosphere = seed.get("atmosphere", self._random_choice(self.ATMOSPHERES))
157
+
158
+ context_note = f" Context: {context['summary']}." if context and "summary" in context else ""
159
+
160
+ prompt = (
161
+ f"A hyperrealistic full-body portrait of a sensual {role} with {hair_style} in {hair_color}, {eye_color} eyes, "
162
+ f"perfect makeup and flawless skin with subtle natural imperfections. Wearing {outfit}. "
163
+ f"Pose: {pose}. Scene: {setting} with {atmosphere}.{context_note} "
164
+ f"{self.TECHNICAL_DETAILS}"
165
  )
166
+
167
+ cache_list = self.cache.get(self.CACHE_KEY, [])
168
+ if prompt in cache_list:
169
+ prompt = prompt + f" [uid:{random.randint(1000,9999)}]"
170
+
171
+ cache_list.append(prompt)
172
+ self.cache.set(self.CACHE_KEY, cache_list)
173
+
174
+ return f"``````"
175
+
176
+ def generate_five_prompts(
177
+ self,
178
+ seed_config: Optional[Dict[str, Any]] = None,
179
+ context: Optional[Dict[str, Any]] = None
180
+ ) -> list[str]:
181
+ prompts = []
182
+ for _ in range(5):
183
+ prompt = self.generate_prompt(seed_config=seed_config, context=context)
184
+ prompts.append(prompt)
185
+ return prompts
186
+
187
+ def update_configuration(self, new_config: Dict[str, Any]) -> None:
188
+ for key, value in new_config.items():
189
+ if hasattr(self, key):
190
+ existing = getattr(self, key)
191
+ if isinstance(existing, list) and isinstance(value, list):
192
+ existing.extend(x for x in value if x not in existing)
193
+ elif isinstance(existing, dict) and isinstance(value, dict):
194
+ existing.update(value)
195
+
 
 
 
 
 
 
 
196
 
197
  if __name__ == "__main__":
198
+ generator = PromptGenerator()
199
+ print("Generating 5 hyperrealistic humanized full-body prompts for individual characters:\n")
200
+ prompts = generator.generate_five_prompts()
201
+ for prompt in prompts:
202
+ print(prompt + "\n")
203
+