Spaces:
Runtime error
Runtime error
Commit Β·
af4739d
1
Parent(s): 3c0d939
Grouped + TOC
Browse filesOTC linke dbyt bage number incorrect
app/DocumentGeneration/grouped.py
CHANGED
|
@@ -80,6 +80,31 @@ def should_break_page_for_group(pdf, group: Dict[str, Any], current_y: int, page
|
|
| 80 |
print(f"DEBUG: -> NO BREAK: Group will fit on current page")
|
| 81 |
return False
|
| 82 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 83 |
def parse_content_into_groups(content: str) -> List[Dict[str, Any]]:
|
| 84 |
"""Parse markdown content into subheading-content groups"""
|
| 85 |
if not content:
|
|
@@ -112,6 +137,9 @@ def parse_content_into_groups(content: str) -> List[Dict[str, Any]]:
|
|
| 112 |
(line.startswith('**') and line.endswith('**') and len(line) > 4) or # Bold headings
|
| 113 |
(re.match(r'^\*\*.*?\*\*:', line) and len(line) > 4) # Bold text before colon as heading
|
| 114 |
)
|
|
|
|
|
|
|
|
|
|
| 115 |
|
| 116 |
# Special handling for bold text following numbered subheadings
|
| 117 |
should_create_new_group = False
|
|
@@ -138,6 +166,10 @@ def parse_content_into_groups(content: str) -> List[Dict[str, Any]]:
|
|
| 138 |
# No previous group or not a numbered subheading, treat as new heading
|
| 139 |
should_create_new_group = True
|
| 140 |
print(f"DEBUG: Line {i+1} '{line[:50]}...' - Treating as NEW HEADING (no numbered subheading)")
|
|
|
|
|
|
|
|
|
|
|
|
|
| 141 |
|
| 142 |
if should_create_new_group:
|
| 143 |
# Save previous group if it exists
|
|
@@ -166,8 +198,14 @@ def parse_content_into_groups(content: str) -> List[Dict[str, Any]]:
|
|
| 166 |
clean_text = line.strip() # Keep numbered headings as-is
|
| 167 |
heading_type = 'numbered'
|
| 168 |
elif is_bold_text:
|
| 169 |
-
|
|
|
|
| 170 |
heading_type = 'bold'
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 171 |
|
| 172 |
print(f"DEBUG: Creating new group '{clean_text[:30]}...' (type: {heading_type})")
|
| 173 |
|
|
@@ -180,17 +218,19 @@ def parse_content_into_groups(content: str) -> List[Dict[str, Any]]:
|
|
| 180 |
'subheading_type': heading_type
|
| 181 |
}
|
| 182 |
else:
|
| 183 |
-
# Add to current group's content
|
| 184 |
if current_group:
|
| 185 |
-
|
|
|
|
| 186 |
if i < 5: # Log first few content lines
|
| 187 |
-
print(f"DEBUG: Added content line to group '{current_group.get('subheading_clean', 'Unknown')[:30]}...': '{
|
| 188 |
else:
|
| 189 |
# Content before any subheading - create a default group
|
| 190 |
if not groups or groups[-1].get('subheading') != '## Introduction':
|
|
|
|
| 191 |
current_group = {
|
| 192 |
'subheading': '## Introduction',
|
| 193 |
-
'content_lines': [
|
| 194 |
'content': '',
|
| 195 |
'subheading_clean': 'Introduction',
|
| 196 |
'subheading_type': 'h2'
|
|
|
|
| 80 |
print(f"DEBUG: -> NO BREAK: Group will fit on current page")
|
| 81 |
return False
|
| 82 |
|
| 83 |
+
def clean_markdown_from_line(line: str) -> str:
|
| 84 |
+
"""Clean markdown formatting from a single line"""
|
| 85 |
+
if not line:
|
| 86 |
+
return ""
|
| 87 |
+
|
| 88 |
+
cleaned = line
|
| 89 |
+
|
| 90 |
+
# Remove bold, italic formatting
|
| 91 |
+
cleaned = re.sub(r'\*\*(.*?)\*\*', r'\1', cleaned) # Remove bold
|
| 92 |
+
cleaned = re.sub(r'\*(.*?)\*', r'\1', cleaned) # Remove italic
|
| 93 |
+
cleaned = re.sub(r'`(.*?)`', r'\1', cleaned) # Remove code
|
| 94 |
+
cleaned = re.sub(r'~~(.*?)~~', r'\1', cleaned) # Remove strikethrough
|
| 95 |
+
|
| 96 |
+
# Remove emphasis markers
|
| 97 |
+
cleaned = re.sub(r'_{1,2}(.*?)_{1,2}', r'\1', cleaned) # Remove underscores
|
| 98 |
+
cleaned = re.sub(r'\*{1,2}(.*?)\*{1,2}', r'\1', cleaned) # Remove asterisks
|
| 99 |
+
|
| 100 |
+
# Remove links (keep text)
|
| 101 |
+
cleaned = re.sub(r'\[([^\]]+)\]\([^)]+\)', r'\1', cleaned) # Remove links, keep text
|
| 102 |
+
|
| 103 |
+
# Remove any remaining HTML-like tags
|
| 104 |
+
cleaned = re.sub(r'<[^>]+>', '', cleaned)
|
| 105 |
+
|
| 106 |
+
return cleaned.strip()
|
| 107 |
+
|
| 108 |
def parse_content_into_groups(content: str) -> List[Dict[str, Any]]:
|
| 109 |
"""Parse markdown content into subheading-content groups"""
|
| 110 |
if not content:
|
|
|
|
| 137 |
(line.startswith('**') and line.endswith('**') and len(line) > 4) or # Bold headings
|
| 138 |
(re.match(r'^\*\*.*?\*\*:', line) and len(line) > 4) # Bold text before colon as heading
|
| 139 |
)
|
| 140 |
+
|
| 141 |
+
# Check if this is a bold list item (e.g., "- **Item**")
|
| 142 |
+
is_bold_list_item = re.match(r'^[-*]\s*\*\*(.*?)\*\*$', line)
|
| 143 |
|
| 144 |
# Special handling for bold text following numbered subheadings
|
| 145 |
should_create_new_group = False
|
|
|
|
| 166 |
# No previous group or not a numbered subheading, treat as new heading
|
| 167 |
should_create_new_group = True
|
| 168 |
print(f"DEBUG: Line {i+1} '{line[:50]}...' - Treating as NEW HEADING (no numbered subheading)")
|
| 169 |
+
elif is_bold_list_item:
|
| 170 |
+
# If it's a bold list item, treat it as a new heading
|
| 171 |
+
should_create_new_group = True
|
| 172 |
+
print(f"DEBUG: Line {i+1} '{line[:50]}...' - Bold list item, creating new group")
|
| 173 |
|
| 174 |
if should_create_new_group:
|
| 175 |
# Save previous group if it exists
|
|
|
|
| 198 |
clean_text = line.strip() # Keep numbered headings as-is
|
| 199 |
heading_type = 'numbered'
|
| 200 |
elif is_bold_text:
|
| 201 |
+
# Remove ** markers from bold text
|
| 202 |
+
clean_text = clean_markdown_from_line(line.strip())
|
| 203 |
heading_type = 'bold'
|
| 204 |
+
elif is_bold_list_item:
|
| 205 |
+
# Extract the bold text from list item and treat as H3 subheading
|
| 206 |
+
# Remove the list marker and ** markers
|
| 207 |
+
clean_text = re.sub(r'^[-*]\s*\*\*(.*?)\*\*', r'\1', line.strip())
|
| 208 |
+
heading_type = 'h3' # Treat as H3 subheading
|
| 209 |
|
| 210 |
print(f"DEBUG: Creating new group '{clean_text[:30]}...' (type: {heading_type})")
|
| 211 |
|
|
|
|
| 218 |
'subheading_type': heading_type
|
| 219 |
}
|
| 220 |
else:
|
| 221 |
+
# Add to current group's content - clean the line
|
| 222 |
if current_group:
|
| 223 |
+
cleaned_line = clean_markdown_from_line(line)
|
| 224 |
+
current_group['content_lines'].append(cleaned_line)
|
| 225 |
if i < 5: # Log first few content lines
|
| 226 |
+
print(f"DEBUG: Added content line to group '{current_group.get('subheading_clean', 'Unknown')[:30]}...': '{cleaned_line[:50]}...'")
|
| 227 |
else:
|
| 228 |
# Content before any subheading - create a default group
|
| 229 |
if not groups or groups[-1].get('subheading') != '## Introduction':
|
| 230 |
+
cleaned_line = clean_markdown_from_line(line)
|
| 231 |
current_group = {
|
| 232 |
'subheading': '## Introduction',
|
| 233 |
+
'content_lines': [cleaned_line],
|
| 234 |
'content': '',
|
| 235 |
'subheading_clean': 'Introduction',
|
| 236 |
'subheading_type': 'h2'
|
app/DocumentGeneration/markdown_renderer.py
CHANGED
|
@@ -23,9 +23,9 @@ def clean_markdown_text(text: str) -> str:
|
|
| 23 |
# PRESERVE HEADINGS - don't strip the # markers, keep them for rendering
|
| 24 |
# We'll handle styling at render time instead of stripping them
|
| 25 |
|
| 26 |
-
#
|
| 27 |
-
|
| 28 |
-
|
| 29 |
cleaned = re.sub(r'`(.*?)`', r'\1', cleaned) # Remove code
|
| 30 |
cleaned = re.sub(r'~~(.*?)~~', r'\1', cleaned) # Remove strikethrough
|
| 31 |
|
|
@@ -48,9 +48,9 @@ def clean_markdown_text(text: str) -> str:
|
|
| 48 |
cleaned = re.sub(r'```[\s\S]*?```', '', cleaned) # Remove code blocks
|
| 49 |
cleaned = re.sub(r'`.*?`', '', cleaned) # Remove any remaining inline code
|
| 50 |
|
| 51 |
-
#
|
| 52 |
-
|
| 53 |
-
|
| 54 |
|
| 55 |
# PRESERVE CHART DATA MARKERS for inline processing
|
| 56 |
# DO NOT REMOVE chart markers - they will be processed inline
|
|
@@ -58,6 +58,10 @@ def clean_markdown_text(text: str) -> str:
|
|
| 58 |
# cleaned = re.sub(r'<!--CHARTDATASTART-->.*$', '', cleaned, flags=re.DOTALL)
|
| 59 |
# cleaned = re.sub(r'<!--CHARTDATAEND-->', '', cleaned)
|
| 60 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 61 |
# Remove any remaining HTML-like tags
|
| 62 |
cleaned = re.sub(r'<[^>]+>', '', cleaned)
|
| 63 |
|
|
@@ -442,12 +446,70 @@ def render_markdown_to_pdf_grouped(pdf, content: str, primary_color, accent_colo
|
|
| 442 |
content_lines = group_content.split('\n')
|
| 443 |
for line in content_lines:
|
| 444 |
if line.strip():
|
| 445 |
-
#
|
| 446 |
-
|
| 447 |
-
|
| 448 |
-
|
| 449 |
-
|
| 450 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 451 |
else:
|
| 452 |
# Empty line spacing
|
| 453 |
pdf.ln(3)
|
|
@@ -489,7 +551,49 @@ def render_markdown_to_docx(doc, content: str):
|
|
| 489 |
# Regular bold text
|
| 490 |
doc.add_paragraph(text)
|
| 491 |
else: # Normal paragraph text
|
| 492 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 493 |
|
| 494 |
|
| 495 |
def render_markdown_to_docx_grouped(doc, content: str):
|
|
@@ -541,8 +645,50 @@ def render_markdown_to_docx_grouped(doc, content: str):
|
|
| 541 |
content_lines = group_content.split('\n')
|
| 542 |
for line in content_lines:
|
| 543 |
if line.strip():
|
| 544 |
-
#
|
| 545 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 546 |
else:
|
| 547 |
doc.add_paragraph() # Empty paragraph for spacing
|
| 548 |
|
|
|
|
| 23 |
# PRESERVE HEADINGS - don't strip the # markers, keep them for rendering
|
| 24 |
# We'll handle styling at render time instead of stripping them
|
| 25 |
|
| 26 |
+
# Remove bold, italic formatting - strip ** or * symbols
|
| 27 |
+
cleaned = re.sub(r'\*\*(.*?)\*\*', r'\1', cleaned) # Remove bold
|
| 28 |
+
cleaned = re.sub(r'\*(.*?)\*', r'\1', cleaned) # Remove italic
|
| 29 |
cleaned = re.sub(r'`(.*?)`', r'\1', cleaned) # Remove code
|
| 30 |
cleaned = re.sub(r'~~(.*?)~~', r'\1', cleaned) # Remove strikethrough
|
| 31 |
|
|
|
|
| 48 |
cleaned = re.sub(r'```[\s\S]*?```', '', cleaned) # Remove code blocks
|
| 49 |
cleaned = re.sub(r'`.*?`', '', cleaned) # Remove any remaining inline code
|
| 50 |
|
| 51 |
+
# Remove emphasis markers - strip ** or * symbols
|
| 52 |
+
cleaned = re.sub(r'_{1,2}(.*?)_{1,2}', r'\1', cleaned) # Remove underscores
|
| 53 |
+
cleaned = re.sub(r'\*{1,2}(.*?)\*{1,2}', r'\1', cleaned) # Remove asterisks
|
| 54 |
|
| 55 |
# PRESERVE CHART DATA MARKERS for inline processing
|
| 56 |
# DO NOT REMOVE chart markers - they will be processed inline
|
|
|
|
| 58 |
# cleaned = re.sub(r'<!--CHARTDATASTART-->.*$', '', cleaned, flags=re.DOTALL)
|
| 59 |
# cleaned = re.sub(r'<!--CHARTDATAEND-->', '', cleaned)
|
| 60 |
|
| 61 |
+
# REMOVE CHART DATA MARKERS for PDF rendering since they're not being processed
|
| 62 |
+
cleaned = re.sub(r'<!--CHART_DATA_START-->.*?<!--CHART_DATA_END-->', '', cleaned, flags=re.DOTALL)
|
| 63 |
+
cleaned = re.sub(r'<!--CHARTDATASTART-->.*?<!--CHARTDATAEND-->', '', cleaned, flags=re.DOTALL)
|
| 64 |
+
|
| 65 |
# Remove any remaining HTML-like tags
|
| 66 |
cleaned = re.sub(r'<[^>]+>', '', cleaned)
|
| 67 |
|
|
|
|
| 446 |
content_lines = group_content.split('\n')
|
| 447 |
for line in content_lines:
|
| 448 |
if line.strip():
|
| 449 |
+
# Check if line contains text ending with ":" that should be bold
|
| 450 |
+
if ':' in line:
|
| 451 |
+
# Split the line by ":" to separate the label from the content
|
| 452 |
+
parts = line.split(':', 1) # Split only on first ":"
|
| 453 |
+
if len(parts) == 2:
|
| 454 |
+
label = parts[0].strip()
|
| 455 |
+
content = parts[1].strip()
|
| 456 |
+
|
| 457 |
+
# Render label in bold
|
| 458 |
+
pdf.set_font("Arial", "B", 12) # Bold
|
| 459 |
+
pdf.set_text_color(*text_color)
|
| 460 |
+
pdf.set_xy(25, current_y)
|
| 461 |
+
pdf.multi_cell(160, 8, label + ":")
|
| 462 |
+
current_y = pdf.get_y()
|
| 463 |
+
|
| 464 |
+
# Render content in regular font
|
| 465 |
+
if content:
|
| 466 |
+
pdf.set_font("Arial", "", 12) # Regular
|
| 467 |
+
pdf.set_text_color(*text_color)
|
| 468 |
+
pdf.set_xy(25, current_y)
|
| 469 |
+
pdf.multi_cell(160, 8, content)
|
| 470 |
+
current_y = pdf.get_y()
|
| 471 |
+
else:
|
| 472 |
+
# No content after ":", just render the whole line
|
| 473 |
+
pdf.set_font("Arial", "B", 12) # Bold for labels ending with ":"
|
| 474 |
+
pdf.set_text_color(*text_color)
|
| 475 |
+
pdf.set_xy(25, current_y)
|
| 476 |
+
pdf.multi_cell(160, 8, line)
|
| 477 |
+
current_y = pdf.get_y()
|
| 478 |
+
elif ' - ' in line:
|
| 479 |
+
# Split the line by " - " to separate the label from the content
|
| 480 |
+
parts = line.split(' - ', 1) # Split only on first " - "
|
| 481 |
+
if len(parts) == 2:
|
| 482 |
+
label = parts[0].strip()
|
| 483 |
+
content = parts[1].strip()
|
| 484 |
+
|
| 485 |
+
# Render label in bold
|
| 486 |
+
pdf.set_font("Arial", "B", 12) # Bold
|
| 487 |
+
pdf.set_text_color(*text_color)
|
| 488 |
+
pdf.set_xy(25, current_y)
|
| 489 |
+
pdf.multi_cell(160, 8, label + " -")
|
| 490 |
+
current_y = pdf.get_y()
|
| 491 |
+
|
| 492 |
+
# Render content in regular font
|
| 493 |
+
if content:
|
| 494 |
+
pdf.set_font("Arial", "", 12) # Regular
|
| 495 |
+
pdf.set_text_color(*text_color)
|
| 496 |
+
pdf.set_xy(25, current_y)
|
| 497 |
+
pdf.multi_cell(160, 8, content)
|
| 498 |
+
current_y = pdf.get_y()
|
| 499 |
+
else:
|
| 500 |
+
# No content after " - ", just render the whole line
|
| 501 |
+
pdf.set_font("Arial", "B", 12) # Bold for labels ending with " -"
|
| 502 |
+
pdf.set_text_color(*text_color)
|
| 503 |
+
pdf.set_xy(25, current_y)
|
| 504 |
+
pdf.multi_cell(160, 8, line)
|
| 505 |
+
current_y = pdf.get_y()
|
| 506 |
+
else:
|
| 507 |
+
# Regular paragraph rendering without mixed text processing
|
| 508 |
+
pdf.set_font("Arial", "", 12)
|
| 509 |
+
pdf.set_text_color(*text_color)
|
| 510 |
+
pdf.set_xy(25, current_y)
|
| 511 |
+
pdf.multi_cell(160, 8, line)
|
| 512 |
+
current_y = pdf.get_y() # Update current_y after each line
|
| 513 |
else:
|
| 514 |
# Empty line spacing
|
| 515 |
pdf.ln(3)
|
|
|
|
| 551 |
# Regular bold text
|
| 552 |
doc.add_paragraph(text)
|
| 553 |
else: # Normal paragraph text
|
| 554 |
+
# Check if line contains text ending with ":" that should be bold
|
| 555 |
+
if ':' in line:
|
| 556 |
+
# Split the line by ":" to separate the label from the content
|
| 557 |
+
parts = line.split(':', 1) # Split only on first ":"
|
| 558 |
+
if len(parts) == 2:
|
| 559 |
+
label = parts[0].strip()
|
| 560 |
+
content = parts[1].strip()
|
| 561 |
+
|
| 562 |
+
# Create paragraph with mixed formatting
|
| 563 |
+
paragraph = doc.add_paragraph()
|
| 564 |
+
# Add label in bold
|
| 565 |
+
run = paragraph.add_run(label + ":")
|
| 566 |
+
run.bold = True
|
| 567 |
+
# Add content in regular font
|
| 568 |
+
if content:
|
| 569 |
+
run = paragraph.add_run(" " + content)
|
| 570 |
+
run.bold = False
|
| 571 |
+
else:
|
| 572 |
+
# No content after ":", just render the whole line in bold
|
| 573 |
+
paragraph = doc.add_paragraph(line)
|
| 574 |
+
paragraph.runs[0].bold = True
|
| 575 |
+
elif ' - ' in line:
|
| 576 |
+
# Split the line by " - " to separate the label from the content
|
| 577 |
+
parts = line.split(' - ', 1) # Split only on first " - "
|
| 578 |
+
if len(parts) == 2:
|
| 579 |
+
label = parts[0].strip()
|
| 580 |
+
content = parts[1].strip()
|
| 581 |
+
|
| 582 |
+
# Create paragraph with mixed formatting
|
| 583 |
+
paragraph = doc.add_paragraph()
|
| 584 |
+
# Add label in bold
|
| 585 |
+
run = paragraph.add_run(label + " -")
|
| 586 |
+
run.bold = True
|
| 587 |
+
# Add content in regular font
|
| 588 |
+
if content:
|
| 589 |
+
run = paragraph.add_run(" " + content)
|
| 590 |
+
run.bold = False
|
| 591 |
+
else:
|
| 592 |
+
# No content after " - ", just render the whole line in bold
|
| 593 |
+
paragraph = doc.add_paragraph(line)
|
| 594 |
+
paragraph.runs[0].bold = True
|
| 595 |
+
else:
|
| 596 |
+
doc.add_paragraph(line)
|
| 597 |
|
| 598 |
|
| 599 |
def render_markdown_to_docx_grouped(doc, content: str):
|
|
|
|
| 645 |
content_lines = group_content.split('\n')
|
| 646 |
for line in content_lines:
|
| 647 |
if line.strip():
|
| 648 |
+
# Check if line contains text ending with ":" that should be bold
|
| 649 |
+
if ':' in line:
|
| 650 |
+
# Split the line by ":" to separate the label from the content
|
| 651 |
+
parts = line.split(':', 1) # Split only on first ":"
|
| 652 |
+
if len(parts) == 2:
|
| 653 |
+
label = parts[0].strip()
|
| 654 |
+
content = parts[1].strip()
|
| 655 |
+
|
| 656 |
+
# Create paragraph with mixed formatting
|
| 657 |
+
paragraph = doc.add_paragraph()
|
| 658 |
+
# Add label in bold
|
| 659 |
+
run = paragraph.add_run(label + ":")
|
| 660 |
+
run.bold = True
|
| 661 |
+
# Add content in regular font
|
| 662 |
+
if content:
|
| 663 |
+
run = paragraph.add_run(" " + content)
|
| 664 |
+
run.bold = False
|
| 665 |
+
else:
|
| 666 |
+
# No content after ":", just render the whole line in bold
|
| 667 |
+
paragraph = doc.add_paragraph(line)
|
| 668 |
+
paragraph.runs[0].bold = True
|
| 669 |
+
elif ' - ' in line:
|
| 670 |
+
# Split the line by " - " to separate the label from the content
|
| 671 |
+
parts = line.split(' - ', 1) # Split only on first " - "
|
| 672 |
+
if len(parts) == 2:
|
| 673 |
+
label = parts[0].strip()
|
| 674 |
+
content = parts[1].strip()
|
| 675 |
+
|
| 676 |
+
# Create paragraph with mixed formatting
|
| 677 |
+
paragraph = doc.add_paragraph()
|
| 678 |
+
# Add label in bold
|
| 679 |
+
run = paragraph.add_run(label + " -")
|
| 680 |
+
run.bold = True
|
| 681 |
+
# Add content in regular font
|
| 682 |
+
if content:
|
| 683 |
+
run = paragraph.add_run(" " + content)
|
| 684 |
+
run.bold = False
|
| 685 |
+
else:
|
| 686 |
+
# No content after " - ", just render the whole line in bold
|
| 687 |
+
paragraph = doc.add_paragraph(line)
|
| 688 |
+
paragraph.runs[0].bold = True
|
| 689 |
+
else:
|
| 690 |
+
# Simple paragraph addition without mixed text processing
|
| 691 |
+
doc.add_paragraph(line)
|
| 692 |
else:
|
| 693 |
doc.add_paragraph() # Empty paragraph for spacing
|
| 694 |
|
app/DocumentGeneration/table_of_content.py
CHANGED
|
@@ -110,9 +110,22 @@ def add_table_of_contents_page(pdf, toc_items: List[Dict[str, Any]], business_id
|
|
| 110 |
pdf.set_font("Arial", "", 10)
|
| 111 |
pdf.set_text_color(*text_color)
|
| 112 |
|
| 113 |
-
# Title
|
|
|
|
| 114 |
pdf.set_xy(25 + indent, y_position)
|
| 115 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 116 |
|
| 117 |
# Dots leading to page number
|
| 118 |
pdf.set_font("Arial", "", 8)
|
|
@@ -128,8 +141,21 @@ def add_table_of_contents_page(pdf, toc_items: List[Dict[str, Any]], business_id
|
|
| 128 |
pdf.set_xy(x, y_position + 3)
|
| 129 |
pdf.cell(1, 1, ".", ln=False)
|
| 130 |
|
| 131 |
-
# Page number
|
|
|
|
| 132 |
pdf.set_xy(160, y_position)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 133 |
pdf.cell(0, 8, str(item["page"]), ln=False)
|
| 134 |
|
| 135 |
# Reduced spacing between items for better page utilization
|
|
|
|
| 110 |
pdf.set_font("Arial", "", 10)
|
| 111 |
pdf.set_text_color(*text_color)
|
| 112 |
|
| 113 |
+
# Title with hyperlink
|
| 114 |
+
title_width = pdf.get_string_width(item["title"])
|
| 115 |
pdf.set_xy(25 + indent, y_position)
|
| 116 |
+
try:
|
| 117 |
+
# FPDF2 uses 0-based indexing, so subtract 1 from displayed page number
|
| 118 |
+
target_page = item["page"] - 1
|
| 119 |
+
# Try different FPDF2 link methods
|
| 120 |
+
if hasattr(pdf, 'add_link'):
|
| 121 |
+
link_id = pdf.add_link()
|
| 122 |
+
pdf.set_link(link_id, page=target_page)
|
| 123 |
+
pdf.link(25 + indent, y_position, title_width, 8, link_id)
|
| 124 |
+
else:
|
| 125 |
+
pdf.link(25 + indent, y_position, title_width, 8, dest=target_page)
|
| 126 |
+
except:
|
| 127 |
+
pass # If hyperlink fails, continue without it
|
| 128 |
+
pdf.cell(title_width, 8, item["title"], ln=False)
|
| 129 |
|
| 130 |
# Dots leading to page number
|
| 131 |
pdf.set_font("Arial", "", 8)
|
|
|
|
| 141 |
pdf.set_xy(x, y_position + 3)
|
| 142 |
pdf.cell(1, 1, ".", ln=False)
|
| 143 |
|
| 144 |
+
# Page number with hyperlink
|
| 145 |
+
page_number_width = pdf.get_string_width(str(item["page"]))
|
| 146 |
pdf.set_xy(160, y_position)
|
| 147 |
+
try:
|
| 148 |
+
# FPDF2 uses 0-based indexing, so subtract 1 from displayed page number
|
| 149 |
+
target_page = item["page"] - 1
|
| 150 |
+
# Try different FPDF2 link methods
|
| 151 |
+
if hasattr(pdf, 'add_link'):
|
| 152 |
+
link_id = pdf.add_link()
|
| 153 |
+
pdf.set_link(link_id, page=target_page)
|
| 154 |
+
pdf.link(160, y_position, page_number_width, 8, link_id)
|
| 155 |
+
else:
|
| 156 |
+
pdf.link(160, y_position, page_number_width, 8, dest=target_page)
|
| 157 |
+
except:
|
| 158 |
+
pass # If hyperlink fails, continue without it
|
| 159 |
pdf.cell(0, 8, str(item["page"]), ln=False)
|
| 160 |
|
| 161 |
# Reduced spacing between items for better page utilization
|
live_pdf_example.html
CHANGED
|
@@ -146,6 +146,7 @@
|
|
| 146 |
</div>
|
| 147 |
|
| 148 |
<button id="addSectionBtn" class="add-section-btn">+ Add New Section</button>
|
|
|
|
| 149 |
</div>
|
| 150 |
|
| 151 |
<div class="pdf-panel">
|
|
@@ -203,6 +204,7 @@
|
|
| 203 |
this.downloadBtn = document.getElementById('downloadPdf');
|
| 204 |
this.refreshBtn = document.getElementById('refreshPdf');
|
| 205 |
this.addSectionBtn = document.getElementById('addSectionBtn');
|
|
|
|
| 206 |
this.statusDiv = document.getElementById('status');
|
| 207 |
this.sectionsContainer = document.getElementById('sectionsContainer');
|
| 208 |
this.pdfViewer = document.getElementById('pdfViewer');
|
|
@@ -214,6 +216,7 @@
|
|
| 214 |
this.downloadBtn.addEventListener('click', () => this.downloadPdf());
|
| 215 |
this.refreshBtn.addEventListener('click', () => this.refreshPdf());
|
| 216 |
this.addSectionBtn.addEventListener('click', () => this.addNewSection());
|
|
|
|
| 217 |
|
| 218 |
// Auto-update content as user types (with debouncing)
|
| 219 |
let updateTimeout;
|
|
@@ -543,6 +546,362 @@
|
|
| 543 |
this.statusDiv.textContent = message;
|
| 544 |
this.statusDiv.className = `status ${type}`;
|
| 545 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 546 |
}
|
| 547 |
|
| 548 |
// Initialize the live PDF client when page loads
|
|
|
|
| 146 |
</div>
|
| 147 |
|
| 148 |
<button id="addSectionBtn" class="add-section-btn">+ Add New Section</button>
|
| 149 |
+
<button id="populateAllBtn" class="add-section-btn" style="background-color: #17a2b8; margin-left: 10px;">π Load Complete Business Plan</button>
|
| 150 |
</div>
|
| 151 |
|
| 152 |
<div class="pdf-panel">
|
|
|
|
| 204 |
this.downloadBtn = document.getElementById('downloadPdf');
|
| 205 |
this.refreshBtn = document.getElementById('refreshPdf');
|
| 206 |
this.addSectionBtn = document.getElementById('addSectionBtn');
|
| 207 |
+
this.populateAllBtn = document.getElementById('populateAllBtn');
|
| 208 |
this.statusDiv = document.getElementById('status');
|
| 209 |
this.sectionsContainer = document.getElementById('sectionsContainer');
|
| 210 |
this.pdfViewer = document.getElementById('pdfViewer');
|
|
|
|
| 216 |
this.downloadBtn.addEventListener('click', () => this.downloadPdf());
|
| 217 |
this.refreshBtn.addEventListener('click', () => this.refreshPdf());
|
| 218 |
this.addSectionBtn.addEventListener('click', () => this.addNewSection());
|
| 219 |
+
this.populateAllBtn.addEventListener('click', () => this.populateAllSections());
|
| 220 |
|
| 221 |
// Auto-update content as user types (with debouncing)
|
| 222 |
let updateTimeout;
|
|
|
|
| 546 |
this.statusDiv.textContent = message;
|
| 547 |
this.statusDiv.className = `status ${type}`;
|
| 548 |
}
|
| 549 |
+
|
| 550 |
+
populateAllSections() {
|
| 551 |
+
// Clear existing sections
|
| 552 |
+
this.sectionsContainer.innerHTML = '';
|
| 553 |
+
this.sections = [];
|
| 554 |
+
this.sectionCounter = 0;
|
| 555 |
+
|
| 556 |
+
// Add all sections with their content
|
| 557 |
+
const sectionData = [
|
| 558 |
+
{
|
| 559 |
+
title: "Executive Summary",
|
| 560 |
+
content: `## Executive Summary
|
| 561 |
+
|
| 562 |
+
### 1.1 Business Name, Tagline & Logo Reference
|
| 563 |
+
- **Business Name:** InnovateWash Solutions
|
| 564 |
+
- **Tagline:** "Revolutionizing Car Care with Intelligent Software"
|
| 565 |
+
- **Logo Concept:** A sleek, modern emblem combining the outline of a car with digital elements such as circuit patterns or AI icons. The color palette features deep green and gold, symbolizing growth and prosperity, while respecting UAE's cultural affinity for luxury and innovation.
|
| 566 |
+
|
| 567 |
+
### 1.2 Business Concept Overview
|
| 568 |
+
InnovateWash Solutions offers cutting-edge software solutions tailored for car wash businesses in the United Arab Emirates. Our AI-powered platform streamlines operations, enhances customer experience, and optimizes resource management. By addressing the needs of small to medium car wash enterprises, we align with the UAE's growing demand for smart, efficient business technologies.
|
| 569 |
+
|
| 570 |
+
### 1.3 Problem Statement
|
| 571 |
+
Many car wash operators in the UAE face challenges in managing customer flow, inventory, and staff efficiently, resulting in lost revenue and customer dissatisfaction. Existing software solutions are often generic, lacking customization for local market conditions and fail to integrate AI-driven insights that can improve operational decision-making.
|
| 572 |
+
|
| 573 |
+
### 1.4 Solution Summary
|
| 574 |
+
InnovateWash Solutions delivers a smart, AI-powered software platform designed specifically for car wash businesses in the UAE. Key benefits include:
|
| 575 |
+
- Enhanced operational efficiency through automation and predictive analytics
|
| 576 |
+
- Improved customer engagement with personalized service options
|
| 577 |
+
- Scalable platform adaptable to the unique needs of small to medium enterprises
|
| 578 |
+
|
| 579 |
+
### 1.5 Vision and Mission Statement
|
| 580 |
+
**Vision:** To become the leading provider of intelligent software solutions that empower UAE car wash businesses to achieve operational excellence and sustainable growth.
|
| 581 |
+
**Mission:** We aim to harness advanced AI technology and local market insights to deliver innovative, user-friendly software that enhances efficiency and customer satisfaction, supporting the UAE's vision for a diversified and tech-driven economy.
|
| 582 |
+
|
| 583 |
+
### 1.6 Financial Snapshot and Funding Requirement
|
| 584 |
+
Our projected revenue is expected to reach between AED 400,000 and AED 600,000 in the first year, driven primarily by subscription sales and service contracts. Major cost drivers include software development, cloud infrastructure, and digital marketing efforts. We anticipate a profit margin of approximately 20% as we scale and optimize operations.
|
| 585 |
+
We require total funding of AED 500,000 to accelerate product development, expand marketing initiatives, and build a strong customer acquisition pipeline. This investment will ensure rapid market penetration and sustainable growth within the UAE car wash sector.
|
| 586 |
+
|
| 587 |
+
### 1.7 Key Milestones and Traction to Date
|
| 588 |
+
- Completed initial software prototype β Q1 2024
|
| 589 |
+
- Assembled a skilled development team of 5 experienced professionals β Q2 2024
|
| 590 |
+
- Secured commitment for AED 500,000 in initial funding β Q2 2024
|
| 591 |
+
- Launched digital marketing campaign targeting UAE car wash businesses β Q2 2024`
|
| 592 |
+
},
|
| 593 |
+
{
|
| 594 |
+
title: "Company Profile",
|
| 595 |
+
content: `## Company Profile
|
| 596 |
+
|
| 597 |
+
### 2.1 Company Overview (Founding, Location)
|
| 598 |
+
Test Business Name is planned to be founded in 2024 by a team of five experienced developers specializing in innovative software solutions. The company will be headquartered in Dubai, United Arab Emirates, selected for its strategic position as a regional technology hub and its robust infrastructure supporting tech startups. Dubai's dynamic business environment and access to a growing market of small to medium enterprises make it an ideal location for launching our AI-powered software solutions.
|
| 599 |
+
|
| 600 |
+
### 2.2 Legal Structure and Ownership
|
| 601 |
+
The company will be registered as a Limited Liability Company (LLC) in the United Arab Emirates, which provides flexibility and limited personal liability for shareholders. Ownership is held by the five founding members, each contributing equally to the initial capital and sharing ownership stakes of 20% each. This structure allows for collaborative decision-making and shared responsibility among the core team.
|
| 602 |
+
|
| 603 |
+
### 2.3 Business Objectives (Short-Term and Long-Term)
|
| 604 |
+
**Short-Term (next 12 months):**
|
| 605 |
+
- Acquire 100 paying customers within the UAE small and medium business sector.
|
| 606 |
+
- Generate AED 500,000 in revenue through digital marketing campaigns and direct sales.
|
| 607 |
+
- Secure initial funding of AED 500,000 to support product development and market entry.
|
| 608 |
+
|
| 609 |
+
**Long-Term (2β5 years):**
|
| 610 |
+
- Expand service offerings to at least two additional Gulf Cooperation Council (GCC) countries.
|
| 611 |
+
- Achieve profitability with a 25% net margin by scaling AI-driven software solutions.
|
| 612 |
+
- Build a development team of 15 experienced professionals to enhance product innovation.
|
| 613 |
+
|
| 614 |
+
### 2.4 Company History or Origin Story
|
| 615 |
+
The idea for Test Business Name originated from the founders' shared experience in software development and their recognition of the challenges faced by small to medium businesses in adopting advanced technology solutions. Observing a gap in the UAE market for affordable, AI-powered software, the team decided to leverage their skills to create innovative solutions tailored to local business needs. Early milestones include developing a prototype system and receiving positive feedback from local SMEs, validating the market potential.
|
| 616 |
+
|
| 617 |
+
### 2.5 Business Type and Operating Model
|
| 618 |
+
Test Business Name operates primarily as a B2B SaaS company, offering subscription-based access to AI-powered software solutions designed to enhance business operations. Revenue is generated through recurring subscription fees, allowing clients to scale their usage based on their needs. The company plans to utilize digital channels for customer acquisition and establish partnerships with local business councils and technology incubators to expand its distribution network within the UAE.`
|
| 619 |
+
},
|
| 620 |
+
{
|
| 621 |
+
title: "Market Analysis",
|
| 622 |
+
content: `## Market Analysis
|
| 623 |
+
|
| 624 |
+
### 3.1 Target Market Segmentation
|
| 625 |
+
- **Small to Medium Enterprises (SMEs) in UAE**: This segment includes businesses with 10-250 employees primarily located in Dubai and Abu Dhabi. They seek innovative software to improve operational efficiency and competitiveness, representing an AED 3 billion market annually.
|
| 626 |
+
- **Tech-Savvy Startups and Entrepreneurs**: Typically younger, growth-oriented companies in sectors such as fintech and e-commerce. These customers value AI-driven solutions and digital transformation, with an estimated market size of AED 1.2 billion.
|
| 627 |
+
|
| 628 |
+
### 3.2 Market Size and Growth Potential
|
| 629 |
+
The total addressable market for innovative software solutions in the UAE is estimated at AED 4.2 billion, driven largely by the rapid digital transformation across industries. Key growth drivers include rising internet adoption and government initiatives such as the UAE's National Innovation Strategy, which promotes tech adoption.
|
| 630 |
+
|
| 631 |
+
### 3.3 Industry Trends and Market Drivers
|
| 632 |
+
- Increased cloud adoption with over 60% of UAE businesses migrating to cloud platforms in 2024.
|
| 633 |
+
- Growing emphasis on AI and machine learning, with AI investments expected to grow by 35% annually in the region.
|
| 634 |
+
- Expansion of smart city initiatives, notably in Dubai and Abu Dhabi, fueling demand for advanced software.
|
| 635 |
+
- Shift towards remote work and digital collaboration tools, accelerated by post-pandemic business models.
|
| 636 |
+
|
| 637 |
+
### 3.4 Customer Needs and Pain Points
|
| 638 |
+
- Need for scalable, customizable software solutions that can adapt to fast-changing business environments in the UAE's dynamic market.
|
| 639 |
+
- Demand for AI-powered automation to reduce operational costs and improve decision-making efficiency.
|
| 640 |
+
- Concerns about data security and compliance with UAE regulations, especially in fintech and healthcare sectors.
|
| 641 |
+
- Frustrations with high costs and complexity of existing software offerings, particularly among SMEs with limited IT budgets.
|
| 642 |
+
|
| 643 |
+
### 3.5 Competitive Landscape Overview
|
| 644 |
+
- **Tech Innovate Solutions**: Provides enterprise software tailored to the UAE market, holding an estimated 25% market share. Their strength lies in deep local partnerships, but they lack advanced AI integration, which Test Business Name offers.
|
| 645 |
+
- **Gulf Digital Systems**: Focuses on cloud-based applications with robust client support, commanding around 18% market share. Test Business Name differentiates itself by leveraging cutting-edge AI features that improve user experience.
|
| 646 |
+
- **Emirates Software Hub**: Known for customizable ERP solutions with a 15% share, they excel in traditional software but lag in AI-powered innovation, an area where Test Business Name leads.
|
| 647 |
+
|
| 648 |
+
### 3.6 SWOT Analysis
|
| 649 |
+
|
| 650 |
+
#### Strengths
|
| 651 |
+
- Differentiation through AI-powered features that enhance software capabilities.
|
| 652 |
+
- Agile team of 5 experienced developers enabling rapid innovation and customization.
|
| 653 |
+
- Understanding of local market needs and regulatory environment in UAE.
|
| 654 |
+
|
| 655 |
+
#### Weaknesses
|
| 656 |
+
- Limited brand recognition as a new entrant in a competitive market.
|
| 657 |
+
- Modest initial funding requirement of AED 500,000 may constrain early scaling efforts.
|
| 658 |
+
- Small team size may limit simultaneous project capacity.
|
| 659 |
+
|
| 660 |
+
#### Opportunities
|
| 661 |
+
- UAE government incentives supporting tech startups and innovation under initiatives like Dubai Future Accelerators.
|
| 662 |
+
- Increasing digital transformation budgets among SMEs seeking competitive advantages.
|
| 663 |
+
- Expansion of smart city projects creating demand for intelligent software solutions.
|
| 664 |
+
|
| 665 |
+
#### Threats
|
| 666 |
+
- Established competitors with strong client relationships and larger market shares.
|
| 667 |
+
- Potential regulatory changes impacting software compliance requirements.
|
| 668 |
+
- Currency fluctuations affecting technology import costs and pricing strategies.`
|
| 669 |
+
},
|
| 670 |
+
{
|
| 671 |
+
title: "Product or Service",
|
| 672 |
+
content: `## Product or Service
|
| 673 |
+
|
| 674 |
+
### 4.1 Product or Service Description
|
| 675 |
+
Test Business Name provides innovative software solutions designed to streamline business operations for small to medium enterprises in the United Arab Emirates. Our AI-powered platform enhances productivity by automating routine tasks and delivering actionable insights tailored to local market needs. The end-user experience focuses on ease of use, with intuitive interfaces and Arabic and English language support to meet UAE consumer preferences. By integrating advanced technology with regional business practices, we help clients adapt quickly to a competitive digital landscape.
|
| 676 |
+
|
| 677 |
+
### 4.2 Core Features and Benefits
|
| 678 |
+
- **AI-Powered Automation**: Automates repetitive processes β **Benefit**: Saves time and reduces costs for UAE businesses facing competitive pressures.
|
| 679 |
+
- **Bilingual Interface (Arabic & English)**: Supports both official languages β **Benefit**: Ensures accessibility and usability across diverse UAE customer segments.
|
| 680 |
+
- **Customizable Dashboards**: Tailors data visualization to user needs β **Benefit**: Enables informed decision-making aligned with UAE market dynamics.
|
| 681 |
+
- **Cloud-Based Platform**: Offers secure, scalable access β **Benefit**: Facilitates remote work and business continuity in UAE's fast-growing digital economy.
|
| 682 |
+
|
| 683 |
+
### 4.3 Unique Selling Proposition (USP)
|
| 684 |
+
Our AI-powered software uniquely combines advanced automation with bilingual functionality tailored specifically for the UAE's diverse business environment.
|
| 685 |
+
- Addresses the multilingual needs of UAE companies, improving adoption and user satisfaction.
|
| 686 |
+
- Delivers AI-driven insights that help local businesses optimize operations amid rapid market changes.
|
| 687 |
+
|
| 688 |
+
### 4.4 Development Stage (MVP, Beta, Market Launch)
|
| 689 |
+
We are currently in the MVP stage, having developed a functional prototype tested by a select group of beta users. To date, we have invested approximately AED 500,000 in development, focusing on refining core AI features and ensuring robust bilingual support. Feedback from early users is guiding enhancements ahead of a full market launch.
|
| 690 |
+
|
| 691 |
+
### 4.5 Intellectual Property and Innovation
|
| 692 |
+
- Proprietary AI algorithms optimized for business process automation (registration pending in the UAE).
|
| 693 |
+
- Trademark for the Test Business Name brand registered with the UAE Ministry of Economy.
|
| 694 |
+
- Customizable bilingual user interface framework (under development for patent application).
|
| 695 |
+
|
| 696 |
+
These innovations give us a strong competitive edge by aligning technology with local linguistic and operational requirements, making our solutions uniquely effective for UAE businesses.`
|
| 697 |
+
},
|
| 698 |
+
{
|
| 699 |
+
title: "Business Model",
|
| 700 |
+
content: `## Business Model
|
| 701 |
+
|
| 702 |
+
### 5.1 Revenue Streams
|
| 703 |
+
- **Subscription Fees: AED 300,000 annually**
|
| 704 |
+
We offer subscription-based access to our AI-powered software solutions, which fits the UAE market's preference for scalable recurring services and ongoing support. Businesses in the region seek reliable, continuously updated software for their operations.
|
| 705 |
+
- **One-time Licensing Fees: AED 150,000 annually**
|
| 706 |
+
Some customers prefer one-time licensing for perpetual use, especially SMEs aiming to control long-term costs. This option suits companies in the UAE looking for upfront clarity on expenses.
|
| 707 |
+
- **Service Contracts: AED 50,000 annually**
|
| 708 |
+
We provide customized implementation, training, and maintenance contracts, which are highly valued in the UAE for ensuring smooth integration and localized support.
|
| 709 |
+
- **Consulting and Custom Development: AED 50,000 annually**
|
| 710 |
+
Tailored AI solutions and consulting services meet the needs of UAE businesses wanting competitive advantages through innovation.
|
| 711 |
+
|
| 712 |
+
### 5.2 Pricing Strategy
|
| 713 |
+
We offer three pricing tiers designed to accommodate various business sizes and budgets in the UAE:
|
| 714 |
+
|
| 715 |
+
- **Basic Package: AED 50,000 per year**
|
| 716 |
+
Includes core AI features and limited support, targeting startups and small businesses.
|
| 717 |
+
- **Premium Package: AED 120,000 per year**
|
| 718 |
+
Offers advanced AI functionalities, full support, and regular updates, suitable for medium-sized enterprises.
|
| 719 |
+
- **Enterprise Package: Custom pricing starting at AED 250,000 per year**
|
| 720 |
+
Tailored solutions with dedicated support and customization for large clients.
|
| 721 |
+
|
| 722 |
+
This tiered pricing aligns with UAE purchasing power and allows flexibility compared to established tech competitors. It also reflects the value of AI-driven innovation in the region.
|
| 723 |
+
|
| 724 |
+
### 5.3 Sales and Distribution Channels
|
| 725 |
+
- **Direct Sales**
|
| 726 |
+
Our sales team engages directly with potential clients, leveraging personal relationships common in the UAE business culture and facilitating contract negotiations.
|
| 727 |
+
- **E-commerce Marketplace**
|
| 728 |
+
We list our software on popular UAE B2B platforms that support local payment methods such as credit cards and digital wallets, enabling easy purchase and subscription management.
|
| 729 |
+
- **Channel Partners and Resellers**
|
| 730 |
+
We collaborate with UAE-based IT consultancies and systems integrators who promote and deploy our solutions, offering localized expertise and faster market reach.
|
| 731 |
+
- **Digital Marketing and Webinars**
|
| 732 |
+
We use digital channels to generate leads and educate prospects, adapting to the UAE's high internet penetration and tech-savvy audience.
|
| 733 |
+
|
| 734 |
+
### 5.4 Customer Acquisition Strategy
|
| 735 |
+
- **Social Media Advertising**
|
| 736 |
+
Targeted ads on LinkedIn and Instagram focus on UAE business decision-makers, aiming for a cost-per-acquisition (CPA) of AED 500.
|
| 737 |
+
- **Referral Program**
|
| 738 |
+
Incentivizing existing customers and partners to refer new clients within the UAE market to leverage word-of-mouth trust.
|
| 739 |
+
- **Local Industry Events and Trade Shows**
|
| 740 |
+
Participation in UAE tech and business events to network and demonstrate our AI solutions directly to SMEs.
|
| 741 |
+
- **Content Marketing and SEO**
|
| 742 |
+
Creating region-specific content to attract organic traffic from UAE companies searching for innovative software solutions.
|
| 743 |
+
|
| 744 |
+
### 5.5 Customer Retention and Loyalty Plan
|
| 745 |
+
- **Loyalty Points Program**
|
| 746 |
+
Customers earn points redeemable for discounts on renewals or add-on services, encouraging ongoing engagement in the UAE's competitive market.
|
| 747 |
+
- **Exclusive Content and Webinars**
|
| 748 |
+
Regular access to expert insights on AI trends tailored for UAE businesses keeps customers informed and involved.
|
| 749 |
+
- **Premium Support Packages**
|
| 750 |
+
Offering dedicated UAE-based support teams ensures fast response times, building trust and long-term relationships.
|
| 751 |
+
- **Customer Success Management**
|
| 752 |
+
Proactive outreach to help clients maximize software value supports retention and upsell opportunities within the UAE business ecosystem.
|
| 753 |
+
|
| 754 |
+
<!--CHART_DATA_START-->
|
| 755 |
+
[["Business Model","DC","Revenue Streams Breakdown","Annual",[["Subscription Fees",300000],["One-time Licensing Fees",150000],["Service Contracts",50000],["Consulting and Custom Development",50000]]],["Business Model","BG","Pricing Tier Comparison","Annual",[["Basic Package",50000],["Premium Package",120000],["Enterprise Package",250000]]]]
|
| 756 |
+
<!--CHART_DATA_END-->`
|
| 757 |
+
},
|
| 758 |
+
{
|
| 759 |
+
title: "Marketing & Growth",
|
| 760 |
+
content: `## Marketing and Growth Strategy
|
| 761 |
+
|
| 762 |
+
### 6.1 Marketing Strategy Overview
|
| 763 |
+
Our marketing approach focuses on leveraging digital channels to reach small to medium businesses across South Africa, utilizing a budget of ZAR 500,000. We will prioritize targeted online advertising, social media campaigns, and AI-driven content personalization to maximize engagement and conversion. Considering South Africa's diverse cultural landscape, our messaging will be inclusive and locally relevant, reflecting multilingual and multicultural nuances to resonate with various customer segments. Local festivals and national events will also be integrated into campaign timing to increase relevance and visibility.
|
| 764 |
+
|
| 765 |
+
### 6.2 Brand Positioning
|
| 766 |
+
Test Business Name is the leading provider of innovative AI-powered software solutions for small to medium businesses in South Africa seeking cutting-edge technology to enhance their operations.
|
| 767 |
+
|
| 768 |
+
- Our tone is professional yet approachable, emphasizing innovation, trust, and empowerment tailored to South African business values.
|
| 769 |
+
- The visual style combines modern digital aesthetics with subtle local cultural elements to create a distinctive and relatable brand presence.
|
| 770 |
+
|
| 771 |
+
### 6.3 Advertising and Promotion Channels
|
| 772 |
+
- **Google Ads:** Targeted search and display ads focusing on business-related keywords, expected reach of over 200,000 impressions monthly, with a moderate cost per click tailored to maximize ROI within the ZAR 500,000 budget.
|
| 773 |
+
- **Social Media Campaigns (LinkedIn and Facebook):** Leveraging platform-specific targeting to engage decision-makers in SMEs, expected to generate high-quality leads at a cost-effective rate.
|
| 774 |
+
- **Influencer Partnerships:** Collaborations with South African tech and business influencers to build credibility and awareness, with costs negotiated based on reach and engagement metrics.
|
| 775 |
+
- **Local Digital Business Forums:** Sponsored posts and banner placements on prominent South African SMB-oriented websites, offering niche visibility within the target market at a reasonable cost.
|
| 776 |
+
|
| 777 |
+
### 6.4 Partnerships and Referral Strategies
|
| 778 |
+
- **Local Business Associations:** Partner with chambers of commerce and SME networks, offering ZAR 100 credit per referred customer to incentivize member referrals, leveraging established trust and networks in South Africa's business community.
|
| 779 |
+
- **Technology Resellers:** Collaborate with regional software resellers who can bundle our AI-powered features, providing referral bonuses to encourage active promotion and broaden market reach.
|
| 780 |
+
- **Educational Institutions:** Engage with universities and coding bootcamps to tap into emerging entrepreneurial talent, offering discounts and referral incentives to foster early adoption and word-of-mouth promotion.
|
| 781 |
+
|
| 782 |
+
<!--CHART_DATA_START-->
|
| 783 |
+
[["Marketing and Growth Strategy","BG","Advertising Reach and Budget Allocation","Annual",[["Google Ads",200000],["Social Media Campaigns",150000],["Influencer Partnerships",100000],["Local Digital Business Forums",50000]]],["Marketing and Growth Strategy","DC","Referral Incentive Allocation","Annual",[["Local Business Associations",100],["Technology Resellers",100],["Educational Institutions",100]]]]
|
| 784 |
+
<!--CHART_DATA_END-->`
|
| 785 |
+
},
|
| 786 |
+
{
|
| 787 |
+
title: "Operations Plan",
|
| 788 |
+
content: `## Operations Plan
|
| 789 |
+
|
| 790 |
+
### 7.1 Operational Workflow Overview
|
| 791 |
+
- Client onboarding begins with initial consultation and needs assessment, ensuring solutions are tailored to small to medium business requirements.
|
| 792 |
+
- Development and customization of AI-powered software features are carried out by our team of 5 experienced developers.
|
| 793 |
+
- Quality assurance testing is conducted internally to maintain high software standards prior to deployment.
|
| 794 |
+
- Delivery and implementation of software solutions are managed digitally, allowing efficient service fulfillment across South Africa.
|
| 795 |
+
- Ongoing support and updates are provided through digital channels, ensuring client satisfaction and retention; regional hubs are utilized to reduce response times.
|
| 796 |
+
|
| 797 |
+
### 7.2 Facility and Equipment Requirements
|
| 798 |
+
- Office space rental in a central South African business district is estimated at ZAR 50,000 per month, providing a collaborative environment for the development team.
|
| 799 |
+
- High-performance computers and software licenses for 5 developers are estimated at ZAR 150,000 in total.
|
| 800 |
+
- Cloud infrastructure services for hosting and data management are budgeted at approximately ZAR 30,000 monthly.
|
| 801 |
+
- Additional equipment such as networking hardware and office furniture is expected to cost around ZAR 40,000 upfront.
|
| 802 |
+
|
| 803 |
+
### 7.3 Supply Chain and Vendor Management
|
| 804 |
+
- Key suppliers include local IT hardware vendors and international software service providers, ensuring access to quality equipment and cloud platforms.
|
| 805 |
+
- Payment terms with suppliers are typically 30-day net, allowing manageable cash flow.
|
| 806 |
+
- Delivery lead times for local hardware suppliers range from 3 to 7 days, while international software services have immediate availability online.
|
| 807 |
+
- Compliance with South African import regulations and customs duties is managed to avoid delays on imported equipment.
|
| 808 |
+
|
| 809 |
+
### 7.4 Regulatory and Compliance Requirements
|
| 810 |
+
- Business registration with the Companies and Intellectual Property Commission (CIPC) is mandatory before commencing operations.
|
| 811 |
+
- Industry-specific approvals related to software and data security must comply with the Protection of Personal Information Act (POPIA).
|
| 812 |
+
- Ongoing tax obligations include VAT registration with the South African Revenue Service (SARS) and regular filing of income tax returns.
|
| 813 |
+
- Annual financial reporting and compliance audits are conducted to maintain good standing with South African authorities.
|
| 814 |
+
|
| 815 |
+
<!--CHART_DATA_START-->
|
| 816 |
+
[["Operations Plan","DC","Facility Cost Breakdown","Monthly",[["Office Rent",50000],["Cloud Infrastructure",30000]]],["Operations Plan","DC","Equipment Investment","Annual",[["Computers and Software",150000],["Networking and Furniture",40000]]]]
|
| 817 |
+
<!--CHART_DATA_END-->`
|
| 818 |
+
},
|
| 819 |
+
{
|
| 820 |
+
title: "Management Team",
|
| 821 |
+
content: `## Management and Team
|
| 822 |
+
|
| 823 |
+
### 8.1 Core Roles and Functional Responsibilities
|
| 824 |
+
- **Chief Executive Officer (CEO)** β Responsible for overall leadership, strategic direction, and ensuring compliance with UAE business laws and regulations. Oversees company growth and stakeholder relations within the UAE market.
|
| 825 |
+
- **Chief Technology Officer (CTO)** β Leads software development and innovation, focusing on integrating AI-powered features tailored for UAE clients and compliance with local data protection standards.
|
| 826 |
+
- **Operations Manager** β Manages daily operations, coordinates between departments, and ensures adherence to UAE labor laws and operational permits.
|
| 827 |
+
- **Marketing Manager** β Develops and executes digital marketing strategies targeting small to medium businesses in the UAE, leveraging local market insights and cultural nuances.
|
| 828 |
+
- **Finance Manager** β Oversees budgeting, financial planning, and regulatory reporting in line with UAE financial regulations and funding requirements.
|
| 829 |
+
|
| 830 |
+
### 8.2 Key Hires or Specialized Team Requirements
|
| 831 |
+
- **Marketing Specialist** β Critical for navigating UAE's diverse market and digital advertising regulations, including Arabic language proficiency.
|
| 832 |
+
- **Legal Advisor** β Ensures compliance with UAE commercial laws, intellectual property rights, and contract regulations essential for technology businesses.
|
| 833 |
+
- **Customer Support Lead** β Provides localized support in both English and Arabic, addressing client needs within the UAE's multicultural environment.
|
| 834 |
+
- **AI Specialist** β Focused on developing and maintaining AI features in compliance with UAE data privacy and ethical standards.
|
| 835 |
+
|
| 836 |
+
### 8.3 Advisory Board and Strategic Mentors
|
| 837 |
+
- **Technology Industry Expert** β Provides guidance on trends and innovation specific to the UAE tech ecosystem, supporting the company's competitive edge.
|
| 838 |
+
- **UAE Business Compliance Consultant** β Advises on regulatory frameworks and helps navigate licensing, permits, and legal requirements unique to the region.
|
| 839 |
+
- **Digital Marketing Strategist** β Offers expertise in effective customer acquisition through UAE-specific digital channels and culturally relevant campaigns.
|
| 840 |
+
|
| 841 |
+
### 8.4 Organizational Structure and Reporting Lines
|
| 842 |
+
- **CEO** -> Board of Directors -> Oversees all operations and strategic partnerships within the UAE market.
|
| 843 |
+
- **CTO** -> CEO -> Leads product development and technology innovation with focus on compliance and AI integration.
|
| 844 |
+
- **Operations Manager** -> CEO -> Manages day-to-day logistics and ensures operational compliance with UAE laws.
|
| 845 |
+
- **Marketing Manager** -> CEO -> Drives customer acquisition through UAE-focused digital marketing initiatives.
|
| 846 |
+
- **Finance Manager** -> CEO -> Handles budgeting, funding, and financial regulatory reporting specific to the UAE.`
|
| 847 |
+
},
|
| 848 |
+
{
|
| 849 |
+
title: "Financial Plan & Funding",
|
| 850 |
+
content: `## Financial Plan and Funding
|
| 851 |
+
|
| 852 |
+
### 9.1 Startup and Operating Costs
|
| 853 |
+
|
| 854 |
+
1. **Startup Costs:**
|
| 855 |
+
- Equipment and software licenses are estimated at AED 150,000 to support AI-powered features.
|
| 856 |
+
- Business registration and licensing fees will cost approximately AED 20,000.
|
| 857 |
+
- Initial marketing campaigns and digital channel setup will require around AED 100,000.
|
| 858 |
+
- Initial working capital to cover unforeseen expenses is budgeted at AED 80,000.
|
| 859 |
+
|
| 860 |
+
2. **Operating Costs (Monthly or Annual):**
|
| 861 |
+
- Rent for office space is estimated at AED 60,000 annually.
|
| 862 |
+
- Salaries for the team of 5 experienced developers will total AED 360,000 per year.
|
| 863 |
+
- Utilities and internet services are expected to cost AED 24,000 annually.
|
| 864 |
+
- Ongoing marketing and sales expenses are projected at AED 40,000 annually.
|
| 865 |
+
|
| 866 |
+
### 9.2 Revenue Forecast and Growth Projections (1β3 Years)
|
| 867 |
+
- **Year 1 Projected Revenue:** AED 500,000 based on initial contracts with small to medium businesses and introduction of AI-powered software solutions.
|
| 868 |
+
- **Year 2 Projected Revenue:** AED 650,000 reflecting a 30% growth driven by expanding customer base and enhanced marketing efforts.
|
| 869 |
+
- **Year 3 Projected Revenue:** AED 845,000 with expected market expansion into additional sectors and increased product adoption.
|
| 870 |
+
|
| 871 |
+
### 9.3 Break-even Analysis (Optional)
|
| 872 |
+
The estimated break-even point is expected by Month 15 with a required revenue of AED 620,000. This assumes fixed costs such as salaries and rent remain stable, while variable costs fluctuate with sales volume. The average sale price per contract supports covering these costs over this timeline.
|
| 873 |
+
|
| 874 |
+
### 9.4 Funding Requirements and Use of Funds
|
| 875 |
+
The total funding needed is AED 500,000 to cover startup costs and initial operating expenses until the business reaches break-even. This investment will support growth and stabilize operations in the early stages.
|
| 876 |
+
|
| 877 |
+
- Research and Development: AED 150,000 to advance AI-powered feature development.
|
| 878 |
+
- Marketing and Digital Campaigns: AED 120,000 to build brand awareness and acquire customers.
|
| 879 |
+
- Staffing and Salaries: AED 180,000 to fund the team's compensation in the initial months.
|
| 880 |
+
- Working Capital: AED 50,000 to manage daily operational costs and contingencies.
|
| 881 |
+
|
| 882 |
+
### 9.5 Financial Milestones and Investor ROI Expectations
|
| 883 |
+
- Reach AED 500,000 revenue by Year 1 with initial market penetration; projected ROI: 15% by Year 3.
|
| 884 |
+
- Achieve AED 650,000 revenue by Year 2 through expanded customer acquisition; projected ROI: 25% by Year 4.
|
| 885 |
+
- Attain AED 845,000 revenue by Year 3 with market expansion and product scaling; projected ROI: 40% by Year 5.
|
| 886 |
+
- Secure a stable customer base of small to medium businesses within 18 months; projected ROI: 20% by Year 3.
|
| 887 |
+
|
| 888 |
+
<!--CHART_DATA_START-->[["Financial Plan and Funding","DC","Startup Cost Breakdown","Annual",[["Equipment and software licenses",150000],["Business registration and licensing",20000],["Marketing and digital campaigns",100000],["Working capital",80000]]],["Financial Plan and Funding","DC","Operating Cost Breakdown","Annual",[["Rent",60000],["Salaries",360000],["Utilities and internet",24000],["Marketing and sales",40000]]],["Financial Plan and Funding","LC","Projected Revenue Over Time","Annual",[["Year 1",500000],["Year 2",650000],["Year 3",845000]]]]<!--CHART_DATA_END-->`
|
| 889 |
+
}
|
| 890 |
+
];
|
| 891 |
+
|
| 892 |
+
// Create sections with content
|
| 893 |
+
sectionData.forEach(sectionInfo => {
|
| 894 |
+
this.addNewSection(sectionInfo.title);
|
| 895 |
+
const lastSection = this.sections[this.sections.length - 1];
|
| 896 |
+
const textarea = document.getElementById(`textarea-${lastSection.id}`);
|
| 897 |
+
if (textarea) {
|
| 898 |
+
textarea.value = sectionInfo.content;
|
| 899 |
+
this.updateSectionContent(lastSection.id, textarea.value);
|
| 900 |
+
}
|
| 901 |
+
});
|
| 902 |
+
|
| 903 |
+
this.updateStatus('All sections populated with business plan content!', 'success');
|
| 904 |
+
}
|
| 905 |
}
|
| 906 |
|
| 907 |
// Initialize the live PDF client when page loads
|